I have a love-hate relationship with the MT4 Strategy Tester. It's an incredibly powerful tool for backtesting, but when you're staring down a "history not available" error or getting slapped with a "trade context busy" during live trading, the love part takes a hike.
These two errors pop up all the time, yet when you search for them, the resources are shockingly thin. Most forums will tell you to "just restart MT4" or "reinstall." That's like telling someone with a flat tire to just buy a new car. It works, but it's overkill and you never actually learn what went wrong. Let's fix that.
Problem 1: The Phantom "History Not Available" Error
You're setting up a backtest, you've got your EA loaded, the pair is selected, but when you hit "Start," you get the dreaded "history not available for [symbol]." The immediate reaction is usually to assume the broker's data server is down or something is broken with the MT4 installation. Sometimes that's true, but most of the time, it's a permissions issue that gets overlooked.
I ran into this a few months back while testing a new scalping algorithm. The EA would backtest fine on my main machine but kept giving the history error on my VPS. After a lot of unnecessary frustration, I realized the VPS had a stricter folder permission setup.
Here's the check that actually solves this 90% of the time:
MQL4 > Tester. Inside, you'll find folders for each symbol. If the folder for the symbol you're testing is missing or empty, that's your answer. The tester needs to write cache files here, and if it can't, it throws the history error.Tester folder as a more sensitive location, especially if MT4 is installed in Program Files. The platform tries to write data, gets blocked, and doesn't give a clear error about the permission denial, just a generic "history not available." As a quick test, I manually copied the historical data files from the history folder (located in the main MT4 directory, not the MQL4 folder) into the Tester folder. Once the files were there, the backtest ran without a hitch. This is a half-workaround, half-diagnostic trick that I've never seen documented anywhere else. If it works, you know the issue is write permissions. If it doesn't, the problem is likely with the broker's data feed.MQL4 folder, select Properties, go to the Security tab, and ensure that your user account has "Full control." Click Apply, then close and restart MT4.MetaQuotes' official documentation explains that the tester uses historical data from the broker's servers, but they don't delve into the local caching permission issues. It's one of those details that you just have to figure out on the battlefield.
Problem 2: The Maddening "Trade Context Busy" Error
This one is the bane of EA developers. You've got a beautifully coded robot, it's opening and closing trades, and then suddenly, nothing. Every attempt to place an order returns "trade context busy" or "market is closed" (when it clearly isn't).
Search engines will tell you it's a lack of error handling in your EA's code. And they're not wrong. But there's a specific, more "hidden" reason for this that's rarely discussed: the EA is trying to execute multiple trade operations faster than the server can acknowledge them.
I spent a full day tracking this down on a client's grid EA. The code was tight, error handling was in place, but during volatile news events, it would just freeze up. Here's the fix that's more effective than just adding
Sleep(100); commands:OrderSend() or OrderModify(), you need to call RefreshRates(). This updates the internal market data (like Ask and Bid) before the order is placed. It sounds basic, but I've seen EAs where the developer put RefreshRates() only in the OrderSend() function, but not in the OrderModify() or OrderClose() functions. This mismatch can lock up the trade context because the EA is trying to send an order with old price data, the server rejects it, and the context gets stuck.ERR_TRADE_CONTEXT_BUSY specifically and then wait. In a recent rescue project, I used this snippet:``
mq4
int retry = 0;
while(retry < 5)
{
RefreshRates();
int ticket = OrderSend(Symbol(), OP_BUY, 0.1, Ask, 3, 0, 0, "Comment", 0, 0, Green);
if(ticket > 0) break;
if(GetLastError() == ERR_TRADE_CONTEXT_BUSY)
{
Sleep(1000);
retry++;
}
else
{
// Handle other errors
break;
}
}
``Reference: MQL4 Documentation – OrderSend and RefreshRates (docs.mql4.com), MetaQuotes Help Center – Strategy Tester (help.metaquotes.net).
This article is originally published on FXEAR.com, original content, reproduction without authorization is prohibited.