Нужна помощь в оптимизации циклов

Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий
Peter Vorobyev
406
Peter Vorobyev  

Ниже код варианта стохастика. Не могу сообразить как оптимизировать код чтобы не пересчитывать все 500 (Barcount) баров за тик. 
Подскажите где докрутить?

#property indicator_separate_window
#property indicator_minimum 0.00
#property indicator_maximum 100.00
#property indicator_color1 Lime
#property indicator_buffers 2
#property indicator_color2 Red
#property indicator_level1 20
#property indicator_level2 80
#property strict

extern double  Slw = 5;
extern int     Pds = 3;
extern double  Slwsignal = 3;
extern int     Barcount = 500;

int LastTradeTime;
double ExtHistoBuffer[];
double ExtHistoBuffer2[];
bool BuyAlert=false, SellAlert=false;

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void SetIndexValue(int shift, double value)
  {
   ExtHistoBuffer[shift] = value;
  }

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void SetIndexValue2(int shift, double value)
  {
   ExtHistoBuffer2[shift] = value;
  }

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double GetIndexValue(int shift)
  {
   return(ExtHistoBuffer[shift]);
  }

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double GetIndexValue2(int shift)
  {
   return(ExtHistoBuffer2[shift]);
  }

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int init()
  {
   IndicatorShortName("");
   PlotIndexSetInteger(0, DRAW_LINE, STYLE_SOLID);
   SetIndexBuffer(0, ExtHistoBuffer);
   IndicatorShortName("");
   PlotIndexSetInteger(1, DRAW_LINE, STYLE_SOLID);
   SetIndexBuffer(1, ExtHistoBuffer2);

   IndicatorShortName("");
   SetIndexLabel(0,NULL);
   SetIndexLabel(1,NULL);

   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[])
  {
   double AA = 0;
   double bb = 0;
   double aa1 = 0;
   int shift = 0;
   double loopbegin = 0;
   double loopbegin2 = 0;
   double loopbegin3 = 0;
   double smconst = 0;
   double smconst1 = 0;
   double prev = 0;
   double prev1 = 0;
   double prev2 = 0;
   double prev3 = 0;
   double MAValue = 0;
   double MAValue2 = 0;
   double mavalue3 = 0;
   double MyHigh = 0;
   double MyLow = 0;
   int counter = 0;
   double Price = 0;
   double tmpDevAA = 0;

   smconst = 2 / (1+Slw);
   smconst1 = 2 / (1+Slwsignal);

   loopbegin = loopbegin+1;
   for(shift =Barcount; shift >=0 ; shift --)
     {
      prev = GetIndexValue2(shift+1);

      AA = 0;
      tmpDevAA = (High[iHighest(NULL, 0, MODE_HIGH,shift+Pds,Pds)] - Low[iLowest(NULL, 0, MODE_LOW,shift+Pds,Pds)]);

      if(tmpDevAA != 0)
         AA = 100* ((Close[shift] - Low[iLowest(NULL, 0, MODE_LOW,shift+Pds,Pds)]) / tmpDevAA);

      MAValue2 = smconst * (AA-prev) + prev;
      SetIndexValue2(shift,MAValue2);
      loopbegin = loopbegin-1;
     }

   loopbegin2 = loopbegin2+1;
   for(shift =Barcount-Pds; shift >=0 ; shift --)
     {
      MyHigh = -999999;
      MyLow = 99999999;
      for(counter =shift; counter <=Pds + shift ; counter ++)
        {
         Price= GetIndexValue2(counter);
         if(Price > MyHigh)
            MyHigh = Price;
         if(Pds <= 0)
            MyHigh = Price;
         if(Price < MyLow)
            MyLow = Price;
         if(Pds <= 0)
            MyLow = Price;
        }

      prev1 = GetIndexValue(shift+1);
      aa1=GetIndexValue2(shift);

      bb= 0;
      if((MyHigh-MyLow) != 0)
         bb=100*(aa1-MyLow)/(MyHigh-MyLow);

      MAValue = smconst * (bb-prev1) + prev1;
      SetIndexValue(shift,MAValue);
      loopbegin2 = loopbegin2-1;
     }

   loopbegin3 = loopbegin3+1;
   for(shift =Barcount; shift >=0 ; shift --)
     {
      prev2=GetIndexValue2(shift+1);
      prev3=GetIndexValue(shift);
      mavalue3= smconst1 * (prev3-prev2) +prev2;
      SetIndexValue2(shift,mavalue3);
      loopbegin3 = loopbegin3-1;
     }

   Comment("\n ",ExtHistoBuffer[0],"\n ",ExtHistoBuffer[1]);

   return(rates_total);
  }

Файлы:
Aleksey Mavrin
3157
Aleksey Mavrin  
Peter Vorobyev:

Ниже код варианта стохастика. Не могу сообразить как оптимизировать код чтобы не пересчитывать все 500 (Barcount) баров за тик. 
Подскажите где докрутить?

 for(shift =prev_calculated; shift <rates_total ; shift ++)
Peter Vorobyev
406
Peter Vorobyev  
Aleksey Mavrin:

