Медленный тест с индикатором AMA MQL4 в MT5

 

тут видео проблемы http://imagicon.info/howto/mql5%20slow%20test%20ama.htm

 

почему такой медленный тест визуальный переведённого на МТ5 индикатора?

Все стандартные индюки работают быстро.... 

//+------------------------------------------------------------------+
//|                                                          AMA.mq4 |
//|                      Copyright © 2004, MetaQuotes Software Corp. |
//|                                        http://www.metaquotes.net |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2004, by konKop,wellx"
#property link      "http://www.metaquotes.net"
 
#property indicator_chart_window
#property indicator_buffers 3
#property indicator_color1 Sienna
#property indicator_color2 DeepSkyBlue
#property indicator_color3 Gold
 
//---- input parameters
extern int       periodAMA=9;
extern int       nfast=2;
extern int       nslow=30;
extern double    G=2.0;
extern double    dK=2.0; 
 
//---- buffers
double kAMAbuffer[];
double kAMAupsig[];
double kAMAdownsig[];
 
//+------------------------------------------------------------------+
 
int    cbars=0, prevbars=0, prevtime=0;
 
double slowSC,fastSC;
 
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
//---- indicators
   SetIndexStyle(0,DRAW_LINE,0,2);
   SetIndexStyle(1,DRAW_ARROW);
   SetIndexArrow(1,159);
   SetIndexStyle(2,DRAW_ARROW);
   SetIndexArrow(2,159);
   //SetIndexDrawBegin(0,nslow+nfast);
   SetIndexBuffer(0,kAMAbuffer);
   SetIndexBuffer(1,kAMAupsig);
   SetIndexBuffer(2,kAMAdownsig);
   
   
   IndicatorDigits(4);
   
   //slowSC=0.064516;
   //fastSC=0.2;
   //cbars=IndicatorCounted();
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
  {
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
  {
   int    i,pos=0;
   double noise=0.000000001,AMA,AMA0,signal,ER;
   double dSC,ERSC,SSC,ddK;
   
   if (prevbars==Bars) return(0);
    
//---- TODO: add your code here
   slowSC=(2.0 /(nslow+1));
   fastSC=(2.0 /(nfast+1));
   cbars=IndicatorCounted();
   if (Bars<=(periodAMA+2)) return(0);
//---- check for possible errors
   if (cbars<0) return(-1);
//---- last counted bar will be recounted
   if (cbars>0) cbars--;
   pos=Bars-periodAMA-2;
   AMA0=Close[pos+1];
   while (pos>=0)
     {
      if(pos==Bars-periodAMA-2) AMA0=Close[pos+1];
      signal=MathAbs(Close[pos]-Close[pos+periodAMA]);
      noise=0.000000001;
      for(i=0;i<periodAMA;i++)
       {
        noise=noise+MathAbs(Close[pos+i]-Close[pos+i+1]);
       }
      ER =signal/noise;
      dSC=(fastSC-slowSC);
      ERSC=ER*dSC;
      SSC=ERSC+slowSC;
      AMA=AMA0+(MathPow(SSC,G)*(Close[pos]-AMA0));
      kAMAbuffer[pos]=AMA;
 
      ddK=(AMA-AMA0);
      if ((MathAbs(ddK)) > (dK*Point) && (ddK > 0)) kAMAupsig[pos] =AMA; else kAMAupsig[pos]=0;
      if ((MathAbs(ddK)) > (dK*Point) && (ddK < 0)) kAMAdownsig[pos]=AMA; else kAMAdownsig[pos]=0; 
 
     
      AMA0=AMA;
      pos--;
     }
//----
   prevbars=Bars;
   return(0);
  }
//+------------------------------------------------------------------+
//|                                                          AMA.mq5 |
//|                        Copyright 2013, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2013, MetaQuotes Software Corp."
#property link      "http://www.mql5.com"
#property version   "1.00"

#property indicator_chart_window
#property indicator_buffers 3

#property indicator_color1 Sienna
#property indicator_type1   DRAW_LINE
#property indicator_width1  2

#property indicator_color2 DeepSkyBlue
#property indicator_type2   DRAW_ARROW

#property indicator_color3 Gold
#property indicator_type3   DRAW_ARROW




//---- input parameters
input int periodAMA=20;
input int nfast=3;
input int nslow=30;
input double G=2.0;
input double dK=2.0;

//---- buffers
double kAMAbuffer[];
double kAMAupsig[];
double kAMAdownsig[];

//+------------------------------------------------------------------+

int cbars=0, prevbars=0, prevtime=0;
double slowSC, fastSC;


#property indicator_plots   3

//--- indicator buffers

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
   IndicatorSetInteger(INDICATOR_DIGITS,_Digits);

//--- indicator buffers mapping
   SetIndexBuffer(0,kAMAbuffer,INDICATOR_DATA);
   SetIndexBuffer(1,kAMAupsig,INDICATOR_DATA);
   SetIndexBuffer(2,kAMAdownsig,INDICATOR_DATA);
   
   PlotIndexSetInteger(1, PLOT_ARROW, 159);
   PlotIndexSetInteger(2, PLOT_ARROW, 159);
   
   
//---
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator 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[])
  {
//---
      int i, pos=0;
      double noise=0.000000001, AMA, AMA0, signal, ER;
      double dSC, ERSC, SSC, ddK;
  
      //if (prevbars==rates_total) return (0);
      
      //---- TODO: add your code here
      slowSC=(2.0 /(nslow+1));
      fastSC=(2.0 /(nfast+1));

      //cbars=IndicatorCounted(prev_calculated);
      if(prev_calculated>0) cbars = prev_calculated-1;
      if(prev_calculated==0) cbars = 0;
      cbars=0;
      //Print(cbars);
      
      if (rates_total<=(periodAMA+2)) return (0);
      //---- check for possible errors
      if (cbars<0) return (-1);
      //---- last counted bar will be recounted
      if (cbars>0) cbars--;
      pos=periodAMA+2;
      AMA0=close[pos-1];
      
      while (pos<rates_total)
      {
         if (pos==periodAMA-2) AMA0=close[pos-1];
         signal=MathAbs (close[pos]-close[pos-periodAMA]);
         
         
         noise=0.000000001;
         for (i=0; i< periodAMA; i++)
         {
            noise=noise+MathAbs (close[pos-i]-close[pos-i-1]);
         }
         ER =signal/noise;
         dSC=(fastSC-slowSC);
         ERSC=ER*dSC;
         SSC=ERSC+slowSC;
         AMA=AMA0+(MathPow (SSC, G)*(close[pos]-AMA0));
         kAMAbuffer[pos]=AMA;
   
         ddK=(AMA-AMA0);
         if ((MathAbs (ddK)) > (dK*_Point) &&(ddK > 0)) kAMAupsig[pos] =AMA; else kAMAupsig[pos]=0;
         if ((MathAbs (ddK)) > (dK*_Point) &&(ddK < 0)) kAMAdownsig[pos]=AMA; else kAMAdownsig[pos]=0;
   
   
         AMA0=AMA;
         pos++;
      }
      
      

     
     prevbars=rates_total;
     
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
//| TradeTransaction function                                        |
//+------------------------------------------------------------------+
void OnTradeTransaction(const MqlTradeTransaction& trans,
                        const MqlTradeRequest& request,
                        const MqlTradeResult& result)
  {
//---
   
  }
//+------------------------------------------------------------------+

 

Навскидку по видео, не вдаваясь в код, можно сказать, что запускать программу командой "Начало отладки" по зеленой кнопке неправильно.

В режиме отладки компилятор генерит детальный, абсолютно неоптимизированный код специально под отладчик. Этот код может работать в разы медленнее обычного.

Документация по MQL5: Стандартные константы, перечисления и структуры / Состояние окружения / Информация о запущенной MQL5-программе
Документация по MQL5: Стандартные константы, перечисления и структуры / Состояние окружения / Информация о запущенной MQL5-программе
  • www.mql5.com
Стандартные константы, перечисления и структуры / Состояние окружения / Информация о запущенной MQL5-программе - Документация по MQL5
 
//|                                                          AMA.mq5 |

      pos=periodAMA+2;

      while (pos<rates_total)
Индикатор полностью пересчитывается на каждом тике.
 
Swan:
Индикатор полностью пересчитывается на каждом тике.

на каждом тике перещитывается 

а разве встроенный АМА от МТ5 не перещитывает на тике каждом? и тем не менее работает быстро

 

//+------------------------------------------------------------------+
//|                                                          AMA.mq5 |
//|                        Copyright 2009, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright   "2009, MetaQuotes Software Corp."
#property link        "http://www.mql5.com"
#property version     "1.00"
#property description "Adaptive Moving Average"

#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots   1
//---- plot ExtAMABuffer
#property indicator_label1  "AMA"
#property indicator_type1   DRAW_LINE
#property indicator_color1  Red
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
//--- default applied price
#property indicator_applied_price PRICE_OPEN
//--- input parameters
input int      InpPeriodAMA=10;      // AMA period
input int      InpFastPeriodEMA=2;   // Fast EMA period
input int      InpSlowPeriodEMA=30;  // Slow EMA period
input int      InpShiftAMA=0;        // AMA shift
//--- indicator buffers
double         ExtAMABuffer[];
//--- global variables
double         ExtFastSC;
double         ExtSlowSC;
int            ExtPeriodAMA;
int            ExtSlowPeriodEMA;
int            ExtFastPeriodEMA;
//+------------------------------------------------------------------+
//| AMA initialization function                                      |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- check for input values
   if(InpPeriodAMA<=0)
     {
      ExtPeriodAMA=10;
      printf("Input parameter InpPeriodAMA has incorrect value (%d). Indicator will use value %d for calculations.",
             InpPeriodAMA,ExtPeriodAMA);
     }
   else ExtPeriodAMA=InpPeriodAMA;
   if(InpSlowPeriodEMA<=0)
     {
      ExtSlowPeriodEMA=30;
      printf("Input parameter InpSlowPeriodEMA has incorrect value (%d). Indicator will use value %d for calculations.",
             InpSlowPeriodEMA,ExtSlowPeriodEMA);
     }
   else ExtSlowPeriodEMA=InpSlowPeriodEMA;
   if(InpFastPeriodEMA<=0)
     {
      ExtFastPeriodEMA=2;
      printf("Input parameter InpFastPeriodEMA has incorrect value (%d). Indicator will use value %d for calculations.",
             InpFastPeriodEMA,ExtFastPeriodEMA);
     }
   else ExtFastPeriodEMA=InpFastPeriodEMA;
//--- indicator buffers mapping
   SetIndexBuffer(0,ExtAMABuffer,INDICATOR_DATA);
//--- set shortname and change label
   string short_name="AMA("+IntegerToString(ExtPeriodAMA)+","+
                      IntegerToString(ExtFastPeriodEMA)+","+
                      IntegerToString(ExtSlowPeriodEMA)+")";
   IndicatorSetString(INDICATOR_SHORTNAME,short_name);
   PlotIndexSetString(0,PLOT_LABEL,short_name);
//--- set accuracy
   IndicatorSetInteger(INDICATOR_DIGITS,_Digits+1);
//--- sets first bar from what index will be drawn
   PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,ExtPeriodAMA);
