Compiler Bug (Build 4885)? False Error '[' - invalid index value After CopyBuffer Sequence

 

Environment:

  • MetaTrader 5 Build:4885
  • Operating System:Microsoft Windows Server 2025 Datacenter (10.0.26100 Build 26100)
  • (Note: Error also reproduced on a different machine with the same MT5 build)

Problem Description:

While developing an Expert Advisor that operates based on M1 data, I've encountered a persistent and apparently incorrect compilation error: '[' - invalid index value .

The error occurs within an if block that detects a new M1 bar. Inside this block, several C opyBuffer  calls are made to retrieve data from indicators (MAs, ATR) and the  iVolumes  indicator.

The specific issue arises when trying toaccess or perform calculations using the copied data immediately after the sequence of  CopyBuffer  calls. The "invalid index value" error message is reported on lines where either there is no index access ( [ ), or the index access should be valid (as the copy success was checked). The exact line number reported varies slightly depending on the code structure but consistently occurs after the  CopyBuffer  calls and before or duringthe use of the copied data.

The errordoes NOToccur if:

  1. A minimal code example (MRE Step 1 below) containingonlythe CopyBuffer calls is compiled (without subsequent calculations/assignments using the copied data).
  2. The CopyBuffer calls related to the iVolumes handle ( h_vol ) are removed.

The errorDOES occurconsistently when:

  1. The CopyBuffer calls for MAs, ATR, and Volume are made in sequence.
  2. And, immediately after, the code attempts to access the resulting arrays or perform calculations with them (See MRE Step 2 below).

This strongly suggests a bug in the parser or compiler of build 4885, which gets confused by this specific sequence of operations, reporting an incorrect error. Cleaning the code file (copy/paste via plain text editor) and performing a full Rebuild did not resolve the issue.

MRE Code - Step 1 (Compiles OK):This code includes all necessary CopyBuffer calls but does not attempt to use the results beyond a simple Print statement. It compiles successfully.


//+------------------------------------------------------------------+
//| Expert Advisor: BugTestInvalidIndex_Step1_5                      |
//| Purpose:     MRE + Handles/Copy MA/ATR + Copy Vol              |
//|                (Compiles OK)                                     |
//+------------------------------------------------------------------+
#include <Trade\Trade.mqh>
#include <Math\Stat\Math.mqh> // Keep include

// --- Handles ---
int h_ma_fast = INVALID_HANDLE;
int h_ma_slow = INVALID_HANDLE;
int h_atr     = INVALID_HANDLE;
int h_vol     = INVALID_HANDLE;

// --- Globals ---
string g_symbol;
datetime lastBarTime_M1 = 0;
int g_digits = 0;
// <<<< Using fixed periods for MRE test >>>>
int MA_Volume_Period = 100;


//+------------------------------------------------------------------+
int OnInit() {
    g_symbol = _Symbol;
    g_digits = (int)SymbolInfoInteger(g_symbol, SYMBOL_DIGITS);
    if(g_digits < 0) { Print("Erro OnInit: Falha ao obter Digits"); return(INIT_FAILED); }

    int MA_Fast_Period = 9;
    int MA_Slow_Period = 20;
    int ATR_Period = 14;

    h_ma_fast = iMA(g_symbol, PERIOD_M1, MA_Fast_Period, 0, MODE_SMA, PRICE_CLOSE);
    h_ma_slow = iMA(g_symbol, PERIOD_M1, MA_Slow_Period, 0, MODE_SMA, PRICE_CLOSE);
    h_atr     = iATR(g_symbol, PERIOD_M1, ATR_Period);
    h_vol     = iVolumes(g_symbol, PERIOD_M1, VOLUME_TICK);

    if(h_ma_fast==INVALID_HANDLE || h_ma_slow==INVALID_HANDLE || h_atr==INVALID_HANDLE || h_vol==INVALID_HANDLE) {
       Print("MRE_Step1_5: Error creating handles.");
       IndicatorRelease(h_ma_fast); IndicatorRelease(h_ma_slow); IndicatorRelease(h_atr); IndicatorRelease(h_vol);
       return(INIT_FAILED);
    }
    Print("MRE_Step1_5 Initialized.");
    return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
void OnDeinit(const int reason) {
   IndicatorRelease(h_ma_fast); IndicatorRelease(h_ma_slow);
   IndicatorRelease(h_atr); IndicatorRelease(h_vol);
   Print("MRE_Step1_5 Deinitialized. Reason: ", reason);
}
//+------------------------------------------------------------------+
void OnTick() {
   MqlRates bars_M1[3];
   if(CopyRates(g_symbol, PERIOD_M1, 0, 3, bars_M1) < 3) return;

   if(bars_M1[1].time != lastBarTime_M1) {
      lastBarTime_M1 = bars_M1[1].time;

      // --- 1. Collect ALL data ---
      bool data_ok = true; // Flag to check if all copies worked
      double ma_fast_1[2], ma_slow_1[2], atr_1[2];
      double m1_volume_history[MA_Volume_Period]; // Array for MA Vol history (double)
      double vol_bar1_buffer[1];                  // Array for bar 1 volume (double)

      // Copy MA/ATR (known to work from Step 1)
      if(CopyBuffer(h_ma_fast, 0, 1, 2, ma_fast_1) < 2) data_ok=false;
      if(data_ok && CopyBuffer(h_ma_slow, 0, 1, 2, ma_slow_1) < 2) data_ok=false;
      if(data_ok && CopyBuffer(h_atr, 0, 1, 2, atr_1) < 2 ) data_ok=false;

      // << Volume CopyBuffer calls >>
      if(data_ok && CopyBuffer(h_vol, 0, 2, MA_Volume_Period, m1_volume_history) < MA_Volume_Period) data_ok=false; // Vol History (shift 2)
      if(data_ok && CopyBuffer(h_vol, 0, 1, 1, vol_bar1_buffer) < 1) data_ok=false; // Vol for bar 1

      // Check if ALL copies were successful
      if(!data_ok) {
         // Print("MRE_Step1_5: Error copying one or more buffers."); // Optional debug
         return; // Exit if any copy failed
      }

      // No assignments or calculations here, JUST the copies.
      Print("MRE_Step1_5: Copied all buffers successfully for bar ", TimeToString(lastBarTime_M1));


   } // End if(New M1 Bar)
}
//+------------------------------------------------------------------+


MRE Code - Step 2 (Fails to Compile):This code is identical to Step 1, but adds the block of calculations and variable assignments after the  CopyBuffer  calls. This version fails to compile.


//+------------------------------------------------------------------+
//| Expert Advisor: BugTestInvalidIndex_Step2                        |
//| Purpose:     MRE + Handles/Copy + Calcs/Assigns                |
//|                (FAILS to Compile)                                |
//+------------------------------------------------------------------+
#include <Trade\Trade.mqh>
#include <Math\Stat\Math.mqh> // Needed for MathMean

// --- Handles ---
int h_ma_fast = INVALID_HANDLE;
int h_ma_slow = INVALID_HANDLE;
int h_atr     = INVALID_HANDLE;
int h_vol     = INVALID_HANDLE;

// --- Globals ---
string g_symbol;
datetime lastBarTime_M1 = 0;
int g_digits = 0;
double point = 0;
// <<<< Using fixed values for MRE test >>>>
int    MA_Volume_Period = 100;
double MA_Volume_Multiplier = 2.0; // Value doesn't matter for compilation error
double DIV_THR = 0.6;             // Value doesn't matter for compilation error


//+------------------------------------------------------------------+
int OnInit() {
    g_symbol = _Symbol;
    g_digits = (int)SymbolInfoInteger(g_symbol, SYMBOL_DIGITS);
    point    = SymbolInfoDouble(g_symbol, SYMBOL_POINT);
    if(g_digits < 0 || point <= 0) { Print("Erro OnInit: Falha ao obter Digits/Point"); return(INIT_FAILED); }

    int MA_Fast_Period = 9;
    int MA_Slow_Period = 20;
    int ATR_Period = 14;

    h_ma_fast = iMA(g_symbol, PERIOD_M1, MA_Fast_Period, 0, MODE_SMA, PRICE_CLOSE);
    h_ma_slow = iMA(g_symbol, PERIOD_M1, MA_Slow_Period, 0, MODE_SMA, PRICE_CLOSE);
    h_atr     = iATR(g_symbol, PERIOD_M1, ATR_Period);
    h_vol     = iVolumes(g_symbol, PERIOD_M1, VOLUME_TICK);

    if(h_ma_fast==INVALID_HANDLE || h_ma_slow==INVALID_HANDLE || h_atr==INVALID_HANDLE || h_vol==INVALID_HANDLE) {
       Print("MRE_Step2: Error creating handles.");
       IndicatorRelease(h_ma_fast); IndicatorRelease(h_ma_slow); IndicatorRelease(h_atr); IndicatorRelease(h_vol);
       return(INIT_FAILED);
    }
    Print("MRE_Step2 Initialized.");
    return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
void OnDeinit(const int reason) {
   IndicatorRelease(h_ma_fast); IndicatorRelease(h_ma_slow);
   IndicatorRelease(h_atr); IndicatorRelease(h_vol);
   Print("MRE_Step2 Deinitialized. Reason: ", reason);
}
//+------------------------------------------------------------------+
void OnTick() {
   MqlRates bars_M1[3];
   if(CopyRates(g_symbol, PERIOD_M1, 0, 3, bars_M1) < 3) return;

   if(bars_M1[1].time != lastBarTime_M1) {
      lastBarTime_M1 = bars_M1[1].time;

      // --- 1. Collect ALL data ---
      bool data_ok = true;
      double ma_fast_1[2], ma_slow_1[2], atr_1[2];
      double m1_volume_history[MA_Volume_Period];
      double vol_bar1_buffer[1];

      if(CopyBuffer(h_ma_fast, 0, 1, 2, ma_fast_1) < 2) data_ok=false;
      if(data_ok && CopyBuffer(h_ma_slow, 0, 1, 2, ma_slow_1) < 2) data_ok=false;
      if(data_ok && CopyBuffer(h_atr, 0, 1, 2, atr_1) < 2 ) data_ok=false;
      if(data_ok && CopyBuffer(h_vol, 0, 2, MA_Volume_Period, m1_volume_history) < MA_Volume_Period) data_ok=false; // Vol History (shift 2)
      if(data_ok && CopyBuffer(h_vol, 0, 1, 1, vol_bar1_buffer) < 1) data_ok=false; // Vol for bar 1

      // Line ~67 - WHERE THE ERROR IS REPORTED
      if(!data_ok) {
         // Print("MRE_Step2: Error copying one or more buffers.");
         return;
      }

      // =======================================================================
      // --- 2. ADDED BACK: Calculations and assignments (Triggers the error) ---
      // =======================================================================
      double val_atr = atr_1[0];
      // Early ATR check
      if(val_atr <= point * 5) {
           return;
      }

      double val_ma_fast = ma_fast_1[0];
      double val_ma_slow = ma_slow_1[0];
      double val_volume_dbl = vol_bar1_buffer[0]; // Original suspected line, error reported earlier though
      long   val_volume = (long)val_volume_dbl;
      double avg_m1_volume_prev = MathMean(m1_volume_history);
      double val_close = bars_M1[1].close;
      double prev_high = bars_M1[2].high;

      double div = (val_ma_fast - val_ma_slow) / val_atr;
      bool strong_candle = (val_close > prev_high);
      bool high_volume = (avg_m1_volume_prev > 0 && val_volume > (long)(avg_m1_volume_prev * MA_Volume_Multiplier));

      // Debug Print
      string condition_check = StringFormat("Barra M1 %s: Div=%.2f Vol=%d AvgVol=%.1f HighVol=%s Strong=%s", // Simplified Print
                                  TimeToString(lastBarTime_M1), div, val_volume, avg_m1_volume_prev,
                                  (high_volume ? "SIM" : "NAO"), (strong_candle ? "SIM" : "NAO") );
      Print(condition_check);
      // =======================================================================


      // --- 3. Final Condition (NOT ADDED) ---
      // if(div > DIV_THR && high_volume && strong_candle) { /*...*/ }


   } // End if(New M1 Bar)
}
//+------------------------------------------------------------------+

 

Exact Error Message When Compiling MRE - Step 2:

'[' - invalid index value BugTestInvalidIndex_Step2.mq5 67 31

(Note: The line number '67' may vary slightly based on formatting, but the error consistently occurs at the if(!data_ok) check line afterthe CopyBuffer calls when the subsequent calculation/assignment block is present).

Additional Observation:

The error seems related to the sequence of c opy Buffer calls followed by calculations/assignments within the same scope, possibly indicating a parser bug in the compiler for this specific pattern.


 

Try replacing;

int    MA_Volume_Period = 100;

 by

#define    MA_Volume_Period 100;

(and check the overall appearance hereafter!)

As far as I remember arrays must not be declared using a variable:

double m1_volume_history[MA_Volume_Period];

But maybe this has changed meanwhile - I don't know as I have avoid it.