2
votes

I have this TEMA indicator which worked fine. I added a piece of code in order to limit the amount of bars to process but the indicator line gets messed up in the back in an abnormal way and when I limit the amount of bars to process to a small value like 500 the indicator doesn't display properly at all it just throws lines up and down.

This is the modified code which I use.

Can someone help me shed some light on this.

If I limit the bars for a simple moving average code I do not get these above mentioned problems.

I for one believe it has something to do with the IMAOnArray() part in the code. I also attached an image to display the problem.

#property indicator_chart_window
#property indicator_buffers 1
#property indicator_color1 DarkBlue
#property  indicator_width1  2
//---- input parameters

extern int       EMA_period=14;
//code added to limit amount of bars.
extern int       BarsBack=1500;
//---- buffers
double TemaBuffer[];
double Ema[];
double EmaOfEma[];
double EmaOfEmaOfEma[];

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
//---- indicators
   IndicatorBuffers(4);
   SetIndexStyle(0,DRAW_LINE);
   SetIndexBuffer(0,TemaBuffer);
   SetIndexBuffer(1,Ema);
   SetIndexBuffer(2,EmaOfEma);
   SetIndexBuffer(3,EmaOfEmaOfEma);
   SetIndexDrawBegin(0, Bars - BarsBack);
   IndicatorShortName("TEMA("+EMA_period+")");

//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
  {
//----

//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
  {
   int i,limit,limit2,limit3,counted_bars=IndicatorCounted();
//---++

      //coded added to limit bars
      if(Bars>BarsBack)
      {
      limit=BarsBack;
      }
      else     
      {
      limit=Bars-counted_bars-1;
      }
      limit2=limit;
      limit3=limit2;

   for (i=limit;i>=0;i--) Ema[i]=iMA(NULL,0,EMA_period,0,MODE_EMA,PRICE_CLOSE,i);
   for (i=limit2;i>=0;i--) EmaOfEma[i]=iMAOnArray(Ema,0,EMA_period,0,MODE_EMA,i);
   for (i=limit3;i>=0;i--) EmaOfEmaOfEma[i]=iMAOnArray(EmaOfEma,0,EMA_period,0,MODE_EMA,i);
   for (i=limit3;i>=0;i--) TemaBuffer[i]=3*Ema[i]-3*EmaOfEma[i]+EmaOfEmaOfEma[i];
//----
   return(0);
  }
//+------------------------------------------------------------------+

enter image description here

1

1 Answers

1
votes

Q : Can someone help me shed some light on this?

Triple Exponential Moving Average was created by Patrick Mulloy and first published in the February 1994 issue of Technical Analysis of Stocks & Commodities magazine – Smoothing Data With Less Lag.

You shall not "limit" the depth of TEMA-triple-"self"-convolution by reducing the depth of input data-window, as it results but in damaged values processed, you rather ought say the CustomIndicator-code, how long does it take to "stabilise" the TEMA-values at the far left edge, before it's left-edge computed values start to make some sense:

SetIndexDrawBegin
Sets the bar number (from the data beginning) from which the drawing of the given indicator line must start.

void  SetIndexDrawBegin(
   int     index,       // line index
   int     begin        // position
   );

Parameters :

index     [in]  Line index. Must lie between 0 and 7.
begin     [in]  First drawing bar position number.

Returned value: None.
Note:
The indicators are drawn from left to right. The indicator array values that are to the left of the given bar will not be shown in the chart or in the DataWindow. 0 will be set as default, and all data will be drawn.

Your modified TEMA-code simply ignores all the ( Bars - BarsBack ) candles and starts green-field computing but for the BarsBack ( which produces all the triple-self-convolution artifacts to happen "near" the hot-end current bar [0] ).

Delete this part of the code and check all your IndicatorBuffer{ 0 | 1 | 2 | 3 }-lines on the far left edge, how fast they "consolidate" their values and only after that visual check, set:

 SetIndexDrawBegin( { 0 | 1 | ... | 3 }, <_N_bars_To_Converge_STABLE_> );

Or may keep the computing-avoidance-code beck in-place,
but need to increase the BarsBack >> <_N_bars_To_Converge_STABLE_>


Iteratively computed values' code-efficiency may get improved :

While MQL4 (as of 2020-Q1) lacks a support for vectorised-math, there is still a room for performance improvement here:

/*
for ( i = limit;  i >= 0; i-- )           Ema[i] = iMA(            NULL, 0, EMA_period, 0, MODE_EMA, PRICE_CLOSE, i );
for ( i = limit2; i >= 0; i-- )      EmaOfEma[i] = iMAOnArray(      Ema, 0, EMA_period, 0, MODE_EMA,              i );
for ( i = limit3; i >= 0; i-- ) EmaOfEmaOfEma[i] = iMAOnArray( EmaOfEma, 0, EMA_period, 0, MODE_EMA,              i );
for ( i = limit3; i >= 0; i-- )    TemaBuffer[i] = EmaOfEmaOfEma[i]
                                                 +         3*Ema[i]
                                                 -    3*EmaOfEma[i];
 */
////////////////////////////////////////////////////////////////////
// 25% MORE EFFICIENT PROCESSING:
//     PROGRESSIVE BUILDUP, AVOIDS DOUBLE limit3-DEEP RE-ITERATIONS:
////////////////////////////////////////////////////////////////////
for ( i = limit;  i >= 0; i-- ) {           Ema[i] = iMA(            NULL, 0, EMA_period, 0, MODE_EMA, PRICE_CLOSE, i ); TemaBuffer[i]  =           Ema[i]; }
for ( i = limit2; i >= 0; i-- ) {      EmaOfEma[i] = iMAOnArray(      Ema, 0, EMA_period, 0, MODE_EMA,              i ); TemaBuffer[i] -=      EmaOfEma[i]; TemaBuffer[i] *= 3; }
for ( i = limit3; i >= 0; i-- ) { EmaOfEmaOfEma[i] = iMAOnArray( EmaOfEma, 0, EMA_period, 0, MODE_EMA,              i ); TemaBuffer[i] += EmaOfEmaOfEma[i]; }

Last, but not least, even more processing efficient TEMA computing-strategies exist here around for nanoseconds latency shaving further off :o)