Не получается переделать индикатор MQL4 на MQL5.

 

Здравствуйте. 

Индикатор  Trend Filter.mq4  скачан на просторах интернета. Задача переделать для МТ5. Индикатор не сложный, но я не справился.

Код индикатора.

#property copyright "TO"
#property link      "http://www.forex-tradexperts-to.narod.ru"

#property indicator_separate_window
#property indicator_buffers 3
#property indicator_color1 Yellow
#property indicator_color2 Lime
#property indicator_color3 OrangeRed
#property indicator_level1  -0.9
#property indicator_level2   0
#property indicator_level3   0.9
#property indicator_minimum -1.05
#property indicator_maximum  1.05
#property indicator_width1 2
#property indicator_width2 2
#property indicator_width3 2

extern int  Nbars=89;
extern int  MA_Period =9;
int  MA_Method =3;

double Value[];
double MA[];
double iFish[];
double Buy[];
double Sell[];

int init() 
{ 
   IndicatorBuffers(5);
   SetIndexBuffer(0, iFish); 
   SetIndexStyle(0,DRAW_LINE);
   SetIndexBuffer(1, Buy); 
   SetIndexStyle(1,DRAW_LINE);
   SetIndexBuffer(2, Sell); 
   SetIndexStyle(2,DRAW_LINE);
   
   SetIndexBuffer(3, Value);
   SetIndexBuffer(4, MA);
   
   IndicatorShortName("TREND FILTER ("+Nbars+","+MA_Period+")" );
   
   return(0); 
}  
int deinit() { return(0); } 

int start() 
{ 
   int counted_bars = IndicatorCounted(), i; 
   if (counted_bars < 0) return(-1); 
   if (counted_bars > 0) counted_bars--;  
   int limit=Bars - counted_bars+2*Nbars;
   double up,dn,osc;
   
   for(i = limit; i >= 0; i--) 
   {      
      up = High[iHighest(NULL,0,MODE_HIGH,Nbars,i)];
      dn = Low[iLowest(NULL,0,MODE_LOW,Nbars,i)]; 
      
      if (up>dn)osc = 100*(Close[i]-dn)/(up-dn);
      else osc = 0;
      if (osc < 0) osc = 0.1;
      if (osc > 100) osc = 99.9;
      Value[i]=0.1*(osc-50.0);      
   }   
   for(i = limit; i >= 0; i--)    
   {
      MA[i]=iMAOnArray(Value,0,MA_Period,0,MA_Method,i);
      iFish[i]=(MathExp(2.0*MA[i])-1.0)/(MathExp(2.0*MA[i])+1.0);
      if (iFish[i]> 0.9) {Buy[i] =iFish[i]; Buy[i+1] =iFish[i+1];}
      if (iFish[i]<-0.9) {Sell[i]=iFish[i]; Sell[i+1]=iFish[i+1];}
   } 
   return(0); 
} 

Trend Filter


Почитал форум вроде всё понятно и не сложно. Переделал. 

Вот код переделки.

//+------------------------------------------------------------------+
//|                                                Trend Filter2.mq5 |
//|                                  Copyright 2021, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2021, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property indicator_separate_window
#property indicator_buffers 5
#property indicator_plots   3
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrYellow
#property indicator_style1  STYLE_SOLID
#property indicator_width1  2
#property indicator_type2   DRAW_LINE
#property indicator_color2  clrLime
#property indicator_style2  STYLE_SOLID
#property indicator_width2  2
#property indicator_type3   DRAW_LINE
#property indicator_color3  clrOrangeRed
#property indicator_style3  STYLE_SOLID
#property indicator_width3  2
#property indicator_level1  -0.9
#property indicator_level2   0
#property indicator_level3   0.9
#property indicator_minimum -1.05
#property indicator_maximum  1.05

input int  Nbars = 89;
input int  MA_Period = 9;

