Generate code in 3 minutes
Enter your idea and AI generates runnable code.
To ensure robust execution in MQL4, you should perform these checks sequentially. Since the trading context can be temporarily busy (e.g., another Expert Advisor is currently trading), it is best practice to implement a retry mechanism rather than immediately failing.
Here is the complete MQL4 code implementing a robust check function.
//+------------------------------------------------------------------+
//| CheckTradeStatus.mq4 |
//| Copyright 2023, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2023, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property strict
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
// Example logic: Place a Buy order if conditions are met
// This is just a trigger example
if(OrdersTotal() == 0)
{
// 1. Perform the safety checks before attempting to trade
if(CheckTradingEnvironment())
{
// 2. If checks pass, refresh rates to ensure Ask/Bid are current
RefreshRates();
// 3. Place the order
int ticket = OrderSend(Symbol(), OP_BUY, 0.1, Ask, 3, 0, 0, "My Order", 0, 0, clrGreen);
if(ticket < 0)
{
Print("OrderSend failed with error #", GetLastError());
}
else
{
Print("Order placed successfully. Ticket: ", ticket);
}
}
}
}
//+------------------------------------------------------------------+
//| Function to check connection, permissions, and trade context |
//+------------------------------------------------------------------+
bool CheckTradingEnvironment()
{
// 1. Check connection to the server
if(!IsConnected())
{
Print("Error: Terminal is not connected to the server.");
return(false);
}
// 2. Check if trading is allowed (AutoTrading button + EA Permission)
// Note: IsTradeAllowed() checks both the global terminal setting and the specific EA setting.
if(!IsTradeAllowed())
{
Print("Error: Trading is not allowed. Check 'AutoTrading' button and EA properties.");
return(false);
}
// 3. Check if Trade Context is busy (with retry mechanism)
// The trade context might be busy if another EA is trading at the exact same moment.
int retryCount = 0;
int maxRetries = 10;
int sleepTime = 100; // Milliseconds
while(IsTradeContextBusy())
{
// If context is busy, wait and try again
Sleep(sleepTime);
retryCount++;
// If we exceeded max retries, abort
if(retryCount >= maxRetries)
{
Print("Error: Trade context is busy. Timeout after ", (maxRetries * sleepTime), "ms.");
return(false);
}
}
// If we waited for the context to clear, we must refresh market info
// because prices might have moved during the Sleep()
if(retryCount > 0)
{
RefreshRates();
}
// All checks passed
return(true);
}
IsConnected():
true if the client terminal is connected to the broker's server. If this returns false, OrderSend will inevitably fail.IsTradeAllowed():
false.IsTradeContextBusy():
OrderSend would fail with error 146 (ERR_TRADE_CONTEXT_BUSY).while loop in the code above waits (using Sleep) for the context to free up before proceeding.RefreshRates():
Sleep() loop because the context was busy, time passes. During that time, the Ask and Bid variables stored in the cache might become outdated. RefreshRates() updates these variables to the absolute latest market prices.Q: Why do I need RefreshRates() after checking IsTradeContextBusy()?
A: MQL4 stores Ask and Bid prices when OnTick starts. If your code pauses (using Sleep) to wait for the trade context to clear, the market prices may change. RefreshRates() forces the EA to fetch the newest prices, preventing "Invalid Price" or "Requote" errors.
Q: Can IsTradeAllowed() return false even if AutoTrading is on?
A: Yes. It can return false if the specific EA does not have the "Allow live trading" permission checked in its properties, or if the terminal is logged in with an Investor (read-only) password.
Q: Does IsTradeContextBusy() exist in MQL5?
A: No. MQL5 is multi-threaded regarding trading operations, so multiple EAs can trade simultaneously without blocking each other. This check is specific to the architecture of MQL4.