Re: How to handle execution latency and broker slippage?
Posted: Thu Nov 05, 2026 9:51 am
MQL5 Implementation: Asynchronous Execution Class
Here is a production-grade asynchronous trade executor class (CAsyncTradeExecutor) that dispatches orders without blocking and tracks them via request IDs and trade transactions:
Here is a production-grade asynchronous trade executor class (CAsyncTradeExecutor) that dispatches orders without blocking and tracks them via request IDs and trade transactions:
Code: Select all
//+------------------------------------------------------------------+
//| CAsyncTradeExecutor.mqh |
//| Copyright 2026, Quant Systems |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2026"
#property link "https://www.mql5.com"
#property version "1.00"
class CAsyncTradeExecutor
private:
// Dictionary or tracking buffer for active asynchronous request IDs
ulong m_tracked_requests[];
void AddTrackedRequest(ulong req_id)
{
int size = ArraySize(m_tracked_requests);
ArrayResize(m_tracked_requests, size + 1);
m_tracked_requests[size] = req_id;
}
void RemoveTrackedRequest(ulong req_id)
{
int size = ArraySize(m_tracked_requests);
for(int i = 0; i < size; i++)
{
if(m_tracked_requests[i] == req_id)
{
// Shift array elements down
for(int j = i; j < size - 1; j++)
m_tracked_requests[j] = m_tracked_requests[j + 1];
ArrayResize(m_tracked_requests, size - 1);
break;
}
}
}
public:
CAsyncTradeExecutor()
{
ArrayFree(m_tracked_requests);
}
~CAsyncTradeExecutor() {}
// 1. Non-Blocking Order Dispatch
bool SendAsync(MqlTradeRequest &request, MqlTradeResult &result)
{
// OrderSendAsync places the packet in the terminal queue and returns immediately
bool dispatched = OrderSendAsync(request, result);
if(dispatched)
{
// Track the request ID to correlate with OnTradeTransaction callbacks
AddTrackedRequest(result.request_id);
Print("[Async Dispatch] Request queued successfully. Request ID: ", result.request_id, " Symbol: ", request.symbol);
return true;
}
else
{
Print("[Async Error] OrderSendAsync failed to queue. System Error: ", GetLastError());
return false;
}
}
// 2. Asynchronous Event Handler (Must be called from EA's OnTradeTransaction)
void HandleTransaction(const MqlTradeTransaction& trans,
const MqlTradeRequest& request,
const MqlTradeResult& result)
{
// Filter transactions related to our dispatched requests
if(trans.type == TRADE_TRANSACTION_DEAL_ADD)
{
Print("[Transaction] Deal successfully added! Deal Ticket: ", trans.deal,
" Symbol: ", trans.symbol, " Price: ", trans.price, " Volume: ", trans.volume);
}
else if(trans.type == TRADE_TRANSACTION_REQUEST)
{
// Request processing completed by terminal/broker
Print("[Transaction] Request processed. Retcode: ", result.retcode,
" Description: ", ResultRetcodeDescription(result.retcode));
// Clean up tracking buffer
RemoveTrackedRequest(result.request_id);
}
}
};