double iFish[], Buy[], Sell[], Value[], MA[];
//+------------------------------------------------------------------+
int OnInit()
  {
   SetIndexBuffer(0, iFish, INDICATOR_DATA);
   SetIndexBuffer(1, Buy, INDICATOR_DATA);
   SetIndexBuffer(2, Sell, INDICATOR_DATA);
   SetIndexBuffer(3, Value, INDICATOR_CALCULATIONS);
   SetIndexBuffer(4, MA, INDICATOR_CALCULATIONS);

   PlotIndexSetDouble(0, PLOT_EMPTY_VALUE, 0.0);
   PlotIndexSetDouble(1, PLOT_EMPTY_VALUE, 0.0);
   PlotIndexSetDouble(2, PLOT_EMPTY_VALUE, 0.0);

   ArraySetAsSeries(iFish, true);
   ArraySetAsSeries(Buy, true);
   ArraySetAsSeries(Sell, true);
   ArraySetAsSeries(Value, true);
   ArraySetAsSeries(MA, true);

   IndicatorSetString(INDICATOR_SHORTNAME, "TREND FILTER2 (" + (string)Nbars + "," + (string)MA_Period + ")");

   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
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, limit;
   if(prev_calculated > 0)
      limit = rates_total - prev_calculated;
   else
      limit =  2 * Nbars;

   double up, dn, osc;
   ArraySetAsSeries(high, true);
   ArraySetAsSeries(low, true);
   ArraySetAsSeries(close, true);

   for(i = limit; i >= 0; i--)
     {
      up = high[iHighest(NULL, 0, MODE_HIGH, Nbars, i)];
      dn = low[iLowest(NULL, 0, MODE_LOW, Nbars, i)];

      if(up > dn)
         osc = 100 * (close[i] - dn) / (up - dn);
      else
         osc = 0;
      if(osc < 0)
         osc = 0.1;
      if(osc > 100)
         osc = 99.9;

      Value[i] = 0.1 * (osc - 50.0);
     }
   int total = ArraySize(Value);
   for(i = limit; i >= 0; i--)
     {
      MA[i] = iMAOnArray(Value, total, MA_Period, 0, i);

      iFish[i] = (MathExp(2.0 * MA[i]) - 1.0) / (MathExp(2.0 * MA[i]) + 1.0);
      if(iFish[i] > 0.9)
         Buy[i] = iFish[i];
      if(iFish[i] < -0.9)
         Sell[i] = iFish[i];
     }
   return(rates_total);
  }
//+------------------------------------------------------------------+
double iMAOnArray(double & array[],  //функцию взял отсюда "ПЕРЕХОД С MQL4 НА MQL5"  https://www.mql5.com/ru/articles/81
                  int total,
                  int period,
                  int ma_shift,
                  int shift)
  {
   double buf[], arr[];
   if(ArrayResize(buf, total) < 0)
      return(0);
   double sum = 0.0, lsum = 0.0;
   double price;
   int    i, weight = 0, pos = total - 1;
   for(i = 1; i <= period; i++, pos--)
     {
      price = array[pos];
      sum += price * i;
      lsum += price;
      weight += i;
     }
   pos++;
   i = pos + period;
   while(pos >= 0)
     {
      buf[pos] = sum / weight;
      if(pos == 0)
         break;
      pos--;
      i--;
      price = array[pos];
      sum = sum - lsum + price * period;
      lsum -= array[i];
      lsum += price;
     }
   return(buf[shift + ma_shift]);
  }
//+------------------------------------------------------------------+


Работает и даже рисует такую же линию как оригинал, но совсем чуть чуть. Если попытаться сделать, чтоб рисовал больше, зависает терминал.

Trend Filter2


Так как с таймсериями дружба у меня не задалась с самого начала, решил сделать без них, ну и заодно убрать лишние графические построения.

И усреднение считает MovingAverages.mqh, а не функция из статьи ПЕРЕХОД С MQL4 НА MQL5. Всё равно они считают одинаково.

Получилось так.

//+------------------------------------------------------------------+
//|                                                Trend Filter3.mq5 |
//|                                  Copyright 2021, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2021, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
#include <MovingAverages.mqh>
#property indicator_separate_window
#property indicator_buffers 4
#property indicator_plots   1
#property indicator_type1   DRAW_COLOR_LINE
#property indicator_color1  clrYellow,clrLime,clrOrangeRed
#property indicator_style1  STYLE_SOLID
#property indicator_width1  2
#property indicator_level1  -0.9
#property indicator_level2   0
#property indicator_level3   0.9
#property indicator_minimum -1.05
#property indicator_maximum  1.05

