cTrader

AlgoWay Blog

Guides, manuals and platform references.

Core
JSON & Alerts
MT5 / Expert Advisors
Errors
Integrations
Other Publications
AlgoWay Strategy Lab

MQL5 CopyBuffer: Bar Shifts vs Array Index Explained

Published November 13, 2026

View Markdown

Indicator observations mapped from chronological tiles into array positions

You ask MQL5 for three indicator values beginning with the current bar, then read array element zero as “now.” With an ordinary destination array, that can give you the oldest of the three values instead. The request and the destination use different coordinate systems.

A bar shift selects what to copy. An array index selects what to read after copying. This matters in automated trading because swapping the earlier and later observations can reverse a crossing or slope test. When comparing custom MT5 signal logic with an AlgoWay MT5 execution setup, establish the signal's bar and timestamp before investigating order delivery. This is an MQL5 data-reading issue, not an AlgoWay setting.

Separate the request from the storage order

In the position-based form of CopyBuffer, a start position of 0 requests the current bar first; 1 starts with the preceding bar. The count determines how many observations are requested going back through history. The indicator buffer number selects the indicator's data series, not a bar.

The copied values are placed oldest first in physical memory, regardless of the destination's series flag. For the examples below, assume an ordinary destination array sized to exactly the requested count, a successful full copy, and an unshifted indicator. This avoids mixing the indexing question with partial copies or shifted plots.

MetaQuotes' indexing-direction guide distinguishes physical storage from logical access. Normal indexing reads from the beginning. Series indexing addresses the same stored values in reverse. Changing that access convention does not recalculate the indicator or move a value to another candle.

Trace three values before testing a signal

Suppose an indicator has the following invented readings: shift 2 is 48, shift 1 is 52, and shift 0 is 49. These numbers illustrate indexing only; they are not market observations or a tested strategy.

RequestNormal index 0Normal index 1Normal index 2
Start 0, count 3Shift 2: 48Shift 1: 52Shift 0: 49
Start 1, count 2Shift 2: 48Shift 1: 52Not requested
Start 1, count 1Shift 1: 52Not requestedNot requested

The last row is a useful counterexample to “array zero always means the current bar.” With a one-value request starting at shift 1, array zero holds the preceding bar. Its array address is zero because it is the only copied value.

For the first row, the latest transition is from 52 to 49, a fall through 50. Reading normal indices 0 and 1 as current and previous instead would compare 48 with 52. Worse, reading indices 0 and 1 as earlier and later would report a rise from 48 to 52, which occurred one bar earlier. Assign meaningful earlier/later labels only after mapping both indices to bar shifts.

What the series flag changes

ArraySetAsSeries can give a one-dimensional dynamic numeric array reverse indexing. After the three-value copy above, series index 0 reads 49, index 1 reads 52 and index 2 reads 48. The physical sequence remains 48, 52, 49.

For the two-value request beginning at shift 1, series index 0 would instead read 52 and series index 1 would read 48. “Newest copied value” still means the newest observation in the requested slice. It does not promise that the slice contains the current bar.

The flag cannot be enabled for a fixed-size array declared with its size at compilation, or for a multidimensional array. Check the function's success result and the actual indexing convention instead of assuming that an attempted change took effect. A fixed-size two-element array is perfectly usable here; simply read it using normal indexing.

Readiness and bar completion are separate checks

Require the returned copy count to match the number your decision needs. CopyBuffer can report an error or return fewer observations while required history is being prepared. Do not evaluate a two-value crossing after retrieving only one observation.

BarsCalculated reports how much indicator data has been calculated and can help diagnose readiness after a handle is created. That readiness check does not replace checking the result of the particular copy request.

Shift 0 belongs to the current, unfinished bar. If the rule intends to compare completed bars, request the appropriate earlier shifts. Using a completed candle does not by itself prove that a custom indicator never revises historical values; that is a separate property of its calculation.

For a diagnostic run, record the requested start and count, returned count, indexing direction, values and corresponding bar opening times. If the rule starts with a timestamp, first check how iBarShift handles missing bars; finding the intended bar and reading the intended array element are two separate steps. A useful log should let you say “this value belongs to this candle,” not merely “element zero looked plausible.”

Last updated: November 13, 2026