2026-04-27 22:49:28 -05:00 | | | //+------------------------------------------------------------------+
|
2026-04-28 08:52:21 -05:00 | | | //| Positions.mqh |
|
2026-04-27 22:49:28 -05:00 | | | //| 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_POSITIONS_MQH
|
| | | #define FULLMT5MCPBYLEO_SRC_TRADE_POSITIONS_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 | | | //| position_list |
|
2026-04-27 22:49:28 -05:00 | | | //+------------------------------------------------------------------+
|
2026-04-28 08:52:21 -05:00 | | | class CMcpFuncPositionList : public CMcpFunction
|
2026-04-27 22:49:28 -05:00 | | | {
|
| | | public:
|
2026-04-28 08:52:21 -05:00 | | | CMcpFuncPositionList() : CMcpFunction(0, false, "position_list") {}
|
| | | ~CMcpFuncPositionList(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 CMcpFuncPositionList::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 = PositionsTotal();
|
| | | for(int i = 0; i < t; i++)
|
2026-04-27 22:49:28 -05:00 | | | {
|
2026-07-13 21:11:54 -05:00 | | | m_shared_builder.Val((long)PositionGetTicket(i));
|
2026-04-27 22:49:28 -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-29 07:59:28 -05:00 | | | //| position_get |
|
2026-04-27 22:49:28 -05:00 | | | //+------------------------------------------------------------------+
|
2026-04-29 07:59:28 -05:00 | | | class CMcpFuncPositionGet : public CMcpFunction
|
2026-04-27 22:49:28 -05:00 | | | {
|
| | | public:
|
2026-04-29 07:59:28 -05:00 | | | CMcpFuncPositionGet() : CMcpFunction(0, false, "position_get") {}
|
| | | ~CMcpFuncPositionGet(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 CMcpFuncPositionGet::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 = param["ticket"].ToInt(0);
|
| | |
|
| | | //---
|
| | | if(!PositionSelectByTicket(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("position_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-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)
|
2026-04-27 22:49:28 -05:00 | | | {
|
| | |
|
2026-04-29 07:59:28 -05:00 | | | //---
|
| | | case 0:
|
| | | {
|
| | | double v;
|
2026-06-28 22:09:10 -05:00 | | | if(PositionGetDouble(CEnumRegBasis::GetValNoRef<ENUM_POSITION_PROPERTY_DOUBLE>(param["property"].ToString(""), WRONG_VALUE), v))
|
2026-04-29 07:59: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.EndObj();
|
| | | m_shared_builder.PutChar('"');
|
2026-04-29 07:59:28 -05:00 | | | return;
|
| | | }
|
| | | break;
|
| | | }
|
| | |
|
| | | //---
|
| | | case 1:
|
| | | {
|
| | | long v;
|
2026-06-28 22:09:10 -05:00 | | | if(PositionGetInteger(CEnumRegBasis::GetValNoRef<ENUM_POSITION_PROPERTY_INTEGER>(param["property"].ToString(""), WRONG_VALUE), v))
|
2026-04-29 07:59: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.EndObj();
|
| | | m_shared_builder.PutChar('"');
|
2026-04-29 07:59:28 -05:00 | | | return;
|
| | | }
|
| | | break;
|
| | | }
|
| | |
|
| | | //---
|
| | | case 2:
|
| | | {
|
| | | string v;
|
2026-06-28 22:09:10 -05:00 | | | if(PositionGetString(CEnumRegBasis::GetValNoRef<ENUM_POSITION_PROPERTY_STRING>(param["property"].ToString(""), WRONG_VALUE), v))
|
2026-04-29 07:59: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").ValS(v);
|
| | | m_shared_builder.EndObj();
|
| | | m_shared_builder.PutChar('"');
|
2026-04-29 07:59:28 -05:00 | | | return;
|
| | | }
|
| | | 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 | | | return;
|
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-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 to call PositionGet*, last err mt5 = %d", ::GetLastError()));
|
| | | m_shared_builder.EndObj();
|
| | | m_shared_builder.PutChar('"');
|
2026-04-28 08:52:21 -05:00 | | | }
|
| | |
|
2026-04-29 07:59:28 -05:00 | | |
|
2026-04-28 08:52:21 -05:00 | | | //+------------------------------------------------------------------+
|
| | | //| position_close |
|
| | | //+------------------------------------------------------------------+
|
| | | class CMcpFuncPositionClose : public CMcpFunction
|
| | | {
|
| | | private:
|
| | | CTrade* m_trade;
|
| | | public:
|
| | | CMcpFuncPositionClose(CTrade* tr) : CMcpFunction(0, false, "position_close"), m_trade(tr) {}
|
| | | ~CMcpFuncPositionClose(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-04-29 07:59:28 -05:00 | | | "type": "by_symbol",
|
| | | "value": "XAUUSD",
|
| | | "deviation": 100
|
| | | "volume" : 0.01 // Campo opcional (si no se indica se cierra todo)
|
2026-04-28 08:52:21 -05:00 | | | }
|
| | | */
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | //| |
|
| | | //+------------------------------------------------------------------+
|
2026-07-13 21:11:54 -05:00 | | | void CMcpFuncPositionClose::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 string type = param["type"].ToString("by_ticket");
|
| | | const ulong deviation = (ulong)param["deviation"].ToInt(ULONG_MAX);
|
| | |
|
| | | //---
|
| | | if(type == "by_symbol")
|
| | | {
|
| | | if(param.HasKey("volume"))
|
| | | {
|
| | | if(!m_trade.PositionClosePartial(param["value"].ToString(""), param["volume"].ToDouble(0.00), deviation))
|
| | | {
|
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("position_close by_symbol failed (partial), last mt5 error = %d", ::GetLastError()));
|
| | | m_shared_builder.EndObj();
|
| | | m_shared_builder.PutChar('"');
|
2026-04-28 08:52:21 -05:00 | | | return;
|
| | | }
|
| | | }
|
| | | else
|
| | | {
|
| | | if(!m_trade.PositionClose(param["value"].ToString(""), deviation))
|
| | | {
|
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("position_close by_symbol failed, last mt5 error = %d", ::GetLastError()));
|
| | | m_shared_builder.EndObj();
|
| | | m_shared_builder.PutChar('"');
|
2026-04-28 08:52:21 -05:00 | | | return;
|
| | | }
|
| | | }
|
| | | }
|
| | | else
|
| | | if(type == "by_ticket")
|
| | | {
|
| | | if(param.HasKey("volume"))
|
| | | {
|
| | | if(!m_trade.PositionClosePartial(ulong(param["value"].ToInt(0)), param["volume"].ToDouble(0.00), deviation))
|
| | | {
|
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("position_close by_ticket (partial) failed, last mt5 error = %d", ::GetLastError()));
|
| | | m_shared_builder.EndObj();
|
| | | m_shared_builder.PutChar('"');
|
2026-04-28 08:52:21 -05:00 | | | return;
|
| | | }
|
| | | }
|
| | | else
|
| | | {
|
| | | if(!m_trade.PositionClose(ulong(param["value"].ToInt(0)), deviation))
|
| | | {
|
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("position_close by_ticket failed, last mt5 error = %d", ::GetLastError()));
|
| | | m_shared_builder.EndObj();
|
| | | m_shared_builder.PutChar('"');
|
2026-04-28 08:52:21 -05:00 | | | return;
|
| | | }
|
| | | }
|
| | | }
|
| | | else
|
| | | {
|
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("invalid type, use 'by_symbol' or 'by_ticket'");
|
| | | m_shared_builder.EndObj();
|
| | | m_shared_builder.PutChar('"');
|
2026-04-28 08:52:21 -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").ValSWV("success");
|
| | | m_shared_builder.EndObj();
|
| | | m_shared_builder.PutChar('"');
|
2026-04-28 08:52:21 -05:00 | | | }
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | //| position_modify |
|
| | | //+------------------------------------------------------------------+
|
| | | class CMcpFuncPositionModify : public CMcpFunction
|
| | | {
|
| | | private:
|
| | | CTrade* m_trade;
|
| | | public:
|
| | | CMcpFuncPositionModify(CTrade* tr) : CMcpFunction(0, false, "position_modify"), m_trade(tr) {}
|
| | | ~CMcpFuncPositionModify(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 CMcpFuncPositionModify::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(!PositionSelectByTicket(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("result").ValSWV(StringFormat("Error select ticket, last mt5 err = %d", ::GetLastError()));
|
| | | m_shared_builder.EndObj();
|
| | | m_shared_builder.PutChar('"');
|
2026-04-28 15:55:06 -05:00 | | | return;
|
2026-04-28 12:26:18 -05:00 | | | }
|
| | |
|
| | | //---
|
| | | if(!m_trade.PositionModify(ticket, param["sl"].ToDouble(PositionGetDouble(POSITION_SL)), param["tp"].ToDouble(PositionGetDouble(POSITION_TP))))
|
2026-04-28 08:52:21 -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("position_modify failed, last mt5 error = %d", ::GetLastError()));
|
| | | m_shared_builder.EndObj();
|
| | | m_shared_builder.PutChar('"');
|
2026-04-28 08:52:21 -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").ValSWV("success");
|
| | | m_shared_builder.EndObj();
|
| | | m_shared_builder.PutChar('"');
|
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_POSITIONS_MQH
|