input int  Nbars = 89;
input int  MA_Period = 9;

double iFish[], Value[], MA[], Color[];
//+------------------------------------------------------------------+
int OnInit()
  {
   SetIndexBuffer(0, iFish, INDICATOR_DATA);
   SetIndexBuffer(1, Color, INDICATOR_COLOR_INDEX);
   SetIndexBuffer(2, Value, INDICATOR_CALCULATIONS);
   SetIndexBuffer(3, MA, INDICATOR_CALCULATIONS);
   IndicatorSetString(INDICATOR_SHORTNAME, "TREND FILTER3 (" + (string)Nbars + "," + (string)MA_Period + ")");
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
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, limit;
   double up, dn, osc;

   if(prev_calculated > 0)
      limit = prev_calculated;
   else
      limit = Nbars;

   for(i = limit; i < rates_total; i++)
     {
      up = high[iHighest(NULL, 0, MODE_HIGH, Nbars, rates_total - i)];
      dn = low[iLowest(NULL, 0, MODE_LOW, Nbars, rates_total - i)];

      if(up > dn)
         osc = 100 * (close[i] - dn) / (up - dn);
      else
         osc = 0;
      if(osc < 0)
         osc = 0.1;
      if(osc > 100)
         osc = 99.9;

      Value[i] = 0.1 * (osc - 50.0);
     }

   for(i = limit; i < rates_total; i++)
     {
      MA[i] = LinearWeightedMA(i, MA_Period, Value);

      iFish[i] = (MathExp(2.0 * MA[i]) - 1.0) / (MathExp(2.0 * MA[i]) + 1.0);

      if(iFish[i - 1] >= 0.9)
         Color[i] = 1;
      else
         if(iFish[i - 1] <= -0.9)
            Color[i] = 2;
     }
   return(rates_total);
  }
//+------------------------------------------------------------------+

 

Но тут он совсем, что попало рисует.

Trend Filter3


И я никак не могу понять, что нужно сделать, чтоб этот индикатор заработал в МТ5.

Подскажите, что в них я сделал не правильно .

Файлы:
 
разместите заказ тут: https://www.mql5.com/ru/job
вам обязательно помогут
Торговые приложения для MetaTrader 5 на заказ
Торговые приложения для MetaTrader 5 на заказ
  • 2021.05.19
  • www.mql5.com
Самый большой фриланс c разработчиками программ на MQL5
 


.                                                                                                                                   .

 
Aleksandr Slavskii:

Здравствуйте. 

Индикатор  Trend Filter.mq4  скачан на просторах интернета. Задача переделать для МТ5. Индикатор не сложный, но я не справился.

Код индикатора.


Почитал форум вроде всё понятно и не сложно. Переделал. 

Вот код переделки.


Работает и даже рисует такую же линию как оригинал, но совсем чуть чуть. Если попытаться сделать, чтоб рисовал больше, зависает терминал.


Так как с таймсериями дружба у меня не задалась с самого начала, решил сделать без них, ну и заодно убрать лишние графические построения.

И усреднение считает MovingAverages.mqh, а не функция из статьи ПЕРЕХОД С MQL4 НА MQL5. Всё равно они считают одинаково.

Получилось так.

 

Но тут он совсем, что попало рисует.


И я никак не могу понять, что нужно сделать, чтоб этот индикатор заработал в МТ5.

Подскажите, что в них я сделал не правильно .

Для индикаторных буферов требуется указывать "серийность"/направление_индексации 

в каждом OnTick делать...ArraySetAsSeries(xx,true/false). 

потому как умолчания у mt4 и 5 разные

 

Рабочий код Trend Filter.mq5

//+------------------------------------------------------------------+
//|                                                Trend Filter.mq5 |
//|                                  Copyright 2021, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2021, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property indicator_separate_window
#property indicator_buffers 5
#property indicator_plots   3

#property indicator_type1   DRAW_LINE
#property indicator_color1  clrYellow
#property indicator_style1  STYLE_SOLID
#property indicator_width1  2

#property indicator_type2   DRAW_LINE
#property indicator_color2  clrLime
#property indicator_style2  STYLE_SOLID
#property indicator_width2  2

