Why EAs That Trade on Closed Bars Don't Repaint
Contents
The short answer: the signals of an EA that decides only on closed bars rarely change because the data it bases its decision on has stopped moving by then. For a forming bar, the close, high, and low can all change on the next tick. For a closed bar, the four prices (open, high, low, close) normally do not move after it closes.
That said, reading closed bars does not guarantee safety. Depending on how an indicator is calculated or how higher timeframes are handled, future values can still leak in even when you believe you are using closed bars.
Why the Forming Bar Is Dangerous
In MQL5, shift 0 is the forming bar and shift 1 is the most recent closed bar. The close at shift 0 is merely "the current price." Using it for decisions causes the following problems:
- Conditions appear and disappear tick by tick, so the reason for an entry can vanish after the fact
- Orders fill on momentary signals that never remain on the chart once the bar closes
- In the tester, results shift easily depending on how ticks are generated, and when intrabar price movement differs from reality, that gap feeds straight into performance
| Item | Forming bar (shift 0) | Closed bar (shift 1 and older) |
|---|---|---|
| Values used for decisions | Change until the bar closes | Normally do not change |
| Signal reproducibility | Low | High |
| Entry speed | Fast | Slower by the wait for the close |
| Effect of tester tick model | The decision itself can change | Small effect on the decision (still affects exits) |
Using the forming bar is not always a mistake. Some designs aim to catch a breakout instantly. In that case, you should acknowledge that the strategy depends on intrabar movement and put more weight on testing with real ticks.
Recommended Broker Comparison →
🎁 Download Free EA📧 Free 8-email course + subscriber-only pack of 13 MT5 indicators
Right after you sign up, you get a download link for a subscriber-only pack of our 13 MT5 indicators: compiled files (.ex5), source code and a setup guide. Then 8 emails on algo-trading essentials, reading backtests correctly and choosing a broker (one a day for the first 5 days, then 7, 14 and 30 days after signing up). You also get notified before each price rise of the versions sold on the MQL5 Market (launch pricing that steps up as copies sell). Our EAs are free on this site with a live account at a partner broker.
* Privacy strictly protected. You can unsubscribe at any time.
Designing a Fixed Signal
Make CopyRates' start position and ordering explicit
Read the closed bars once, on the first tick of each new bar.
datetime g_lastBar = 0;
void OnTick()
{
datetime t = iTime(_Symbol, _Period, 0);
if(t == 0 || t == g_lastBar) return;
MqlRates r[];
ArraySetAsSeries(r, true);
if(CopyRates(_Symbol, _Period, 1, 2, r) != 2) return;
g_lastBar = t;
// r[0] is the most recent closed bar, r[1] is the one before it
}
There are three key points. Set the start position to 1 so the forming bar is outside the requested range. Use ArraySetAsSeries to fix the ordering. And if the copy fails, do not update g_lastBar, so the next tick retries. If you forget to set the ordering, the first element of the array is the oldest bar.
iBarShift is a trap with higher timeframes
When referencing a higher timeframe, iBarShift returns "the bar that contains that time." If you pass the current time, it normally returns the forming higher-timeframe bar.
int s = iBarShift(_Symbol, PERIOD_H1, TimeCurrent(), false);
if(s < 0) return;
double closedH1 = iClose(_Symbol, PERIOD_H1, s + 1);
If you want a closed higher-timeframe bar, specify the bar one step older, as above.
The classic repaint occurs in indicators that draw higher-timeframe values on a lower-timeframe chart. If each past lower-timeframe bar is assigned the close of the higher-timeframe bar that contains it, the chart shows final values that did not yet exist at that moment. It may look accurate on the chart, but you could not have made the same decision in real time.
If the fourth argument, exact, is false, the nearest bar is returned when no matching bar exists. This makes data gaps easy to miss, so it is safer to also check the time of the bar you obtained. Data for other symbols or timeframes may also update late, so verify that the bar has the expected time before making a decision.
Prevent double decisions after a restart
g_lastBar in the code above returns to its initial value when the EA restarts. To avoid judging the same closed bar again and entering twice, the design should also check open positions and the time of the most recent fill.
Checks You Can Do as a User
Even if you cannot read the source code, you can get a reasonable idea with the following methods.
- Watch in visual mode: In the tester's visual mode, check whether entry times line up near the start of bars. If fills happen frequently mid-bar, the EA may be using the forming bar (exits are a separate matter).
- Compare different modeling settings: With the same period and settings, try Open prices only, Every tick, and Every tick based on real ticks. If the number or timing of entries differs substantially, suspect a dependence on intrabar movement.
- Record indicator arrows: Save the time each arrow appeared, for example with a screenshot, and compare it with the chart a few bars later. If the position changes or the arrow disappears, the indicator repaints.
- Ask the distributor: Ask whether the EA decides on closed bars and how it handles higher timeframes.
All of these are circumstantial evidence, and none of them alone proves "no repainting." If you want to try indicators, practice the procedure with the free indicators, and see the EA setup guide for installing an EA.
Limits and Cautions
Deciding on closed bars also has drawbacks.
- Entries are delayed: Price keeps moving while you wait for the close, so you may enter at a worse level. In sharp rallies or sell-offs, the difference can be large.
- Cost at the start of a bar: In designs where orders cluster on the first tick of a new bar, you can be hit by wide spreads or gaps at the open.
- Indicators that reference the future are not prevented: Indicators like ZigZag, whose shape changes later, or those that need subsequent bars to confirm, can change values even on closed bars depending on which position you read.
- Closed bars differ by broker: Different server times or price feeds produce different four prices, so the same EA can decide differently at a different broker. It is also impossible to rule out later corrections to history data.
- Exits happen inside the bar: Even if the entry decision is made on a closed bar, stop losses and take profits fill mid-bar. This part still depends on tick quality.
Most importantly, not repainting and being profitable are two different things. Some of our own EAs show good results in historical testing yet are negative in demo-account forward tests. Using closed bars is one prerequisite for trusting test results, not an indicator of future performance. Whether closed bars are used also differs by EA design, so check each EA individually when choosing, and weigh it together with the figures in the measured ranking. Related testing concepts are collected in EA & MT5 know-how.
Summary
- Forming-bar values move until the bar closes, so signals can disappear or change
- Deciding on closed bars fixes the inputs and makes results less sensitive to how ticks are generated
- Make
CopyRates' start position and ordering explicit, and retry if the copy fails iBarShifttends to return the forming higher-timeframe bar, so shift the index when you want a closed bar- Drawing higher-timeframe values on a lower-timeframe chart, and indicators that reference the future, are classic repaint cases
- Closed bars come with delay and cost issues, and they do not promise profit
Related
2026-10-29
MQL5 OnTick vs OnTimer: How to Use Each in EA Design
2026-07-14
We Backtested 43 Popular Gold EAs on 11.5 Years of Real Data
2026-07-07
MT5 AutoTrading Disabled (10027 / 10026): 4 Switches to Check
2026-07-07
MT5 'Invalid Stops' Error (10016 / 130): 6 Causes and the Fix for Each
📧 Free 8-email course + subscriber-only pack of 13 MT5 indicators
Right after you sign up, you get a download link for a subscriber-only pack of our 13 MT5 indicators: compiled files (.ex5), source code and a setup guide. Then 8 emails on algo-trading essentials, reading backtests correctly and choosing a broker (one a day for the first 5 days, then 7, 14 and 30 days after signing up). You also get notified before each price rise of the versions sold on the MQL5 Market (launch pricing that steps up as copies sell). Our EAs are free on this site with a live account at a partner broker.
* Privacy strictly protected. You can unsubscribe at any time.
Have a question about EAs or FX?
You can post it on the Nattzy trading forum (free sign-up). Questions beyond this article are welcome too — EA settings, choosing a broker and more.
Ask on Nattzy ↗