mirror of
https://github.com/vdemydiuk/mtapi.git
synced 2026-08-15 19:58:10 +00:00
Changed design of monitors for better extensibility
This commit is contained in:
@@ -0,0 +1,113 @@
|
|||||||
|
using System;
|
||||||
|
using MtApi.Monitors.Triggers;
|
||||||
|
|
||||||
|
namespace MtApi.Monitors
|
||||||
|
{
|
||||||
|
public abstract class MtMonitorBase
|
||||||
|
{
|
||||||
|
#region Fields
|
||||||
|
private volatile bool _isStarted = false;
|
||||||
|
private bool _syncTrigger;
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Properties
|
||||||
|
/// <summary>
|
||||||
|
/// ApiClient
|
||||||
|
/// </summary>
|
||||||
|
protected MtApiClient ApiClient { get; }
|
||||||
|
/// <summary>
|
||||||
|
/// Returns true if the <see cref="ApiClient"/> is connected.
|
||||||
|
/// </summary>
|
||||||
|
public bool IsMtConnected => ApiClient.ConnectionState == MtConnectionState.Connected;
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the trigger which will be used to raise the monitoring call.
|
||||||
|
/// </summary>
|
||||||
|
public IMonitorTrigger MonitorTrigger { get; }
|
||||||
|
/// <summary>
|
||||||
|
/// Returns true if the Monitor is started.
|
||||||
|
/// </summary>
|
||||||
|
public bool IsStarted { get => _isStarted; }
|
||||||
|
/// <summary>
|
||||||
|
/// If true, the <see cref="MonitorTrigger"/> will be stopped or started automatically when <see cref="Start"/> or <see cref="Stop"/> will be called.
|
||||||
|
/// <para>CAUTION: If you use the MonitorTrigger for different Monitors, this will stop all monitors if you call stop and <see cref="SyncTrigger"/> is <c>true</c>.</para>
|
||||||
|
/// </summary>
|
||||||
|
public bool SyncTrigger { get => _syncTrigger; set => _syncTrigger = value; }
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region ctor
|
||||||
|
/// <summary>
|
||||||
|
/// Default constructor for Monitors
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="apiClient">The apiClient which will be used to work with.</param>
|
||||||
|
/// <param name="monitorTrigger">The trigger which lead this Monitor to do his work.</param>
|
||||||
|
/// <param name="syncTrigger">See property <see cref="SyncTrigger"/>.</param>
|
||||||
|
public MtMonitorBase(MtApiClient apiClient, IMonitorTrigger monitorTrigger, bool syncTrigger = false)
|
||||||
|
{
|
||||||
|
ApiClient = apiClient ?? throw new ArgumentNullException(nameof(apiClient));
|
||||||
|
MonitorTrigger = monitorTrigger ?? throw new ArgumentNullException(nameof(monitorTrigger));
|
||||||
|
SyncTrigger = syncTrigger;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Methods
|
||||||
|
/// <summary>
|
||||||
|
/// Let the monitor listen to the <see cref="MonitorTrigger"/>.
|
||||||
|
/// </summary>
|
||||||
|
public virtual void Start()
|
||||||
|
{
|
||||||
|
if (!_isStarted)
|
||||||
|
{
|
||||||
|
ApiClient.ConnectionStateChanged += ApiClientConnectionStateChanged;
|
||||||
|
MonitorTrigger.Raised += MonitorTriggerRaised;
|
||||||
|
_isStarted = true;
|
||||||
|
OnStart();
|
||||||
|
if (SyncTrigger)
|
||||||
|
MonitorTrigger.Start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// Let the monitor stop listening to the <see cref="MonitorTrigger"/>.
|
||||||
|
/// </summary>
|
||||||
|
public virtual void Stop()
|
||||||
|
{
|
||||||
|
if (_isStarted)
|
||||||
|
{
|
||||||
|
MonitorTrigger.Raised -= MonitorTriggerRaised;
|
||||||
|
ApiClient.ConnectionStateChanged -= ApiClientConnectionStateChanged;
|
||||||
|
_isStarted = false;
|
||||||
|
OnStop();
|
||||||
|
if (SyncTrigger)
|
||||||
|
MonitorTrigger.Stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private void MonitorTriggerRaised(object sender, EventArgs e) => OnTriggerRaised();
|
||||||
|
private void ApiClientConnectionStateChanged(object sender, MtConnectionEventArgs e)
|
||||||
|
{
|
||||||
|
if (e.Status == MtConnectionState.Connected)
|
||||||
|
OnMtConnected();
|
||||||
|
else if (e.Status == MtConnectionState.Failed || e.Status == MtConnectionState.Disconnected)
|
||||||
|
OnMtDisconnected();
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// Will be called when <see cref="Start"/> will be called.
|
||||||
|
/// </summary>
|
||||||
|
protected virtual void OnStart() { }
|
||||||
|
/// <summary>
|
||||||
|
/// Will be called when <see cref="Stop"/> will be called.
|
||||||
|
/// </summary>
|
||||||
|
protected virtual void OnStop() { }
|
||||||
|
/// <summary>
|
||||||
|
/// Will be called when the <see cref="ApiClient"/> is successfully connected.
|
||||||
|
/// </summary>
|
||||||
|
protected virtual void OnMtConnected() { }
|
||||||
|
/// <summary>
|
||||||
|
/// Will be called when <see cref="ApiClient"/> is disconnected.
|
||||||
|
/// </summary>
|
||||||
|
protected virtual void OnMtDisconnected() { }
|
||||||
|
/// <summary>
|
||||||
|
/// Will be called when the <see cref="MonitorTrigger"/> raised.
|
||||||
|
/// </summary>
|
||||||
|
protected abstract void OnTriggerRaised();
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,56 +1,13 @@
|
|||||||
|
using MtApi.Monitors.Triggers;
|
||||||
|
|
||||||
namespace MtApi.Monitors
|
namespace MtApi.Monitors
|
||||||
{
|
{
|
||||||
public class TimeframeTradeMonitor : TradeMonitor
|
public class TimeframeTradeMonitor : TradeMonitor
|
||||||
{
|
{
|
||||||
#region Fields
|
|
||||||
private volatile bool _isStarted;
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region ctor
|
|
||||||
public TimeframeTradeMonitor(MtApiClient apiClient)
|
public TimeframeTradeMonitor(MtApiClient apiClient)
|
||||||
: base(apiClient)
|
: base(apiClient, new NewBarTrigger(apiClient))
|
||||||
{
|
{
|
||||||
apiClient.OnLastTimeBar += ApiClient_OnLastTimeBar;
|
SyncTrigger = true; //Sync-Trigger set to true, to have the same behavior as before
|
||||||
}
|
}
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Public Methods
|
|
||||||
//
|
|
||||||
// Summary:
|
|
||||||
// Gets a value indicating whether the TimeframeTradeMonitor should raise checking orders
|
|
||||||
//
|
|
||||||
// Returns:
|
|
||||||
// true if PositionMonitor should check orders
|
|
||||||
// otherwise, false.
|
|
||||||
public override bool IsStarted => _isStarted;
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Protected Methods
|
|
||||||
protected override void OnMtConnected() {}
|
|
||||||
|
|
||||||
protected override void OnMtDisconnected() {}
|
|
||||||
|
|
||||||
protected override void OnStart()
|
|
||||||
{
|
|
||||||
_isStarted = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnStop()
|
|
||||||
{
|
|
||||||
_isStarted = false;
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Private Methods
|
|
||||||
private void ApiClient_OnLastTimeBar(object sender, TimeBarArgs e)
|
|
||||||
{
|
|
||||||
if (_isStarted)
|
|
||||||
{
|
|
||||||
Check();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,90 +1,27 @@
|
|||||||
using System.Timers;
|
using System;
|
||||||
|
using MtApi.Monitors.Triggers;
|
||||||
|
|
||||||
namespace MtApi.Monitors
|
namespace MtApi.Monitors
|
||||||
{
|
{
|
||||||
public class TimerTradeMonitor : TradeMonitor
|
public class TimerTradeMonitor : TradeMonitor
|
||||||
{
|
{
|
||||||
#region Fields
|
private readonly TimeElapsedTrigger _timeElapsedTrigger;
|
||||||
private readonly Timer _timer = new Timer();
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region ctor
|
|
||||||
public TimerTradeMonitor(MtApiClient apiClient)
|
|
||||||
: base(apiClient)
|
|
||||||
{
|
|
||||||
_timer.Interval = 10000; //default interval 10 sec
|
|
||||||
_timer.Elapsed += _timer_Elapsed;
|
|
||||||
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Public Methods
|
|
||||||
//
|
|
||||||
// Summary:
|
|
||||||
// Gets or sets the interval, expressed in milliseconds, at which to check orders
|
|
||||||
//
|
|
||||||
// Returns:
|
|
||||||
// The time, in milliseconds, between checking events. The value
|
|
||||||
// must be greater than zero, and less than or equal to System.Int32.MaxValue.
|
|
||||||
// The default is 10000 milliseconds.
|
|
||||||
//
|
|
||||||
// Exceptions:
|
|
||||||
// T:System.ArgumentException:
|
|
||||||
// The interval is less than or equal to zero.-or-The interval is greater than System.Int32.MaxValue,
|
|
||||||
// and the PositionMonitor is currently started.
|
|
||||||
public double Interval
|
public double Interval
|
||||||
{
|
{
|
||||||
get { return _timer.Interval; }
|
get => _timeElapsedTrigger.Interval.TotalMilliseconds;
|
||||||
set { _timer.Interval = value; }
|
set => _timeElapsedTrigger.Interval = TimeSpan.FromMilliseconds(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
public TimerTradeMonitor(MtApiClient apiClient)
|
||||||
// Summary:
|
: this(apiClient, new TimeElapsedTrigger(TimeSpan.FromSeconds(10)))
|
||||||
// Gets a value indicating whether the PositionMonitor should raise checking orders
|
|
||||||
//
|
|
||||||
// Returns:
|
|
||||||
// true if TimerTradeMonitor should check orders
|
|
||||||
// otherwise, false.
|
|
||||||
public override bool IsStarted
|
|
||||||
{
|
{
|
||||||
get { return _timer.Enabled; }
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Protected Methods
|
}
|
||||||
protected override void OnStart()
|
public TimerTradeMonitor(MtApiClient apiClient, TimeElapsedTrigger timeElapsedTrigger)
|
||||||
|
: base(apiClient, timeElapsedTrigger)
|
||||||
{
|
{
|
||||||
if (IsMtConnected)
|
SyncTrigger = true; //Sync-Trigger set to true, to have the same behavior as before
|
||||||
{
|
_timeElapsedTrigger = timeElapsedTrigger;
|
||||||
_timer.Start();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnStop()
|
|
||||||
{
|
|
||||||
_timer.Stop();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnMtConnected()
|
|
||||||
{
|
|
||||||
_timer.Start();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnMtDisconnected()
|
|
||||||
{
|
|
||||||
_timer.Stop();
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Private Methods
|
|
||||||
private void _timer_Elapsed(object sender, ElapsedEventArgs e)
|
|
||||||
{
|
|
||||||
_timer.Elapsed -= _timer_Elapsed; //unregister from events to prevent rise condition during work with orders
|
|
||||||
|
|
||||||
Check();
|
|
||||||
|
|
||||||
_timer.Elapsed += _timer_Elapsed; //register again
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+33
-116
@@ -1,63 +1,18 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using MtApi.Monitors.Triggers;
|
||||||
|
|
||||||
namespace MtApi.Monitors
|
namespace MtApi.Monitors
|
||||||
{
|
{
|
||||||
public abstract class TradeMonitor
|
public class TradeMonitor : MtMonitorBase
|
||||||
{
|
{
|
||||||
#region Fields
|
#region Fields
|
||||||
private readonly MtApiClient _apiClient;
|
|
||||||
private List<MtOrder> _prevOrders;
|
private List<MtOrder> _prevOrders;
|
||||||
private readonly object _locker = new object();
|
private readonly object _locker = new object();
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region ctor
|
|
||||||
protected TradeMonitor(MtApiClient apiClient)
|
|
||||||
{
|
|
||||||
if (apiClient == null)
|
|
||||||
throw new ArgumentNullException(nameof(apiClient));
|
|
||||||
|
|
||||||
_apiClient = apiClient;
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Public Methods
|
|
||||||
//
|
|
||||||
// Summary:
|
|
||||||
// Gets a value indicating whether the TradeMonitor should raise checking orders
|
|
||||||
//
|
|
||||||
// Returns:
|
|
||||||
// true if TradeMonitor should check orders
|
|
||||||
// otherwise, false.
|
|
||||||
public abstract bool IsStarted { get; }
|
|
||||||
|
|
||||||
//
|
|
||||||
// Summary:
|
|
||||||
// Start checking orders.
|
|
||||||
//
|
|
||||||
public void Start()
|
|
||||||
{
|
|
||||||
_apiClient.ConnectionStateChanged += _apiClient_ConnectionStateChanged;
|
|
||||||
if (IsMtConnected)
|
|
||||||
{
|
|
||||||
InitialCheck();
|
|
||||||
}
|
|
||||||
|
|
||||||
OnStart();
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Summary:
|
|
||||||
// Stop checking orders.
|
|
||||||
//
|
|
||||||
public void Stop()
|
|
||||||
{
|
|
||||||
_apiClient.ConnectionStateChanged -= _apiClient_ConnectionStateChanged;
|
|
||||||
OnStop();
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Events
|
#region Events
|
||||||
//
|
//
|
||||||
// Summary:
|
// Summary:
|
||||||
@@ -65,17 +20,23 @@ namespace MtApi.Monitors
|
|||||||
public event EventHandler<AvailabilityOrdersEventArgs> AvailabilityOrdersChanged;
|
public event EventHandler<AvailabilityOrdersEventArgs> AvailabilityOrdersChanged;
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Protected Methods
|
#region ctor
|
||||||
|
public TradeMonitor(MtApiClient apiClient, IMonitorTrigger monitorTrigger) : base(apiClient, monitorTrigger) { }
|
||||||
|
#endregion
|
||||||
|
|
||||||
protected abstract void OnStart();
|
protected override void OnMtConnected()
|
||||||
protected abstract void OnStop();
|
{
|
||||||
|
InitialCheck();
|
||||||
protected abstract void OnMtConnected();
|
base.OnMtConnected();
|
||||||
protected abstract void OnMtDisconnected();
|
}
|
||||||
|
protected override void OnStart()
|
||||||
public bool IsMtConnected => _apiClient.ConnectionState == MtConnectionState.Connected;
|
{
|
||||||
|
if (IsMtConnected)
|
||||||
protected void Check()
|
InitialCheck();
|
||||||
|
base.OnStart();
|
||||||
|
}
|
||||||
|
protected override void OnTriggerRaised() => Check();
|
||||||
|
private void Check()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -90,92 +51,48 @@ namespace MtApi.Monitors
|
|||||||
//TODO: write error to log
|
//TODO: write error to log
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endregion
|
private void InitialCheck()
|
||||||
|
{
|
||||||
|
lock (_locker)
|
||||||
|
_prevOrders = null;
|
||||||
|
|
||||||
#region Private Methods
|
Task.Factory.StartNew(Check);
|
||||||
|
}
|
||||||
private void CheckOrders()
|
private void CheckOrders()
|
||||||
{
|
{
|
||||||
var openedOrders = new List<MtOrder>();
|
var openedOrders = new List<MtOrder>();
|
||||||
var closedOrders = new List<MtOrder>();
|
var closedOrders = new List<MtOrder>();
|
||||||
|
List<MtOrder> prevOrders;
|
||||||
|
|
||||||
// get current orders from MetaTrader
|
// get current orders from MetaTrader
|
||||||
var tradesOrders = _apiClient.GetOrders(OrderSelectSource.MODE_TRADES);
|
var tradesOrders = ApiClient.GetOrders(OrderSelectSource.MODE_TRADES);
|
||||||
|
|
||||||
List<MtOrder> prevOrders;
|
lock (_locker)
|
||||||
lock(_locker)
|
|
||||||
{
|
|
||||||
prevOrders = _prevOrders;
|
prevOrders = _prevOrders;
|
||||||
}
|
|
||||||
|
|
||||||
if (prevOrders != null) //skip checking on first load orders
|
if (prevOrders != null) //skip checking on first load orders
|
||||||
{
|
{
|
||||||
//check open orders
|
//check open orders
|
||||||
foreach (var order in tradesOrders)
|
openedOrders = tradesOrders.Where(to => prevOrders.Find(a => a.Ticket == to.Ticket) == null).ToList();
|
||||||
{
|
|
||||||
if (prevOrders.Find(a => a.Ticket == order.Ticket) == null)
|
|
||||||
{
|
|
||||||
openedOrders.Add(order);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//check closed orders
|
//check closed orders
|
||||||
var closeOrdersTemp = new List<MtOrder>();
|
var closeOrdersTemp = prevOrders.Where(po => tradesOrders.Find(a => a.Ticket == po.Ticket) == null).ToList();
|
||||||
foreach (var order in prevOrders)
|
|
||||||
{
|
|
||||||
if (tradesOrders.Find(a => a.Ticket == order.Ticket) == null)
|
|
||||||
{
|
|
||||||
closeOrdersTemp.Add(order);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (closeOrdersTemp.Count > 0)
|
if (closeOrdersTemp.Count > 0)
|
||||||
{
|
{
|
||||||
//get closed orders from history with actual values
|
//get closed orders from history with actual values
|
||||||
var historyOrders = _apiClient.GetOrders(OrderSelectSource.MODE_HISTORY);
|
var historyOrders = ApiClient.GetOrders(OrderSelectSource.MODE_HISTORY);
|
||||||
foreach (var order in closeOrdersTemp)
|
closedOrders = closeOrdersTemp.Where(cot => historyOrders.Find(a => a.Ticket == cot.Ticket) != null).ToList();
|
||||||
{
|
|
||||||
var closedOrder = historyOrders.Find(a => a.Ticket == order.Ticket);
|
|
||||||
if (closedOrder != null)
|
|
||||||
{
|
|
||||||
closedOrders.Add(closedOrder);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
lock(_locker)
|
lock (_locker)
|
||||||
{
|
|
||||||
_prevOrders = tradesOrders;
|
_prevOrders = tradesOrders;
|
||||||
}
|
|
||||||
|
|
||||||
if (openedOrders.Count > 0 || closedOrders.Count > 0)
|
if (openedOrders.Count > 0 || closedOrders.Count > 0)
|
||||||
{
|
{
|
||||||
AvailabilityOrdersChanged?.Invoke(this, new AvailabilityOrdersEventArgs(openedOrders, closedOrders));
|
AvailabilityOrdersChanged?.Invoke(this, new AvailabilityOrdersEventArgs(openedOrders, closedOrders));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void _apiClient_ConnectionStateChanged(object sender, MtConnectionEventArgs e)
|
|
||||||
{
|
|
||||||
if (e.Status == MtConnectionState.Connected)
|
|
||||||
{
|
|
||||||
InitialCheck();
|
|
||||||
OnMtConnected();
|
|
||||||
}
|
|
||||||
else if (e.Status == MtConnectionState.Failed || e.Status == MtConnectionState.Disconnected)
|
|
||||||
{
|
|
||||||
OnMtDisconnected();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void InitialCheck()
|
|
||||||
{
|
|
||||||
lock (_locker)
|
|
||||||
{
|
|
||||||
_prevOrders = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
Task.Factory.StartNew(Check);
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace MtApi.Monitors.Triggers
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Interface for triggers which can be used to trigger a <see cref="MtMonitorBase"/>.
|
||||||
|
/// </summary>
|
||||||
|
public interface IMonitorTrigger
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Event will be called if the trigger raised.
|
||||||
|
/// </summary>
|
||||||
|
event EventHandler Raised;
|
||||||
|
/// <summary>
|
||||||
|
/// Returns whether the trigger is started
|
||||||
|
/// </summary>
|
||||||
|
bool IsStarted { get; }
|
||||||
|
/// <summary>
|
||||||
|
/// Stops the trigger and prevents further calls of the <see cref="Raised"/> event.
|
||||||
|
/// </summary>
|
||||||
|
void Stop();
|
||||||
|
/// <summary>
|
||||||
|
/// Starts the trigger.
|
||||||
|
/// </summary>
|
||||||
|
void Start();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace MtApi.Monitors.Triggers
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Raises the <see cref="Raised"/> event if a bar is closed and a new one started.
|
||||||
|
/// </summary>
|
||||||
|
public class NewBarTrigger : IMonitorTrigger
|
||||||
|
{
|
||||||
|
#region Fields
|
||||||
|
private volatile bool _isStarted;
|
||||||
|
private readonly MtApiClient _apiClient;
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
public bool IsStarted => _isStarted;
|
||||||
|
public event EventHandler Raised;
|
||||||
|
public NewBarTrigger(MtApiClient apiClient)
|
||||||
|
{
|
||||||
|
_apiClient = apiClient;
|
||||||
|
_apiClient.OnLastTimeBar += _apiClient_OnLastTimeBar;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void _apiClient_OnLastTimeBar(object sender, TimeBarArgs e)
|
||||||
|
{
|
||||||
|
if (_isStarted)
|
||||||
|
Raised?.Invoke(this, EventArgs.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Start() => SetIsStarted(true);
|
||||||
|
public void Stop() => SetIsStarted(false);
|
||||||
|
private void SetIsStarted(bool value)
|
||||||
|
{
|
||||||
|
if (value != _isStarted)
|
||||||
|
{
|
||||||
|
_isStarted = value;
|
||||||
|
if (value)
|
||||||
|
_apiClient.OnLastTimeBar += _apiClient_OnLastTimeBar;
|
||||||
|
else
|
||||||
|
_apiClient.OnLastTimeBar -= _apiClient_OnLastTimeBar;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
using System;
|
||||||
|
using System.Timers;
|
||||||
|
|
||||||
|
namespace MtApi.Monitors.Triggers
|
||||||
|
{
|
||||||
|
public class TimeElapsedTrigger : IMonitorTrigger
|
||||||
|
{
|
||||||
|
readonly Timer _timer;
|
||||||
|
|
||||||
|
public event EventHandler Raised;
|
||||||
|
/// <summary>
|
||||||
|
/// Interval for raising the trigger
|
||||||
|
/// </summary>
|
||||||
|
public TimeSpan Interval
|
||||||
|
{
|
||||||
|
get => TimeSpan.FromMilliseconds(_timer.Interval);
|
||||||
|
set => _timer.Interval = value.TotalMilliseconds;
|
||||||
|
}
|
||||||
|
public bool IsStarted => _timer.Enabled;
|
||||||
|
|
||||||
|
public bool AutoReset { get => _timer.AutoReset; set => _timer.AutoReset = value; }
|
||||||
|
|
||||||
|
public TimeElapsedTrigger(TimeSpan time, bool autoReset = true)
|
||||||
|
{
|
||||||
|
_timer = new Timer(time.TotalMilliseconds);
|
||||||
|
_timer.Elapsed += _timer_Elapsed;
|
||||||
|
AutoReset = autoReset;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void _timer_Elapsed(object sender, ElapsedEventArgs e)
|
||||||
|
{
|
||||||
|
_timer.Elapsed -= _timer_Elapsed;
|
||||||
|
Raised?.Invoke(this, EventArgs.Empty);
|
||||||
|
_timer.Elapsed += _timer_Elapsed;
|
||||||
|
}
|
||||||
|
public void Stop() => _timer.Stop();
|
||||||
|
|
||||||
|
public void Start() => _timer.Start();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -76,6 +76,10 @@
|
|||||||
<Compile Include="EnumTerminalInfoInteger.cs" />
|
<Compile Include="EnumTerminalInfoInteger.cs" />
|
||||||
<Compile Include="FlagFontStyle.cs" />
|
<Compile Include="FlagFontStyle.cs" />
|
||||||
<Compile Include="Monitors\AvailabilityOrdersEventArgs.cs" />
|
<Compile Include="Monitors\AvailabilityOrdersEventArgs.cs" />
|
||||||
|
<Compile Include="Monitors\MtMonitorBase.cs" />
|
||||||
|
<Compile Include="Monitors\Triggers\ITrigger.cs" />
|
||||||
|
<Compile Include="Monitors\Triggers\NewBarTrigger.cs" />
|
||||||
|
<Compile Include="Monitors\Triggers\TimeElapsedTrigger.cs" />
|
||||||
<Compile Include="MqlRates.cs" />
|
<Compile Include="MqlRates.cs" />
|
||||||
<Compile Include="MqlTick.cs" />
|
<Compile Include="MqlTick.cs" />
|
||||||
<Compile Include="MtChartEvent.cs" />
|
<Compile Include="MtChartEvent.cs" />
|
||||||
|
|||||||
Reference in New Issue
Block a user