#property indicator_type3   DRAW_LINE
#property indicator_color3  clrOrangeRed
#property indicator_style3  STYLE_SOLID
#property indicator_width3  2

#property indicator_level1  -0.9
#property indicator_level2   0
#property indicator_level3   0.9

#property indicator_minimum -1.05
#property indicator_maximum  1.05

input int  Nbars = 89;
input int  MA_Period = 9;

double iFish[], Buy[], Sell[], Value[], MA[];
//+------------------------------------------------------------------+
int OnInit()
  {
   SetIndexBuffer(0, iFish);
   SetIndexBuffer(1, Buy);
   SetIndexBuffer(2, Sell);
   SetIndexBuffer(3, Value, INDICATOR_CALCULATIONS);
   SetIndexBuffer(4, MA, INDICATOR_CALCULATIONS);

   PlotIndexSetDouble(0, PLOT_EMPTY_VALUE, 0.0);
   PlotIndexSetDouble(1, PLOT_EMPTY_VALUE, 0.0);
   PlotIndexSetDouble(2, PLOT_EMPTY_VALUE, 0.0);
   PlotIndexSetDouble(3, PLOT_EMPTY_VALUE, 0.0);
   PlotIndexSetDouble(4, PLOT_EMPTY_VALUE, 0.0);

   ArraySetAsSeries(iFish, true);
   ArraySetAsSeries(Buy, true);
   ArraySetAsSeries(Sell, true);
   ArraySetAsSeries(Value, true);
   ArraySetAsSeries(MA, true);

   ArrayInitialize(iFish,EMPTY_VALUE);
   ArrayInitialize(Buy,EMPTY_VALUE);
   ArrayInitialize(Sell,EMPTY_VALUE);
   ArrayInitialize(Value,EMPTY_VALUE);
   ArrayInitialize(MA,EMPTY_VALUE);

   /*PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,Nbars);
   PlotIndexSetInteger(1,PLOT_DRAW_BEGIN,Nbars);
   PlotIndexSetInteger(2,PLOT_DRAW_BEGIN,Nbars);
   PlotIndexSetInteger(3,PLOT_DRAW_BEGIN,Nbars);
   PlotIndexSetInteger(4,PLOT_DRAW_BEGIN,Nbars);
   PlotIndexSetInteger(5,PLOT_DRAW_BEGIN,Nbars);*/


   IndicatorSetString(INDICATOR_SHORTNAME, "TREND FILTER2 (" + (string)Nbars + "," + (string)MA_Period + ")");

   return(INIT_SUCCEEDED);
  }

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int IndicatorCounted(int prev_calculated_=-1)
  {
   if(prev_calculated_>0)
      return(prev_calculated_-1);
   if(prev_calculated_==0)
      return(0);
   return(0);
  }

//+------------------------------------------------------------------+
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[])
  {
   ArraySetAsSeries(high, true);
   ArraySetAsSeries(close, true);
   ArraySetAsSeries(low, true);

   int counted_bars = IndicatorCounted(), i;
   if(counted_bars < 0)
      return(-1);
   if(counted_bars > 0)
      counted_bars--;
   int limit=counted_bars+2*Nbars;
   double up,dn,osc;

   ArrayInitialize(iFish,0);
   ArrayInitialize(Buy,0);
   ArrayInitialize(Sell,0);
   ArrayInitialize(Value,0);
   ArrayInitialize(MA,0);

   for(i = limit; i >= 0; i--)
     {
      up = high[iHighest(NULL,Period(),MODE_HIGH,Nbars,i)];
      dn = low[iLowest(NULL,Period(),MODE_LOW,Nbars,i)];

      if(up>dn)
         osc = 100*(close[i]-dn)/(up-dn);
      else
         osc = 0;
      if(osc < 0)
         osc = 0.1;
      if(osc > 100)
         osc = 99.9;
      Value[i]=0.1*(osc-50.0);

      MA[i]=iMAOnArray(Value,0,MA_Period,0,0,i);
      iFish[i]=(MathExp(2.0*MA[i])-1.0)/(MathExp(2.0*MA[i])+1.0);
      if(iFish[i]> 0.9)
        {
         Buy[i] =iFish[i];
         Buy[i+1] =iFish[i+1];
        }
      if(iFish[i]<-0.9)
        {
         Sell[i]=iFish[i];
         Sell[i+1]=iFish[i+1];
        }
     }
   return(rates_total);
  }
