diff --git a/MtApi5/Mt5CommandType.cs b/MtApi5/Mt5CommandType.cs index 62f3dd5f..87d809b4 100755 --- a/MtApi5/Mt5CommandType.cs +++ b/MtApi5/Mt5CommandType.cs @@ -182,59 +182,59 @@ namespace MtApi5 //Chart Operations - ChartId = 206, - ChartRedraw = 207, - ChartApplyTemplate = 236, - ChartSaveTemplate = 237, - ChartWindowFind = 238, - ChartTimePriceToXY = 239, - ChartXYToTimePrice = 240, - ChartOpen = 241, - ChartFirst = 242, - ChartNext = 243, - ChartClose = 244, - ChartSymbol = 245, - ChartPeriod = 246, - ChartSetDouble = 247, - ChartSetInteger = 248, - ChartSetString = 249, - ChartGetDouble = 250, - ChartGetInteger = 251, - ChartGetString = 252, - ChartNavigate = 253, - ChartIndicatorDelete = 254, - ChartIndicatorName = 255, - ChartIndicatorsTotal = 256, - ChartWindowOnDropped = 257, - ChartPriceOnDropped = 258, - ChartTimeOnDropped = 259, - ChartXOnDropped = 260, - ChartYOnDropped = 261, - ChartSetSymbolPeriod = 262, - ChartScreenShot = 263, + ChartId = 206, + ChartRedraw = 207, + ChartApplyTemplate = 236, + ChartSaveTemplate = 237, + ChartWindowFind = 238, + ChartTimePriceToXY = 239, + ChartXYToTimePrice = 240, + ChartOpen = 241, + ChartFirst = 242, + ChartNext = 243, + ChartClose = 244, + ChartSymbol = 245, + ChartPeriod = 246, + ChartSetDouble = 247, + ChartSetInteger = 248, + ChartSetString = 249, + ChartGetDouble = 250, + ChartGetInteger = 251, + ChartGetString = 252, + ChartNavigate = 253, + ChartIndicatorDelete = 254, + ChartIndicatorName = 255, + ChartIndicatorsTotal = 256, + ChartWindowOnDropped = 257, + ChartPriceOnDropped = 258, + ChartTimeOnDropped = 259, + ChartXOnDropped = 260, + ChartYOnDropped = 261, + ChartSetSymbolPeriod = 262, + ChartScreenShot = 263, // Windows Operations - WindowBarsPerChart = 264, - WindowExpertName = 265, - WindowFind = 266, - WindowFirstVisibleBar = 267, - WindowHandle = 268, - WindowIsVisible = 269, - WindowOnDropped = 270, - WindowPriceMax = 271, - WindowPriceMin = 272, - WindowPriceOnDropped = 273, - WindowRedraw = 274, - WindowScreenShot = 275, - WindowTimeOnDropped = 276, - WindowsTotal = 277, - WindowXOnDropped = 278, - WindowYOnDropped = 279, + WindowBarsPerChart = 264, + WindowExpertName = 265, + WindowFind = 266, + WindowFirstVisibleBar = 267, + WindowHandle = 268, + WindowIsVisible = 269, + WindowOnDropped = 270, + WindowPriceMax = 271, + WindowPriceMin = 272, + WindowPriceOnDropped = 273, + WindowRedraw = 274, + WindowScreenShot = 275, + WindowTimeOnDropped = 276, + WindowsTotal = 277, + WindowXOnDropped = 278, + WindowYOnDropped = 279, // Terminal Operations - TerminalCompany = 68, - TerminalName = 69, - TerminalPath = 70, + TerminalCompany = 68, + TerminalName = 69, + TerminalPath = 70, //Checkup GetLastError = 132, diff --git a/MtApi5/Mt5TimeConverter.cs b/MtApi5/Mt5TimeConverter.cs index 8e209401..6e1bacc6 100755 --- a/MtApi5/Mt5TimeConverter.cs +++ b/MtApi5/Mt5TimeConverter.cs @@ -16,12 +16,13 @@ namespace MtApi5 return new DateTime(tmpTime.Ticks + (time * 0x989680L)); } - public static int ConvertToMtTime(DateTime time) + public static int ConvertToMtTime(DateTime? time) { var result = 0; - if (time == DateTime.MinValue) return result; + if (time == null || time == DateTime.MinValue) + return result; var tmpTime = new DateTime(1970, 1, 1); - result = (int)((time.Ticks - tmpTime.Ticks) / 0x989680L); + result = (int)((time.Value.Ticks - tmpTime.Ticks) / 0x989680L); return result; } } diff --git a/MtApi5/MtApi5.csproj b/MtApi5/MtApi5.csproj index 58dfa757..ec727208 100755 --- a/MtApi5/MtApi5.csproj +++ b/MtApi5/MtApi5.csproj @@ -85,6 +85,8 @@ + + diff --git a/MtApi5/MtApi5Client.cs b/MtApi5/MtApi5Client.cs index e76eeb20..4919acfc 100755 --- a/MtApi5/MtApi5Client.cs +++ b/MtApi5/MtApi5Client.cs @@ -1386,6 +1386,23 @@ namespace MtApi5 return SendCommand(Mt5CommandType.SymbolInfoString, commandParameters); } + /// + ///Returns the corresponding property of a specified symbol. + /// + ///Symbol name. + ///Identifier of a symbol property. + ///Variable of the string type receiving the value of the requested property. + public bool SymbolInfoString(string symbolName, ENUM_SYMBOL_INFO_STRING propId, out string value) + { + var response = SendRequest(new SymbolInfoStringRequest + { + SymbolName = symbolName, + PropId = propId + }); + + value = response?.StringVar; + return response?.RetVal ?? false; + } /// ///The function returns current prices of a specified symbol in a variable of the MqlTick type. @@ -1561,7 +1578,7 @@ namespace MtApi5 /// public bool ChartTimePriceToXY(long chartId, int subWindow, DateTime? time, double price, out int x, out int y) { - var commandParameters = new ArrayList { chartId, subWindow, Mt5TimeConverter.ConvertToMtTime((DateTime)time), price }; + var commandParameters = new ArrayList { chartId, subWindow, Mt5TimeConverter.ConvertToMtTime(time), price }; var str = SendCommand(Mt5CommandType.ChartTimePriceToXY, commandParameters); var res = false; x = 0; diff --git a/MtApi5/Requests/RequestType.cs b/MtApi5/Requests/RequestType.cs index 735ce6f3..1ba9024c 100755 --- a/MtApi5/Requests/RequestType.cs +++ b/MtApi5/Requests/RequestType.cs @@ -4,13 +4,14 @@ namespace MtApi5.Requests { internal enum RequestType { - Unknown = 0, - CopyTicks = 1, - iCustom = 2, - OrderSend = 3, - PositionOpen = 4, - OrderCheck = 5, - MarketBookGet = 6, - IndicatorCreate = 7 + Unknown = 0, + CopyTicks = 1, + iCustom = 2, + OrderSend = 3, + PositionOpen = 4, + OrderCheck = 5, + MarketBookGet = 6, + IndicatorCreate = 7, + SymbolInfoString = 8 } } \ No newline at end of file diff --git a/MtApi5/Requests/SymbolInfoStringRequest.cs b/MtApi5/Requests/SymbolInfoStringRequest.cs new file mode 100644 index 00000000..7b77b347 --- /dev/null +++ b/MtApi5/Requests/SymbolInfoStringRequest.cs @@ -0,0 +1,10 @@ +namespace MtApi5.Requests +{ + internal class SymbolInfoStringRequest : RequestBase + { + public override RequestType RequestType => RequestType.SymbolInfoString; + + public string SymbolName { get; set; } + public ENUM_SYMBOL_INFO_STRING PropId { get; set; } + } +} \ No newline at end of file diff --git a/MtApi5/Requests/SymbolInfoStringResult.cs b/MtApi5/Requests/SymbolInfoStringResult.cs new file mode 100644 index 00000000..38b186e5 --- /dev/null +++ b/MtApi5/Requests/SymbolInfoStringResult.cs @@ -0,0 +1,8 @@ +namespace MtApi5.Requests +{ + internal class SymbolInfoStringResult + { + public bool RetVal { get; set; } + public string StringVar { get; set; } + } +} \ No newline at end of file diff --git a/mq5/MtApi5.ex5 b/mq5/MtApi5.ex5 index 14774e8c..4bfb69c7 100755 Binary files a/mq5/MtApi5.ex5 and b/mq5/MtApi5.ex5 differ diff --git a/mq5/MtApi5.mq5 b/mq5/MtApi5.mq5 old mode 100755 new mode 100644 index bb3d3b39..a0c1e514 --- a/mq5/MtApi5.mq5 +++ b/mq5/MtApi5.mq5 @@ -704,9 +704,28 @@ int executeCommand() break; case 131: //IndicatorRelease Execute_IndicatorRelease(); + break; + case 132: //GetLastError + Execute_GetLastError(); + break; + case 143: //ResetLastError + Execute_ResetLastError(); + break; + case 153: //TerminalInfoString + Execute_TerminalInfoString(); + break; + case 204: //TerminalInfoInteger + Execute_TerminalInfoInteger(); + break; + case 205: //TerminalInfoDouble + Execute_TerminalInfoDouble(); + break; + case 236: //ChartApplyTemplate + Execute_ChartApplyTemplate(); + break; + case 237: //ChartApplyTemplate + Execute_ChartSaveTemplate(); break; - - case 241: //ChartOpen Execute_ChartOpen(); break; @@ -722,36 +741,6 @@ int executeCommand() case 252: //ChartGetString Execute_ChartGetString(); break; - - case 236: //ChartApplyTemplate - Execute_ChartApplyTemplate(); - break; - - case 237: //ChartApplyTemplate - Execute_ChartSaveTemplate(); - break; - - - - case 153: //TerminalInfoString - Execute_TerminalInfoString(); - break; - case 204: //TerminalInfoInteger - Execute_TerminalInfoInteger(); - break; - case 205: //TerminalInfoDouble - Execute_TerminalInfoDouble(); - break; - - - - case 132: //GetLastError - Execute_GetLastError(); - break; - case 143: //ResetLastError - Execute_ResetLastError(); - break; - default: Print("Unknown command type = ", commandType); sendVoidResponse(ExpertHandle, _response_error); @@ -5580,6 +5569,206 @@ void Execute_ResetLastError() PrintResponseError("ResetLastError", _response_error); } } + +void Execute_ChartOpen() +{ + string symbol; + int timeframe; + StringInit(symbol, 100, 0); + + if (!getStringValue(ExpertHandle, 0, symbol, _error)) + { + PrintParamError("ChartOpen", "symbol", _error); + sendErrorResponse(ExpertHandle, -1, _error, _response_error); + return; + } + if (!getIntValue(ExpertHandle, 1, timeframe, _error)) + { + PrintParamError("ChartOpen", "timeframe", _error); + sendErrorResponse(ExpertHandle, -1, _error, _response_error); + return; + } + + + if (!sendLongResponse(ExpertHandle, ChartOpen(symbol, (ENUM_TIMEFRAMES)timeframe), _response_error)) + { + PrintResponseError("ChartOpen", _response_error); + } +} + +void Execute_ChartFirst() +{ + if (!sendLongResponse(ExpertHandle, ChartFirst(), _response_error)) + { + PrintResponseError("ChartFirst", _response_error); + } +} + +void Execute_ChartNext() +{ + long ChartId; + + if (!getLongValue(ExpertHandle, 0, ChartId, _error)) + { + PrintParamError("ChartFirst", "ChartId", _error); + sendErrorResponse(ExpertHandle, -1, _error, _response_error); + return; + } + + if (!sendLongResponse(ExpertHandle, ChartNext(ChartId), _response_error)) + { + PrintResponseError("ChartFirst", _response_error); + } +} + +void Execute_ChartSymbol() +{ + long ChartId; + + if (!getLongValue(ExpertHandle, 0, ChartId, _error)) + { + PrintParamError("ChartSymbol", "ChartId", _error); + sendErrorResponse(ExpertHandle, -1, _error, _response_error); + return; + } + + if (!sendStringResponse(ExpertHandle, ChartSymbol(ChartId), _response_error)) + { + PrintResponseError("ChartSymbol", _response_error); + } +} + +void Execute_ChartApplyTemplate() +{ + long ChartId; + string TemplateFileName; + StringInit(TemplateFileName, 100, 0); + + + if (!getLongValue(ExpertHandle, 0, ChartId, _error)) + { + PrintParamError("ChartApplyTemplate", "ChartId", _error); + sendErrorResponse(ExpertHandle, -1, _error, _response_error); + return; + } + if (!getStringValue(ExpertHandle, 1, TemplateFileName, _error)) + { + PrintParamError("ChartApplyTemplate", "TemplateFileName", _error); + sendErrorResponse(ExpertHandle, -1, _error, _response_error); + return; + } + StringReplace(TemplateFileName, "\\", "\\\\"); + + if (!sendBooleanResponse(ExpertHandle, ChartApplyTemplate(ChartId, TemplateFileName), _response_error)) + { + PrintResponseError("ChartApplyTemplate", _response_error); + } + ChartRedraw(ChartId); +} + +void Execute_ChartSaveTemplate() +{ + long ChartId; + string TemplateFileName; + StringInit(TemplateFileName, 100, 0); + + + if (!getLongValue(ExpertHandle, 0, ChartId, _error)) + { + PrintParamError("ChartSaveTemplate", "ChartId", _error); + sendErrorResponse(ExpertHandle, -1, _error, _response_error); + return; + } + if (!getStringValue(ExpertHandle, 1, TemplateFileName, _error)) + { + PrintParamError("ChartSaveTemplate", "TemplateFileName", _error); + sendErrorResponse(ExpertHandle, -1, _error, _response_error); + return; + } + StringReplace(TemplateFileName, "\\", "\\\\"); + + if (!sendBooleanResponse(ExpertHandle, ChartSaveTemplate(ChartId, TemplateFileName), _response_error)) + { + PrintResponseError("ChartSaveTemplate", _response_error); + } + ChartRedraw(ChartId); +} + +void Execute_ChartGetString() +{ + long ChartId; + int PropId; + + if (!getLongValue(ExpertHandle, 0, ChartId, _error)) + { + PrintParamError("ChartGetString", "ChartId", _error); + sendErrorResponse(ExpertHandle, -1, _error, _response_error); + return; + } + if (!getIntValue(ExpertHandle, 1, PropId, _error)) + { + PrintParamError("ChartGetString", "PropId", _error); + sendErrorResponse(ExpertHandle, -1, _error, _response_error); + return; + } + + if (!sendStringResponse(ExpertHandle, ChartGetString(ChartId, (ENUM_CHART_PROPERTY_STRING)PropId), _response_error)) + { + PrintResponseError("ChartGetString", _response_error); + } + ChartRedraw(ChartId); +} + +void Execute_TerminalInfoString() +{ + int propertyId; + + if (!getIntValue(ExpertHandle, 0, propertyId, _error)) + { + PrintParamError("TerminalInfoString", "propertyId", _error); + sendErrorResponse(ExpertHandle, -1, _error, _response_error); + return; + } + + if (!sendStringResponse(ExpertHandle, TerminalInfoString((ENUM_TERMINAL_INFO_STRING)propertyId), _response_error)) + { + PrintResponseError("TerminalInfoString", _response_error); + } +} + +void Execute_TerminalInfoInteger() +{ + int propertyId; + + if (!getIntValue(ExpertHandle, 0, propertyId, _error)) + { + PrintParamError("TerminalInfoInteger", "propertyId", _error); + sendErrorResponse(ExpertHandle, -1, _error, _response_error); + return; + } + + if (!sendIntResponse(ExpertHandle, TerminalInfoInteger((ENUM_TERMINAL_INFO_INTEGER)propertyId), _response_error)) + { + PrintResponseError("TerminalInfoInteger", _response_error); + } +} + +void Execute_TerminalInfoDouble() +{ + int propertyId; + + if (!getIntValue(ExpertHandle, 0, propertyId, _error)) + { + PrintParamError("TerminalInfoDouble", "propertyId", _error); + sendErrorResponse(ExpertHandle, -1, _error, _response_error); + return; + } + + if (!sendDoubleResponse(ExpertHandle, TerminalInfoDouble((ENUM_TERMINAL_INFO_DOUBLE)propertyId), _response_error)) + { + PrintResponseError("TerminalInfoDouble", _response_error); + } +} void PrintParamError(string paramName) { @@ -5752,6 +5941,9 @@ string OnRequest(string json) case 7: //IndicatorCreate response = ExecuteRequest_IndicatorCreate(jo); break; + case 8: //SymbolInfoString + response = ExecuteRequest_SymbolInfoString(jo); + break; default: PrintFormat("%s [WARNING]: Unknown request type %d", __FUNCTION__, requestType); response = CreateErrorResponse(-1, "Unknown request type"); @@ -6072,211 +6264,6 @@ string ExecuteRequest_MarketBookGet(JSONObject *jo) return CreateSuccessResponse("Value", book_ja); } -void Execute_ChartOpen() -{ - string symbol; - int timeframe; - StringInit(symbol, 100, 0); - - if (!getStringValue(ExpertHandle, 0, symbol, _error)) - { - PrintParamError("ChartOpen", "symbol", _error); - sendErrorResponse(ExpertHandle, -1, _error, _response_error); - return; - } - if (!getIntValue(ExpertHandle, 1, timeframe, _error)) - { - PrintParamError("ChartOpen", "timeframe", _error); - sendErrorResponse(ExpertHandle, -1, _error, _response_error); - return; - } - - - if (!sendLongResponse(ExpertHandle, ChartOpen(symbol, (ENUM_TIMEFRAMES)timeframe), _response_error)) - { - PrintResponseError("ChartOpen", _response_error); - } -} - -void Execute_ChartFirst() -{ - if (!sendLongResponse(ExpertHandle, ChartFirst(), _response_error)) - { - PrintResponseError("ChartFirst", _response_error); - } -} - -void Execute_ChartNext() -{ - long ChartId; - - if (!getLongValue(ExpertHandle, 0, ChartId, _error)) - { - PrintParamError("ChartFirst", "ChartId", _error); - sendErrorResponse(ExpertHandle, -1, _error, _response_error); - return; - } - - if (!sendLongResponse(ExpertHandle, ChartNext(ChartId), _response_error)) - { - PrintResponseError("ChartFirst", _response_error); - } -} - -void Execute_ChartSymbol() -{ - long ChartId; - - if (!getLongValue(ExpertHandle, 0, ChartId, _error)) - { - PrintParamError("ChartSymbol", "ChartId", _error); - sendErrorResponse(ExpertHandle, -1, _error, _response_error); - return; - } - - if (!sendStringResponse(ExpertHandle, ChartSymbol(ChartId), _response_error)) - { - PrintResponseError("ChartSymbol", _response_error); - } -} - - -void Execute_ChartApplyTemplate() -{ - long ChartId; - string TemplateFileName; - StringInit(TemplateFileName, 100, 0); - - - if (!getLongValue(ExpertHandle, 0, ChartId, _error)) - { - PrintParamError("ChartApplyTemplate", "ChartId", _error); - sendErrorResponse(ExpertHandle, -1, _error, _response_error); - return; - } - if (!getStringValue(ExpertHandle, 1, TemplateFileName, _error)) - { - PrintParamError("ChartApplyTemplate", "TemplateFileName", _error); - sendErrorResponse(ExpertHandle, -1, _error, _response_error); - return; - } - StringReplace(TemplateFileName, "\\", "\\\\"); - - if (!sendBooleanResponse(ExpertHandle, ChartApplyTemplate(ChartId, TemplateFileName), _response_error)) - { - PrintResponseError("ChartApplyTemplate", _response_error); - } - ChartRedraw(ChartId); -} - -void Execute_ChartSaveTemplate() -{ - long ChartId; - string TemplateFileName; - StringInit(TemplateFileName, 100, 0); - - - if (!getLongValue(ExpertHandle, 0, ChartId, _error)) - { - PrintParamError("ChartSaveTemplate", "ChartId", _error); - sendErrorResponse(ExpertHandle, -1, _error, _response_error); - return; - } - if (!getStringValue(ExpertHandle, 1, TemplateFileName, _error)) - { - PrintParamError("ChartSaveTemplate", "TemplateFileName", _error); - sendErrorResponse(ExpertHandle, -1, _error, _response_error); - return; - } - StringReplace(TemplateFileName, "\\", "\\\\"); - - if (!sendBooleanResponse(ExpertHandle, ChartSaveTemplate(ChartId, TemplateFileName), _response_error)) - { - PrintResponseError("ChartSaveTemplate", _response_error); - } - ChartRedraw(ChartId); -} - - -void Execute_ChartGetString() -{ - long ChartId; - int PropId; - - if (!getLongValue(ExpertHandle, 0, ChartId, _error)) - { - PrintParamError("ChartGetString", "ChartId", _error); - sendErrorResponse(ExpertHandle, -1, _error, _response_error); - return; - } - if (!getIntValue(ExpertHandle, 1, PropId, _error)) - { - PrintParamError("ChartGetString", "PropId", _error); - sendErrorResponse(ExpertHandle, -1, _error, _response_error); - return; - } - - if (!sendStringResponse(ExpertHandle, ChartGetString(ChartId, (ENUM_CHART_PROPERTY_STRING)PropId), _response_error)) - { - PrintResponseError("ChartGetString", _response_error); - } - ChartRedraw(ChartId); -} - -void Execute_TerminalInfoString() -{ - int propertyId; - - if (!getIntValue(ExpertHandle, 0, propertyId, _error)) - { - PrintParamError("TerminalInfoString", "propertyId", _error); - sendErrorResponse(ExpertHandle, -1, _error, _response_error); - return; - } - - if (!sendStringResponse(ExpertHandle, TerminalInfoString((ENUM_TERMINAL_INFO_STRING)propertyId), _response_error)) - { - PrintResponseError("TerminalInfoString", _response_error); - } -} - - -void Execute_TerminalInfoInteger() -{ - int propertyId; - - if (!getIntValue(ExpertHandle, 0, propertyId, _error)) - { - PrintParamError("TerminalInfoInteger", "propertyId", _error); - sendErrorResponse(ExpertHandle, -1, _error, _response_error); - return; - } - - if (!sendIntResponse(ExpertHandle, TerminalInfoInteger((ENUM_TERMINAL_INFO_INTEGER)propertyId), _response_error)) - { - PrintResponseError("TerminalInfoInteger", _response_error); - } -} - -void Execute_TerminalInfoDouble() -{ - int propertyId; - - if (!getIntValue(ExpertHandle, 0, propertyId, _error)) - { - PrintParamError("TerminalInfoDouble", "propertyId", _error); - sendErrorResponse(ExpertHandle, -1, _error, _response_error); - return; - } - - if (!sendDoubleResponse(ExpertHandle, TerminalInfoDouble((ENUM_TERMINAL_INFO_DOUBLE)propertyId), _response_error)) - { - PrintResponseError("TerminalInfoDouble", _response_error); - } -} - - - string ExecuteRequest_IndicatorCreate(JSONObject *jo) { //Symbol @@ -6344,6 +6331,32 @@ string ExecuteRequest_IndicatorCreate(JSONObject *jo) return CreateSuccessResponse("Value", new JSONNumber(indicator_handle)); } +string ExecuteRequest_SymbolInfoString(JSONObject *jo) +{ + CHECK_JSON_VALUE(jo, "SymbolName", CreateErrorResponse(-1, "Undefinded mandatory parameter SymbolName")); + string symbol_name = jo.getString("SymbolName"); + + CHECK_JSON_VALUE(jo, "PropId", CreateErrorResponse(-1, "Undefinded mandatory parameter PropId")); + ENUM_SYMBOL_INFO_STRING prop_id = (ENUM_SYMBOL_INFO_STRING) jo.getInt("PropId"); + +#ifdef __DEBUG_LOG__ + PrintFormat("%s: symbol_name = %s, prop_id = %s", __FUNCTION__, symbol_name, EnumToString(prop_id)); +#endif + + string string_var; + bool ok = SymbolInfoString(symbol_name, prop_id, string_var); + +#ifdef __DEBUG_LOG__ + PrintFormat("%s: ok = %s, string_var = %s", __FUNCTION__, BoolToString(ok), string_var); +#endif + + JSONObject* result_value_jo = new JSONObject(); + result_value_jo.put("RetVal", new JSONBool(ok)); + result_value_jo.put("StringVar", new JSONString(string_var)); + + return CreateSuccessResponse("Value", result_value_jo); +} + //------------ Events ------------------------------------------------------- enum MtEventTypes