Edgoro
Critical runtime error · MQL5

MQL5 'array out of range' error: causes and fix

Why an MT5 EA or indicator stops with "array out of range", how to find the line from the Experts tab, and how to size and check arrays in MQL5.

Experts tab · critical error, the program stops
array out of range in 'MyEA.mq5' (24,15)

What it means

The program read or wrote an array element that doesn't exist: an index below 0, or equal to or above the array's size. It's a critical error. MetaTrader stops the program on the spot, so the rest of the handler doesn't run and the EA or indicator stops working. There's no GetLastError() code to catch: the check has to happen before the access.

Usual causes

  • A copy that returned fewer values than you read. CopyBuffer(), CopyRates() and CopyClose() return how many values they copied, or -1. An array that received 0 or 2 values and is read at index 2 is out of range.
  • An off-by-one loop. for(int i = 0; i <= ArraySize(a); i++) reads one element too many. The last valid index is size - 1.
  • Series order confusion. After ArraySetAsSeries(a, true), index 0 is the newest value; without it, the oldest. Code written for one order and run with the other reads past the end.
  • Indicator loops at the edges of history. Reading close[i - period] at the start of the chart, or close[i + 1] on the newest bar.
  • A dynamic array that was never sized with ArrayResize().

How to detect it

  • The Experts tab shows a line such as array out of range in 'MyEA.mq5' (24,15): the file, then the line and column of the access.
  • Open the file in MetaEditor and go to that line: the array and the index are there. Print ArraySize() and the index just before it to see the mismatch.

Broken code

This EA compiles. On a tick where the copy returns fewer than 3 values, reading ma[2] stops it with array out of range.

MQL5
input int InpPeriod = 20; // Moving average period

int maHandle = INVALID_HANDLE;

int OnInit()
  {
   maHandle = iMA(_Symbol, PERIOD_CURRENT, InpPeriod, 0, MODE_EMA, PRICE_CLOSE);
   return maHandle == INVALID_HANDLE ? INIT_FAILED : INIT_SUCCEEDED;
  }

void OnTick()
  {
   double ma[];
   ArraySetAsSeries(ma, true);
   CopyBuffer(maHandle, 0, 0, 3, ma);   // may copy fewer than 3 values, or none
   // Reads index 2 without checking how many values arrived
   if(ma[1] > ma[2])
      Comment("EMA rising");
  }

Fixed code

The same program with the check that prevents the error. It compiles in MetaEditor with 0 errors and 0 warnings.

MQL5
input int InpPeriod = 20; // Moving average period

int maHandle = INVALID_HANDLE;

int OnInit()
  {
   maHandle = iMA(_Symbol, PERIOD_CURRENT, InpPeriod, 0, MODE_EMA, PRICE_CLOSE);
   return maHandle == INVALID_HANDLE ? INIT_FAILED : INIT_SUCCEEDED;
  }

void OnTick()
  {
   double ma[];
   ArraySetAsSeries(ma, true);
   // Use the values only if all 3 arrived
   if(CopyBuffer(maHandle, 0, 0, 3, ma) != 3)
      return;
   Comment(ma[1] > ma[2] ? "EMA rising" : "EMA not rising");
  }

void OnDeinit(const int reason)
  {
   IndicatorRelease(maHandle);
   Comment("");
  }

Why the fix works

CopyBuffer() returns the number of values it copied. Comparing it with the number requested before reading makes sure that indexes 0, 1 and 2 exist; when they don't, the EA waits for the next tick instead of crashing. The same rule applies to every array: compare the index with ArraySize() (or with what a copy function returned) before using it.

Questions

Can I catch array out of range with GetLastError()?

No. It's a critical error: MetaTrader stops the program before any of your code runs again, and MQL5 has no try/catch. The only fix is to check the index or the copied count before accessing the array.

Why does array out of range only happen sometimes?

Because the number of values available changes: on the first ticks after the EA starts, after a timeframe change, at the start of the chart's history, or when indicator data isn't ready. Code that assumes a fixed number of values breaks only in those moments.

What do the numbers in brackets mean?

The line and the column in the source file where the out-of-range access happened, for example (24,15) is line 24, column 15 of the file named before it.

The programs on this page are minimal examples written to show the error and its fix, not trading systems. Some of them send orders when they run: try them on a demo account. Trading involves substantial risk of loss and is not suitable for every investor. Edgoro is a software tool, not a broker or financial adviser: nothing it produces is investment advice, and past or backtested performance does not guarantee future results.

Working code that avoids it

All MQL5 examples

Rather not write the error handling yourself?

Edgoro's MT5 EA generator writes complete MQL5 Expert Advisors from plain English and compiles each one in MetaEditor before you get it. A clean build proves the code compiles, not that a strategy works: test it on a demo account.