Вопрос - как работает бесконечный цикл в экспертах?

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

Возникло желание сделать такую штуковину:

Каждый час в начале часа проверять определённое условие (не скажу, какое :) ) и, если оно выполняется, генерировать случайное число i от 0 до 59 и открываться в i-ю минуту этого часа с заданными стоп-тейк параметрами.

Сразу уточняю, что штуковина нужна исключительно для тестирования на истории.

Попытка номер раз:

//+------------------------------------------------------------------+
//|                                              TesterCondition.mq4 |
//|                                 Copyright © 2006, D&S Kiriyenko. |
//|                 http://groups.google.com/group/expert-developing |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2006, D&S Kiriyenko."
#property link      "http://groups.google.com/group/expert-developing"
 
#include <TradingLib.mqh>
 
//+------------------------------------------------------------------+
//| макроопределения                                                 |
//+------------------------------------------------------------------+
 
//---- строковые константы
#define EXPERT_NAME "Tester of condition"
 
//---- магическое число
#define MAGIC 20061116
 
 
//+------------------------------------------------------------------+
//| внешние переменные                                               |
//+------------------------------------------------------------------+
 
//----управление капиталом
extern string MoneyManagement = "<-------- Управление капиталом -------->";
extern int Lots  = 1; //количество лотов на сделку
extern int SL = 1000; //стоп-лосс в пунктах
extern int TP = 1000; //стоп-лосс в процентах
 
//+------------------------------------------------------------------+
//| Инициализация                                                    |
//+------------------------------------------------------------------+
int init()
  {
   return(0);
  }
 
//+------------------------------------------------------------------+
//| Деинициализация                                                  |
//+------------------------------------------------------------------+
int deinit()
  {
   return(0);
  }
 
//+------------------------------------------------------------------+
//| Итерационная функция                                             |
//+------------------------------------------------------------------+
int start()
  {
//----  анализировать только полные бары
   static datetime prev_time = 0;
   if (prev_time == Time[0]) return (0);
   prev_time = Time[0];
//---- проверяем, разрешает ли этот час сделать сделку
   bool Condition = <проверяем_выполнение_некоегословия>;
   if (!Condition) return (0);
//---- открываемся в случайную минуту
   MathSrand(TimeLocal()); //инициализируем генератор случайных чисел
   int Min = MathRand()%Period(); //Min = 0..59
   int Hr  = Hour(); //запоминаем текущий час
   while (true) //организуем бесконечный цикл
     {
      if (Minute() >= Min) //если заказанная минута сейчас или уже прошла
        {
         <открываем_ордер_с_заданными_параметрами>; //открываемся
         break; //и выходим из бесконечного цикла
        }
      if (Hour() > Hr) break; //если уже следующий час, то тем более выходим
      Sleep(60000); //эту строчку я и включал и выключал - один хрен не меняет сути
     }
//---- готово
   return(0);
  }
//+------------------------------------------------------------------+
Если что-то и нелогично, я этого не увидел.

Однако же, при тестировании на истории (запуск на H1) обнаружился неожиданный результат. Лично я думал, что когда зацикливаешь эксперт, то зацикливается именно эксперт. Время продолжает неумолимо лететь вперёд и функции типа Minute() будут возвращать уже новую текущую минуту.

Но я был неправ. Всё тупо зациклилось. При добавлении в тело бесконечного цикла строчки:
Print(Min," ",TimeToStr(TimeCurrent()));
в журнал стала принтоваться исключительно одна и та же строка: к примеру,

2006.11.17 17:07:57 2004.06.21 18:00 TesterCondition USDCAD, H1: 45 2004.06. 21 18:00
2006.11.17 17:07:57 2004.06.21 18:00 TesterCondition USDCAD, H1: 45 2004.06. 21 18:00
2006.11.17 17:07:57 2004.06.21 18:00 TesterCondition USDCAD, H1: 45 2004.06. 21 18:00

Т.е., эксперт в 18:00 решил, что открываться можно, сгенерил себе 45-ю минуту и зациклился. Вместе с тестером.

Штуковина всё равно нужна, да и интерес академический есть, в связи с чем вопросы:

  1. Я всё правильно сделал? :)
  2. Если да, то: эта фишка с зацикливанием - она только на истории, или в реальном времени тоже так будет? По идее, нет, но в этом случае имеем явный глюк тестера. Который было бы неплохо исправить.
  3. Тем не менее, как иначе мне реализовать такую затею? Подскажите, ничего в голову не идёт.
Заранее спасибо и с уважением.
 
Где-то здесь разработчики писали, что в тестере зацикленные эксперты не работают
 

Ренат неоднократно замечал, что зацикленные эксперты не работают в тестере

 
Integer:
Где-то здесь разработчики писали, что в тестере зацикленные эксперты не работают
Типа, это не глюк. Это такая фича. А жаль...

