using MtApi.Monitors.Triggers; namespace MtApi.Monitors { public class TradeMonitor : MtMonitorBase { #region Fields private List? _prevOrders; private readonly object _locker = new(); #endregion #region Events // // Summary: // Occurs when orders are opened or closed. public event EventHandler? AvailabilityOrdersChanged; #endregion #region ctor /// /// Constructor for initializing an instance of . /// /// The which will be used to communicate with MetaTrader. /// The custom instance of which will be used to trigger this instance of . public TradeMonitor(MtApiClient apiClient, IMonitorTrigger monitorTrigger) : base(apiClient, monitorTrigger) { } #endregion protected override void OnMtConnected() { InitialCheck(); base.OnMtConnected(); } protected override void OnStart() { if (IsMtConnected) InitialCheck(); base.OnStart(); } protected override void OnTriggerRaised() { if (IsMtConnected) Check(); } private void Check() { try { CheckOrders(); } catch (MtConnectionException) { //TODO: write error to log } catch (MtExecutionException) { //TODO: write error to log } } private void InitialCheck() { lock (_locker) _prevOrders = null; Task.Factory.StartNew(Check); } private void CheckOrders() { var openedOrders = new List(); var closedOrders = new List(); List? prevOrders; // get current orders from MetaTrader var tradesOrders = ApiClient.GetOrders(OrderSelectSource.MODE_TRADES) ?? []; lock (_locker) prevOrders = _prevOrders; if (prevOrders != null) //skip checking on first load orders { //check open orders openedOrders = tradesOrders.Where(to => prevOrders.Find(a => a.Ticket == to.Ticket) == null).ToList(); //check closed orders var closeOrdersTemp = prevOrders.Where(po => tradesOrders.Find(a => a.Ticket == po.Ticket) == null).ToList(); if (closeOrdersTemp.Count > 0) { //get closed orders from history with actual values var historyOrders = ApiClient.GetOrders(OrderSelectSource.MODE_HISTORY) ?? []; closedOrders = closeOrdersTemp.Where(cot => historyOrders.Find(a => a.Ticket == cot.Ticket) != null).ToList(); } } lock (_locker) _prevOrders = tradesOrders; if (openedOrders.Count > 0 || closedOrders.Count > 0) { AvailabilityOrdersChanged?.Invoke(this, new AvailabilityOrdersEventArgs(openedOrders, closedOrders)); } } } }