Ошибки, баги, вопросы - страница 2437

 
Alexey Navoykov:

Т.е. OnTesterPass вызывается без наличия фрэймов?  Ну тогда это очевидная ошибка.  Данное событие означает получение фрэйма, а не окончание прохода.

Все фрэймы должны придти в OnTesterPass до того, как вызывать событие OnTesterDeinit. Это нормальная здоровая логика.   Если, повторюсь, речь не идёт о принудительном прерывании тестирования.

OnTesterPass вызывается, когда пришёл хотя бы один фрейм. Может прийти пачка фреймов. Поэтому в OnTesterPass надо принимать фреймы в цикле, а не по одному. Но если "после последнего раза - ни разу", то OnTesterPass не вызывается.

Оптимизация прекращается, когда пришёл последний результат. Фреймы могут поступить позднее, особенно если в фрейме передаётся большое количество данных или если передаётся сразу несколько фреймов на один проход. Поэтому в OnTesterDeinit, которая запускается по завершению оптимизации нужно организовывать приём оставшихся фреймов.  Тоже в цикле.

Это - нормальная здоровая логика.

Я несколько раз давал примеры приёма фреймов именно в OnTesterDeinit, а не только в OnTesterPass. И именно приём сложных фреймов разных типов

 
Slava:

если передаётся сразу несколько фреймов на один проход.

Когда-то пробовал, такое не прокатывало. Только один FrameAdd срабатывал.

 
Slava:

Оптимизация прекращается, когда пришёл последний результат. Фреймы могут поступить позднее, особенно если в фрейме передаётся большое количество данных или если передаётся сразу несколько фреймов на один проход. Поэтому в OnTesterDeinit, которая запускается по завершению оптимизации нужно организовывать приём оставшихся фреймов.  Тоже в цикле.

Если фрэймы могут поступить позднее, то значит нет гарантии, что и в OnTesterDeinit они будут сразу?  Т.е. надо делать цикл ожидания?  И как долго ждать?

Я то ранее подумал, что дело обстоит так:  OnTesterPass вызывается только для тех фрэймов, которые пришли с момент окончания предыдущего OnTesterPass.  Если же новый фрэйм пришёл в процессе выполнения OnTesterPass , а конкретней - с момента последнего вызова FrameNext и до завершения функции, то этот фрэйм так и останется висеть, пока не придёт новый фрэйм, генерирующий событие.   Поэтому OnTesterDeinit и необходим для получения этих висящих фрэймов.

 
Alexey Navoykov:

Если фрэймы могут поступить позднее, то значит нет гарантии, что и в OnTesterDeinit они будут сразу?  Т.е. надо делать цикл ожидания?  И как долго ждать?

Я то ранее подумал, что дело обстоит так:  OnTesterPass вызывается только для тех фрэймов, которые пришли с момент окончания предыдущего OnTesterPass.  Если же новый фрэйм пришёл в процессе выполнения OnTesterPass , а конкретней - с момента последнего вызова FrameNext и до завершения функции, то этот фрэйм так и останется висеть, пока не придёт новый фрэйм, генерирующий событие.   Поэтому OnTesterDeinit и необходим для получения этих висящих фрэймов.

FrameNext - это тупое чтение mqd-файла и больше ничего.

FrameFirst - FileSeek.
 
fxsaber:

Когда-то пробовал, такое не прокатывало. Только один FrameAdd срабатывал.

Здесь я пример показывал.
 

Спасибо.


PS FrameFirst здесь лишний

Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

Тестирование стратегий по расписанию с автоподстановкой результата в советника

Slava, 2013.04.10 15:04

Вот пример. В OnTester советник отсылает 2 фрейма - история сделок и история, на которой он работал.

В OnTesterDeinit приём и обработка всех фреймов первого и второго типа

void OnTesterDeinit()
  {
   string        name;
   ulong         pass;
   long          id;
   double        value;
   int           handle,i;
   BalanceInTime balance[];
   MqlRates      rates[];
//---
   FrameFirst();
   FrameFilter("",1);
   while(FrameNext(pass,name,id,value,balance))
     {
      handle=FileOpen(name+"_"+string(id)+"_"+IntegerToString(pass,5,'0')+".txt",FILE_WRITE|FILE_CSV|FILE_ANSI);
      if(handle!=INVALID_HANDLE)
        {
         for(i=0; i<ArraySize(balance); i++)
            FileWrite(handle,balance[i].date,EnumToString(balance[i].entry),DoubleToString(balance[i].price,5),DoubleToString(balance[i].balance,2));
         FileClose(handle);
        }
     }
//---
   FrameFirst();
   FrameFilter("",2);
   while(FrameNext(pass,name,id,value,rates))
     {
      handle=FileOpen(name+"_"+string(id)+"_"+IntegerToString(pass,5,'0')+".txt",FILE_WRITE|FILE_CSV|FILE_ANSI);
      if(handle!=INVALID_HANDLE)
        {
         for(i=0; i<ArraySize(rates); i++)
            FileWrite(handle,rates[i].time,DoubleToString(rates[i].open,5),DoubleToString(rates[i].high,5),DoubleToString(rates[i].low,5),DoubleToString(rates[i].close,5),string(rates[i].tick_volume));
         FileClose(handle);
        }
     }
//---
  }
 
fxsaber:


PS FrameFirst здесь лишний

Нет. Не лишний - чисто методически. Законченный блок кода безо всяких умолчаний

Этот код был выдран из более сложного кода. Передавали 4 типа разных фреймов. При этом читали в OnTesterPass тоже. Здесь представлен "рафинированный" код.

 
Slava:

Нет. Не лишний - чисто методически. Законченный блок кода безо всяких умолчаний

Этот код был выдран из более сложного кода. Передавали 4 типа разных фреймов. При этом читали в OnTesterPass тоже. Здесь представлен "рафинированный" код.

Про то, что FrameFirst всегда лишний, если вызывается перед FrameFilter.

Не рекомендовал бы передачу данных более, чем через один фрейм.

 
fxsaber:

Про то, что FrameFirst всегда лишний, если вызывается перед FrameFilter.

Не рекомендовал бы передачу данных более, чем через один фрейм.

1. Да. Может быть лишний.

2. Один тип фреймов читается в OnTesterPass, дочитывается в OnTesterDeinit. Остальные фреймы вычитываются в OnTesterDeinit

Нам эта возможность передачи-получения нескольких типов фреймов позволила исправить несколько трудновоспроизводимых ошибок в тестере. Причём фреймы передавались только если возникало различие с неким эталонным значением.

 
Slava:

Откроете opt-формат?

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