MQL5Book/Scripts/p6/TradeGuardExample.mq5
super.admin 1c8e83ce31 convert
2025-05-30 16:09:41 +02:00

70 lines
No EOL
2.8 KiB
MQL5

//+------------------------------------------------------------------+
//| TradeGuardExample.mq5 |
//| Copyright 2022, MetaQuotes Ltd. |
//| https://www.mql5.com |
//| Open pending order if not exists. As soon as it's triggered into |
//| position, close the position. Normally, order or position |
//| should exist, no more than one of either kind. Yet if trade |
//| environment is not synced, OrdersTotal() may report 0 (order is |
//| already filled), but position is not yet listed in |
//| PositionsTotal(). This is why we need the guard. |
//+------------------------------------------------------------------+
#include "..\..\Include\MqlTradeSync.mqh"
#include "..\..\Include\TradeGuard.mqh"
// uncomment this define to run without the guard: duplicated positions are possible
// #define SKIP_TRADE_GUARD
#ifndef SKIP_TRADE_GUARD
TradeGuard guard;
#endif
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
if(AccountInfoInteger(ACCOUNT_TRADE_MODE) != ACCOUNT_TRADE_MODE_DEMO)
{
Alert("This is a test script! Run it on a DEMO account only!");
return;
}
// 2 positions, 2 orders, or order and position is a broken state: stop the script
while(!IsStopped() && (OrdersTotal() + PositionsTotal() < 2))
{
#ifndef SKIP_TRADE_GUARD
if(guard.waitsync()) // active orders, history and positions are consistent (in sync)
#endif
{
MqlTradeRequestSync trade;
if(PositionsTotal() == 1)
{
trade.close(PositionGetTicket(0)); // close position if it exists
}
else if(!OrdersTotal()) // neither position nor order does exist
{
// create a pending order
const ulong ticket = trade.buyLimit(0.01, SymbolInfoDouble(_Symbol, SYMBOL_ASK));
#ifndef SKIP_TRADE_GUARD
if(ticket) guard.push(ticket); // add the order into environment to control
#endif
}
Sleep(100); // adjust for acceptable CPU load
}
#ifndef SKIP_TRADE_GUARD
else // on timeout some error handling is required
{
guard.pop(); // here we just drop problematic order from the guard
}
#endif
}
}
//+------------------------------------------------------------------+
/*
The guard sporadically outputs:
2022.08.24 14:03:25.552 Order is missing: 1437363765
2022.08.24 14:03:25.661 Order found (position opened): 1437363765 (1437363765)
*/