diff --git a/MtApi5/MtApi5Client.cs b/MtApi5/MtApi5Client.cs
index b75bd2a0..613f2255 100755
--- a/MtApi5/MtApi5Client.cs
+++ b/MtApi5/MtApi5Client.cs
@@ -860,6 +860,157 @@ public bool Sell(out MqlTradeResult? result, double volume, string? symbol = nul
result = response?.Result;
return response != null && response.RetVal;
}
+
+ ///
+ /// Places a Buy Limit pending order (buy at a price lower than the current market price) with specified parameters
+ ///
+ /// output result
+ /// Requested order volume.
+ /// Order execution price.
+ /// Order symbol. If it is not specified, the current symbol will be used.
+ /// Stop Loss price.
+ /// Take Profit price.
+ /// Order expiration type.
+ /// Order expiration time (used with typeTime ORDER_TIME_SPECIFIED or ORDER_TIME_SPECIFIED_DAY).
+ /// Comment.
+ /// true - successful check of the structures, otherwise - false.
+ public bool BuyLimit(out MqlTradeResult? result, double volume, double price, string? symbol = null, double sl = 0.0, double tp = 0.0, ENUM_ORDER_TYPE_TIME typeTime = ENUM_ORDER_TYPE_TIME.ORDER_TIME_GTC, DateTime? expiration = null, string? comment = null)
+ {
+ Dictionary cmdParams = new() { { "Volume", volume }, { "Price", price }, { "Sl", sl }, { "Tp", tp },
+ { "TypeTime", (int)typeTime }, { "Expiration", Mt5TimeConverter.ConvertToMtTime(expiration) } };
+ if (symbol != null)
+ cmdParams["Symbol"] = symbol;
+ if (comment != null)
+ cmdParams["Comment"] = comment;
+
+ var response = SendCommand>(ExecutorHandle, Mt5CommandType.BuyLimit, cmdParams);
+
+ result = response?.Result;
+ return response != null && response.RetVal;
+ }
+
+ ///
+ /// Places a Sell Limit pending order (sell at a price higher than the current market price) with specified parameters
+ ///
+ /// output result
+ /// Requested order volume.
+ /// Order execution price.
+ /// Order symbol. If it is not specified, the current symbol will be used.
+ /// Stop Loss price.
+ /// Take Profit price.
+ /// Order expiration type.
+ /// Order expiration time (used with typeTime ORDER_TIME_SPECIFIED or ORDER_TIME_SPECIFIED_DAY).
+ /// Comment.
+ /// true - successful check of the structures, otherwise - false.
+ public bool SellLimit(out MqlTradeResult? result, double volume, double price, string? symbol = null, double sl = 0.0, double tp = 0.0, ENUM_ORDER_TYPE_TIME typeTime = ENUM_ORDER_TYPE_TIME.ORDER_TIME_GTC, DateTime? expiration = null, string? comment = null)
+ {
+ Dictionary cmdParams = new() { { "Volume", volume }, { "Price", price }, { "Sl", sl }, { "Tp", tp },
+ { "TypeTime", (int)typeTime }, { "Expiration", Mt5TimeConverter.ConvertToMtTime(expiration) } };
+ if (symbol != null)
+ cmdParams["Symbol"] = symbol;
+ if (comment != null)
+ cmdParams["Comment"] = comment;
+
+ var response = SendCommand>(ExecutorHandle, Mt5CommandType.SellLimit, cmdParams);
+
+ result = response?.Result;
+ return response != null && response.RetVal;
+ }
+
+ ///
+ /// Places a Buy Stop pending order (buy at a price higher than the current market price) with specified parameters
+ ///
+ /// output result
+ /// Requested order volume.
+ /// Order execution price.
+ /// Order symbol. If it is not specified, the current symbol will be used.
+ /// Stop Loss price.
+ /// Take Profit price.
+ /// Order expiration type.
+ /// Order expiration time (used with typeTime ORDER_TIME_SPECIFIED or ORDER_TIME_SPECIFIED_DAY).
+ /// Comment.
+ /// true - successful check of the structures, otherwise - false.
+ public bool BuyStop(out MqlTradeResult? result, double volume, double price, string? symbol = null, double sl = 0.0, double tp = 0.0, ENUM_ORDER_TYPE_TIME typeTime = ENUM_ORDER_TYPE_TIME.ORDER_TIME_GTC, DateTime? expiration = null, string? comment = null)
+ {
+ Dictionary cmdParams = new() { { "Volume", volume }, { "Price", price }, { "Sl", sl }, { "Tp", tp },
+ { "TypeTime", (int)typeTime }, { "Expiration", Mt5TimeConverter.ConvertToMtTime(expiration) } };
+ if (symbol != null)
+ cmdParams["Symbol"] = symbol;
+ if (comment != null)
+ cmdParams["Comment"] = comment;
+
+ var response = SendCommand>(ExecutorHandle, Mt5CommandType.BuyStop, cmdParams);
+
+ result = response?.Result;
+ return response != null && response.RetVal;
+ }
+
+ ///
+ /// Places a Sell Stop pending order (sell at a price lower than the current market price) with specified parameters
+ ///
+ /// output result
+ /// Requested order volume.
+ /// Order execution price.
+ /// Order symbol. If it is not specified, the current symbol will be used.
+ /// Stop Loss price.
+ /// Take Profit price.
+ /// Order expiration type.
+ /// Order expiration time (used with typeTime ORDER_TIME_SPECIFIED or ORDER_TIME_SPECIFIED_DAY).
+ /// Comment.
+ /// true - successful check of the structures, otherwise - false.
+ public bool SellStop(out MqlTradeResult? result, double volume, double price, string? symbol = null, double sl = 0.0, double tp = 0.0, ENUM_ORDER_TYPE_TIME typeTime = ENUM_ORDER_TYPE_TIME.ORDER_TIME_GTC, DateTime? expiration = null, string? comment = null)
+ {
+ Dictionary cmdParams = new() { { "Volume", volume }, { "Price", price }, { "Sl", sl }, { "Tp", tp },
+ { "TypeTime", (int)typeTime }, { "Expiration", Mt5TimeConverter.ConvertToMtTime(expiration) } };
+ if (symbol != null)
+ cmdParams["Symbol"] = symbol;
+ if (comment != null)
+ cmdParams["Comment"] = comment;
+
+ var response = SendCommand>(ExecutorHandle, Mt5CommandType.SellStop, cmdParams);
+
+ result = response?.Result;
+ return response != null && response.RetVal;
+ }
+
+ ///
+ /// Modifies the parameters of a previously placed pending order
+ ///
+ /// output result
+ /// Ticket of the pending order to be modified.
+ /// New order execution price.
+ /// New Stop Loss price.
+ /// New Take Profit price.
+ /// Order expiration type.
+ /// Order expiration time (used with typeTime ORDER_TIME_SPECIFIED or ORDER_TIME_SPECIFIED_DAY).
+ /// Limit order price for the StopLimit order.
+ /// true - successful check of the structures, otherwise - false.
+ public bool OrderModify(out MqlTradeResult? result, ulong ticket, double price, double sl, double tp, ENUM_ORDER_TYPE_TIME typeTime = ENUM_ORDER_TYPE_TIME.ORDER_TIME_GTC, DateTime? expiration = null, double stoplimit = 0.0)
+ {
+ Dictionary cmdParams = new() { { "Ticket", ticket }, { "Price", price }, { "Sl", sl }, { "Tp", tp },
+ { "TypeTime", (int)typeTime }, { "Expiration", Mt5TimeConverter.ConvertToMtTime(expiration) }, { "Stoplimit", stoplimit } };
+
+ var response = SendCommand>(ExecutorHandle, Mt5CommandType.OrderModify, cmdParams);
+
+ result = response?.Result;
+ return response != null && response.RetVal;
+ }
+
+ ///
+ /// Removes a previously placed pending order
+ ///
+ /// output result
+ /// Ticket of the pending order to be deleted.
+ /// true - successful check of the structures, otherwise - false.
+ public bool OrderDelete(out MqlTradeResult? result, ulong ticket)
+ {
+ Dictionary cmdParams = new() { { "Ticket", ticket } };
+
+ var response = SendCommand>(ExecutorHandle, Mt5CommandType.OrderDelete, cmdParams);
+
+ result = response?.Result;
+ return response != null && response.RetVal;
+ }
#endregion
#region Account Information functions
diff --git a/MtApi5/MtProtocol/Mt5CommandType.cs b/MtApi5/MtProtocol/Mt5CommandType.cs
index 4af91bdb..1edc5a70 100755
--- a/MtApi5/MtProtocol/Mt5CommandType.cs
+++ b/MtApi5/MtProtocol/Mt5CommandType.cs
@@ -260,6 +260,13 @@ internal enum Mt5CommandType
OrderCheck = 303,
Buy = 304,
Sell = 305,
- GetSymbols = 306
+ GetSymbols = 306,
+
+ BuyLimit = 320,
+ SellLimit = 321,
+ BuyStop = 322,
+ SellStop = 323,
+ OrderModify = 324,
+ OrderDelete = 325
}
}
diff --git a/TestClients/MtApi5TestClient/MainWindow.xaml b/TestClients/MtApi5TestClient/MainWindow.xaml
index c30fe43e..32bb5a04 100755
--- a/TestClients/MtApi5TestClient/MainWindow.xaml
+++ b/TestClients/MtApi5TestClient/MainWindow.xaml
@@ -529,6 +529,8 @@
+
+
diff --git a/TestClients/MtApi5TestClient/ViewModel.cs b/TestClients/MtApi5TestClient/ViewModel.cs
index c585d1f7..2f2ce300 100755
--- a/TestClients/MtApi5TestClient/ViewModel.cs
+++ b/TestClients/MtApi5TestClient/ViewModel.cs
@@ -104,6 +104,8 @@ public class ViewModel : INotifyPropertyChanged
public DelegateCommand PositionCloseAllCommand { get; private set; }
public DelegateCommand BuyCommand { get; private set; }
public DelegateCommand SellCommand { get; private set; }
+ public DelegateCommand BuyLimitCommand { get; private set; }
+ public DelegateCommand OrderDeleteCommand { get; private set; }
public DelegateCommand GetLastErrorCommand { get; private set; }
public DelegateCommand ResetLastErrorCommand { get; private set; }
@@ -450,6 +452,8 @@ private void InitCommands()
PositionCloseAllCommand = new DelegateCommand(ExecutePositionCloseAll);
BuyCommand = new DelegateCommand(ExecuteBuy);
SellCommand = new DelegateCommand(ExecuteSell);
+ BuyLimitCommand = new DelegateCommand(ExecuteBuyLimit);
+ OrderDeleteCommand = new DelegateCommand(ExecuteOrderDelete);
PrintCommand = new DelegateCommand(ExecutePrint);
AlertCommand = new DelegateCommand(ExecuteAlert);
@@ -1302,6 +1306,35 @@ private async void ExecuteSell(object obj)
AddLog($"Sell: symbol EURUSD retVal = {retVal}, result = {tradeResult}");
}
+ private async void ExecuteBuyLimit(object obj)
+ {
+ const string symbol = "EURUSD";
+ const double volume = 0.1;
+
+ MqlTick tick = null;
+ var gotTick = await Execute(() => _mtApiClient.SymbolInfoTick(symbol, out tick));
+ if (gotTick == false || tick == null)
+ {
+ AddLog("BuyLimit: failed to get current tick");
+ return;
+ }
+
+ var price = Math.Round(tick.bid - 0.00500, 5);
+ MqlTradeResult tradeResult = null;
+
+ var retVal = await Execute(() => _mtApiClient.BuyLimit(out tradeResult, volume, price, symbol));
+ AddLog($"BuyLimit: symbol {symbol} price {price} retVal = {retVal}, result = {tradeResult}");
+ }
+
+ private async void ExecuteOrderDelete(object obj)
+ {
+ var ticket = PositionTicketValue;
+ MqlTradeResult tradeResult = null;
+
+ var retVal = await Execute(() => _mtApiClient.OrderDelete(out tradeResult, ticket));
+ AddLog($"OrderDelete: ticket {ticket} retVal = {retVal}, result = {tradeResult}");
+ }
+
private async void ExecutePrint(object obj)
{
var message = MessageText;
diff --git a/mq5/MtApi5.ex5 b/mq5/MtApi5.ex5
index 95e17467..0cf26a35 100755
Binary files a/mq5/MtApi5.ex5 and b/mq5/MtApi5.ex5 differ
diff --git a/mq5/MtApi5.mq5 b/mq5/MtApi5.mq5
index 18c0b55e..eae61b4e 100644
--- a/mq5/MtApi5.mq5
+++ b/mq5/MtApi5.mq5
@@ -381,7 +381,14 @@ int preinit()
ADD_EXECUTOR(304, Buy);
ADD_EXECUTOR(305, Sell);
ADD_EXECUTOR(306, GetSymbols);
-
+
+ ADD_EXECUTOR(320, BuyLimit);
+ ADD_EXECUTOR(321, SellLimit);
+ ADD_EXECUTOR(322, BuyStop);
+ ADD_EXECUTOR(323, SellStop);
+ ADD_EXECUTOR(324, OrderModify);
+ ADD_EXECUTOR(325, OrderDelete);
+
return (0);
}
@@ -3449,7 +3456,210 @@ string Execute_Sell()
result_value_jo.put("RetVal", new JSONBool(ok));
result_value_jo.put("Result", MqlTradeResultToJson(trade_result));
- return CreateSuccessResponse(result_value_jo);
+ return CreateSuccessResponse(result_value_jo);
+}
+
+string Execute_BuyLimit()
+{
+ GET_JSON_PAYLOAD(jo);
+ GET_DOUBLE_JSON_VALUE(jo, "Volume", volume);
+ GET_DOUBLE_JSON_VALUE(jo, "Price", price);
+ GET_DOUBLE_JSON_VALUE(jo, "Sl", sl);
+ GET_DOUBLE_JSON_VALUE(jo, "Tp", tp);
+ GET_INT_JSON_VALUE(jo, "TypeTime", type_time);
+ GET_LONG_JSON_VALUE(jo, "Expiration", expiration);
+
+ //Symbol
+ string symbol = Symbol();
+ if (jo.p.getValue("Symbol") != NULL)
+ symbol = jo.p.getString("Symbol");
+
+ //Comment
+ string comment = "";
+ if (jo.p.getValue("Comment") != NULL)
+ comment = jo.p.getString("Comment");
+
+#ifdef __DEBUG_LOG__
+ PrintFormat("%s: symbol = %s, volume = %f, price = %f, sl = %f, tp = %f, type_time = %d, expiration = %I64d, comment = %s",
+ __FUNCTION__, symbol, volume, price, sl, tp, type_time, expiration, comment);
+#endif
+
+ CTrade trade;
+ bool ok = trade.BuyLimit(volume, price, symbol, sl, tp, (ENUM_ORDER_TYPE_TIME)type_time, (datetime)expiration, comment);
+
+ MqlTradeResult trade_result={0};
+ trade.Result(trade_result);
+
+ JSONObject* result_value_jo = new JSONObject();
+ result_value_jo.put("RetVal", new JSONBool(ok));
+ result_value_jo.put("Result", MqlTradeResultToJson(trade_result));
+
+ return CreateSuccessResponse(result_value_jo);
+}
+
+string Execute_SellLimit()
+{
+ GET_JSON_PAYLOAD(jo);
+ GET_DOUBLE_JSON_VALUE(jo, "Volume", volume);
+ GET_DOUBLE_JSON_VALUE(jo, "Price", price);
+ GET_DOUBLE_JSON_VALUE(jo, "Sl", sl);
+ GET_DOUBLE_JSON_VALUE(jo, "Tp", tp);
+ GET_INT_JSON_VALUE(jo, "TypeTime", type_time);
+ GET_LONG_JSON_VALUE(jo, "Expiration", expiration);
+
+ //Symbol
+ string symbol = Symbol();
+ if (jo.p.getValue("Symbol") != NULL)
+ symbol = jo.p.getString("Symbol");
+
+ //Comment
+ string comment = "";
+ if (jo.p.getValue("Comment") != NULL)
+ comment = jo.p.getString("Comment");
+
+#ifdef __DEBUG_LOG__
+ PrintFormat("%s: symbol = %s, volume = %f, price = %f, sl = %f, tp = %f, type_time = %d, expiration = %I64d, comment = %s",
+ __FUNCTION__, symbol, volume, price, sl, tp, type_time, expiration, comment);
+#endif
+
+ CTrade trade;
+ bool ok = trade.SellLimit(volume, price, symbol, sl, tp, (ENUM_ORDER_TYPE_TIME)type_time, (datetime)expiration, comment);
+
+ MqlTradeResult trade_result={0};
+ trade.Result(trade_result);
+
+ JSONObject* result_value_jo = new JSONObject();
+ result_value_jo.put("RetVal", new JSONBool(ok));
+ result_value_jo.put("Result", MqlTradeResultToJson(trade_result));
+
+ return CreateSuccessResponse(result_value_jo);
+}
+
+string Execute_BuyStop()
+{
+ GET_JSON_PAYLOAD(jo);
+ GET_DOUBLE_JSON_VALUE(jo, "Volume", volume);
+ GET_DOUBLE_JSON_VALUE(jo, "Price", price);
+ GET_DOUBLE_JSON_VALUE(jo, "Sl", sl);
+ GET_DOUBLE_JSON_VALUE(jo, "Tp", tp);
+ GET_INT_JSON_VALUE(jo, "TypeTime", type_time);
+ GET_LONG_JSON_VALUE(jo, "Expiration", expiration);
+
+ //Symbol
+ string symbol = Symbol();
+ if (jo.p.getValue("Symbol") != NULL)
+ symbol = jo.p.getString("Symbol");
+
+ //Comment
+ string comment = "";
+ if (jo.p.getValue("Comment") != NULL)
+ comment = jo.p.getString("Comment");
+
+#ifdef __DEBUG_LOG__
+ PrintFormat("%s: symbol = %s, volume = %f, price = %f, sl = %f, tp = %f, type_time = %d, expiration = %I64d, comment = %s",
+ __FUNCTION__, symbol, volume, price, sl, tp, type_time, expiration, comment);
+#endif
+
+ CTrade trade;
+ bool ok = trade.BuyStop(volume, price, symbol, sl, tp, (ENUM_ORDER_TYPE_TIME)type_time, (datetime)expiration, comment);
+
+ MqlTradeResult trade_result={0};
+ trade.Result(trade_result);
+
+ JSONObject* result_value_jo = new JSONObject();
+ result_value_jo.put("RetVal", new JSONBool(ok));
+ result_value_jo.put("Result", MqlTradeResultToJson(trade_result));
+
+ return CreateSuccessResponse(result_value_jo);
+}
+
+string Execute_SellStop()
+{
+ GET_JSON_PAYLOAD(jo);
+ GET_DOUBLE_JSON_VALUE(jo, "Volume", volume);
+ GET_DOUBLE_JSON_VALUE(jo, "Price", price);
+ GET_DOUBLE_JSON_VALUE(jo, "Sl", sl);
+ GET_DOUBLE_JSON_VALUE(jo, "Tp", tp);
+ GET_INT_JSON_VALUE(jo, "TypeTime", type_time);
+ GET_LONG_JSON_VALUE(jo, "Expiration", expiration);
+
+ //Symbol
+ string symbol = Symbol();
+ if (jo.p.getValue("Symbol") != NULL)
+ symbol = jo.p.getString("Symbol");
+
+ //Comment
+ string comment = "";
+ if (jo.p.getValue("Comment") != NULL)
+ comment = jo.p.getString("Comment");
+
+#ifdef __DEBUG_LOG__
+ PrintFormat("%s: symbol = %s, volume = %f, price = %f, sl = %f, tp = %f, type_time = %d, expiration = %I64d, comment = %s",
+ __FUNCTION__, symbol, volume, price, sl, tp, type_time, expiration, comment);
+#endif
+
+ CTrade trade;
+ bool ok = trade.SellStop(volume, price, symbol, sl, tp, (ENUM_ORDER_TYPE_TIME)type_time, (datetime)expiration, comment);
+
+ MqlTradeResult trade_result={0};
+ trade.Result(trade_result);
+
+ JSONObject* result_value_jo = new JSONObject();
+ result_value_jo.put("RetVal", new JSONBool(ok));
+ result_value_jo.put("Result", MqlTradeResultToJson(trade_result));
+
+ return CreateSuccessResponse(result_value_jo);
+}
+
+string Execute_OrderModify()
+{
+ GET_JSON_PAYLOAD(jo);
+ GET_ULONG_JSON_VALUE(jo, "Ticket", ticket);
+ GET_DOUBLE_JSON_VALUE(jo, "Price", price);
+ GET_DOUBLE_JSON_VALUE(jo, "Sl", sl);
+ GET_DOUBLE_JSON_VALUE(jo, "Tp", tp);
+ GET_INT_JSON_VALUE(jo, "TypeTime", type_time);
+ GET_LONG_JSON_VALUE(jo, "Expiration", expiration);
+ GET_DOUBLE_JSON_VALUE(jo, "Stoplimit", stoplimit);
+
+#ifdef __DEBUG_LOG__
+ PrintFormat("%s: ticket = %I64u, price = %f, sl = %f, tp = %f, type_time = %d, expiration = %I64d, stoplimit = %f",
+ __FUNCTION__, ticket, price, sl, tp, type_time, expiration, stoplimit);
+#endif
+
+ CTrade trade;
+ bool ok = trade.OrderModify(ticket, price, sl, tp, (ENUM_ORDER_TYPE_TIME)type_time, (datetime)expiration, stoplimit);
+
+ MqlTradeResult trade_result={0};
+ trade.Result(trade_result);
+
+ JSONObject* result_value_jo = new JSONObject();
+ result_value_jo.put("RetVal", new JSONBool(ok));
+ result_value_jo.put("Result", MqlTradeResultToJson(trade_result));
+
+ return CreateSuccessResponse(result_value_jo);
+}
+
+string Execute_OrderDelete()
+{
+ GET_JSON_PAYLOAD(jo);
+ GET_ULONG_JSON_VALUE(jo, "Ticket", ticket);
+
+#ifdef __DEBUG_LOG__
+ PrintFormat("%s: ticket = %I64u", __FUNCTION__, ticket);
+#endif
+
+ CTrade trade;
+ bool ok = trade.OrderDelete(ticket);
+
+ MqlTradeResult trade_result={0};
+ trade.Result(trade_result);
+
+ JSONObject* result_value_jo = new JSONObject();
+ result_value_jo.put("RetVal", new JSONBool(ok));
+ result_value_jo.put("Result", MqlTradeResultToJson(trade_result));
+
+ return CreateSuccessResponse(result_value_jo);
}
string Execute_GetSymbols()