Simulating Index Buffers In An EA.

 

Hi,

I am developing an indicator that I have adjusted to run as an EA. The reason for this is that I find that an EA works much more reliably in the debugger than an indicator. The screenshot below is the result when running in the indicator - I am imposing a histogram over the bodies of the candles that use an up wave or a down wave colour. When I run the code in the form of an EA, I've added the following code:-


//---
   int size = iBars(NULL, Config.TimeFrame);
//----  Checking the change of the zero bar
   if(ArraySize(buffer1) < size)
     {
      //---- Set the direct indexing direction in the array
      ArraySetAsSeries(buffer1, false);
      ArraySetAsSeries(buffer2, false);
      //---- Change the size of the emulated indicator buffers
      ArrayResize(buffer1, size);
      ArrayResize(buffer2, size);
      //---- Set the reverse indexing direction in the array
      ArraySetAsSeries(buffer1, true);
      ArraySetAsSeries(buffer2, true);
      //---
     }
//---

I've added the above code because the EA doesn't interact with the source arrays like an indicator does.

With this code, all the values stay correct as if using then indicator version. However, nothing prints on the chart when running the EA. The "buffers" don't render anything and all I see is the original candle bodies/colours. I don't know whether there is something else I need to do, whether this approach used to work in MT4 but it no longer supports this?

Just to confirm, I'm not trying to run an indicator from an EA so, using iCustom is not an option. I'm simply developing an indicator and running it as an EA for the enhanced debugging experience.

Any advice would be appreciated.


 
Geester:

Hi,

I am developing an indicator that I have adjusted to run as an EA. The reason for this is that I find that an EA works much more reliably in the debugger than an indicator. The screenshot below is the result when running in the indicator - I am imposing a histogram over the bodies of the candles that use an up wave or a down wave colour. When I run the code in the form of an EA, I've added the following code:-


I've added the above code because the EA doesn't interact with the source arrays like an indicator does.

With this code, all the values stay correct as if using then indicator version. However, nothing prints on the chart when running the EA. The "buffers" don't render anything and all I see is the original candle bodies/colours. I don't know whether there is something else I need to do, whether this approach used to work in MT4 but it no longer supports this?

Just to confirm, I'm not trying to run an indicator from an EA so, using iCustom is not an option. I'm simply developing an indicator and running it as an EA for the enhanced debugging experience.

Any advice would be appreciated.


Everything is right😄

The EA cannot display buffers as an indicator. Similarly, the indicator cannot trade :)

To display buffers, use the indicator. Use the EA where you consider its work to be much more reliable, pursuing the goals for which you created it. But as an auxiliary tool.


"I bought a helmet because it is safer to snowboard in it. But the helmet prevents me from taking a shower. Is there any solution to both snowboarding safely and showering comfortably?"

Use a helmet for snowboarding and shower normally (no helmet)

 

The entire buffer calculation algorithm is in a separate file ('calculateBuffers.mqh').

'Indicator.mq4' and 'Advisor.mq4' are just situational wrappers.

I just typed it, didn't even try to compile. I hope you get the idea.

// Include\calculateBuffers.mqh

void calculateBuffers(double &a_buff1[], double &a_buff2[], int rates_total, int prev_calculated)
  {
   //...
  }
// Indicator.mq4

#include <calculateBuffers.mqh>

double buffer1[];
double buffer2[];

int OnInit()
  {
   //...
   SetIndexBuffer(0, buffer1);
   SetIndexBuffer(1, buffer2);
   //...
   return(INIT_SUCCEEDED);
  }

int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
   calculateBuffers(buffer1, buffer2, rates_total, prev_calculated);
   return(rates_total);
  }
// Advisor.mq4

#include <calculateBuffers.mqh>
const int BUFFERS_RESERVE = 500;

double buffer1[];
double buffer2[];

int OnInit()
  {
   //...
   buffersResize(0);
   //...
   return(INIT_SUCCEEDED);
  }

void OnTick()
  {
   // ------------------------------------------------
   // Not reliable:
   // int rates_total = iBars(NULL, Config.TimeFrame);
   // ------------------------------------------------
   int rates_total = ArraySize(Close); // The array size of the series you will use is more reliable
   int prev_calculated = ArraySize(buffer1); // Is equal to ArraySize(buffer2)
   if(rates_total != prev_calculated)
     {
      buffersSetAsSeries(false);
      buffersResize(rates_total);
      buffersSetAsSeries(true);
     }
   calculateBuffers(buffer1, buffer2, rates_total, prev_calculated);
   return(rates_total);
  }

void buffersSetAsSeries(bool flag)
  {
   ArraySetAsSeries(buffer1, flag);
   ArraySetAsSeries(buffer2, flag);
  }

void buffersResize(int newSize)
  {
   ArrayResize(buffer1, newSize, BUFFERS_RESERVE);
   ArrayResize(buffer2, newSize, BUFFERS_RESERVE);
  }
 
Vladislav Boyko #:

Everything is right😄

The EA cannot display buffers as an indicator. Similarly, the indicator cannot trade :)

To display buffers, use the indicator. Use the EA where you consider its work to be much more reliable, pursuing the goals for which you created it. But as an auxiliary tool.


"I bought a helmet because it is safer to snowboard in it. But the helmet prevents me from taking a shower. Is there any solution to both snowboarding safely and showering comfortably?"

Use a helmet for snowboarding and shower normally (no helmet)

Hi, thanks for confirming this. It saves me a ton of time trying to make it work! Cheers and, thanks once again. 

 
Vladislav Boyko #:

The entire buffer calculation algorithm is in a separate file ('calculateBuffers.mqh').

'Indicator.mq4' and 'Advisor.mq4' are just situational wrappers.

I just typed it, didn't even try to compile. I hope you get the idea.

Just saw the above - again, thank you. I'll give this a try :)

 
Vladislav Boyko #:
void OnTick()
  {
   // ------------------------------------------------
   // Not reliable:
   // int rates_total = iBars(NULL, Config.TimeFrame);
   // ------------------------------------------------
   int rates_total = ArraySize(Close); // The array size of the series you will use is more reliable
   int prev_calculated = ArraySize(buffer1); // Is equal to ArraySize(buffer2)
   if(rates_total != prev_calculated)
     {
      buffersSetAsSeries(false);
      buffersResize(rates_total);
      buffersSetAsSeries(true);
     }
   calculateBuffers(buffer1, buffer2, rates_total, prev_calculated);
   return(rates_total);
  }

This is not needed here (accidentally copied)

Reason: