Navigation:Home > Content >

jma.mq5

Time: 2017-11-16 | Download file:jma.mq5

//+------------------------------------------------------------------+ 
//|                                                          JMA.mq5 | 
//|                    MQL5 code: Copyright © 2010, Nikolay Kositsin |
//|                              Khabarovsk,   farria@mail.redcom.ru | 
//+------------------------------------------------------------------+ 
#property copyright "Copyright © 2010, Nikolay Kositsin"
#property link "farria@mail.redcom.ru" 
//---- номер версии индикатора
#property version   "1.02"
//---- отрисовка индикатора в главном окне
#property indicator_chart_window 
//---- количество индикаторных буферов
#property indicator_buffers 1 
//---- использовано всего одно графическое построение
#property indicator_plots   1
//+----------------------------------------------+
//| Параметры отрисовки индикатора               |
//+----------------------------------------------+
//---- отрисовка индикатора в виде линии
#property indicator_type1   DRAW_LINE
//---- в качестве цвета линии индикатора использован красный цвет
#property indicator_color1 clrRed
//---- линия индикатора - непрерывная кривая
#property indicator_style1  STYLE_SOLID
//---- толщина линии индикатора равна 1
#property indicator_width1  1
//---- отображение метки индикатора
#property indicator_label1  "JMA"
//+----------------------------------------------+
//| Объявление перечислений                      |
//+----------------------------------------------+
enum ENUM_APPLIED_PRICE_ //Тип константы
  {
   PRICE_CLOSE_ = 1,     //PRICE_CLOSE
   PRICE_OPEN_,          //PRICE_OPEN
   PRICE_HIGH_,          //PRICE_HIGH
   PRICE_LOW_,           //PRICE_LOW
   PRICE_MEDIAN_,        //PRICE_MEDIAN
   PRICE_TYPICAL_,       //PRICE_TYPICAL
   PRICE_WEIGHTED_,      //PRICE_WEIGHTED
   PRICE_SIMPL_,         //PRICE_SIMPL_
   PRICE_QUARTER_,       //PRICE_QUARTER_
   PRICE_TRENDFOLLOW0_,  //PRICE_TRENDFOLLOW0_
   PRICE_TRENDFOLLOW1_,  //TrendFollow_2 Price 
   PRICE_DEMARK_         //Demark Price 
  };
//+----------------------------------------------+
//| Входные параметры индикатора                 |
//+----------------------------------------------+
input int Length_=7;                              // Глубина сглаживания
input int Phase_=100;                             // Параметр сглаживания
//---- изменяющийся в пределах -100 ... +100,
//---- влияет на качество переходного процесса;
input ENUM_APPLIED_PRICE_ IPC=PRICE_CLOSE_;       // Ценовая константа
input int Shift=0;                                // Сдвиг индикатора по горизонтали в барах
input int PriceShift=0;                           // Сдвиг индикатора по вертикали в пунктах
//+----------------------------------------------+
//---- объявление динамических массивов, которые будут в 
//---- дальнейшем использованы в качестве индикаторных буферов
double IndBuffer[];
//---- объявление глобальных переменных
double dPriceShift;
int min_rates_total;
//----
bool m_start;
//----
double m_array[62];
//----
double m_degree,m_Phase,m_sense;
double m_Krx,m_Kfd,m_Krj,m_Kct;
double m_var1,m_var2;
//----
int m_pos2,m_pos1;
int m_Loop1,m_Loop2;
int m_midd1,m_midd2;
int m_count1,m_count2,m_count3;
//----
double m_ser1,m_ser2;
double m_Sum1,m_Sum2,m_JMA;
double m_storage1,m_storage2,m_djma;
double m_hoop1[128],m_hoop2[11],m_data[128];
//---- переменные для восстановления расчетов на незакрытом баре
int m_pos2_,m_pos1_;
int m_Loop1_,m_Loop2_;
int m_midd1_,m_midd2_;
int m_count1_,m_count2_,m_count3_;
//----
double m_ser1_,m_ser2_;
double m_Sum1_,m_Sum2_,m_JMA_;
double m_storage1_,m_storage2_,m_djma_;
double m_hoop1_[128],m_hoop2_[11],m_data_[128];
//----
bool m_bhoop1[128],m_bhoop2[11],m_bdata[128];
//+------------------------------------------------------------------+    
//| JMA indicator initialization function                            | 
//+------------------------------------------------------------------+  
void OnInit()
  {
//---- инициализация глобальных переменных 
   min_rates_total=30+1;
//---- превращение динамического массива в индикаторный буфер
   SetIndexBuffer(0,IndBuffer,INDICATOR_DATA);
//---- осуществление сдвига индикатора по горизонтали на Shift
   PlotIndexSetInteger(0,PLOT_SHIFT,Shift);
//---- осуществление сдвига начала отсчета отрисовки индикатора
   PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,min_rates_total);
