Closed Bar or Forming Bar: Which Candle Your EA's Signals Should Read
Every indicator-based Expert Advisor has to decide which candle it reads: the one that is still forming, or the last one that closed. The same moving-average crossover or RSI threshold behaves differently depending on the answer. It changes how many signals the EA sees, how many of them turn out to be false, and how early it acts on them.
Neither option is right for every system. What matters is making the choice on purpose, in code, and knowing what each side costs.
What the choice trades off
| Closed candle | Live candle | |
|---|---|---|
| Signals | Fewer, which lowers the risk of false signals | More, which raises the risk of false signals |
| Basis | Closing prices of finished candles | The most recent price action |
| Timing | Later: the signal waits for the close | Earlier and more responsive to short-term moves |
| Weak spot | Can lag current market conditions | More sensitive to short-term moves, less reliable in choppy markets |
Take a 20-period and a 50-period moving average on a daily chart. On closed candles, a cross of the 20 above the 50 is read as a buy signal and a cross below as a sell signal, once the candle has finished. Put the same pair on a 5-minute chart and read it on the live candle, and the signal arrives sooner, from the price action still in progress. An RSI reading above 70 or below 30 follows the same split: on a closed candle the reading is final, while on the live candle it can still change before the close.
What "closed" and "live" mean in MQL5
In a timeseries, index 0 is the current bar. The documentation on indexing direction says the element with index 0 "contains the information about the latest quote of a symbol", and that the data of the current, not yet completed period sit at the zero position. Index 1 is the last bar that closed.
CopyBuffer() counts the same way. In its documentation, a "starting position of 0 means the current bar (indicator value for the current bar)". So an EA that copies from position 0 is trading on a live candle, whether its author meant to or not: the value at index 0 is recalculated as new quotes arrive, until the bar closes. From position 1 it reads bars that have finished.
Evaluating once per closed bar
One way to read closed candles is to run the signal logic once, when a new bar opens, and look at the bar that has just finished. iTime() returns the opening time of the bar at the given shift, or 0 on error, so a change in the opening time of bar 0 marks a new bar:
The first tick of each new bar returns true, as does the first tick after the EA starts; every other tick of that bar returns false.
Reading a crossover from closed bars
The crossover itself only needs the last two values of each average. The start position decides which two:
Two details carry the logic. The arrays are dynamic, because ArraySetAsSeries() cannot set the flag on a static array. And the flag is what makes index 0 the newest value: CopyBuffer() stores the oldest element first whatever the flag, so without it fast[0] would be the older of the two bars and the comparison would run backwards. CopyBuffer() returns the number of elements copied, or -1 on error, so the code compares the result with the 2 values it needs: a short copy fails the same way an error does.
What the live version does differently
Called with a start position of 0, the same function compares the forming bar with the last closed one. The value at index 0 moves with each new quote, so a crossover can appear during a bar and be gone by its close. Called on every tick, the function reports each of those. That is the mechanism behind "more signals, more false signals", and also the reason the live version reacts earlier: it is looking at the price action still in progress.
A live-candle EA also has to stop itself acting on the same crossover on every tick while it holds. That needs a latch of its own, which is not shown here.
Making the choice testable
The choice depends on the indicator, the strategy, and how much risk of a false signal the system can absorb, so it is worth testing both rather than settling it by habit. Making it an input keeps the two versions in one EA:
Run it over the same period once with each setting and compare the signal counts, not only the equity curve. Combining different indicators may also help the reliability of either mode. What we would rather not see is the choice made by accident, because the code happened to read index 0.
The trader-side comparison, with the moving-average and RSI examples, is on our blog.


