Include a personalized indicator in an Expert Advisor - page 2

 
William Roeder #:
If new history arrives, any remember Bars or previous Bars will be misleading.

There have never been any problems with this in MT4:

Forum on trading, automated trading systems and testing trading strategies

Include a personalized indicator in an Expert Advisor

Vladislav Boyko, 2024.03.31 18:58

If the difference between "rates_total" and "prev_calculated" is not equal to 0 and not equal to 1, then recalculate all indicator values. If this happens, it is very rare (I add a message to the experts’ journal when calculating indicators “from scratch”)

Forum on trading, automated trading systems and testing trading strategies

Include a personalized indicator in an Expert Advisor

Vladislav Boyko, 2024.04.01 01:50

This is not difficult to implement in MT4. Below is the method code of one of my old advisors. Think of it as pseudocode

This method controls the sizes of buffers and returns rates_total and prev_calculated

void emulateBuffers(int &rates_total,int &prev_calculated)
  {
   prev_calculated = buffersGetSize();
   if(prev_calculated < 0)
      prev_calculated = 0;
   rates_total = ArraySize(Time);
   int notCalculated = rates_total - prev_calculated;
   if(notCalculated == 0)
      return;
   if(notCalculated != 1 && notCalculated != rates_total)
     {
      PrintFormat(__FUNCTION__" Looks like %i bars have been missed! rates_total %i, prev_calculated %i",notCalculated,rates_total,prev_calculated);
      prev_calculated = 0;
     }
   buffersSetAsSeries(false);
   buffersResize(rates_total);
   buffersSetAsSeries(true);
  }

But I don't really like this implementation (it's quite old). This is the first thing I found right now. I remember that I had better implementations, but I deleted them after the customer confirmed that they worked correctly.

Therefore, I emphasize once again: take this as pseudocode

 

Forum on trading, automated trading systems and testing trading strategies

Include a personalized indicator in an Expert Advisor

Vladislav Boyko, 2024.04.01 01:50

bool CMacd::buffersSetAsSeries(bool a_flag)
  {
   return(setAsSeries(buffMacd, a_flag) && setAsSeries(buffSignalSma, a_flag) && setAsSeries(buffSignal2, a_flag)
          && setAsSeries(buffHistogram, a_flag));
  }

This doesn't look good because the return value of this function is not checked. I remember that I simply changed my mind about checking it, since in the case of ArraySetAsSeries, if the error did not occur during the first test, then it will definitely never occur.

 
Vladislav Boyko #: This is not difficult to implement in MT4.
  1. Really? If a history update or refresh, adds bars to history, how do you detect it and reset prev_calculated to zero or recompute all bars?
  2. Why are you writing nineteen (19) lines above, instead of just a single iCustom call?
 

I would like to hear how you think about this solution:

#define BARS_BACK 1000

double buffer[];
bool first_call=true;

int OnInit()
  {
   ArrayResize(buffer, BARS_BACK);
   ArraySetAsSeries(buffer, true);
   first_call=true;
   return(INIT_SUCCEEDED);
  }

  
void OnTick()
  {
      if(first_call)
      {
         CalculateBuffers(BARS_BACK-1);
         first_call=false;
      }
      else
      {
         if(isNewBar())
         {
            ArraySetAsSeries(buffer, false);
            ArrayResize(buffer, ArraySize(buffer)+1);
            ArraySetAsSeries(buffer, true);
         }
         CalculateBuffers(1);
      }
  }

void CalculateBuffers(int count)
{
   for(int i=count;i>=0;i--)
   {
      //do buffer calculations
   }
}
 
William Roeder #:
If a history update or refresh, adds bars to history, how do you detect it and reset prev_calculated to zero or recompute all bars?

If the terminal adds bars to the history, then notCalculated will be greater than 1, which will lead to the recalculation of all indicator values. I don't think the terminal will only add 1 bar when loading history.

Forum on trading, automated trading systems and testing trading strategies

Include a personalized indicator in an Expert Advisor

Vladislav Boyko, 2024.04.01 01:50

void emulateBuffers(int &rates_total,int &prev_calculated)
  {
   prev_calculated = buffersGetSize();
   if(prev_calculated < 0)
      prev_calculated = 0;
   rates_total = ArraySize(Time);
   int notCalculated = rates_total - prev_calculated;
   if(notCalculated == 0)
      return;
   if(notCalculated != 1 && notCalculated != rates_total)
     {
      PrintFormat(__FUNCTION__" Looks like %i bars have been missed! rates_total %i, prev_calculated %i",notCalculated,rates_total,prev_calculated);
      prev_calculated = 0;
     }
   buffersSetAsSeries(false);
   buffersResize(rates_total);
   buffersSetAsSeries(true);
  }
William Roeder #:
Why are you writing nineteen (19) lines above, instead of just a single iCustom call?

It requires a lot more lines than 19😄

  1. Sometimes customers ask to hide indicators (so that it would be impossible to find out which indicators are used)
  2. This often provides an opportunity to improve performance
  3. If you use ArrayCopyRates to receive data from another timeframe, then calculating indicators on the MqlRates array (which you pass to ArrayCopyRates) ensures the synchronization of the MqlRates array and indicator values