FullMt5McpByLeo/Src/Trade/Orders.mqh

469 lines
16 KiB
MQL5

2026-04-27 22:49:28 -05:00
//+------------------------------------------------------------------+
//| Orders.mqh |
//| Copyright 2026, Niquel Mendoza. |
//| https://www.mql5.com/es/users/nique_372 |
//+------------------------------------------------------------------+
#property copyright "Copyright 2026, Niquel Mendoza."
#property link "https://www.mql5.com/es/users/nique_372"
#property strict
#ifndef FULLMT5MCPBYLEO_SRC_TRADE_ORDERS_MQH
#define FULLMT5MCPBYLEO_SRC_TRADE_ORDERS_MQH
//+------------------------------------------------------------------+
//| Include |
//+------------------------------------------------------------------+
#include "..\\Def\\Def.mqh"
2026-06-03 20:39:25 -05:00
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
namespace TSN
{
2026-04-27 22:49:28 -05:00
//+------------------------------------------------------------------+
2026-04-28 08:52:21 -05:00
//| order_get_total |
2026-04-27 22:49:28 -05:00
//+------------------------------------------------------------------+
2026-04-28 08:52:21 -05:00
class CMcpFuncOrderList : public CMcpFunction
2026-04-27 22:49:28 -05:00
{
public:
2026-04-28 08:52:21 -05:00
CMcpFuncOrderList() : CMcpFunction(0, false, "order_list") {}
~CMcpFuncOrderList(void) {}
2026-04-27 22:49:28 -05:00
2026-07-13 21:11:54 -05:00
void Run(CJsonNode& param, CJsonBuilderStr* &out) override final;
2026-04-27 22:49:28 -05:00
};
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
2026-07-13 21:11:54 -05:00
void CMcpFuncOrderList::Run(CJsonNode& param, CJsonBuilderStr* &out)
2026-04-27 22:49:28 -05:00
{
2026-07-13 21:11:54 -05:00
//---
out = m_shared_builder;
m_shared_builder.PutChar('"');
m_shared_builder.Obj();
m_shared_builder.KeyWV("ok").Val(true);
m_shared_builder.KeyWV("result").Arr();
2026-04-28 08:52:21 -05:00
const int t = OrdersTotal();
for(int i = 0; i < t; i++)
{
2026-07-13 21:11:54 -05:00
m_shared_builder.Val((long)OrderGetTicket(i));
2026-04-28 08:52:21 -05:00
}
2026-07-13 21:11:54 -05:00
m_shared_builder.EndArr();
m_shared_builder.EndObj();
m_shared_builder.PutChar('"');
2026-04-27 22:49:28 -05:00
}
//+------------------------------------------------------------------+
2026-04-28 08:52:21 -05:00
//| |
2026-04-27 22:49:28 -05:00
//+------------------------------------------------------------------+
2026-04-28 08:52:21 -05:00
class CMcpFuncOrderClose : public CMcpFunction
2026-04-27 22:49:28 -05:00
{
2026-04-28 08:52:21 -05:00
private:
CTrade* m_trade;
2026-04-27 22:49:28 -05:00
public:
2026-04-28 08:52:21 -05:00
CMcpFuncOrderClose(CTrade* tr) : CMcpFunction(0, false, "order_close"), m_trade(tr) {}
~CMcpFuncOrderClose(void) {}
2026-07-13 21:11:54 -05:00
void Run(CJsonNode& param, CJsonBuilderStr* &out) override final;
2026-04-27 22:49:28 -05:00
};
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
2026-07-13 21:11:54 -05:00
void CMcpFuncOrderClose::Run(CJsonNode& param, CJsonBuilderStr* &out)
2026-04-27 22:49:28 -05:00
{
2026-07-13 21:11:54 -05:00
//---
out = m_shared_builder;
2026-04-27 22:49:28 -05:00
::ResetLastError();
2026-04-28 08:52:21 -05:00
const ulong ticket = (ulong)param["ticket"].ToInt(0);
2026-07-13 21:11:54 -05:00
m_shared_builder.PutChar('"');
m_shared_builder.Obj();
2026-04-28 08:52:21 -05:00
if(!m_trade.OrderDelete(ticket))
2026-04-27 22:49:28 -05:00
{
2026-07-13 21:11:54 -05:00
m_shared_builder.KeyWV("ok").Val(false);
m_shared_builder.KeyWV("result").ValSWV(StringFormat("Failed close order with ticket = %I64u, last mt5 err = %d", ticket, ::GetLastError()));
2026-04-27 22:49:28 -05:00
}
2026-04-28 08:52:21 -05:00
else
{
2026-07-13 21:11:54 -05:00
m_shared_builder.KeyWV("ok").Val(true);
m_shared_builder.KeyWV("result").ValSWV("success");
2026-04-28 08:52:21 -05:00
}
2026-07-13 21:11:54 -05:00
m_shared_builder.EndObj();
m_shared_builder.PutChar('"');
2026-04-28 08:52:21 -05:00
}
2026-04-27 22:49:28 -05:00
2026-04-28 08:52:21 -05:00
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
class CMcpFuncOrderModify : public CMcpFunction
{
private:
CTrade* m_trade;
public:
CMcpFuncOrderModify(CTrade* tr) : CMcpFunction(0, false, "order_modify"), m_trade(tr) {}
~CMcpFuncOrderModify(void) {}
2026-07-13 21:11:54 -05:00
void Run(CJsonNode& param, CJsonBuilderStr* &out) override final;
2026-04-28 08:52:21 -05:00
};
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
2026-07-13 21:11:54 -05:00
void CMcpFuncOrderModify::Run(CJsonNode& param, CJsonBuilderStr* &out)
2026-04-28 08:52:21 -05:00
{
2026-07-13 21:11:54 -05:00
//---
out = m_shared_builder;
2026-04-28 08:52:21 -05:00
::ResetLastError();
const ulong ticket = (ulong)param["ticket"].ToInt(0);
2026-04-28 12:26:18 -05:00
//---
if(!::OrderSelect(ticket))
{
2026-07-13 21:11:54 -05:00
m_shared_builder.PutChar('"');
m_shared_builder.Obj();
m_shared_builder.KeyWV("ok").Val(false);
m_shared_builder.KeyWV("error").ValSWV(StringFormat("order not found, last mt5 error = %d", ::GetLastError()));
m_shared_builder.EndObj();
m_shared_builder.PutChar('"');
2026-04-28 12:26:18 -05:00
return;
}
//---
2026-07-13 21:11:54 -05:00
m_shared_builder.PutChar('"');
m_shared_builder.Obj();
2026-04-28 12:26:18 -05:00
if(!m_trade.OrderModify(ticket,
param["new_price"].ToDouble(OrderGetDouble(ORDER_PRICE_OPEN)),
param["new_sl"].ToDouble(OrderGetDouble(ORDER_SL)),
param["new_tp"].ToDouble(OrderGetDouble(ORDER_TP)),
2026-06-28 22:09:10 -05:00
CEnumRegBasis::GetValNoRef<ENUM_ORDER_TYPE_TIME>(param["new_type_time"].ToString(), (ENUM_ORDER_TYPE_TIME)OrderGetInteger(ORDER_TYPE_TIME)),
2026-04-28 12:26:18 -05:00
StringToTime(param["new_expiration_time"].ToString(TimeToString(OrderGetInteger(ORDER_TIME_EXPIRATION))))
))
2026-04-28 08:52:21 -05:00
{
2026-07-13 21:11:54 -05:00
m_shared_builder.KeyWV("ok").Val(false);
m_shared_builder.KeyWV("result").ValSWV(StringFormat("Failed modify order with ticket = %I64u, last mt5 err = %d", ticket, ::GetLastError()));
2026-04-28 08:52:21 -05:00
}
else
{
2026-07-13 21:11:54 -05:00
m_shared_builder.KeyWV("ok").Val(true);
m_shared_builder.KeyWV("result").ValSWV("success");
2026-04-28 08:52:21 -05:00
}
2026-07-13 21:11:54 -05:00
m_shared_builder.EndObj();
m_shared_builder.PutChar('"');
2026-04-27 22:49:28 -05:00
}
//+------------------------------------------------------------------+
2026-04-29 07:59:28 -05:00
//| order_get |
2026-04-27 22:49:28 -05:00
//+------------------------------------------------------------------+
2026-04-29 07:59:28 -05:00
class CMcpFuncOrderGet : public CMcpFunction
2026-04-27 22:49:28 -05:00
{
public:
2026-04-29 07:59:28 -05:00
CMcpFuncOrderGet() : CMcpFunction(0, false, "order_get") {}
~CMcpFuncOrderGet(void) {}
2026-04-27 22:49:28 -05:00
2026-07-13 21:11:54 -05:00
void Run(CJsonNode& param, CJsonBuilderStr* &out) override final;
2026-04-27 22:49:28 -05:00
};
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
2026-07-13 21:11:54 -05:00
void CMcpFuncOrderGet::Run(CJsonNode& param, CJsonBuilderStr* &out)
2026-04-27 22:49:28 -05:00
{
2026-07-13 21:11:54 -05:00
//---
out = m_shared_builder;
2026-04-27 22:49:28 -05:00
::ResetLastError();
const ulong ticket = (ulong)param["ticket"].ToInt(0);
//---
2026-04-28 08:52:21 -05:00
if(!::OrderSelect(ticket))
2026-04-27 22:49:28 -05:00
{
2026-07-13 21:11:54 -05:00
m_shared_builder.PutChar('"');
m_shared_builder.Obj();
m_shared_builder.KeyWV("ok").Val(false);
m_shared_builder.KeyWV("error").ValSWV(StringFormat("order_not_found, last mt5 error = %d", ::GetLastError()));
m_shared_builder.EndObj();
m_shared_builder.PutChar('"');
2026-04-27 22:49:28 -05:00
return;
}
2026-07-01 08:32:45 -05:00
2026-04-27 22:49:28 -05:00
//---
2026-06-03 20:39:25 -05:00
const int8_t mode = (int8_t)param["mode"].ToInt(0);
2026-04-29 07:59:28 -05:00
switch(mode)
{
//--- DOUBLE
case 0:
{
double v;
if(OrderGetDouble(
2026-06-28 22:09:10 -05:00
CEnumRegBasis::GetValNoRef<ENUM_ORDER_PROPERTY_DOUBLE>(param["property"].ToString(""), WRONG_VALUE),
2026-04-29 07:59:28 -05:00
v))
{
2026-07-13 21:11:54 -05:00
m_shared_builder.PutChar('"');
m_shared_builder.Obj();
m_shared_builder.KeyWV("ok").Val(true);
m_shared_builder.KeyWV("result").Val(v);
m_shared_builder.EndObj();
m_shared_builder.PutChar('"');
2026-04-29 07:59:28 -05:00
return;
}
break;
}
2026-04-27 22:49:28 -05:00
2026-04-29 07:59:28 -05:00
//--- INTEGER
case 1:
{
long v;
if(OrderGetInteger(
2026-06-28 22:09:10 -05:00
CEnumRegBasis::GetValNoRef<ENUM_ORDER_PROPERTY_INTEGER>(param["property"].ToString(""), WRONG_VALUE),
2026-04-29 07:59:28 -05:00
v))
{
2026-07-13 21:11:54 -05:00
m_shared_builder.PutChar('"');
m_shared_builder.Obj();
m_shared_builder.KeyWV("ok").Val(true);
m_shared_builder.KeyWV("result").Val(v);
m_shared_builder.EndObj();
m_shared_builder.PutChar('"');
2026-04-29 07:59:28 -05:00
return;
}
break;
}
2026-04-27 22:49:28 -05:00
2026-04-29 07:59:28 -05:00
//--- STRING
case 2:
{
string v;
if(OrderGetString(
2026-06-28 22:09:10 -05:00
CEnumRegBasis::GetValNoRef<ENUM_ORDER_PROPERTY_STRING>(param["property"].ToString(""), WRONG_VALUE),
2026-04-29 07:59:28 -05:00
v))
{
2026-07-13 21:11:54 -05:00
m_shared_builder.PutChar('"');
m_shared_builder.Obj();
m_shared_builder.KeyWV("ok").Val(true);
m_shared_builder.KeyWV("result").ValS(v);
m_shared_builder.EndObj();
m_shared_builder.PutChar('"');
2026-04-29 07:59:28 -05:00
return;
}
break;
}
2026-04-27 22:49:28 -05:00
2026-04-29 07:59:28 -05:00
default:
2026-07-13 21:11:54 -05:00
m_shared_builder.PutChar('"');
m_shared_builder.Obj();
m_shared_builder.KeyWV("ok").Val(false);
m_shared_builder.KeyWV("error").ValSWV(StringFormat("Invalid mode = %d", mode));
m_shared_builder.EndObj();
m_shared_builder.PutChar('"');
2026-04-29 07:59:28 -05:00
return;
2026-04-27 22:49:28 -05:00
}
//---
2026-07-13 21:11:54 -05:00
m_shared_builder.PutChar('"');
m_shared_builder.Obj();
m_shared_builder.KeyWV("ok").Val(false);
m_shared_builder.KeyWV("error").ValSWV(StringFormat("Failed call OrderGet*, last err mt5 = %d", ::GetLastError()));
m_shared_builder.EndObj();
m_shared_builder.PutChar('"');
2026-04-27 22:49:28 -05:00
}
2026-07-01 08:32:45 -05:00
2026-04-27 22:49:28 -05:00
//+------------------------------------------------------------------+
2026-04-29 07:59:28 -05:00
//| |
2026-04-27 22:49:28 -05:00
//+------------------------------------------------------------------+
2026-04-29 07:59:28 -05:00
class CMcpFuncCalcOrder : public CMcpFunction
2026-04-27 22:49:28 -05:00
{
2026-04-29 07:59:28 -05:00
private:
CGetLote m_get_lote;
2026-04-27 22:49:28 -05:00
public:
2026-04-29 07:59:28 -05:00
CMcpFuncCalcOrder() : CMcpFunction(0, false, "calc_order"), m_get_lote("") {}
~CMcpFuncCalcOrder(void) {}
2026-04-27 22:49:28 -05:00
2026-07-13 21:11:54 -05:00
void Run(CJsonNode& param, CJsonBuilderStr* &out) override final;
2026-04-27 22:49:28 -05:00
};
2026-07-01 08:32:45 -05:00
2026-04-27 22:49:28 -05:00
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
2026-07-13 21:11:54 -05:00
void CMcpFuncCalcOrder::Run(CJsonNode &param, CJsonBuilderStr* &out)
2026-04-27 22:49:28 -05:00
{
2026-04-29 07:59:28 -05:00
//---
2026-07-13 21:11:54 -05:00
out = m_shared_builder;
2026-07-01 09:24:34 -05:00
const int8_t mode = CEnumRegFullMt5Mcp::GetValNoRef<int8_t>(param["mode"].ToString(""), WRONG_VALUE);
2026-07-01 08:32:45 -05:00
const ENUM_ORDER_TYPE type = CEnumRegBasis::GetValNoRef<ENUM_ORDER_TYPE>(param["order_type"].ToString(""), ORDER_TYPE_CLOSE_BY);
2026-04-29 07:59:28 -05:00
2026-07-01 08:32:45 -05:00
//---
2026-04-29 07:59:28 -05:00
m_get_lote.SetSymbol(param["symbol"].ToString(""));
2026-04-28 08:52:21 -05:00
2026-04-27 22:49:28 -05:00
//---
2026-04-29 07:59:28 -05:00
switch(mode)
2026-04-27 22:49:28 -05:00
{
2026-04-29 07:59:28 -05:00
//--- CalculateSLWithLot
2026-07-01 08:32:45 -05:00
case MCPFUNC_CALCORDER_CALCULATE_SL_WITH_LOT:
2026-04-29 07:59:28 -05:00
{
long v = m_get_lote.CalculateSLWithLot(
param["risk_per_operation"].ToDouble(0.0),
param["entry_price"].ToDouble(0.0),
param["lot_size"].ToDouble(0.0),
2026-06-03 20:39:25 -05:00
(ulong)param["deviation"].ToInt(0),
(ulong)param["stop_limit"].ToInt(0)
2026-04-29 07:59:28 -05:00
);
2026-04-27 22:49:28 -05:00
2026-04-29 07:59:28 -05:00
if(v <= 0)
{
2026-07-13 21:11:54 -05:00
m_shared_builder.PutChar('"');
m_shared_builder.Obj();
m_shared_builder.KeyWV("ok").Val(false);
m_shared_builder.KeyWV("error").ValSWV("Failed CalculateSLWithLot, check logs");
m_shared_builder.EndObj();
m_shared_builder.PutChar('"');
2026-04-29 07:59:28 -05:00
return;
}
2026-07-13 21:11:54 -05:00
m_shared_builder.PutChar('"');
m_shared_builder.Obj();
m_shared_builder.KeyWV("ok").Val(true);
m_shared_builder.KeyWV("result").Val(v);
m_shared_builder.EndObj();
m_shared_builder.PutChar('"');
2026-04-29 07:59:28 -05:00
break;
}
//--- MoneyToPoints
2026-07-01 08:32:45 -05:00
case MCPFUNC_CALCORDER_MONEY_TO_POINTS:
2026-04-29 07:59:28 -05:00
{
2026-07-01 08:32:45 -05:00
double chosen_lot = 0.00;
2026-04-29 07:59:28 -05:00
long v = m_get_lote.MoneyToPoints(
type,
param["risk_per_operation"].ToDouble(0.0),
param["entry_price"].ToDouble(0.0),
chosen_lot,
2026-06-03 20:39:25 -05:00
(ulong)param["deviation"].ToInt(0),
(ulong)param["stop_limit"].ToInt(0)
2026-04-29 07:59:28 -05:00
);
if(v <= 0)
{
2026-07-13 21:11:54 -05:00
m_shared_builder.PutChar('"');
m_shared_builder.Obj();
m_shared_builder.KeyWV("ok").Val(false);
m_shared_builder.KeyWV("error").ValSWV("Failed MoneyToPoints, check logs");
m_shared_builder.EndObj();
m_shared_builder.PutChar('"');
2026-04-29 07:59:28 -05:00
return;
}
2026-04-27 22:49:28 -05:00
2026-07-13 21:11:54 -05:00
m_shared_builder.PutChar('"');
m_shared_builder.Obj();
m_shared_builder.KeyWV("ok").Val(true);
m_shared_builder.KeyWV("result").Val(v);
m_shared_builder.KeyWV("lot").Val(chosen_lot);
m_shared_builder.EndObj();
m_shared_builder.PutChar('"');
2026-04-29 07:59:28 -05:00
break;
}
//--- GetLoteByRiskPerOperationAndSL
2026-07-01 08:32:45 -05:00
case MCPFUNC_CALCORDER_GET_LOTE_BY_RISK_MONEY_AND_SL_POINTS:
2026-04-29 07:59:28 -05:00
{
double new_risk = 0.0;
double v = m_get_lote.GetLoteByRiskPerOperationAndSL(
param["max_lot"].ToDouble(0.0),
param["risk_per_operation"].ToDouble(0.0),
new_risk,
2026-06-03 20:39:25 -05:00
(long)param["sl"].ToInt(0)
2026-04-29 07:59:28 -05:00
);
if(v <= 0.0)
{
2026-07-13 21:11:54 -05:00
m_shared_builder.PutChar('"');
m_shared_builder.Obj();
m_shared_builder.KeyWV("ok").Val(false);
m_shared_builder.KeyWV("error").ValSWV("Failed GetLoteByRiskPerOperationAndSL, check logs");
m_shared_builder.EndObj();
m_shared_builder.PutChar('"');
2026-04-29 07:59:28 -05:00
return;
}
2026-07-13 21:11:54 -05:00
m_shared_builder.PutChar('"');
m_shared_builder.Obj();
m_shared_builder.KeyWV("ok").Val(true);
m_shared_builder.KeyWV("result").Val(v);
m_shared_builder.KeyWV("risk").Val(new_risk);
m_shared_builder.EndObj();
m_shared_builder.PutChar('"');
2026-04-29 07:59:28 -05:00
break;
}
//--- GetMaxLote
2026-07-01 08:32:45 -05:00
case MCPFUNC_CALCORDER_GET_MAX_LOTE_TO_TRADE:
2026-04-29 07:59:28 -05:00
{
double v = m_get_lote.GetMaxLote(
type,
param["entry_price"].ToDouble(0.0),
2026-06-03 20:39:25 -05:00
(ulong)param["deviation"].ToInt(0),
(ulong)param["stop_limit"].ToInt(0)
2026-04-29 07:59:28 -05:00
);
if(v <= 0.0)
{
2026-07-13 21:11:54 -05:00
m_shared_builder.PutChar('"');
m_shared_builder.Obj();
m_shared_builder.KeyWV("ok").Val(false);
m_shared_builder.KeyWV("error").ValSWV("Failed GetMaxLote, check logs");
m_shared_builder.EndObj();
m_shared_builder.PutChar('"');
2026-04-29 07:59:28 -05:00
return;
}
2026-07-13 21:11:54 -05:00
m_shared_builder.PutChar('"');
m_shared_builder.Obj();
m_shared_builder.KeyWV("ok").Val(true);
m_shared_builder.KeyWV("result").Val(v);
m_shared_builder.EndObj();
m_shared_builder.PutChar('"');
2026-04-29 07:59:28 -05:00
break;
}
//--- GetLoteByRiskPerOperation
2026-07-01 08:32:45 -05:00
case MCPFUNC_CALCORDER_GET_LOTE_BY_ONLY_RISK_MONEY:
2026-04-29 07:59:28 -05:00
{
double v = m_get_lote.GetLoteByRiskPerOperation(
type,
param["risk_per_operation"].ToDouble(0.0),
param["entry_price"].ToDouble(0.0),
2026-06-03 20:39:25 -05:00
(ulong)param["deviation"].ToInt(0),
(ulong)param["stop_limit"].ToInt(0)
2026-04-29 07:59:28 -05:00
);
if(v <= 0.0)
{
2026-07-13 21:11:54 -05:00
m_shared_builder.PutChar('"');
m_shared_builder.Obj();
m_shared_builder.KeyWV("ok").Val(false);
m_shared_builder.KeyWV("error").ValSWV("Failed GetLoteByRiskPerOperation, check logs");
m_shared_builder.EndObj();
m_shared_builder.PutChar('"');
2026-04-29 07:59:28 -05:00
return;
}
2026-07-13 21:11:54 -05:00
m_shared_builder.PutChar('"');
m_shared_builder.Obj();
m_shared_builder.KeyWV("ok").Val(true);
m_shared_builder.KeyWV("result").Val(v);
m_shared_builder.EndObj();
m_shared_builder.PutChar('"');
2026-04-29 07:59:28 -05:00
break;
}
default:
2026-07-13 21:11:54 -05:00
m_shared_builder.PutChar('"');
m_shared_builder.Obj();
m_shared_builder.KeyWV("ok").Val(false);
m_shared_builder.KeyWV("error").ValSWV(StringFormat("Invalid mode = %d", mode));
m_shared_builder.EndObj();
m_shared_builder.PutChar('"');
2026-04-29 07:59:28 -05:00
break;
}
}
2026-04-27 22:49:28 -05:00
//+------------------------------------------------------------------+
2026-06-03 20:39:25 -05:00
} // namespace TSN
2026-04-27 22:49:28 -05:00
#endif // FULLMT5MCPBYLEO_SRC_TRADE_ORDERS_MQH