в shift будет номер первого бара истории с индексом в несколько тысяч

вы наверно имели ввиду 

shift = rates_total - prev_calculated

получаю 2020.02.06 02:34:18.484 ptr_DDS_test EURUSD.I,M1: array out of range in 'ptr_DDS_test.mq4' (53,32)

но не понимаю почему выход за диапазон. 
Файлы:
Ihor Herasko
21867
Ihor Herasko  
Peter Vorobyev:

в shift будет номер первого бара истории с индексом в несколько тысяч

вы наверно имели ввиду 

получаю 2020.02.06 02:34:18.484 ptr_DDS_test EURUSD.I,M1: array out of range in 'ptr_DDS_test.mq4' (53,32)

но не понимаю почему выход за диапазон. 

Потому что если limit указывает на первый бар в истории (тот, что левее всех по графику), то левее него (индекс + 1 и более) ничего нет - выход за пределы массива.

А вот здесь:

     for(counter =shift; counter <=Pds + shift ; counter ++)
        {
         Price= GetIndexValue2(counter);
         if(Price > MyHigh)
            MyHigh = Price;
         if(Pds <= 0)
            MyHigh = Price;
         if(Price < MyLow)
            MyLow = Price;
         if(Pds <= 0)
            MyLow = Price;
        }

происходит обращение к элементам массива ExtHistoBuffer2, которых не существует (они должны быть левее на графике, но их нет).

Все потому, что в функции GetIndexValue2() нет проверки на ошибку выхода за пределы массива.

Документация по MQL5: Основы языка / Переменные
Документация по MQL5: Основы языка / Переменные
  • www.mql5.com
Переменные должны быть объявлены перед их использованием. Для идентификации переменных используются уникальные имена. Описания переменных используются для их определения и объявления типов. Описание не является оператором. Индексом массива может быть только целое число. Допускаются не более чем четырехмерные массивы. Нумерация элементов...
Aleksey Mavrin
3157
Aleksey Mavrin  
Peter Vorobyev:

в shift будет номер первого бара истории с индексом в несколько тысяч

вы наверно имели ввиду 

получаю 2020.02.06 02:34:18.484 ptr_DDS_test EURUSD.I,M1: array out of range in 'ptr_DDS_test.mq4' (53,32)

но не понимаю почему выход за диапазон. 

Вы спросили что надо чтобы не пересчитывать все 500 баров, я именно это и ответил, что вы с shift дальше делаете для этого не важно.

Peter Vorobyev
406
Peter Vorobyev  
Ihor Herasko:

Потому что если limit указывает на первый бар в истории (тот, что левее всех по графику), то левее него (индекс + 1 и более) ничего нет - выход за пределы массива.

А вот здесь:

происходит обращение к элементам массива ExtHistoBuffer2, которых не существует (они должны быть левее на графике, но их нет).

Все потому, что в функции GetIndexValue2() нет проверки на ошибку выхода за пределы массива.

спасибо за подсказку - исправил.
Историю отрисовывает правильно. А вот онлайн рисовать не хочет. 

Файлы:
Peter Vorobyev
406
Peter Vorobyev  
Peter Vorobyev:

спасибо за подсказку - исправил.
Историю отрисовывает правильно. А вот онлайн рисовать не хочет. 

т.е. что-то не могу сообразить из алгоритма, вообще реально не пересчитывать всю историю чтобы получить теже данные на выходе, что и при пересчете.

Aleksey Mavrin
3157
Aleksey Mavrin  
судя по тому что вы пишите про шифт - вы не запутались с индексацией массивов индикатора? он индексируется так что 0 ячейка массива - самый старый бар - самый левый т.е.
Peter Vorobyev
406
Peter Vorobyev  
Aleksey Mavrin:
судя по тому что вы пишите про шифт - вы не запутались с индексацией массивов индикатора? он индексируется так что 0 ячейка массива - самый старый бар - самый левый т.е.

да вроде не запутался

ArraySetAsSeries(ExtHistoBuffer, true);
***
int limit = rates_total - prev_calculated;
if (limit != 0) limit --;

for(shift = limit; shift >=0 ; shift --)
   ExtHistoBuffer[shift] = value;   
Aleksey Mavrin
3157
Aleksey Mavrin  
Peter Vorobyev:

да вроде не запутался

а какой смысл в  ExtHistoBuffer[shift] = value

шифт всегда будет ноль, кроме первого просчёта истории. т.е. вы меняете самый старый бар, а надо наверное самый новый, не? а говорите не запутались)

Peter Vorobyev
406
Peter Vorobyev  
Aleksey Mavrin:

а какой смысл в  ExtHistoBuffer[shift] = value

шифт всегда будет ноль, кроме первого просчёта истории. т.е. вы меняете самый старый бар, а надо наверное самый новый, не? а говорите не запутались)

почему 0 - это самый старый ? 
0 - это самый новый бар - нулевая свеча. Ведь ArraySetAsSeries(ExtHistoBuffer, true); указывает что хранение элементов как в тайм серии. Или я чего-то не понимаю?

12
Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий