Refactored MtApi4 (MT4) for working with new architecture

This commit is contained in:
Viacheslav Demydiuk
2024-06-16 13:57:50 +03:00
parent 6dd5e0190f
commit a830dc11a6
89 changed files with 1648 additions and 2390 deletions
+4 -12
View File
@@ -1,22 +1,14 @@
using System;
using System.Collections.Generic;
namespace MtApi.Monitors
namespace MtApi.Monitors
{
public class AvailabilityOrdersEventArgs : EventArgs
public class AvailabilityOrdersEventArgs(List<MtOrder> opened, List<MtOrder> closed) : EventArgs
{
public AvailabilityOrdersEventArgs(List<MtOrder> opened, List<MtOrder> closed)
{
Opened = opened;
Closed = closed;
}
/// <summary>
/// Contains all newly opened orders since the last time the monitor checked the open orders.
/// </summary>
public List<MtOrder> Opened { get; private set; }
public List<MtOrder> Opened { get; private set; } = opened;
/// <summary>
/// Contains all newly closed orders since the last time the monitor checked the open orders.
/// </summary>
public List<MtOrder> Closed { get; private set; }
public List<MtOrder> Closed { get; private set; } = closed;
}
}
+2 -2
View File
@@ -80,8 +80,8 @@ namespace MtApi.Monitors
MonitorTrigger.Stop();
}
}
private void MonitorTriggerRaised(object sender, EventArgs e) => OnTriggerRaised();
private void ApiClientConnectionStateChanged(object sender, MtConnectionEventArgs e)
private void MonitorTriggerRaised(object? sender, EventArgs e) => OnTriggerRaised();
private void ApiClientConnectionStateChanged(object? sender, MtConnectionEventArgs e)
{
if (e.Status == MtConnectionState.Connected)
OnMtConnected();
@@ -1,10 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MtApi.Monitors
namespace MtApi.Monitors
{
public class ModifiedOrdersEventArgs : EventArgs
{
@@ -1,16 +1,11 @@
using MtApi.Monitors.Triggers;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MtApi.Monitors
{
public class ModifiedOrdersMonitor : MtMonitorBase
{
#region Fields
private List<MtOrder> _lastOrders = null;
private List<MtOrder>? _lastOrders;
#endregion
@@ -25,7 +20,7 @@ namespace MtApi.Monitors
/// <summary>
/// Will be raised when this monitor detects changes on open orders
/// </summary>
public event EventHandler<ModifiedOrdersEventArgs> OrdersModified;
public event EventHandler<ModifiedOrdersEventArgs>? OrdersModified;
#endregion
#region ctor
@@ -41,7 +36,7 @@ namespace MtApi.Monitors
/// Requests all current open orders
/// </summary>
/// <returns></returns>
private List<MtOrder> GetOrders() => IsMtConnected ? ApiClient.GetOrders(OrderSelectSource.MODE_TRADES) : null;
private List<MtOrder>? GetOrders() => IsMtConnected ? ApiClient.GetOrders(OrderSelectSource.MODE_TRADES) : null;
protected override void OnTriggerRaised()
{
if(_lastOrders == null)
@@ -49,19 +44,23 @@ namespace MtApi.Monitors
_lastOrders = GetOrders();
return;
}
List<MtOrder> currentOrders = GetOrders();
var currentOrders = GetOrders() ?? ([]);
OrderModifiedTypes omt = OrderModifiedTypes;
var mtModifiedOrders = currentOrders
.Select(co => new MtModifiedOrder(_lastOrders.FirstOrDefault(x => x.Ticket == co.Ticket), co))
.ToList();
List<MtModifiedOrder> modifiedOrders = new List<MtModifiedOrder>();
List<MtModifiedOrder> modifiedOrders = new();
modifiedOrders.AddRange(GetMtModifiedOrdersWithModType(mtModifiedOrders, omt, OrderModifiedTypes.TakeProfit)); //If the takeprofit were changed between both calls
modifiedOrders.AddRange(GetMtModifiedOrdersWithModType(mtModifiedOrders, omt, OrderModifiedTypes.StopLoss)); //If the stoploss were changed between both calls
modifiedOrders.AddRange(GetMtModifiedOrdersWithModType(mtModifiedOrders, omt, OrderModifiedTypes.Operation)); //If an order changed from limit / stop order to an open order
if (modifiedOrders.Count > 0)
OrdersModified?.Invoke(this, new ModifiedOrdersEventArgs(modifiedOrders));
_lastOrders = currentOrders;
}
private static IEnumerable<MtModifiedOrder> GetMtModifiedOrdersWithModType(IEnumerable<MtModifiedOrder> orders, OrderModifiedTypes globalSearchFlag, OrderModifiedTypes modifiedType)
=> globalSearchFlag.HasFlag(modifiedType) ? orders.Where(o => o.ModifyType.HasFlag(modifiedType)) : new List<MtModifiedOrder>();
}
@@ -1,21 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MtApi.Monitors
namespace MtApi.Monitors
{
public class MtModifiedOrder
{
/// <summary>
/// The order in its old state (before the changes)
/// </summary>
public MtOrder OldOrder { get; }
public MtOrder? OldOrder { get; }
/// <summary>
/// The order in its new state (after the changes)
/// </summary>
public MtOrder NewOrder { get; }
public MtOrder? NewOrder { get; }
/// <summary>
/// The changes found by this instance
/// </summary>
@@ -25,7 +19,7 @@ namespace MtApi.Monitors
/// </summary>
/// <param name="oldOrder">The order in its old state (before the changes)</param>
/// <param name="newOrder">The order in its new state (after the changes)</param>
public MtModifiedOrder(MtOrder oldOrder, MtOrder newOrder)
public MtModifiedOrder(MtOrder? oldOrder, MtOrder ?newOrder)
{
if (oldOrder != null && newOrder != null && oldOrder.Ticket != newOrder.Ticket)
throw new ArgumentException(nameof(oldOrder) + " and " + nameof(newOrder) + " need to have the same ticket id");
@@ -1,10 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MtApi.Monitors
namespace MtApi.Monitors
{
[Flags]
public enum OrderModifiedTypes
+1 -2
View File
@@ -1,5 +1,4 @@
using System;
using MtApi.Monitors.Triggers;
using MtApi.Monitors.Triggers;
namespace MtApi.Monitors
{
+7 -11
View File
@@ -1,23 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using MtApi.Monitors.Triggers;
using MtApi.Monitors.Triggers;
namespace MtApi.Monitors
{
public class TradeMonitor : MtMonitorBase
{
#region Fields
private List<MtOrder> _prevOrders;
private readonly object _locker = new object();
private List<MtOrder>? _prevOrders;
private readonly object _locker = new();
#endregion
#region Events
//
// Summary:
// Occurs when orders are opened or closed.
public event EventHandler<AvailabilityOrdersEventArgs> AvailabilityOrdersChanged;
public event EventHandler<AvailabilityOrdersEventArgs>? AvailabilityOrdersChanged;
#endregion
#region ctor
@@ -73,10 +69,10 @@ namespace MtApi.Monitors
{
var openedOrders = new List<MtOrder>();
var closedOrders = new List<MtOrder>();
List<MtOrder> prevOrders;
List<MtOrder>? prevOrders;
// get current orders from MetaTrader
var tradesOrders = ApiClient.GetOrders(OrderSelectSource.MODE_TRADES);
var tradesOrders = ApiClient.GetOrders(OrderSelectSource.MODE_TRADES) ?? [];
lock (_locker)
prevOrders = _prevOrders;
@@ -92,7 +88,7 @@ namespace MtApi.Monitors
if (closeOrdersTemp.Count > 0)
{
//get closed orders from history with actual values
var historyOrders = ApiClient.GetOrders(OrderSelectSource.MODE_HISTORY);
var historyOrders = ApiClient.GetOrders(OrderSelectSource.MODE_HISTORY) ?? [];
closedOrders = closeOrdersTemp.Where(cot => historyOrders.Find(a => a.Ticket == cot.Ticket) != null).ToList();
}
}
+1 -3
View File
@@ -1,6 +1,4 @@
using System;
namespace MtApi.Monitors.Triggers
namespace MtApi.Monitors.Triggers
{
/// <summary>
/// Interface for triggers which can be used to trigger a <see cref="MtMonitorBase"/>.
+3 -5
View File
@@ -1,6 +1,4 @@
using System;
namespace MtApi.Monitors.Triggers
namespace MtApi.Monitors.Triggers
{
/// <summary>
/// Raises the <see cref="Raised"/> event if a bar is closed and a new one started.
@@ -23,7 +21,7 @@ namespace MtApi.Monitors.Triggers
/// <summary>
/// Event will be called if the trigger raised.
/// </summary>
public event EventHandler Raised;
public event EventHandler? Raised;
#endregion
#region ctor
@@ -46,7 +44,7 @@ namespace MtApi.Monitors.Triggers
#endregion
#region Private methods
private void _apiClient_OnLastTimeBar(object sender, TimeBarArgs e)
private void _apiClient_OnLastTimeBar(object? sender, TimeBarArgs e)
{
if (_isStarted)
Raised?.Invoke(this, EventArgs.Empty);
@@ -1,12 +1,11 @@
using System;
using System.Timers;
using System.Timers;
namespace MtApi.Monitors.Triggers
{
public class TimeElapsedTrigger : IMonitorTrigger
{
#region Fields
readonly Timer _timer;
readonly System.Timers.Timer _timer;
#endregion
#region Properties
@@ -34,7 +33,7 @@ namespace MtApi.Monitors.Triggers
/// <summary>
/// Returns true if the trigger is started, otherwise false
/// </summary>
public event EventHandler Raised;
public event EventHandler? Raised;
#endregion
#region ctor
@@ -45,7 +44,7 @@ namespace MtApi.Monitors.Triggers
/// <param name="autoReset">If true, the trigger will raise continuosly after elapsed <see cref="Interval"/>, otherwise the trigger will raise only once after elapsed <see cref="Interval"/>.</param>
public TimeElapsedTrigger(TimeSpan time, bool autoReset = true)
{
_timer = new Timer(time.TotalMilliseconds);
_timer = new System.Timers.Timer(time.TotalMilliseconds);
_timer.Elapsed += _timer_Elapsed;
AutoReset = autoReset;
}
@@ -63,7 +62,7 @@ namespace MtApi.Monitors.Triggers
#endregion
#region private methods
private void _timer_Elapsed(object sender, ElapsedEventArgs e)
private void _timer_Elapsed(object? sender, ElapsedEventArgs e)
{
_timer.Elapsed -= _timer_Elapsed;
Raised?.Invoke(this, EventArgs.Empty);