//+------------------------------------------------------------------+
double iMAOnArray(double &array[], int total, int periods, int ma_shift, int ma_method, int shift)
  {
   double buf[],arr[];
   if(total==0)
      total=ArraySize(array);
   if(total>0 && total<=periods)
      return(0);
   if(shift>total-periods-ma_shift)
      return(0);
   switch(ma_method)
     {
      case MODE_SMA :
        {
         total=ArrayCopy(arr,array,0,shift+ma_shift,periods);
         if(ArrayResize(buf,total)<0)
            return(0);
         double sum=0;
         int    i,pos=total-1;
         for(i=1; i<periods; i++,pos--)
            sum+=arr[pos];
         while(pos>=0)
           {
            sum+=arr[pos];
            buf[pos]=sum/periods;
            sum-=arr[pos+periods-1];
            pos--;
           }
         return(buf[0]);
        }
      case MODE_EMA :
        {
         total=ArrayCopy(arr,array,0,shift+ma_shift,periods);
         if(ArrayResize(buf,total)<0)
            return(0);
         double pr=2.0/(periods+1);
         int    pos=total-2;
         while(pos>=0)
           {
            if(pos==total-2)
               buf[pos+1]=array[pos+1];
            buf[pos]=array[pos]*pr+buf[pos+1]*(1-pr);
            pos--;
           }
         return(buf[0]);
        }
      case MODE_SMMA :
        {
         if(ArrayResize(buf,total)<0)
            return(0);
         double sum=0;
         int    i,k,pos;
         pos=total-periods;
         while(pos>=0)
           {
            if(pos==total-periods)
              {
               for(i=0,k=pos; i<periods; i++,k++)
                 {
                  sum+=array[k];
                  buf[k]=0;
                 }
              }
            else
               sum=buf[pos+1]*(periods-1)+array[pos];
            buf[pos]=sum/periods;
            pos--;
           }
         return(buf[shift+ma_shift]);
        }
      case MODE_LWMA :
        {
         if(ArrayResize(buf,total)<0)
            return(0);
         double sum=0.0,lsum=0.0;
         double price;
         int    i,weight=0,pos=total-1;
         for(i=1; i<=periods; i++,pos--)
           {
            price=array[pos];
            sum+=price*i;
            lsum+=price;
            weight+=i;
           }
         pos++;
         i=pos+periods;
         while(pos>=0)
           {
            buf[pos]=sum/weight;
            if(pos==0)
               break;
            pos--;
            i--;
            price=array[pos];
            sum=sum-lsum+price*periods;
            lsum-=array[i];
            lsum+=price;
           }
         return(buf[shift+ma_shift]);
        }
      default:
         return(0);
     }
   return(0);
  }
//+------------------------------------------------------------------+
 
spoun77 #:

Рабочий код Trend Filter.mq5

Спасибо.

А я и надежду потерял, что кто то ответит)))

И за темой вообще перестал следить.

А тут вон оно чё )))

 
Предположительно в этой статье есть этот индикатор в готовом виде. Это стохастик и преобразования Фишера.
 
Dmitry Fedoseev #:
Предположительно в этой статье есть этот индикатор в готовом виде. Это стохастик и преобразования Фишера.

В статье индикатор похож на  Trend Filter, но не он.  

Зато статья оказалась мне интересной и познавательной. Спасибо.

 
spoun77 #:

Рабочий код Trend Filter.mq5

И индикатор становится совсем рабочим если инициализацию массивов сделать один раз, а не при каждом вызове OnCalculate


   ArraySetAsSeries(high, true);
   ArraySetAsSeries(close, true);
   ArraySetAsSeries(low, true);
   
   int i, limit = 0;

   if(prev_calculated <= 0)
     {
      limit = rates_total - 2 * Nbars;
      ArrayInitialize(iFish, 0);
      ArrayInitialize(Buy, 0);
      ArrayInitialize(Sell, 0);
      ArrayInitialize(Value, 0);
      ArrayInitialize(MA, 0);
     }
   else
      limit = rates_total - prev_calculated;

   double up, dn, osc;

   for(i = limit; i >= 0; i--)
Причина обращения: