ArrayResize needed when using dynamic array with CopyBuffer?

 

According to https://www.mql5.com/en/docs/series/copybuffer, we can simple use

double indicatorArr[];
CopyBuffer(m_indicator.Handle(), 0, 0, 10, indicatorArr); // puts the latest 10 indicator values into array

But why do I see many examples where it is used like this:

double indicatorArr[];
ArrayResize(indicatorArr, 10); // unnecessary operation?
CopyBuffer(m_indicator.Handle(), 0, 0, 10, indicatorArr); // puts the latest 10 indicator values into array

Both work. Which one is best practice? 

Documentation on MQL5: Timeseries and Indicators Access / CopyBuffer
Documentation on MQL5: Timeseries and Indicators Access / CopyBuffer
  • www.mql5.com
Gets data of a specified buffer of a certain indicator in the necessary quantity. Counting of elements of copied data (indicator buffer with the...
[Deleted]  

Your second example, with array resizing, will offer no benefit compared to the first. It is in fact, unnecessary.

It would be better to use a statically allocated buffer if you plan to work a predetermined array size.

Documentation on MQL5: Language Basics / Data Types / Dynamic Array Object
Documentation on MQL5: Language Basics / Data Types / Dynamic Array Object
  • www.mql5.com
Maximum 4-dimension array can be declared. When declaring a dynamic array (an array of unspecified value in the first pair of square brackets), the...
 
harryma23:

According to https://www.mql5.com/en/docs/series/copybuffer, we can simple use

But why do I see many examples where it is used like this:

Both work. Which one is best practice? 

these dont answer your q, but some points to make:

I always use the 3rd parameter of ArrayResize. See online documentation for reasoning. If i remember correctly, the documentation says it is slower when used without that 3rd parameter.

When using CopyBuffer -- ALWAYS validate the result before allowing the ea/indicator to continue, otherwise if the result is 0 or empty, then, you could get false signals or worse, break the code and your ea/indicator could detach itself without warning.

 
Fernando Carreiro #:

Your second example, with array resizing, will offer no benefit compared to the first. It is in fact, unnecessary.

It would be better to use a statically allocated buffer if you plan to work a predetermined array size.

Thanks! So in this case, I should do:

double indicatorArr[10]; // static array with 10 elements
CopyBuffer(m_indicator.Handle(), 0, 0, 10, indicatorArr); // puts the latest 10 indicator values into array
 
Michael Charles Schefe #:

these dont answer your q, but some points to make:

I always use the 3rd parameter of ArrayResize. See online documentation for reasoning. If i remember correctly, the documentation says it is slower when used without that 3rd parameter.

When using CopyBuffer -- ALWAYS validate the result before allowing the ea/indicator to continue, otherwise if the result is 0 or empty, then, you could get false signals or worse, break the code and your ea/indicator could detach itself without warning.

Thanks for your suggestions. I will do something like this:

double indicatorArr[];
if(CopyBuffer(m_indicator.Handle(), 0, 0, 10, indicatorArr) == -1) {
   Print("Error: CopyBuffer error");
   return false;
}; 

Is the indicatorArr still completely empty when CopyBuffer returns -1, or can it be partially or incorrectly filled with values?

 
harryma23 #:

Thanks for your suggestions. I will do something like this:

Is the indicatorArr still completely empty when CopyBuffer returns -1, or can it be partially or incorrectly filled with values?

see example for using CopyBuffer in the link that is at bottom of your first comment.
 
Fernando Carreiro #:

Your second example, with array resizing, will offer no benefit compared to the first. It is in fact, unnecessary.

It would be better to use a statically allocated buffer if you plan to work a predetermined array size.

I thought that it would be fine to use a statically allocated buffer if you know the exact number of elements to pass, but I experienced an EA not working when doing so! I'm not sure if I can explain why.

See code. It would be interesting to know why, I was scratching my head with confusion about this. It was a code published by someone else on the codebase.

Files:
[Deleted]  
Conor Mcnamara #:

I thought that it would be fine to use a statically allocated buffer if you know the exact number of elements to pass, but I experienced an EA not working when doing so! I'm not sure if I can explain why.

See code. It would be interesting to know why, I was scratching my head with confusion about this. It was a code published by someone else on the codebase.

Please define "not working", and provide log output if necessary.

PS! I see also, that you are not pre-checking the the amount of calculated bars — Documentation on MQL5: Timeseries and Indicators Access / BarsCalculated

 
Fernando Carreiro #:

Please define "not working", and provide log output if necessary.

PS! I see also, that you are not pre-checking the the amount of calculated bars — Documentation on MQL5: Timeseries and Indicators Access / BarsCalculated

It's the exact issue the first commenter reported in the comments here:

https://www.mql5.com/en/code/62732

It wouldn't log any errors in the journal. I can try and do more error logging later 
EMA_RSI_RISK-EA
EMA_RSI_RISK-EA
  • 2025.08.20
  • www.mql5.com
Expert Advisor for MetaTrader 5 that combines Exponential Moving Averages (EMA) and Relative Strength Index (RSI) to generate trading signals. Includes risk management features and trading time filter.
[Deleted]  

@Conor Mcnamara #It's the exact issue the first commenter reported in the comments here: https://www.mql5.com/en/code/62732

It wouldn't log any errors in the journal. I can try and do more error logging later 

Sorry, but I am not willing to debug someone else's CodeBase publication code. 

So, I have provided a test script to demonstrated that it does work, as well as sample log output ...

#property   script_show_inputs
#define     MBarCount 10         // Number of bars to copy from indicator buffer
input int   i_nPeriodRSI = 14;   // RSI Period

void OnStart() {
   ResetLastError();
   int hRSI = iRSI( _Symbol, _Period, i_nPeriodRSI, PRICE_CLOSE );
   if( hRSI != INVALID_HANDLE ) {
      // Wait for indicator to calculate buffer or the script to be stopped
         while( !IsStopped() && BarsCalculated( hRSI ) < 0 ) Sleep( 1000 );
         if( IsStopped() ) return;  // Return if script has been stopped
      // Check the number of calculated bars and copy the buffer
         int nBarsCalc = BarsCalculated( hRSI );
         PrintFormat( "Bars calculated: %d", nBarsCalc );
         if( nBarsCalc > MBarCount ) {
            // Declare both types of arrays, static and dynamic
               double adbStatic[ MBarCount ], adbDynamic[];
            // Define macro to make sure the implementation is exactly the same for both cases
               #define MCopyBars( _array ) CopyBuffer( hRSI, 0, 1, MBarCount, _array )
            // Get the buffer data for both array types
               int nBarsStatic  = MCopyBars( adbStatic  ),
                   nBarsDynamic = MCopyBars( adbDynamic );
            // Output the data to the log
               PrintFormat( "Bars copied — Static: %d, Dynamic: %d", nBarsStatic, nBarsDynamic );
               int nBars = fmin( nBarsStatic, nBarsDynamic );
               for( int i = 0; i < nBars; i++ ) {
                  Print( "index: ", i, ", static|dynamic = ", adbStatic[ i ], " | ", adbDynamic[ i ] );
            };
         } else
            Print( "Insufficient bars available to copy from indicator buffer" );
      // Release indicator handle      
         IndicatorRelease( hRSI );
   } else
      Print( "Invalid indicator handle, with error code: ", _LastError );
};
2025.10.06 21:52:52.168 TestCopyBuffer (EURUSD,H1)      Bars calculated: 173768
2025.10.06 21:52:52.168 TestCopyBuffer (EURUSD,H1)      Bars copied — Static: 10, Dynamic: 10
2025.10.06 21:52:52.168 TestCopyBuffer (EURUSD,H1)      index: 0, static|dynamic = 24.485687037217545 | 24.485687037217545
2025.10.06 21:52:52.168 TestCopyBuffer (EURUSD,H1)      index: 1, static|dynamic = 33.37251962774074 | 33.37251962774074
2025.10.06 21:52:52.168 TestCopyBuffer (EURUSD,H1)      index: 2, static|dynamic = 41.733488739498206 | 41.733488739498206
2025.10.06 21:52:52.168 TestCopyBuffer (EURUSD,H1)      index: 3, static|dynamic = 47.10750103940623 | 47.10750103940623
2025.10.06 21:52:52.168 TestCopyBuffer (EURUSD,H1)      index: 4, static|dynamic = 54.63241008697406 | 54.63241008697406
2025.10.06 21:52:52.168 TestCopyBuffer (EURUSD,H1)      index: 5, static|dynamic = 50.12297995707563 | 50.12297995707563
2025.10.06 21:52:52.168 TestCopyBuffer (EURUSD,H1)      index: 6, static|dynamic = 52.425844481867934 | 52.425844481867934
2025.10.06 21:52:52.168 TestCopyBuffer (EURUSD,H1)      index: 7, static|dynamic = 51.67833215816743 | 51.67833215816743
2025.10.06 21:52:52.168 TestCopyBuffer (EURUSD,H1)      index: 8, static|dynamic = 52.677476423168514 | 52.677476423168514
2025.10.06 21:52:52.168 TestCopyBuffer (EURUSD,H1)      index: 9, static|dynamic = 51.68355002723079 | 51.68355002723079