//---- установка значений индикатора, которые не будут видимы на графике
   PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,EMPTY_VALUE);
//---- инициализация переменной для короткого имени индикатора
   string shortname;
   StringConcatenate(shortname,"JMA( Length = ",Length_,", Phase = ",Phase_,")");
//--- создание имени для отображения в отдельном подокне и во всплывающей подсказке
   IndicatorSetString(INDICATOR_SHORTNAME,shortname);
//--- определение точности отображения значений индикатора
   IndicatorSetInteger(INDICATOR_DIGITS,_Digits+1);
//---- инициализация сдвига по вертикали
   dPriceShift=_Point*PriceShift;
//---- завершение инициализации
  }
//+------------------------------------------------------------------+  
//| JMA iteration function                                           | 
//+------------------------------------------------------------------+  
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[])
  {
//---- проверка количества баров на достаточность для расчета
   if(rates_totalrates_total || prev_calculated<=0) // проверка на первый старт расчета индикатора
     {
      first=0; // стартовый номер для расчета всех баров
      //---- инициализация коэффициентов
      JJMAInit(Phase_,Length_,PriceSeries(IPC,0,open,low,high,close));
     }
   else first=prev_calculated-1; // стартовый номер для расчета новых баров
//---- основной цикл расчета индикатора
   for(bar=first; bar30)
        {
         if(!m_start)
           {
            m_start= true;
            shift1 = 1;
            back=29;
            //----
            m_ser2 = m_array[1];
            m_ser1 = m_ser2;
           }
         else back=0;
         //----
         for(int rrr=back; rrr>=0; rrr--)
           {
            if(rrr==0)
               ser0=series;
            else ser0=m_array[31-rrr];
            //----
            dser1 = ser0 - m_ser1;
            dser2 = ser0 - m_ser2;
            //----
            if(MathAbs(dser1)>MathAbs(dser2))
               m_var2=MathAbs(dser1);
            else m_var2=MathAbs(dser2);
            //----
            Res=m_var2;
            newvel=Res+0.0000000001;
            //----
            if(m_count1<=1)
               m_count1=127;
            else m_count1--;
            //----
            if(m_count2<=1)
               m_count2=10;
            else m_count2--;
            //----
            if(m_count3<128) m_count3++;
            //----          
            m_Sum1+=newvel-m_hoop2[m_count2];
            //----
            m_hoop2[m_count2]=newvel;
            m_bhoop2[m_count2]=true;
            //----
            if(m_count3>10)
               SmVel=m_Sum1/10.0;
            else SmVel=m_Sum1/m_count3;
            //----
            if(m_count3>127)
              {
               hoop1=m_hoop1[m_count1];
               m_hoop1[m_count1]=SmVel;
               m_bhoop1[m_count1]=true;
               numb = 64;
               posB = numb;
               //----
               while(numb>1)
                 {
                  if(m_data[posB]127)
                 {
                  m_midd2--;
                  posB=m_midd2;
                 }
               else
                 {
                  m_midd1++;
                  posB=m_midd1;
                 }
               //----
               if(m_midd1>96)
                  m_pos2=96;
               else m_pos2=m_midd1;
               //----
               if(m_midd2<32)
                  m_pos1=32;
               else m_pos1=m_midd2;
              }
            //----
            numb = 64;
            posA = numb;
            //----
            while(numb>1)
              {
               if(m_data[posA]>=SmVel)
                 {
                  if(m_data[posA-1]<=SmVel) numb=1;
                  else
                    {
                     numb /= 2.0;
                     posA -= numb;
                    }
                 }
               else
                 {
                  numb /= 2.0;
                  posA += numb;
                 }
               //----
               if(posA==127)
                  if(SmVel>m_data[127]) posA=128;
              }
            //----
            if(m_count3>127)
              {
               if(posB>=posA)
                 {
                  if(m_pos2+1>posA)
                     if(m_pos1-1posA)
                  if(m_pos1-1=posA)
                 {
                  if(m_pos2+1posB)
                        m_Sum2+=m_data[m_pos2+1];
                 }
               else if(m_pos2+2>posA) m_Sum2+=SmVel;
               //----               
               else if(m_pos2+1posB)
                  m_Sum2+=m_data[m_pos2+1];
               //----        
               if(posB>posA)
                 {
                  if(m_pos1-1posB)
                        m_Sum2-=m_data[posB];
                  //----
                  else if(m_pos2posA)
                     m_Sum2-=m_data[m_pos2];
                 }
               else
                 {
                  if(m_pos2+1>posB && m_pos1-1posB)
                  if(m_pos1-0=posA; numb--)
                 {
                  m_data[numb+1]=m_data[numb];
                  m_bdata[numb+1]=true;
                 }
               //----                    
               m_data[posA]=SmVel;
               m_bdata[posA]=true;
              }
            //---- 
            if(m_count3<=127)
              {
               m_Sum2=0;
               for(numb=m_pos1; numb<=m_pos2; numb++)
                  m_Sum2+=m_data[numb];
              }
            //---- 
            resalt=m_Sum2/(m_pos2-m_pos1+1.0);
            //----
            if(m_Loop2>30)
               m_Loop2=31;
            else m_Loop2++;
            //----
            if(m_Loop2<=30)
              {
               if(dser1>0.0)
                  m_ser1=ser0;
               else m_ser1=ser0-dser1*m_Kct;
               //----
               if(dser2<0.0)
                  m_ser2=ser0;
               else m_ser2=ser0-dser2*m_Kct;
               //----
               m_JMA=series;
               //----
               if(m_Loop2!=30) continue;
               else
                 {
                  m_storage1=series;
                  if(MathCeil(m_Krx)>=1)
                     dSupr=MathCeil(m_Krx);
                  else dSupr=1.0;
                  //----
                  if(dSupr>0) Suprem2=MathFloor(dSupr);
                  else
                    {
                     if(dSupr<0)
                        Suprem2=MathCeil(dSupr);
                     else Suprem2=0.0;
                    }
                  //----
                  if(MathFloor(m_Krx)>=1)
                     m_var2=MathFloor(m_Krx);
                  else m_var2=1.0;
                  //----
                  if(m_var2>0) Suprem1=MathFloor(m_var2);
                  else
                    {
                     if(m_var2<0)
                        Suprem1=MathCeil(m_var2);
                     else Suprem1=0.0;
                    }
                  //----
                  if(Suprem2==Suprem1) factor=1.0;
                  else
                    {
                     dSupr=Suprem2-Suprem1;
                     factor=(m_Krx-Suprem1)/dSupr;
                    }
                  //---- 
                  if(Suprem1<=29)
                     shift1=(int)Suprem1;
                  else shift1=29;
                  //----
                  if(Suprem2<=29)
                     shift2=(int)Suprem2;
                  else shift2=29;

                  dser3 = series - m_array[m_Loop1 - shift1];
                  dser4 = series - m_array[m_Loop1 - shift2];
                  //----
                  m_djma=dser3 *(1.0-factor)/Suprem1+dser4*factor/Suprem2;
                 }
              }
            else
              {
               ResPow=MathPow(Res/resalt,m_degree);
               //----
               if(m_Kfd>=ResPow)
                  m_var1= ResPow;
               else m_var1=m_Kfd;
               //----
               if(m_var1<1.0)m_var2=1.0;
               else
                 {
                  if(m_Kfd>=ResPow)
                     m_sense=ResPow;
                  else m_sense=m_Kfd;

                  m_var2=m_sense;
                 }
               //---- 
               extent=m_var2;
               Pow1=MathPow(m_Kct,MathSqrt(extent));
               //----
               if(dser1>0.0)
                  m_ser1=ser0;
               else m_ser1=ser0-dser1*Pow1;
               //----
               if(dser2<0.0)
                  m_ser2=ser0;
               else m_ser2=ser0-dser2*Pow1;
              }
           }
         //---- 
         if(m_Loop2>30)
           {
            Pow2=MathPow(m_Krj,extent);
            //----
            m_storage1 *= Pow2;
            m_storage1 += (1.0 - Pow2) * series;
            m_storage2 *= m_Krj;
            m_storage2 += (series - m_storage1) * (1.0 - m_Krj);
            //----
            Extr=m_Phase*m_storage2+m_storage1;
            //----
            Pow2x2= Pow2 * Pow2;
            ratio = Pow2x2-2.0 * Pow2+1.0;
            m_djma *= Pow2x2;
            m_djma += (Extr - m_JMA) * ratio;
            //----
            m_JMA+=m_djma;
           }
        }
      //----
      if(m_Loop1<=30) continue;
      jjma=m_JMA;
      //---- восстановление значений переменных
      if(bar==rates_total-1)
        {
         //---- восстановление измененных ячеек массивов из памяти
         for(numb = 0; numb < 128; numb++) if(m_bhoop1[numb]) m_hoop1[numb] = m_hoop1_[numb];
         for(numb = 0; numb < 11;  numb++) if(m_bhoop2[numb]) m_hoop2[numb] = m_hoop2_[numb];
         for(numb = 0; numb < 128; numb++) if(m_bdata [numb]) m_data [numb] = m_data_ [numb];
         //---- обнуление номеров измененных ячеек массивов
         ArrayInitialize(m_bhoop1,false);
         ArrayInitialize(m_bhoop2,false);
         ArrayInitialize(m_bdata,false);
         //---- запись значений переменных из памяти 
         m_JMA=m_JMA_;
         m_djma = m_djma_;
         m_ser1 = m_ser1_;
         m_ser2 = m_ser2_;
         m_Sum2 = m_Sum2_;
         m_pos1 = m_pos1_;
         m_pos2 = m_pos2_;
         m_Sum1 = m_Sum1_;
         m_Loop1 = m_Loop1_;
         m_Loop2 = m_Loop2_;
         m_count1 = m_count1_;
         m_count2 = m_count2_;
         m_count3 = m_count3_;
         m_storage1 = m_storage1_;
         m_storage2 = m_storage2_;
         m_midd1 = m_midd1_;
         m_midd2 = m_midd2_;
        }
      //---- сохранение значений переменных
      if(bar==rates_total-2)
        {
         //---- запись измененных ячеек массивов в память
         for(numb = 0; numb < 128; numb++) if(m_bhoop1[numb]) m_hoop1_[numb] = m_hoop1[numb];
         for(numb = 0; numb < 11;  numb++) if(m_bhoop2[numb]) m_hoop2_[numb] = m_hoop2[numb];
         for(numb = 0; numb < 128; numb++) if(m_bdata [numb]) m_data_ [numb] = m_data [numb];
         //---- обнуление номеров измененных ячеек массивов
         ArrayInitialize(m_bhoop1,false);
         ArrayInitialize(m_bhoop2,false);
         ArrayInitialize(m_bdata,false);
         //---- запись значений переменных в память
         m_JMA_=m_JMA;
         m_djma_ = m_djma;
         m_Sum2_ = m_Sum2;
         m_ser1_ = m_ser1;
         m_ser2_ = m_ser2;
         m_pos1_ = m_pos1;
         m_pos2_ = m_pos2;
         m_Sum1_ = m_Sum1;
         m_Loop1_ = m_Loop1;
         m_Loop2_ = m_Loop2;
         m_count1_ = m_count1;
         m_count2_ = m_count2;
         m_count3_ = m_count3;
         m_storage1_ = m_storage1;
         m_storage2_ = m_storage2;
         m_midd1_ = m_midd1;
         m_midd2_ = m_midd2;
        }
      //----       
      IndBuffer[bar]=jjma+dPriceShift;
     }
//----     
   return(rates_total);
  }
//+------------------------------------------------------------------+
//| Инициализация переменных алгоритма JMA                           |
//+------------------------------------------------------------------+    
void JJMAInit(double Phase,double Length,double series)
  {
//---- расчет коэффициентов
   m_midd1 = 63;
   m_midd2 = 64;
   m_start = false;
//----
   for(int numb = 0;   numb <= m_midd1; numb++) m_data[numb] = -1000000.0;
   for(int numb = m_midd2; numb <= 127;   numb++) m_data[numb] = +1000000.0;
//---- все ячейки массивов должны быть переписаны
   ArrayInitialize(m_bhoop1,true);
   ArrayInitialize(m_bhoop2,true);
   ArrayInitialize(m_bdata,true);
//---- удаление мусора из массивов при повторных инициализациях 
   ArrayInitialize(m_hoop1_, 0.0);
   ArrayInitialize(m_hoop2_, 0.0);
   ArrayInitialize(m_hoop1,  0.0);
   ArrayInitialize(m_hoop2,  0.0);
   ArrayInitialize(m_array,  0.0);
//----
   m_djma = 0.0;
   m_Sum1 = 0.0;
   m_Sum2 = 0.0;
   m_ser1 = 0.0;
   m_ser2 = 0.0;
   m_pos1 = 0.0;
   m_pos2 = 0.0;
   m_Loop1 = 0.0;
   m_Loop2 = 0.0;
   m_count1 = 0.0;
   m_count2 = 0.0;
   m_count3 = 0.0;
   m_storage1 = 0.0;
   m_storage2 = 0.0;
   m_JMA=series;
//----
   if(Phase>=-100 && Phase<=100)
      m_Phase=Phase/100.0+1.5;
//----  
   if(Phase > +100) m_Phase = 2.5;
   if(Phase < -100) m_Phase = 0.5;
//----
   double velA,velB,velC,velD;
//----
   if(Length>=1.0000000002)
      velA=(Length-1.0)/2.0;
   else velA=0.0000000001;
//----
   velA *= 0.9;
   m_Krj = velA / (velA + 2.0);
   velC = MathSqrt(velA);
   velD = MathLog(velC);
   m_var1= velD;
   m_var2= m_var1;
//----
   velB=MathLog(2.0);
   m_sense=(m_var2/velB)+2.0;
   if(m_sense<0.0) m_sense=0.0;
   m_Kfd=m_sense;
//----
   if(m_Kfd>=2.5)
      m_degree=m_Kfd-2.0;
   else m_degree=0.5;
//----
   m_Krx = velC * m_Kfd;
   m_Kct = m_Krx / (m_Krx + 1.0);
  }
//+------------------------------------------------------------------+   
//| Получение значения ценовой таймсерии                             |
//+------------------------------------------------------------------+ 
double PriceSeries(uint applied_price,// ценовая константа
                   uint   bar,        // индекс сдвига относительно текущего бара на указанное количество периодов назад или вперед).
                   const double &Open[],
                   const double &Low[],
                   const double &High[],
                   const double &Close[])
  {
//----
   switch(applied_price)
     {
      //---- ценовые константы из перечисления ENUM_APPLIED_PRICE
      case  PRICE_CLOSE: return(Close[bar]);
      case  PRICE_OPEN: return(Open [bar]);
      case  PRICE_HIGH: return(High [bar]);
      case  PRICE_LOW: return(Low[bar]);
      case  PRICE_MEDIAN: return((High[bar]+Low[bar])/2.0);
      case  PRICE_TYPICAL: return((Close[bar]+High[bar]+Low[bar])/3.0);
      case  PRICE_WEIGHTED: return((2*Close[bar]+High[bar]+Low[bar])/4.0);
      //----                            
      case  8: return((Open[bar] + Close[bar])/2.0);
      case  9: return((Open[bar] + Close[bar] + High[bar] + Low[bar])/4.0);
      //----                                
      case 10:
        {
         if(Close[bar]>Open[bar])return(High[bar]);
         else
           {
            if(Close[bar]Open[bar])return((High[bar]+Close[bar])/2.0);
         else
           {
            if(Close[bar]Open[bar]) res=(res+High[bar])/2;
         if(Close[bar]==Open[bar]) res=(res+Close[bar])/2;
         return(((res-Low[bar])+(res-High[bar]))/2);
        }
      //----
      default: return(Close[bar]);
     }
//----
//return(0);
  }
//+------------------------------------------------------------------+

Recommend