//--- set index shift
   PlotIndexSetInteger(0,PLOT_SHIFT,InpShiftAMA);
//--- calculate ExtFastSC & ExtSlowSC
   ExtFastSC=2.0/(ExtFastPeriodEMA+1.0);
   ExtSlowSC=2.0/(ExtSlowPeriodEMA+1.0);
//--- OnInit done
   return(0);
  }
//+------------------------------------------------------------------+
//| AMA iteration function                                           |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const int begin,
                const double &price[])
  {
   int i;
//--- check for rates count
   if(rates_total<ExtPeriodAMA+begin)
      return(0);
//--- draw begin may be corrected
   if(begin!=0) PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,ExtPeriodAMA+begin);
//--- detect position
   int pos=prev_calculated-1;
//--- first calculations
   if(pos<ExtPeriodAMA+begin)
     {
      pos=ExtPeriodAMA+begin;
      for(i=0;i<pos-1;i++) ExtAMABuffer[i]=0.0;
      ExtAMABuffer[pos-1]=price[pos-1];
     }
//--- main cycle
   for(i=pos;i<rates_total && !IsStopped();i++)
     {
      //--- calculate SSC
      double dCurrentSSC=(CalculateER(i,price)*(ExtFastSC-ExtSlowSC))+ExtSlowSC;
      //--- calculate AMA
      double dPrevAMA=ExtAMABuffer[i-1];
      ExtAMABuffer[i]=pow(dCurrentSSC,2)*(price[i]-dPrevAMA)+dPrevAMA;
     }
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
//| Calculate ER value                                               |
//+------------------------------------------------------------------+
double CalculateER(const int nPosition,const double &PriceData[])
  {
   double dSignal=fabs(PriceData[nPosition]-PriceData[nPosition-ExtPeriodAMA]);
   double dNoise=0.0;
   for(int delta=0;delta<ExtPeriodAMA;delta++)
      dNoise+=fabs(PriceData[nPosition-delta]-PriceData[nPosition-delta-1]);
   if(dNoise!=0.0)
      return(dSignal/dNoise);
   return(0.0);
  }
