Предложение как ускорить оптимизацию. - страница 3

 
Academic:


Простите но если Вы имелли ввиду что "мой" код не оптимален. То посмотрите еще раз. И все таки прогоните пожалуйста в тестере, а еще лучше в оптимизации - с такой скоростью вообще не жизнь.

Посмотрим. Мы постоянно работаем над ускорением. И, может быть, Ваш код нам тоже поможет в этом.
 
stringo:
Посмотрим. Мы постоянно работаем над ускорением. И, может быть, Ваш код нам тоже поможет в этом.
Самое грустное, еще и то что эксперт вообще не торгует. Я подправлю код чтобы сигналы были для торговли - и тогда все вообще встает. Код выложу.
 

Указанный эксперт при прогоне с 2000.01.01 по 2011.01.01 на EURUSD M1 сгенерировал более 2 млн сделок, что привело к тормозам терминала.

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

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


Спасибо за тест - в следующем билде будут поправки.

Документация по MQL5: Торговые функции / HistoryDealsTotal
Документация по MQL5: Торговые функции / HistoryDealsTotal
  • www.mql5.com
Торговые функции / HistoryDealsTotal - Документация по MQL5
 

Academic, разберём Ваш индикатор (хоть это не относится к скорости тестирования)

   for ( int i=prev_calculated; i<rates_total; i++){

Эта строка говорит о том, что проводится либо полный расчёт от нуля, либо пересчёт на новом баре. Развитие бара никак не обрабатывается. Экономно.

Смотрим дальше. Пересчёт на открытии нового бара. 

      int e=i+Par;
      if ( e > rates_total )
         e=rates_total;
         
      if ( (e-i)/3 != 0 ){   

На открытии нового бара при  Par>1 e всегда будет присвоено значение rates_total. Поэтому разница e-i всегда будет равна 1, и (e-i)/3 всегда будет равно 0. Пересчёта не будет. Экономно. Но правильно ли?

При Par=0 разница e-i всегда равна 0. При Par=1 разница e-i всегда 1. (e-1)/3 всегда 0.

То есть, на экономном дорасчёте индикатора вы никогда не получите ни одного значения! Потому что прошлое на глубину Par Вы не рассматриваете. И поэтому полный пересчёт будет отличаться от дорасчёта.

Кстати, текущее значение индикатора всегда будет нулевым, поэтому я не понимаю, как срабатывают условия торговли

  if ( i1Buffer[0] != 0 )
      Sell();
   if ( i2Buffer[0] != 0 )
      Buy(); 

Может, я чего-то не учёл?

Добавление. Возможно, я не учёл EMPTY_VALUE. Надо проверить

Ещё добавление. Вы вообще никак не инициализируете индикаторные буфера. А там потенциально может находиться любой мусор. 

 
stringo:

Academic, разберём Ваш индикатор (хоть это не относится к скорости тестирования)

Эта строка говорит о том, что проводится либо полный расчёт от нуля, либо пересчёт на новом баре. Развитие бара никак не обрабатывается. Экономно.

Смотрим дальше. Пересчёт на открытии нового бара. 

На открытии нового бара при  Par>1 e всегда будет присвоено значение rates_total. Поэтому разница e-i всегда будет равна 1, и (e-i)/3 всегда будет равно 0. Пересчёта не будет. Экономно. Но правильно ли?

При Par=0 разница e-i всегда равна 0. При Par=1 разница e-i всегда 1. (e-1)/3 всегда 0.

То есть, на экономном дорасчёте индикатора вы никогда не получите ни одного значения! Потому что прошлое на глубину Par Вы не рассматриваете. И поэтому полный пересчёт будет отличаться от дорасчёта.

Кстати, текущее значение индикатора всегда будет нулевым, поэтому я не понимаю, как срабатывают условия торговли

Может, я чего-то не учёл?

Добавление. Возможно, я не учёл EMPTY_VALUE. Надо проверить

Слава, спасибо, что посмотрели. Вы совершенно правы,  сигналов при таком индикаторе не будет ни одной. Я уже даже написал про тоже. :) Это на самом деле результат попытки создать на коленке пример индикатора. Но вот ниже я приведу пример где все более правильно для проверки.
 

i1 =

#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots   1

#property indicator_label1  "i1"
#property indicator_type1   DRAW_LINE
#property indicator_color1  Red
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1

input int      Par=15;

double         Label1Buffer[];

int OnInit()
  {
   SetIndexBuffer(0,Label1Buffer,INDICATOR_DATA);
   
   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[])
  {
   
   int s=prev_calculated;
   
   if ( s < 3 )
      s=3;
   
   for ( int i=s; i<rates_total; i++){
      
      int sum=0;
      
      int e = i-Par; 
      if ( e < 0 )
         e=0;
         
 
      for ( int j=e; j<=i; j++ )
         sum += (int)((open[j]/_Point)+0.5);
         
      sum = sum / ( (i-e)/3 );
         
      if ( (sum % Par) == 0 ) 
         Label1Buffer[i]=open[i];

   }
   return(rates_total);
  }

i2 =
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots   1

#property indicator_label1  "i2"
#property indicator_type1   DRAW_LINE
#property indicator_color1  Red
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1

input int      Par=15;

double         Label1Buffer[];

int OnInit()
  {
   SetIndexBuffer(0,Label1Buffer,INDICATOR_DATA);
   
   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[])
  {
   
   int s=prev_calculated;
   
   if ( s < 3 )
      s=3;
   
   for ( int i=s; i<rates_total; i++){
      
      int sum=0;
      
      int e = i-Par; 
      if ( e < 0 )
         e=0;
         
 
      for ( int j=e; j<=i; j++ )
         sum += (int)((open[j]/_Point)+0.5);
         
      sum = sum / ( (i-e)/3 );
         
      if ( (sum % (Par+Par/2) ) == 0 ) 
         Label1Buffer[i]=open[i];

   }
   return(rates_total);
  }

 

 
Renat:

Указанный эксперт при прогоне с 2000.01.01 по 2011.01.01 на EURUSD M1 сгенерировал более 2 млн сделок, что привело к тормозам терминала.

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

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


Спасибо за тест - в следующем билде будут поправки.


Ринат, да конечно 2 миллиона это много. Но мне кажется, что даже при условии что их будет 20000 это уже сильно тормозит терминал. Мне кажется, что может быть длинный список? Хотя я уже писал об этом, ранее, но я могу только гадать. Но то что когда сделок много а позиция всего одна это не дело тормозить? :) Или я не прав ? Это же нетто торговля.
 
Academic:

i1 =

i2 =

Обязательно инициализировать нулевые значения! Вы ведь в эксперте значение индикаторов на 0 проверяете

      if ( (sum % Par) == 0 ) 
         Label1Buffer[i]=open[i];
      else
         Label1Buffer[i]=0;

 

 
stringo:

Обязательно инициализировать нулевые значения! Вы ведь в эксперте значение индикаторов на 0 проверяете

 

Я же вроде именно НОЛЬ или НЕ НОЛЬ присваиваю.


Кстати прогоните с Par=112 от 1 января 10 года. Смешно, кстати. Хороший пример для заумных стратегий. :)

 
Academic:

Я же вроде именно НОЛЬ или НЕ НОЛЬ присваиваю.

 

Где? Ткните пальцем где Вы присваиваете НОЛЬ. Это должна быть строка Label1Buffer[i]=0;

Вы присваиваете только НЕ НОЛЬ 

Причина обращения: