mirror of
https://github.com/vdemydiuk/mtapi.git
synced 2026-08-17 20:58:11 +00:00
Refactored MtApi4 (MT4) for working with new architecture
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,5 +1,4 @@
|
||||
using System;
|
||||
using MtApi.Monitors.Triggers;
|
||||
using MtApi.Monitors.Triggers;
|
||||
|
||||
namespace MtApi.Monitors
|
||||
{
|
||||
|
||||
@@ -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,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"/>.
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user