Расчет функции ТЕМА

 

Доброго дня

Мне для советника понадобилось написать функцию по сглаживанию пользовательского массива через ТЕМА

за основу взял TEMA в исполнении Rosh

попробовал вынести расчет в отдельную функцию

мне нужно значение на одном баре а не на всей истории так что писАлось именно под эти нужды

понимая что нужно иметь два массива как серии

первый  размерность 2*maPeriod

второй   размерность maPeriod

и одно значение по второму массиву (из нулевого индекса)

...

но так и не получилось "точно" воссоздать индикатор (разрабатывался для проверки работомпособности функции ТЕМА)

вот код почти исходного индикатора ТЕМА 

//+------------------------------------------------------------------+
//|                                                         TEMA.mq4 |
//|                      Copyright © 2007, MetaQuotes Software Corp. |
//|                                        http://www.metaquotes.net/ru/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2007, MetaQuotes Software Corp."
#property link      "http://www.metaquotes.net/ru/"

#property indicator_chart_window
#property indicator_buffers 4
#property indicator_color1 DarkBlue
#property indicator_color2 Aqua
#property indicator_color3 Yellow
#property indicator_color4 Red
#property  indicator_width1  2
//---- input parameters
extern int       EMA_period=5;
//---- 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);
   SetIndexStyle(1,DRAW_LINE);
   SetIndexBuffer(1,Ema);
   SetIndexStyle(2,DRAW_LINE);
   SetIndexBuffer(2,EmaOfEma);
   SetIndexStyle(3,DRAW_LINE);
   SetIndexBuffer(3,EmaOfEmaOfEma);

   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();
//----
   if (counted_bars==0)
      {
      limit=Bars-1;
      limit2=limit-EMA_period;
      limit3=limit2-EMA_period;
      }
   if (counted_bars>0)
      {
      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];
   Comment(EmaOfEma[0],"\n",EmaOfEma[1],"\n",EmaOfEma[2],"\n",EmaOfEma[3],"\n",EmaOfEma[4]);
//----
   return(0);
  }
//+------------------------------------------------------------------+

добавлены отрисовка "второстепенных" индектов индикатора и комментарий

вот код моего исполнения

//+------------------------------------------------------------------+
//|                                                    TEMA_TEST.mq4 |
//|                                                      by olyakish |
//|                            https://www.mql5.com/ru/users/olyakish |
//|                                                                  |
//|                                                                  |
//|                                                                  |
//|                                                                  |
//|                                                                  |
//|                                                                  |
//|                                                                  |
//+------------------------------------------------------------------+
#property copyright "by olyakish"
#property link      "https://www.mql5.com/ru/users/olyakish"

#property indicator_chart_window
#property indicator_buffers 1
#property indicator_color1 DeepPink

//#include <globalVar.mqh>
//#include <raschet.mqh>           /// v.0.0.0.6

int maPeriod=5;



double TEMA[];
double arrMA[];




//+------------------------------------------------------------------+
int init()
  {
   string name;
   name="TEMA_TEST("+maPeriod+")";
  

   SetIndexStyle(0,DRAW_LINE);
   SetIndexBuffer(0,TEMA);
   SetIndexLabel(0,"TEMA");
   SetIndexEmptyValue(0,0.0);
   IndicatorShortName(name);
  
   ArraySetAsSeries(arrMA,true);
   return(0);
  }
//+------------------------------------------------------------------+  
int deinit()
   {
      return(0);
   }
//+------------------------------------------------------------------+    
int start()
  {
   int counted_bars=IndicatorCounted();
   int limit,i;
   if (counted_bars<0) return(-1);
   if (counted_bars==0)    {limit=Bars-1-maPeriod;ArrayResize(arrMA,limit);}
   if (counted_bars>0)     {limit=Bars-counted_bars;}    
   for (i=limit-1;i>=0;i--)
      {
         arrMA[i]=iMA(NULL,0,maPeriod,0,MODE_EMA,PRICE_CLOSE,i);
      }      
   for (i=limit-maPeriod*2;i>=0;i--)
      {    
         TEMA[i]=f_TEMA(arrMA,maPeriod,i);      
      }
      
   return(0);
  }
//+------------------------------------------------------------------+  


//+------------------------------------------------------------------+
// Функция расчета f_TEMA
// входные параметры
// indexBar - с какого бара берем значение
double f_TEMA(double & arrIn[],int maPeriod,int indexBar)
   {      
      int i,k=maPeriod-1;
      double EmaOfEma[];
      ArrayResize(EmaOfEma,maPeriod);
      ArraySetAsSeries(EmaOfEma,true);


      for (i=maPeriod+indexBar-1;i>=indexBar-1;i--)
         {
            EmaOfEma[k]=iMAOnArray(arrIn,0,maPeriod,0,MODE_EMA,i);
            k--;
         }
      Comment("k=",k);
      double ret;
      double EmaOfEmaOfEma= iMAOnArray(EmaOfEma,0,maPeriod,0,MODE_EMA,0);    
      //ret=3*arrIn[indexBar]-3*EmaOfEma[0]+EmaOfEmaOfEma;
      ret=EmaOfEma[0];
      //ret=EmaOfEmaOfEma;
      Comment(EmaOfEma[0],"\n",EmaOfEma[1],"\n",EmaOfEma[2],"\n",EmaOfEma[3],"\n",EmaOfEma[4]);
      return(ret);
   }
//+------------------------------------------------------------------+  

вот картинка, где  комментарии совпалают, следовательно расчет EmaOfEma произведен верно

но если в моем коде вывести значение EmaOfEmaOfEma

      double EmaOfEmaOfEma= iMAOnArray(EmaOfEma,0,maPeriod,0,MODE_EMA,0);    
      //ret=3*arrIn[indexBar]-3*EmaOfEma[0]+EmaOfEmaOfEma;
      //ret=EmaOfEma[0];
      ret=EmaOfEmaOfEma;

и наложить на график то линии красная и DeepPink

не совпадают

 соответсвенно получается расхождение  в расчете самой ТЕМА

линии DarkBlue(исходная) и DeepPink(мое исполение)

Подскажите, где ошибка.

 

Посмотри мой индикатор VininI_nEMA

Сделано до пятого уровня ЕМА, ДЕМА, ТЕМА, ЧЕМА, ПЕМА

 

Нашел сам

дело все в расчете EMA

EMA = (CLOSE (i) * P) + (EMA (i - 1) * (100 - P))

тоесть для расчета чем больше массив исходный тем более точное получится значание

я свой массив  

      ArrayResize(EmaOfEma,maPeriod*2);
увеличил в 2 раза

расхождения в итоговой ТЕМА получились гдето в  среднем в 1 пункт