diff --git a/MtApi/MtApiClient.cs b/MtApi/MtApiClient.cs index bb1b947a..cf01f89a 100755 --- a/MtApi/MtApiClient.cs +++ b/MtApi/MtApiClient.cs @@ -1403,11 +1403,6 @@ namespace MtApi return response != null ? response.Rates : null; } - private void BaBacktestingReady() - { - SendCommand(MtCommandType.BacktestingReady, null); - } - #endregion #region Checkup @@ -1464,7 +1459,7 @@ namespace MtApi IsBacktestingMode = IsTesting(); if (IsBacktestingMode) { - BaBacktestingReady(); + BacktestingReady(); } } @@ -1622,6 +1617,10 @@ namespace MtApi OnLastTimeBar.FireEventAsync(this, new TimeBarArgs(timeBar)); } + private void BacktestingReady() + { + SendCommand(MtCommandType.BacktestingReady, null); + } #endregion #region Events diff --git a/MtApi5/MtCommandType.cs b/MtApi5/Mt5CommandType.cs similarity index 93% rename from MtApi5/MtCommandType.cs rename to MtApi5/Mt5CommandType.cs index 754daa9f..980e0b07 100755 --- a/MtApi5/MtCommandType.cs +++ b/MtApi5/Mt5CommandType.cs @@ -5,7 +5,7 @@ using System.Text; namespace MtApi5 { - enum Mt5CommandType + internal enum Mt5CommandType { //NoCommand = 0 @@ -104,6 +104,10 @@ namespace MtApi5 //CTrade PositionClose = 64, - PositionOpen = 65 + PositionOpen = 65, + + //Backtesting + BacktestingReady = 66, + IsTesting = 67 } } diff --git a/MtApi5/MtApi5.csproj b/MtApi5/MtApi5.csproj index 632c4e0a..aedabacf 100755 --- a/MtApi5/MtApi5.csproj +++ b/MtApi5/MtApi5.csproj @@ -55,7 +55,7 @@ - + diff --git a/MtApi5/MtApi5Client.cs b/MtApi5/MtApi5Client.cs index 7613900b..b1770ade 100755 --- a/MtApi5/MtApi5Client.cs +++ b/MtApi5/MtApi5Client.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Text; using MTApiService; using System.Collections; @@ -25,6 +24,12 @@ namespace MtApi5 public delegate void QuoteHandler(object sender, string symbol, double bid, double ask); + + #region Private Fields + private readonly MtClient _client = new MtClient(); + private volatile bool _isBacktestingMode = false; + #endregion + #region Public Methods public MtApi5Client() { @@ -83,6 +88,14 @@ namespace MtApi5 return quotes != null ? (from q in quotes select q.Parse()) : null; } + /// + ///Checks if the Expert Advisor runs in the testing mode.. + /// + public bool IsTesting() + { + return SendCommand(Mt5CommandType.IsTesting, null); + } + #region Trading functions /// @@ -105,7 +118,7 @@ namespace MtApi5 var commandParameters = request.ToArrayList(); - string strResult = sendCommand(Mt5CommandType.OrderSend, commandParameters); + var strResult = SendCommand(Mt5CommandType.OrderSend, commandParameters); return strResult.ParseResult(PARAM_SEPARATOR, out result); } @@ -129,7 +142,7 @@ namespace MtApi5 { var commandParameters = new ArrayList { (int)action, symbol, volume, price }; - string strResult = sendCommand(Mt5CommandType.OrderCalcMargin, commandParameters); + var strResult = SendCommand(Mt5CommandType.OrderCalcMargin, commandParameters); return strResult.ParseResult(PARAM_SEPARATOR, out margin); } @@ -154,7 +167,7 @@ namespace MtApi5 { var commandParameters = new ArrayList { (int)action, symbol, volume, price_open, price_close }; - string strResult = sendCommand(Mt5CommandType.OrderCalcProfit, commandParameters); + var strResult = SendCommand(Mt5CommandType.OrderCalcProfit, commandParameters); return strResult.ParseResult(PARAM_SEPARATOR, out profit); } @@ -181,7 +194,7 @@ namespace MtApi5 var commandParameters = request.ToArrayList(); - string strResult = sendCommand(Mt5CommandType.OrderSend, commandParameters); + var strResult = SendCommand(Mt5CommandType.OrderSend, commandParameters); return strResult.ParseResult(PARAM_SEPARATOR, out result); } @@ -191,7 +204,7 @@ namespace MtApi5 /// public int PositionsTotal() { - return sendCommand(Mt5CommandType.PositionsTotal, null); + return SendCommand(Mt5CommandType.PositionsTotal, null); } /// @@ -202,7 +215,7 @@ namespace MtApi5 { var commandParameters = new ArrayList { index }; - return sendCommand(Mt5CommandType.PositionGetSymbol, commandParameters); + return SendCommand(Mt5CommandType.PositionGetSymbol, commandParameters); } /// @@ -213,7 +226,7 @@ namespace MtApi5 { var commandParameters = new ArrayList { symbol }; - return sendCommand(Mt5CommandType.PositionSelect, commandParameters); + return SendCommand(Mt5CommandType.PositionSelect, commandParameters); } /// @@ -224,7 +237,7 @@ namespace MtApi5 { var commandParameters = new ArrayList { (int)property_id }; - return sendCommand(Mt5CommandType.PositionGetDouble, commandParameters); + return SendCommand(Mt5CommandType.PositionGetDouble, commandParameters); } /// @@ -235,7 +248,7 @@ namespace MtApi5 { var commandParameters = new ArrayList { (int)property_id }; - return sendCommand(Mt5CommandType.PositionGetInteger, commandParameters); + return SendCommand(Mt5CommandType.PositionGetInteger, commandParameters); } /// @@ -246,7 +259,7 @@ namespace MtApi5 { var commandParameters = new ArrayList { (int)property_id }; - return sendCommand(Mt5CommandType.PositionGetString, commandParameters); + return SendCommand(Mt5CommandType.PositionGetString, commandParameters); } /// @@ -254,7 +267,7 @@ namespace MtApi5 /// public int OrdersTotal() { - return sendCommand(Mt5CommandType.OrdersTotal, null); + return SendCommand(Mt5CommandType.OrdersTotal, null); } /// @@ -265,7 +278,7 @@ namespace MtApi5 { var commandParameters = new ArrayList { index }; - return sendCommand(Mt5CommandType.OrderGetTicket, commandParameters); + return SendCommand(Mt5CommandType.OrderGetTicket, commandParameters); } /// @@ -276,7 +289,7 @@ namespace MtApi5 { var commandParameters = new ArrayList { ticket }; - return sendCommand(Mt5CommandType.OrderSelect, commandParameters); + return SendCommand(Mt5CommandType.OrderSelect, commandParameters); } /// @@ -287,7 +300,7 @@ namespace MtApi5 { var commandParameters = new ArrayList { (int)property_id }; - return sendCommand(Mt5CommandType.OrderGetDouble, commandParameters); + return SendCommand(Mt5CommandType.OrderGetDouble, commandParameters); } /// @@ -298,7 +311,7 @@ namespace MtApi5 { var commandParameters = new ArrayList { (int)property_id }; - return sendCommand(Mt5CommandType.OrderGetInteger, commandParameters); + return SendCommand(Mt5CommandType.OrderGetInteger, commandParameters); } /// @@ -309,7 +322,7 @@ namespace MtApi5 { var commandParameters = new ArrayList { (int)property_id }; - return sendCommand(Mt5CommandType.OrderGetString, commandParameters); + return SendCommand(Mt5CommandType.OrderGetString, commandParameters); } /// @@ -321,7 +334,7 @@ namespace MtApi5 { var commandParameters = new ArrayList { Mt5TimeConverter.ConvertToMtTime(from_date), Mt5TimeConverter.ConvertToMtTime(to_date) }; - return sendCommand(Mt5CommandType.HistorySelect, commandParameters); + return SendCommand(Mt5CommandType.HistorySelect, commandParameters); } /// @@ -332,7 +345,7 @@ namespace MtApi5 { var commandParameters = new ArrayList { position_id }; - return sendCommand(Mt5CommandType.HistorySelectByPosition, commandParameters); + return SendCommand(Mt5CommandType.HistorySelectByPosition, commandParameters); } /// @@ -343,7 +356,7 @@ namespace MtApi5 { var commandParameters = new ArrayList { ticket }; - return sendCommand(Mt5CommandType.HistoryOrderSelect, commandParameters); + return SendCommand(Mt5CommandType.HistoryOrderSelect, commandParameters); } /// @@ -351,7 +364,7 @@ namespace MtApi5 /// public int HistoryOrdersTotal() { - return sendCommand(Mt5CommandType.HistoryOrdersTotal, null); + return SendCommand(Mt5CommandType.HistoryOrdersTotal, null); } /// @@ -362,7 +375,7 @@ namespace MtApi5 { var commandParameters = new ArrayList { index }; - return sendCommand(Mt5CommandType.HistoryOrderGetTicket, commandParameters); + return SendCommand(Mt5CommandType.HistoryOrderGetTicket, commandParameters); } /// @@ -374,7 +387,7 @@ namespace MtApi5 { var commandParameters = new ArrayList { ticket_number, (int)property_id }; - return sendCommand(Mt5CommandType.HistoryOrderGetDouble, commandParameters); + return SendCommand(Mt5CommandType.HistoryOrderGetDouble, commandParameters); } /// @@ -386,7 +399,7 @@ namespace MtApi5 { var commandParameters = new ArrayList { ticket_number, (int)property_id }; - return sendCommand(Mt5CommandType.HistoryOrderGetInteger, commandParameters); + return SendCommand(Mt5CommandType.HistoryOrderGetInteger, commandParameters); } /// @@ -398,7 +411,7 @@ namespace MtApi5 { var commandParameters = new ArrayList { ticket_number, (int)property_id }; - return sendCommand(Mt5CommandType.HistoryOrderGetString, commandParameters); + return SendCommand(Mt5CommandType.HistoryOrderGetString, commandParameters); } /// @@ -409,7 +422,7 @@ namespace MtApi5 { var commandParameters = new ArrayList { ticket }; - return sendCommand(Mt5CommandType.HistoryDealSelect, commandParameters); + return SendCommand(Mt5CommandType.HistoryDealSelect, commandParameters); } /// @@ -417,7 +430,7 @@ namespace MtApi5 /// public int HistoryDealsTotal() { - return sendCommand(Mt5CommandType.HistoryDealsTotal, null); + return SendCommand(Mt5CommandType.HistoryDealsTotal, null); } /// @@ -428,7 +441,7 @@ namespace MtApi5 { var commandParameters = new ArrayList { index }; - return sendCommand(Mt5CommandType.HistoryDealGetTicket, commandParameters); + return SendCommand(Mt5CommandType.HistoryDealGetTicket, commandParameters); } /// @@ -440,7 +453,7 @@ namespace MtApi5 { var commandParameters = new ArrayList { ticket_number, property_id }; - return sendCommand(Mt5CommandType.HistoryDealGetDouble, commandParameters); + return SendCommand(Mt5CommandType.HistoryDealGetDouble, commandParameters); } /// @@ -452,7 +465,7 @@ namespace MtApi5 { var commandParameters = new ArrayList { ticket_number, property_id }; - return sendCommand(Mt5CommandType.HistoryDealGetInteger, commandParameters); + return SendCommand(Mt5CommandType.HistoryDealGetInteger, commandParameters); } /// @@ -464,7 +477,7 @@ namespace MtApi5 { var commandParameters = new ArrayList { ticket_number, property_id }; - return sendCommand(Mt5CommandType.HistoryDealGetString, commandParameters); + return SendCommand(Mt5CommandType.HistoryDealGetString, commandParameters); } /// @@ -472,7 +485,7 @@ namespace MtApi5 /// public bool OrderCloseAll() { - return sendCommand(Mt5CommandType.OrderCloseAll, null); + return SendCommand(Mt5CommandType.OrderCloseAll, null); } /// @@ -483,7 +496,7 @@ namespace MtApi5 { var commandParameters = new ArrayList { ticket}; - return sendCommand(Mt5CommandType.PositionClose, commandParameters); + return SendCommand(Mt5CommandType.PositionClose, commandParameters); } /// @@ -501,7 +514,7 @@ namespace MtApi5 { var commandParameters = new ArrayList { symbol, (int) orderType, volume, price, sl, tp, comment }; - return sendCommand(Mt5CommandType.PositionOpen, commandParameters); + return SendCommand(Mt5CommandType.PositionOpen, commandParameters); } #endregion @@ -515,7 +528,7 @@ namespace MtApi5 { var commandParameters = new ArrayList { (int)property_id }; - return sendCommand(Mt5CommandType.AccountInfoDouble, commandParameters); + return SendCommand(Mt5CommandType.AccountInfoDouble, commandParameters); } /// @@ -526,7 +539,7 @@ namespace MtApi5 { var commandParameters = new ArrayList { (int)property_id }; - return sendCommand(Mt5CommandType.AccountInfoInteger, commandParameters); + return SendCommand(Mt5CommandType.AccountInfoInteger, commandParameters); } /// @@ -537,7 +550,7 @@ namespace MtApi5 { var commandParameters = new ArrayList { (int)property_id }; - return sendCommand(Mt5CommandType.AccountInfoString, commandParameters); + return SendCommand(Mt5CommandType.AccountInfoString, commandParameters); } #endregion @@ -552,7 +565,7 @@ namespace MtApi5 { var commandParameters = new ArrayList { symbol_name, (int)timeframe, (int)prop_id }; - return sendCommand(Mt5CommandType.SeriesInfoInteger, commandParameters); + return SendCommand(Mt5CommandType.SeriesInfoInteger, commandParameters); } /// @@ -564,7 +577,7 @@ namespace MtApi5 { var commandParameters = new ArrayList { symbol_name, (int)timeframe }; - return sendCommand(Mt5CommandType.Bars, commandParameters); + return SendCommand(Mt5CommandType.Bars, commandParameters); } /// @@ -578,7 +591,7 @@ namespace MtApi5 { var commandParameters = new ArrayList { symbol_name, (int)timeframe, Mt5TimeConverter.ConvertToMtTime(start_time), Mt5TimeConverter.ConvertToMtTime(stop_time) }; - return sendCommand(Mt5CommandType.Bars2, commandParameters); + return SendCommand(Mt5CommandType.Bars2, commandParameters); } /// @@ -589,7 +602,7 @@ namespace MtApi5 { var commandParameters = new ArrayList { indicator_handle }; - return sendCommand(Mt5CommandType.BarsCalculated, commandParameters); + return SendCommand(Mt5CommandType.BarsCalculated, commandParameters); } /// @@ -603,8 +616,8 @@ namespace MtApi5 public int CopyBuffer(int indicator_handle, int buffer_num, int start_pos, int count, out double[] buffer) { var commandParameters = new ArrayList { indicator_handle, buffer_num, start_pos, count }; - buffer = sendCommand(Mt5CommandType.CopyBuffer, commandParameters); - return buffer != null ? buffer.Length : 0; + buffer = SendCommand(Mt5CommandType.CopyBuffer, commandParameters); + return buffer?.Length ?? 0; } /// @@ -618,8 +631,8 @@ namespace MtApi5 public int CopyBuffer(int indicator_handle, int buffer_num, DateTime start_time, int count, out double[] buffer) { var commandParameters = new ArrayList { indicator_handle, buffer_num, Mt5TimeConverter.ConvertToMtTime(start_time), count }; - buffer = sendCommand(Mt5CommandType.CopyBuffer1, commandParameters); - return buffer != null ? buffer.Length : 0; + buffer = SendCommand(Mt5CommandType.CopyBuffer1, commandParameters); + return buffer?.Length ?? 0; } /// @@ -633,8 +646,8 @@ namespace MtApi5 public int CopyBuffer(int indicator_handle, int buffer_num, DateTime start_time, DateTime stop_time, out double[] buffer) { var commandParameters = new ArrayList { indicator_handle, buffer_num, Mt5TimeConverter.ConvertToMtTime(start_time), Mt5TimeConverter.ConvertToMtTime(stop_time) }; - buffer = sendCommand(Mt5CommandType.CopyBuffer1, commandParameters); - return buffer != null ? buffer.Length : 0; + buffer = SendCommand(Mt5CommandType.CopyBuffer1, commandParameters); + return buffer?.Length ?? 0; } /// @@ -651,7 +664,7 @@ namespace MtApi5 rates_array = null; - var retVal = sendCommand(Mt5CommandType.CopyRates, commandParameters); + var retVal = SendCommand(Mt5CommandType.CopyRates, commandParameters); if (retVal != null) { rates_array = new MqlRates[retVal.Length]; @@ -668,7 +681,7 @@ namespace MtApi5 } } - return rates_array != null ? rates_array.Length : 0; + return rates_array?.Length ?? 0; } /// @@ -685,7 +698,7 @@ namespace MtApi5 rates_array = null; - var retVal = sendCommand(Mt5CommandType.CopyRates1, commandParameters); + var retVal = SendCommand(Mt5CommandType.CopyRates1, commandParameters); if (retVal != null) { rates_array = new MqlRates[retVal.Length]; @@ -702,7 +715,7 @@ namespace MtApi5 } } - return rates_array != null ? rates_array.Length : 0; + return rates_array?.Length ?? 0; } /// @@ -719,7 +732,7 @@ namespace MtApi5 rates_array = null; - var retVal = sendCommand(Mt5CommandType.CopyRates2, commandParameters); + var retVal = SendCommand(Mt5CommandType.CopyRates2, commandParameters); if (retVal != null) { rates_array = new MqlRates[retVal.Length]; @@ -736,7 +749,7 @@ namespace MtApi5 } } - return rates_array != null ? rates_array.Length : 0; + return rates_array?.Length ?? 0; } /// @@ -753,7 +766,7 @@ namespace MtApi5 time_array = null; - var retVal = sendCommand(Mt5CommandType.CopyTime, commandParameters); + var retVal = SendCommand(Mt5CommandType.CopyTime, commandParameters); if (retVal != null) { time_array = new DateTime[retVal.Length]; @@ -763,7 +776,7 @@ namespace MtApi5 } } - return time_array != null ? time_array.Length : 0; + return time_array?.Length ?? 0; } /// @@ -780,7 +793,7 @@ namespace MtApi5 time_array = null; - var retVal = sendCommand(Mt5CommandType.CopyTime1, commandParameters); + var retVal = SendCommand(Mt5CommandType.CopyTime1, commandParameters); if (retVal != null) { time_array = new DateTime[retVal.Length]; @@ -790,7 +803,7 @@ namespace MtApi5 } } - return time_array != null ? time_array.Length : 0; + return time_array?.Length ?? 0; } /// @@ -807,7 +820,7 @@ namespace MtApi5 time_array = null; - var retVal = sendCommand(Mt5CommandType.CopyTime2, commandParameters); + var retVal = SendCommand(Mt5CommandType.CopyTime2, commandParameters); if (retVal != null) { time_array = new DateTime[retVal.Length]; @@ -817,7 +830,7 @@ namespace MtApi5 } } - return time_array != null ? time_array.Length : 0; + return time_array?.Length ?? 0; } /// @@ -832,9 +845,9 @@ namespace MtApi5 { var commandParameters = new ArrayList { symbol_name, (int)timeframe, start_pos, count }; - open_array = sendCommand(Mt5CommandType.CopyOpen, commandParameters); + open_array = SendCommand(Mt5CommandType.CopyOpen, commandParameters); - return open_array != null ? open_array.Length : 0; + return open_array?.Length ?? 0; } /// @@ -849,9 +862,9 @@ namespace MtApi5 { var commandParameters = new ArrayList { symbol_name, (int)timeframe, Mt5TimeConverter.ConvertToMtTime(start_time), count }; - open_array = sendCommand(Mt5CommandType.CopyOpen1, commandParameters); + open_array = SendCommand(Mt5CommandType.CopyOpen1, commandParameters); - return open_array != null ? open_array.Length : 0; + return open_array?.Length ?? 0; } /// @@ -866,9 +879,9 @@ namespace MtApi5 { var commandParameters = new ArrayList { symbol_name, (int)timeframe, Mt5TimeConverter.ConvertToMtTime(start_time), Mt5TimeConverter.ConvertToMtTime(stop_time) }; - open_array = sendCommand(Mt5CommandType.CopyOpen2, commandParameters); + open_array = SendCommand(Mt5CommandType.CopyOpen2, commandParameters); - return open_array != null ? open_array.Length : 0; + return open_array?.Length ?? 0; } /// @@ -883,9 +896,9 @@ namespace MtApi5 { var commandParameters = new ArrayList { symbol_name, (int)timeframe, start_pos, count }; - high_array = sendCommand(Mt5CommandType.CopyHigh, commandParameters); + high_array = SendCommand(Mt5CommandType.CopyHigh, commandParameters); - return high_array != null ? high_array.Length : 0; + return high_array?.Length ?? 0; } /// @@ -900,9 +913,9 @@ namespace MtApi5 { var commandParameters = new ArrayList { symbol_name, (int)timeframe, Mt5TimeConverter.ConvertToMtTime(start_time), count }; - high_array = sendCommand(Mt5CommandType.CopyHigh1, commandParameters); + high_array = SendCommand(Mt5CommandType.CopyHigh1, commandParameters); - return high_array != null ? high_array.Length : 0; + return high_array?.Length ?? 0; } /// @@ -917,9 +930,9 @@ namespace MtApi5 { var commandParameters = new ArrayList { symbol_name, (int)timeframe, Mt5TimeConverter.ConvertToMtTime(start_time), Mt5TimeConverter.ConvertToMtTime(stop_time) }; - high_array = sendCommand(Mt5CommandType.CopyHigh2, commandParameters); + high_array = SendCommand(Mt5CommandType.CopyHigh2, commandParameters); - return high_array != null ? high_array.Length : 0; + return high_array?.Length ?? 0; } /// @@ -934,9 +947,9 @@ namespace MtApi5 { var commandParameters = new ArrayList { symbol_name, (int)timeframe, start_pos, count }; - low_array = sendCommand(Mt5CommandType.CopyLow, commandParameters); + low_array = SendCommand(Mt5CommandType.CopyLow, commandParameters); - return low_array != null ? low_array.Length : 0; + return low_array?.Length ?? 0; } /// @@ -951,9 +964,9 @@ namespace MtApi5 { var commandParameters = new ArrayList { symbol_name, (int)timeframe, Mt5TimeConverter.ConvertToMtTime(start_time), count }; - low_array = sendCommand(Mt5CommandType.CopyLow1, commandParameters); + low_array = SendCommand(Mt5CommandType.CopyLow1, commandParameters); - return low_array != null ? low_array.Length : 0; + return low_array?.Length ?? 0; } /// @@ -968,9 +981,9 @@ namespace MtApi5 { var commandParameters = new ArrayList { symbol_name, (int)timeframe, Mt5TimeConverter.ConvertToMtTime(start_time), Mt5TimeConverter.ConvertToMtTime(stop_time) }; - low_array = sendCommand(Mt5CommandType.CopyLow2, commandParameters); + low_array = SendCommand(Mt5CommandType.CopyLow2, commandParameters); - return low_array != null ? low_array.Length : 0; + return low_array?.Length ?? 0; } /// @@ -985,9 +998,9 @@ namespace MtApi5 { var commandParameters = new ArrayList { symbol_name, (int)timeframe, start_pos, count }; - close_array = sendCommand(Mt5CommandType.CopyClose, commandParameters); + close_array = SendCommand(Mt5CommandType.CopyClose, commandParameters); - return close_array != null ? close_array.Length : 0; + return close_array?.Length ?? 0; } /// @@ -1002,9 +1015,9 @@ namespace MtApi5 { var commandParameters = new ArrayList { symbol_name, (int)timeframe, Mt5TimeConverter.ConvertToMtTime(start_time), count }; - close_array = sendCommand(Mt5CommandType.CopyClose1, commandParameters); + close_array = SendCommand(Mt5CommandType.CopyClose1, commandParameters); - return close_array != null ? close_array.Length : 0; + return close_array?.Length ?? 0; } /// @@ -1019,9 +1032,9 @@ namespace MtApi5 { var commandParameters = new ArrayList { symbol_name, (int)timeframe, Mt5TimeConverter.ConvertToMtTime(start_time), Mt5TimeConverter.ConvertToMtTime(stop_time) }; - close_array = sendCommand(Mt5CommandType.CopyClose2, commandParameters); + close_array = SendCommand(Mt5CommandType.CopyClose2, commandParameters); - return close_array != null ? close_array.Length : 0; + return close_array?.Length ?? 0; } /// @@ -1036,9 +1049,9 @@ namespace MtApi5 { var commandParameters = new ArrayList { symbol_name, (int)timeframe, start_pos, count }; - volume_array = sendCommand(Mt5CommandType.CopyTickVolume, commandParameters); + volume_array = SendCommand(Mt5CommandType.CopyTickVolume, commandParameters); - return volume_array != null ? volume_array.Length : 0; + return volume_array?.Length ?? 0; } /// @@ -1053,9 +1066,9 @@ namespace MtApi5 { var commandParameters = new ArrayList { symbol_name, (int)timeframe, Mt5TimeConverter.ConvertToMtTime(start_time), count }; - volume_array = sendCommand(Mt5CommandType.CopyTickVolume1, commandParameters); + volume_array = SendCommand(Mt5CommandType.CopyTickVolume1, commandParameters); - return volume_array != null ? volume_array.Length : 0; + return volume_array?.Length ?? 0; } /// @@ -1070,9 +1083,9 @@ namespace MtApi5 { var commandParameters = new ArrayList { symbol_name, (int)timeframe, Mt5TimeConverter.ConvertToMtTime(start_time), Mt5TimeConverter.ConvertToMtTime(stop_time) }; - volume_array = sendCommand(Mt5CommandType.CopyTickVolume2, commandParameters); + volume_array = SendCommand(Mt5CommandType.CopyTickVolume2, commandParameters); - return volume_array != null ? volume_array.Length : 0; + return volume_array?.Length ?? 0; } /// @@ -1087,9 +1100,9 @@ namespace MtApi5 { var commandParameters = new ArrayList { symbol_name, (int)timeframe, start_pos, count }; - volume_array = sendCommand(Mt5CommandType.CopyRealVolume, commandParameters); + volume_array = SendCommand(Mt5CommandType.CopyRealVolume, commandParameters); - return volume_array != null ? volume_array.Length : 0; + return volume_array?.Length ?? 0; } /// @@ -1104,9 +1117,9 @@ namespace MtApi5 { var commandParameters = new ArrayList { symbol_name, (int)timeframe, Mt5TimeConverter.ConvertToMtTime(start_time), count }; - volume_array = sendCommand(Mt5CommandType.CopyRealVolume1, commandParameters); + volume_array = SendCommand(Mt5CommandType.CopyRealVolume1, commandParameters); - return volume_array != null ? volume_array.Length : 0; + return volume_array?.Length ?? 0; } /// @@ -1121,9 +1134,9 @@ namespace MtApi5 { var commandParameters = new ArrayList { symbol_name, (int)timeframe, Mt5TimeConverter.ConvertToMtTime(start_time), Mt5TimeConverter.ConvertToMtTime(stop_time) }; - volume_array = sendCommand(Mt5CommandType.CopyRealVolume2, commandParameters); + volume_array = SendCommand(Mt5CommandType.CopyRealVolume2, commandParameters); - return volume_array != null ? volume_array.Length : 0; + return volume_array?.Length ?? 0; } /// @@ -1138,9 +1151,9 @@ namespace MtApi5 { var commandParameters = new ArrayList { symbol_name, (int)timeframe, start_pos, count }; - spread_array = sendCommand(Mt5CommandType.CopySpread, commandParameters); + spread_array = SendCommand(Mt5CommandType.CopySpread, commandParameters); - return spread_array != null ? spread_array.Length : 0; + return spread_array?.Length ?? 0; } /// @@ -1155,9 +1168,9 @@ namespace MtApi5 { var commandParameters = new ArrayList { symbol_name, (int)timeframe, Mt5TimeConverter.ConvertToMtTime(start_time), count }; - spread_array = sendCommand(Mt5CommandType.CopySpread1, commandParameters); + spread_array = SendCommand(Mt5CommandType.CopySpread1, commandParameters); - return spread_array != null ? spread_array.Length : 0; + return spread_array?.Length ?? 0; } /// @@ -1172,9 +1185,9 @@ namespace MtApi5 { var commandParameters = new ArrayList { symbol_name, (int)timeframe, Mt5TimeConverter.ConvertToMtTime(start_time), Mt5TimeConverter.ConvertToMtTime(stop_time) }; - spread_array = sendCommand(Mt5CommandType.CopySpread2, commandParameters); + spread_array = SendCommand(Mt5CommandType.CopySpread2, commandParameters); - return spread_array != null ? spread_array.Length : 0; + return spread_array?.Length ?? 0; } #endregion @@ -1184,12 +1197,11 @@ namespace MtApi5 ///Returns the number of available (selected in Market Watch or all) symbols. /// ///Request mode. Can be true or false. - public int SymbolsTotal(bool selected) { var commandParameters = new ArrayList { selected }; - return sendCommand(Mt5CommandType.SymbolsTotal, commandParameters); + return SendCommand(Mt5CommandType.SymbolsTotal, commandParameters); } /// @@ -1197,12 +1209,11 @@ namespace MtApi5 /// ///Order number of a symbol. ///Request mode. If the value is true, the symbol is taken from the list of symbols selected in MarketWatch. If the value is false, the symbol is taken from the general list. - public string SymbolName(int pos, bool selected) { var commandParameters = new ArrayList { pos, selected }; - return sendCommand(Mt5CommandType.SymbolName, commandParameters); + return SendCommand(Mt5CommandType.SymbolName, commandParameters); } /// @@ -1210,24 +1221,22 @@ namespace MtApi5 /// ///Symbol name. ///Switch. If the value is false, a symbol should be removed from MarketWatch, otherwise a symbol should be selected in this window. A symbol can't be removed if the symbol chart is open, or there are open positions for this symbol. - public bool SymbolSelect(string name, bool selected) { var commandParameters = new ArrayList { name, selected }; - return sendCommand(Mt5CommandType.SymbolSelect, commandParameters); + return SendCommand(Mt5CommandType.SymbolSelect, commandParameters); } /// ///The function checks whether data of a selected symbol in the terminal are synchronized with data on the trade server. /// ///Symbol name. - public bool SymbolIsSynchronized(string name) { var commandParameters = new ArrayList { name }; - return sendCommand(Mt5CommandType.SymbolIsSynchronized, commandParameters); + return SendCommand(Mt5CommandType.SymbolIsSynchronized, commandParameters); } /// @@ -1235,12 +1244,11 @@ namespace MtApi5 /// ///Symbol name. ///Identifier of a symbol property. - public double SymbolInfoDouble(string name, ENUM_SYMBOL_INFO_DOUBLE prop_id) { var commandParameters = new ArrayList { name, (int)prop_id }; - return sendCommand(Mt5CommandType.SymbolInfoDouble, commandParameters); + return SendCommand(Mt5CommandType.SymbolInfoDouble, commandParameters); } /// @@ -1248,12 +1256,11 @@ namespace MtApi5 /// ///Symbol name. ///Identifier of a symbol property. - public long SymbolInfoInteger(string name, ENUM_SYMBOL_INFO_INTEGER prop_id) { var commandParameters = new ArrayList { name, (int)prop_id }; - return sendCommand(Mt5CommandType.SymbolInfoInteger, commandParameters); + return SendCommand(Mt5CommandType.SymbolInfoInteger, commandParameters); } /// @@ -1261,12 +1268,11 @@ namespace MtApi5 /// ///Symbol name. ///Identifier of a symbol property. - public string SymbolInfoString(string name, ENUM_SYMBOL_INFO_STRING prop_id) { var commandParameters = new ArrayList { name, (int)prop_id }; - return sendCommand(Mt5CommandType.SymbolInfoString, commandParameters); + return SendCommand(Mt5CommandType.SymbolInfoString, commandParameters); } @@ -1274,14 +1280,13 @@ namespace MtApi5 ///The function returns current prices of a specified symbol in a variable of the MqlTick type. ///The function returns true if successful, otherwise returns false. /// - ///Symbol name. - /// Link to the structure of the MqlTick type, to which the current prices and time of the last price update will be placed. - + ///Symbol name. + /// Link to the structure of the MqlTick type, to which the current prices and time of the last price update will be placed. public bool SymbolInfoTick(string symbol, out MqlTick tick) { var commandParameters = new ArrayList { symbol }; - var retVal = sendCommand(Mt5CommandType.SymbolInfoTick, commandParameters); + var retVal = SendCommand(Mt5CommandType.SymbolInfoTick, commandParameters); tick = null; if (retVal != null) @@ -1305,7 +1310,7 @@ namespace MtApi5 { var commandParameters = new ArrayList { name, (int)day_of_week, session_index }; - string strResult = sendCommand(Mt5CommandType.SymbolInfoSessionQuote, commandParameters); + string strResult = SendCommand(Mt5CommandType.SymbolInfoSessionQuote, commandParameters); return strResult.ParseResult(PARAM_SEPARATOR, out from, out to); } @@ -1322,7 +1327,7 @@ namespace MtApi5 { var commandParameters = new ArrayList { name, (int)day_of_week, session_index }; - string strResult = sendCommand(Mt5CommandType.SymbolInfoSessionTrade, commandParameters); + string strResult = SendCommand(Mt5CommandType.SymbolInfoSessionTrade, commandParameters); return strResult.ParseResult(PARAM_SEPARATOR, out from, out to); } @@ -1330,44 +1335,44 @@ namespace MtApi5 /// ///Provides opening of Depth of Market for a selected symbol, and subscribes for receiving notifications of the DOM changes. /// - ///Symbol name. + ///Symbol name. public bool MarketBookAdd(string symbol) { var commandParameters = new ArrayList { symbol }; - return sendCommand(Mt5CommandType.MarketBookAdd, commandParameters); + return SendCommand(Mt5CommandType.MarketBookAdd, commandParameters); } /// ///Provides closing of Depth of Market for a selected symbol, and cancels the subscription for receiving notifications of the DOM changes. /// - ///Symbol name. + ///Symbol name. public bool MarketBookRelease(string symbol) { var commandParameters = new ArrayList { symbol }; - return sendCommand(Mt5CommandType.MarketBookRelease, commandParameters); + return SendCommand(Mt5CommandType.MarketBookRelease, commandParameters); } /// ///Returns a structure array MqlBookInfo containing records of the Depth of Market of a specified symbol. /// - ///Symbol name. + ///Symbol name. ///Reference to an array of Depth of Market records. public bool MarketBookGet(string symbol, out MqlBookInfo[] book) { var commandParameters = new ArrayList { symbol }; - var retVal = sendCommand(Mt5CommandType.MarketBookGet, commandParameters); + var retVal = SendCommand(Mt5CommandType.MarketBookGet, commandParameters); book = null; if (retVal != null) { book = new MqlBookInfo[retVal.Length]; - for (int i = 0; i < retVal.Length; i++) + foreach (var t in retVal) { - book[0] = new MqlBookInfo((ENUM_BOOK_TYPE)retVal[i].type, retVal[i].price, retVal[i].volume); + book[0] = new MqlBookInfo((ENUM_BOOK_TYPE)t.type, t.price, t.volume); } } @@ -1415,6 +1420,8 @@ namespace MtApi5 ConnectionState = Mt5ConnectionState.Connected; ConnectionStateChanged.FireEvent(this , new Mt5ConnectionEventArgs(Mt5ConnectionState.Connected, "Connected to " + host + ":" + port)); + + OnConnected(); } private void Connect(int port) @@ -1440,6 +1447,8 @@ namespace MtApi5 ConnectionState = Mt5ConnectionState.Connected; ConnectionStateChanged.FireEvent(this , new Mt5ConnectionEventArgs(Mt5ConnectionState.Connected, "Connected to 'localhost':" + port)); + + OnConnected(); } private void Disconnect() @@ -1451,7 +1460,7 @@ namespace MtApi5 ConnectionStateChanged.FireEvent(this, new Mt5ConnectionEventArgs(Mt5ConnectionState.Disconnected, "Disconnected")); } - private T sendCommand(Mt5CommandType commandType, ArrayList commandParameters) + private T SendCommand(Mt5CommandType commandType, ArrayList commandParameters) { var response = _client.SendCommand((int)commandType, commandParameters); @@ -1529,10 +1538,19 @@ namespace MtApi5 QuoteAdded.FireEvent(this, new Mt5QuoteEventArgs(quote.Parse())); } - #endregion + private void OnConnected() + { + _isBacktestingMode = IsTesting(); + if (_isBacktestingMode) + { + BacktestingReady(); + } + } - #region Private Fields - private readonly MtClient _client = new MtClient(); + private void BacktestingReady() + { + SendCommand(Mt5CommandType.BacktestingReady, null); + } #endregion } } diff --git a/mq5/MtApi5.ex5 b/mq5/MtApi5.ex5 index 81def48d..7c9326fd 100755 Binary files a/mq5/MtApi5.ex5 and b/mq5/MtApi5.ex5 differ diff --git a/mq5/MtApi5.mq5 b/mq5/MtApi5.mq5 index a17afd01..3ec3394b 100755 --- a/mq5/MtApi5.mq5 +++ b/mq5/MtApi5.mq5 @@ -43,6 +43,8 @@ int ExpertHandle; string message; bool isCrashed = false; +bool IsRemoteReadyForTesting = false; + string symbolValue; string commentValue; @@ -54,6 +56,12 @@ int OnInit() return (result); } +double OnTester() +{ + Print("OnTester"); + return 0; +} + void OnDeinit(const int reason) { deinit(); @@ -81,6 +89,12 @@ bool IsDemo() return(false); } +bool IsTesting() +{ + bool isTesting = MQLInfoInteger(MQL_TESTER); + return isTesting; +} + int init() { preinit(); @@ -125,6 +139,27 @@ int init() isCrashed = true; return (1); } + + PrintFormat("Expert Handle = %d", ExpertHandle); + + //--- Backtesting mode + if (IsTesting()) + { + Print("Waiting on remote client..."); + //wait for command (BacktestingReady) from remote side to be ready for work + while(!IsRemoteReadyForTesting) + { + executeCommand(); + + //This section uses a while loop to simulate Sleep() during Backtest. + unsigned int viSleepUntilTick = GetTickCount() + 100; //100 milliseconds + while(GetTickCount() < viSleepUntilTick) + { + //Do absolutely nothing. Just loop until the desired tick is reached. + } + } + } + //--- return (0); } @@ -139,6 +174,7 @@ int deinit() isCrashed = true; return (1); } + Print("Wxpert was deinitialized."); } return (0); @@ -1631,7 +1667,28 @@ int executeCommand() sendBooleanResponse(ExpertHandle, result); Print("command PositionOpen: result = ", result); } - break; + break; + + case 66: //BacktestingReady + { + if (IsTesting()) + { + Print("Remote client is ready for backteting"); + IsRemoteReadyForTesting = true; + sendBooleanResponse(ExpertHandle, true); + } + else + { + sendBooleanResponse(ExpertHandle, false); + } + } + break; + + case 67: //IsTesting + { + sendBooleanResponse(ExpertHandle, IsTesting()); + } + break; default: Print("Unknown command type = ", commandType);