А какой другой конструкцией мне бы реализовать изначально поставленную задачу? Правда, ну ничего в голову не идёт, а сделать надо сегодня, чтобы на выходные зарядить оптимизацию.
 
Тики приходят достаточно часто, так что можно обойтись без циклами.

Берем флаг и сбрасываем его.На очередном тике смотрим наступило ли указанное время (вернее промеждуток, напр. м/у час:00 и час:05) и сброшен ли флаг. Если да тогда: Поднимаем флаг (что бы условие не сработало еще раз на следующем тике) и делаем что надо. Дополнительно смотрим еще если време м/у час:05 и час:10 и флаг поднят. Тогда флаг сбрасываем и все. Все делается с учетом, что за 5 минут хоть раз прийдет новая цена.
 
int init()
  {
   MathSrand(TimeLocal()); //инициализируем генератор случайных чисел
   return(0);
  }
int start()
  {
   static bool Condition;
   int Min, Hr;
//----  анализировать только полные бары
   static datetime prev_time = 0;
   if (prev_time < Time[0])
   {
   //---- проверяем, разрешает ли этот час сделать сделку
      Condition = <про�еряем_в��полнение_��екое�о_у��ло�ия>;
      prev_time = Time[0];
      if (Condition)
      { 
         Min = MathRand()%Period(); //Min = 0..59
         Hr  = Hour(); //запоминаем текущий час
      }
   }
   if (!Condition) return (0);
   if (Hour() > Hr)
   {
      Condition = false; //если уже следующий час, то тем более выходим
      return (0);
   }
   if (Minute() >= Min) //если заказанная минута сейчас или уже прошла
   {
      <откры�аем_��рдер_�_��аданными_��араметрами>; //открываемся
      Condition = false;
   }
 
//---- готово
   return(0);
  }
//+------------------------------------------------------------------+
Что-то типа того ;)
 
Itso:
Тики приходят достаточно часто, так что можно обойтись без циклами.

Берем флаг и сбрасываем его.На очередном тике смотрим наступило ли указанное время (вернее промеждуток, напр. м/у час:00 и час:05) и сброшен ли флаг. Если да тогда: Поднимаем флаг (что бы условие не сработало еще раз на следующем тике) и делаем что надо. Дополнительно смотрим еще если време м/у час:05 и час:10 и флаг поднят. Тогда флаг сбрасываем и все. Все делается с учетом, что за 5 минут хоть раз прийдет новая цена.
Спасибо, примерно так я писать и собирался. Уже пишу. :)

Digger писал (а):
Ренат неоднократно замечал, что зацикленные эксперты не работают в тестере

В том-то и дело. "Не хочешь исправлять ошибку - задокументируй её!" Тем более обидно, что в остальном разработчики вполне адекватно реагируют и оперативно исправляют баги.
 
dmitriy:

В том-то и дело. "Не хочешь исправлять ошибку - задокументируй её!" Тем более обидно, что в остальном разработчики вполне адекватно реагируют и оперативно исправляют баги.
Я так понимаю, что знание базовых принципов программирования необязательно перед выдачей советов?

Человек зацикливает код, думает что тестер будет сам распознавать цикл и умно-умно его разрывать. Человек получает явные объяснения, что зацикленного эксперта никак нельзя тестировать, но делает вид, что не понимает и заявляет про ошибку разработчиков.
 
Можно даже попроще - смотрим когда появился новый часовой бар (новый iTime(Symbol(),PERIOD_H1,0) не равен старым) и делаем что надо.
 
Renat писал (а):
dmitriy писал (а):

В том-то и дело. "Не хочешь исправлять ошибку - задокументируй её!" Тем более обидно, что в остальном разработчики вполне адекватно реагируют и оперативно исправляют баги.
Я так понимаю, что знание базовых принципов программирования необязательно перед выдачей советов?

Человек зацикливает код, думает что тестер будет сам распознавать цикл и умно-умно его разрывать. Человек получает явные объяснения, что зацикленного эксперта никак нельзя тестировать, но делает вид, что не понимает и заявляет про ошибку разработчиков.

И сколько максимум может выполнятся функция start? В документации не сказано что есть ограничение на выполнение функции start так оно и есть или это выполннеие какт о ограничивается? Я зацикливать не буду но интересно есть ли ограничение на время выполнения этой функции?
 
elritmo:

И сколько максимум может выполнятся функция start? В документации не сказано что есть ограничение на выполнение функции start так оно и есть или это выполннеие какт о ограничивается? Я зацикливать не буду но интересно есть ли ограничение на время выполнения этой функции?
Неограниченно долго. Детали на https://docs.mql4.com/ru/runtime/start и в поиске:
https://www.mql5.com/ru/search?utm_campaign=MQL4.community
Причина обращения: