Page 1 of 1

ATR in an MT5 EA: handle, CopyBuffer, series order and the bar shift that moves lot size

Posted: Sat Oct 24, 2026 7:58 pm
by Fairman
ATR in an MT5 EA: handle, CopyBuffer, series order and the bar shift that moves lot size

In MT5, iATR does not return a number. It returns a handle, and you read values from it with CopyBuffer. Forgetting a line here can quietly change the stop, and so the lot size.

int h = iATR(_Symbol, PERIOD_M15, 14); // once, in OnInit
double atr[];
ArraySetAsSeries(atr, true);
CopyBuffer(h, 0, 0, 3, atr);

With the series flag set, atr[0] is the forming bar, atr[1] the last closed bar and atr[2] the one before. Without ArraySetAsSeries the array is ordered the other way, so atr[0] is the oldest of the three and atr[2] the newest. The code compiles either way and returns a plausible number.

Worked example. EURUSD, $10,000, risk 1%, stop 1.5 ATR. The closed bar's ATR is 0.00084, so 8.4 pips, and the stop is 12.6 pips. Lots = 100 / (12.6 x 10) = 0.79. If the array was not set as series and the code reads the oldest value, say 0.00079, the stop becomes 11.85 pips and the size 0.84 lots. A 6% error in position size, from an index.

Also use atr[1] for decisions, not atr[0]. The forming bar's ATR changes with every tick, so a sizing rule that reads it will give a different lot size depending on the moment the signal fires.

Re: ATR in an MT5 EA: handle, CopyBuffer, series order and the bar shift that moves lot size

Posted: Mon Oct 26, 2026 9:02 pm
by FXS HongKong Scalper
The series order is a classic trap. I also check the return value of CopyBuffer, since it can return fewer values than requested if history is still loading, especially right after the terminal starts. Using the last closed bar, atr[1], rather than the forming one also keeps the stop stable while the bar is still moving.

Re: ATR in an MT5 EA: handle, CopyBuffer, series order and the bar shift that moves lot size

Posted: Sat Oct 31, 2026 5:50 am
by Fairman
Check CopyBuffer's return value. It gives the number of elements copied, or -1 on failure. Right after creating the indicator on a symbol that has not been loaded, the data may not be ready, and the call can return fewer values than you asked for, or none. A line such as if(CopyBuffer(h, 0, 0, 3, atr) < 3) return; stops the EA from sizing a trade on a zero. A stop distance of zero, passed through a lot size formula, either divides by zero or produces a huge position. In the tester the data is usually ready, so the problem shows up only on the live chart, typically right after a terminal restart or a first load of a new symbol.

Re: ATR in an MT5 EA: handle, CopyBuffer, series order and the bar shift that moves lot size

Posted: Sat Oct 31, 2026 6:25 am
by Fairman
Release the handle when the EA ends. Each call to iATR creates an indicator instance on the terminal, and in OnDeinit you should call IndicatorRelease(h). An EA that creates a new handle on every tick, a common error when the iATR call sits inside OnTick, makes the terminal hold thousands of copies, uses memory and slows the chart. Create it once in OnInit, store it in a global, and check that it is not INVALID_HANDLE. Parameter changes work the same way: if the period is an input, the handle is built from it once, and changing the input restarts the EA, which builds a fresh handle. Nothing else should need to rebuild it.

Re: ATR in an MT5 EA: handle, CopyBuffer, series order and the bar shift that moves lot size

Posted: Sat Oct 31, 2026 7:07 am
by Fairman
Symbols quoting different digits make pip arithmetic differ. For EURUSD, with 5 digit quotes, an ATR of 0.00084 is 8.4 pips, since one pip is 0.0001. For USDJPY with 3 digit quotes, an ATR of 0.126 is 12.6 pips, since a pip is 0.01. If the code converts using _Point and assumes 10 points per pip, it works for both, but gold, indices and 2 or 4 digit brokers need their own handling. Compute the stop in price distance, atr[1] times 1.5, and convert to money using SYMBOL_TRADE_TICK_VALUE and SYMBOL_TRADE_TICK_SIZE, which is robust across instruments, and avoid the pip conversion for anything but display.

Re: ATR in an MT5 EA: handle, CopyBuffer, series order and the bar shift that moves lot size

Posted: Sat Oct 31, 2026 7:35 am
by Fairman
To verify your code, print the ATR values and compare them with the indicator on the chart. Add the built in ATR with period 14 to an M15 chart, hover over the last closed bar and read the value. It should match atr[1] in the Experts log for the same bar, to the displayed number of digits. If it matches atr[0] while the bar is still forming and then changes, the shift is wrong. If the numbers do not match the chart at all, check that the timeframe and period in iATR equal the indicator on the chart. One printed line per new bar and a few minutes of watching settles it, and it protects every later calculation that depends on the stop distance.