//+------------------------------------------------------------------+
 
так же  я ставлю индикатору 1 минутки а не тики, почему всё равно медленно?
 
eurgbp:

на каждом тике перещитывается 

а разве встроенный АМА от МТ5 не перещитывает на тике каждом? и тем не менее работает быстро

пересчитывается, но таки только последние 1-2 бара.

поправил пред. пост.

 

а как мне починить АМА от МТ4 тогда?

 

 
eurgbp:

а как мне починить АМА от МТ4 тогда?

Основной цикл сделайте по образу и подобию) любого стандартного MT5 индюкатора.

Например таки AMA.mq5


Как-то так:

      //cbars=IndicatorCounted(prev_calculated);
      if(prev_calculated>0) cbars = prev_calculated-1;
      if(prev_calculated==0) cbars = 0;
      cbars=0;
      //Print(cbars);
      
      if (rates_total<=(periodAMA+2)) return (0);
      //---- check for possible errors
      if (cbars<0) return (-1);
      //---- last counted bar will be recounted
      if (cbars>0) cbars--;
      pos=periodAMA+2;
      AMA0=close[pos-1];

заменить на

      //cbars=IndicatorCounted(prev_calculated);
      if (rates_total<=(periodAMA+2)) return (0);
      pos=periodAMA+2;
      if(prev_calculated>0) pos = prev_calculated-1;

      AMA0=close[pos-1];

 

проклятие, всё равно очень медленно в сравнении со встроенным АМА МТ5.

Сколько будет стоить ускорить АМА самодельный? 

 
eurgbp:

проклятие, всё равно очень медленно в сравнении со встроенным АМА МТ5.

Сколько будет стоить ускорить АМА самодельный? 

В остальном всё вроде впорядке с кодом, можно пару переменных в Init вычислить, но таки это ускорит на совсем чуть-чуть..


В эксперте:


В mql5 это должно быть в Init() - получение хэндла индикатора..

 
eurgbp:
Как вариант: если имеется код стандартного AMA на  mql5, и его скорость устраивает, то взять этот код за основу своего  mql5-индикатора и внести в него дополнения в соответствии с различиями в логике стандартного и самодельного индикаторов. Посмотреть результаты.