Edgoro
Runtime error 4806 · MQL5

MQL5 error 4806: requested data not found (CopyBuffer)

Why CopyBuffer() fails with MQL5 error 4806 (requested data not found) and how to wait for the indicator with BarsCalculated() before reading its values.

Runtime error · GetLastError()
4806 ERR_INDICATOR_DATA_NOT_FOUND
“Requested data not found”

What it means

CopyBuffer() asked an indicator for values it doesn't have yet. In MQL5 an indicator handle is created at once, but the indicator calculates afterwards, in the background. Until it has calculated the bars you ask for, the copy fails, returns -1 and GetLastError() returns 4806.

Usual causes

  • Copying right after creating the handle, typically in OnInit. The indicator hasn't run yet.
  • History that isn't loaded yet. An indicator on another timeframe or symbol needs that history first; MetaQuotes' reference says the terminal starts downloading or building it and the copy returns what's ready, possibly nothing.
  • Asking for more bars than exist, for example 500 values on a symbol with 300 bars of history.
  • The first ticks after a change: after the EA starts, the chart's timeframe changes or the terminal reconnects, the indicator recalculates.

How to detect it

  • CopyBuffer() returns -1 (or fewer values than requested) and GetLastError() returns 4806.
  • BarsCalculated(handle) returns -1 while the indicator hasn't calculated anything, then the number of calculated bars. Check it before copying.
  • An EA that reads values from a failed copy works with zeros or stale numbers. That's worse than the error itself.

Broken code

This EA compiles. The copy in OnInit fails with 4806 and leaves the array empty, so reading buf[0] stops the EA with array out of range.

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

int    maHandle = INVALID_HANDLE;
double lastMa   = 0.0;

int OnInit()
  {
   maHandle = iMA(_Symbol, PERIOD_H4, InpPeriod, 0, MODE_SMA, PRICE_CLOSE);
   double buf[];
   // Copied at once: the indicator hasn't calculated yet, so this fails with 4806
   CopyBuffer(maHandle, 0, 1, 1, buf);
   lastMa = buf[0];
   return INIT_SUCCEEDED;
  }

void OnTick()
  {
   Comment("H4 SMA: ", DoubleToString(lastMa, _Digits));
  }

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 = 50; // Moving average period

int maHandle = INVALID_HANDLE;

int OnInit()
  {
   // Create the handle once; read the values later, when they exist
   maHandle = iMA(_Symbol, PERIOD_H4, InpPeriod, 0, MODE_SMA, PRICE_CLOSE);
   if(maHandle == INVALID_HANDLE)
     {
      PrintFormat("iMA failed: error %d", GetLastError());
      return INIT_FAILED;
     }
   return INIT_SUCCEEDED;
  }

void OnTick()
  {
   // Not calculated yet: try again on the next tick instead of reading nothing
   if(BarsCalculated(maHandle) < 2)
      return;
   double buf[];
   ResetLastError();
   if(CopyBuffer(maHandle, 0, 1, 1, buf) != 1)
     {
      PrintFormat("CopyBuffer failed: error %d", GetLastError());
      return;
     }
   Comment("H4 SMA: ", DoubleToString(buf[0], _Digits));
  }

void OnDeinit(const int reason)
  {
   if(maHandle != INVALID_HANDLE)
      IndicatorRelease(maHandle);
   Comment("");
  }

Why the fix works

The handle is created once in OnInit and checked, but the values are read in OnTick, after BarsCalculated() confirms the indicator has calculated enough bars. The copy's return value is compared with the number of values asked for, so a partial or failed copy is never used. When data isn't ready, the EA simply returns and tries again on the next tick: no Sleep(), no loop that blocks the terminal.

Questions

Why does CopyBuffer return -1 in OnInit?

Because the indicator only starts calculating after its handle is created, and OnInit runs before it has had a chance to. Create the handle in OnInit and copy the values in OnTick (or OnCalculate), once BarsCalculated() shows the data is there.

Should I use Sleep() to wait for indicator data?

No. Return from the handler and try again on the next tick or timer event. Waiting inside the handler doesn't make the data arrive sooner, and it blocks the program.

What's the difference between error 4806 and 4807?

4806 means the indicator exists but the requested data isn't there yet. 4807 (ERR_INDICATOR_WRONG_HANDLE) means the handle itself is wrong, usually INVALID_HANDLE from an indicator that couldn't be created.

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.