diff --git a/MtApi5/Events/Mt5EventTypes.cs b/MtApi5/Events/Mt5EventTypes.cs index 6fb3a3bd..bc7a8266 100644 --- a/MtApi5/Events/Mt5EventTypes.cs +++ b/MtApi5/Events/Mt5EventTypes.cs @@ -3,6 +3,7 @@ internal enum Mt5EventTypes { OnTradeTransaction = 1, - OnBookEvent = 2 + OnBookEvent = 2, + OnTick = 3 } } diff --git a/MtApi5/Events/OnTickEvent.cs b/MtApi5/Events/OnTickEvent.cs new file mode 100644 index 00000000..42994636 --- /dev/null +++ b/MtApi5/Events/OnTickEvent.cs @@ -0,0 +1,9 @@ +namespace MtApi5.Events +{ + internal class OnTickEvent + { + public MqlTick Tick { get; set; } + public string Instrument { get; set; } + public int ExpertHandle { get; set; } + } +} \ No newline at end of file diff --git a/MtApi5/Mt5Quote.cs b/MtApi5/Mt5Quote.cs index 463fa9b0..c3ec47c4 100755 --- a/MtApi5/Mt5Quote.cs +++ b/MtApi5/Mt5Quote.cs @@ -1,4 +1,5 @@ -using MTApiService; +using System; +using MTApiService; namespace MtApi5 { @@ -8,8 +9,13 @@ namespace MtApi5 public double Bid { get; } public double Ask { get; } public int ExpertHandle { get; set; } + public DateTime Time { get; set; } + public double Last { get; set; } + public ulong Volume { get; set; } +// public long TimeMsc { get; set; } +// public uint Flags { get; set; } - private Mt5Quote(string instrument, double bid, double ask) + internal Mt5Quote(string instrument, double bid, double ask) { Instrument = instrument; Bid = bid; diff --git a/MtApi5/MtApi5.csproj b/MtApi5/MtApi5.csproj index 286efa50..d83a75da 100755 --- a/MtApi5/MtApi5.csproj +++ b/MtApi5/MtApi5.csproj @@ -49,6 +49,7 @@ + diff --git a/MtApi5/MtApi5Client.cs b/MtApi5/MtApi5Client.cs index 72d48e3c..6bc71b64 100755 --- a/MtApi5/MtApi5Client.cs +++ b/MtApi5/MtApi5Client.cs @@ -40,12 +40,19 @@ namespace MtApi5 private volatile bool _isBacktestingMode; private Mt5ConnectionState _connectionState = Mt5ConnectionState.Disconnected; private int _executorHandle; + private readonly Dictionary> _mtEventHandlers = + new Dictionary>(); + #endregion #region Public Methods public MtApi5Client() { LogConfigurator.Setup(LogProfileName); + + _mtEventHandlers[Mt5EventTypes.OnBookEvent] = ReceivedOnBookEvent; + _mtEventHandlers[Mt5EventTypes.OnTick] = ReceivedOnTickEvent; + _mtEventHandlers[Mt5EventTypes.OnTradeTransaction] = ReceivedOnTradeTransaction; } /// @@ -3002,21 +3009,11 @@ namespace MtApi5 } } + private void _client_MtEventReceived(MtEvent e) { var eventType = (Mt5EventTypes)e.EventType; - - switch (eventType) - { - case Mt5EventTypes.OnTradeTransaction: - ReceivedOnTradeTransaction(e.ExpertHandle, e.Payload); - break; - case Mt5EventTypes.OnBookEvent: - ReceivedOnBookEvent(e.ExpertHandle, e.Payload); - break; - default: - throw new ArgumentOutOfRangeException(); - } + _mtEventHandlers[eventType](e.ExpertHandle, e.Payload); } private void ReceivedOnTradeTransaction(int expertHandler, string payload) @@ -3041,6 +3038,21 @@ namespace MtApi5 }); } + private void ReceivedOnTickEvent(int expertHandler, string payload) + { + var e = JsonConvert.DeserializeObject(payload); + var quote = new Mt5Quote(e.Instrument, e.Tick.bid, e.Tick.ask) + { + ExpertHandle = expertHandler, + Volume = e.Tick.volume, + Time = e.Tick.time, + Last = e.Tick.last + }; + + QuoteUpdated?.Invoke(this, quote.Instrument, quote.Bid, quote.Ask); + QuoteUpdate?.Invoke(this, new Mt5QuoteEventArgs(quote)); + } + private void Connect(string host, int port) { var client = new MtClient(host, port); diff --git a/TestClients/MtApi5TestClient/ViewModel.cs b/TestClients/MtApi5TestClient/ViewModel.cs index c309b4bd..870f43cf 100755 --- a/TestClients/MtApi5TestClient/ViewModel.cs +++ b/TestClients/MtApi5TestClient/ViewModel.cs @@ -240,7 +240,6 @@ namespace MtApi5TestClient _mtApiClient.ConnectionStateChanged += mMtApiClient_ConnectionStateChanged; _mtApiClient.QuoteAdded += mMtApiClient_QuoteAdded; _mtApiClient.QuoteRemoved += mMtApiClient_QuoteRemoved; - _mtApiClient.QuoteUpdated += mMtApiClient_QuoteUpdated; _mtApiClient.QuoteUpdate += mMtApiClient_QuoteUpdate; _mtApiClient.OnTradeTransaction += mMtApiClient_OnTradeTransaction; _mtApiClient.OnBookEvent += _mtApiClient_OnBookEvent; @@ -1427,13 +1426,13 @@ namespace MtApi5TestClient Application.Current?.Dispatcher.Invoke(action, args); } - private static void mMtApiClient_QuoteUpdated(object sender, string symbol, double bid, double ask) - { - Console.WriteLine(@"Quote: Symbol = {0}, Bid = {1}, Ask = {2}", symbol, bid, ask); - } - private void mMtApiClient_QuoteUpdate(object sender, Mt5QuoteEventArgs e) { + var q = e.Quote; + + Console.WriteLine(@"Quote: Symbol = {0}, Bid = {1}, Ask = {2}, Volume = {3}, Time = {4}, Last = {5}" + , q.Instrument, q.Bid, q.Ask, q.Volume, q.Time, q.Last); + if (_quotesMap.ContainsKey(e.Quote.ExpertHandle)) { var qvm = _quotesMap[e.Quote.ExpertHandle]; diff --git a/mq5/MtApi5.ex5 b/mq5/MtApi5.ex5 index 5f63c7ca..cee3a9de 100755 Binary files a/mq5/MtApi5.ex5 and b/mq5/MtApi5.ex5 differ diff --git a/mq5/MtApi5.mq5 b/mq5/MtApi5.mq5 index c905027c..d81a727a 100644 --- a/mq5/MtApi5.mq5 +++ b/mq5/MtApi5.mq5 @@ -1,7 +1,7 @@ #property copyright "Vyacheslav Demidyuk" #property link "" -#property version "1.5" +#property version "1.6" #property description "MtApi (MT5) connection expert" #include @@ -41,7 +41,7 @@ bool getBooleanValue(int expertHandle, int paramIndex, bool& res, string& err); #import -//#define __DEBUG_LOG__ +#define __DEBUG_LOG__ input int Port = 8228; @@ -74,7 +74,13 @@ void OnDeinit(const int reason) void OnTick() { - start(); + MqlTick last_tick; + SymbolInfoTick(Symbol(),last_tick); + + MtOnTickEvent * tick_event = new MtOnTickEvent(Symbol(), last_tick); + SendMtEvent(ON_TICK_EVENT, tick_event); + delete tick_event; + if (IsTesting()) OnTimer(); } @@ -213,21 +219,6 @@ int deinit() return (0); } -int start() -{ - MqlTick last_tick; - SymbolInfoTick(Symbol(),last_tick); - double Bid = last_tick.bid; - double Ask = last_tick.ask; - - if (!updateQuote(ExpertHandle, Symbol(), Bid, Ask, _error)) - { - Print("updateQuote: [ERROR] ", _error); - } - - return (0); -} - void OnTimer() { while(true) @@ -6980,7 +6971,8 @@ string ExecuteRequest_ChartXYToTimePrice(JSONObject *jo) enum MtEventTypes { ON_TRADE_TRANSACTION_EVENT = 1, - ON_BOOK_EVENT = 2 + ON_BOOK_EVENT = 2, + ON_TICK_EVENT = 3 }; class MtEvent @@ -7033,6 +7025,29 @@ private: string _symbol; }; +class MtOnTickEvent : public MtEvent +{ +public: + MtOnTickEvent(string symbol, const MqlTick& tick) + { + _symbol = symbol; + _tick = tick; + } + + virtual JSONObject* CreateJson() + { + JSONObject *jo = new JSONObject(); + jo.put("Tick", MqlTickToJson(_tick)); + jo.put("Instrument", new JSONString(_symbol)); + jo.put("ExpertHandle", new JSONNumber(ExpertHandle)); + return jo; + } + +private: + string _symbol; + MqlTick _tick; +}; + void SendMtEvent(MtEventTypes eventType, MtEvent* mtEvent) { #ifdef __DEBUG_LOG__