Некорректная работа функций времени в теле индикаторов и скриптов на истории.

 

Не первый раз столкнулся с такой проблемой что индикаторы и скрипты при тестировании на истории (запуск пустого эксперта, добавление индикатора/скрипта на график) выдают неправильные значения времени.

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

   ObjectCreate("Bars", OBJ_LABEL, 0, 0, 0);

   ObjectSet("Bars", OBJPROP_CORNER, 0);   

   ObjectSet("Bars", OBJPROP_XDISTANCE, 10);

   ObjectSet("Bars", OBJPROP_YDISTANCE, 15);

   ObjectSetText("Bars",StringConcatenate("",DayOfWeek()), 12, "Tahoma", White);
 

Однако если эта же функция DayOfWeek используется в расчетах, то все вроде бы работает, да только частично:

вот код индикатора который в левом верхнем углу возвращает количество баров от начала недели, запустим его с понедельника мы увидим 0 1 2 на первых двух свечах, потом отсчет остановится до вторника а во вторник целиком зависает терминал и умирает. Если запустить со вторника то отсчет будет идти до пятницы включительно, в понедельник счета не будет а во вторник (через неделю который) он опять зависнет.

//+------------------------------------------------------------------+
//|                                                       Cowboy.mq4 |
//|                                               Nikolay Khrushchev |
//|                                         N.A.Khrushchev@gmail.com |
//+------------------------------------------------------------------+
#property copyright "Nikolay Khrushchev"
#property link      "N.A.Khrushchev@gmail.com"
#property indicator_chart_window

//extern int AtrPeriod=14;



int TF;
//+------------------------------------------------------------------+
int start()
  {
   //int    counted_bars=IndicatorCounted();
   int BarsM1=DayOfWeek()*1440-(24-Hour())*60-(60-Minute());
   if (BarsM1<0) BarsM1=0;
   int BarsTF=NormalizeDouble(BarsM1/TF,0);
   while(true)
      {
      if (TimeDayOfWeek(Time[BarsTF])!=1) BarsTF--;
      if (TimeDayOfWeek(Time[BarsTF])==1) break;
      }
   ObjectSetText("Bars",StringConcatenate("",BarsTF), 12, "Tahoma", White);
   return(0);
  }
//+------------------------------------------------------------------+
int init()
  {
   ObjectCreate("Bars", OBJ_LABEL, 0, 0, 0);// Создание объ.
   ObjectSet("Bars", OBJPROP_CORNER, 0);    // Привязка угол
   ObjectSet("Bars", OBJPROP_XDISTANCE, 10);// Координата Х
   ObjectSet("Bars", OBJPROP_YDISTANCE, 15);// Координата Y
   TF=(Time[0]-Time[1])/60;
   return(0);
  }
//+------------------------------------------------------------------+
int deinit()
  {
   return(0);
  }
 
Sys15975382:

Однако если эта же функция DayOfWeek используется в расчетах, то все вроде бы работает, да только частично:

вот код индикатора который в левом верхнем углу возвращает количество баров от начала недели, запустим его с понедельника мы увидим 0 1 2 на первых двух свечах, потом отсчет остановится до вторника а во вторник целиком зависает терминал и умирает. Если запустить со вторника то отсчет будет идти до пятницы включительно, в понедельник счета не будет а во вторник (через неделю который) он опять зависнет.


Зачем так сложно

#property indicator_chart_window


//+------------------------------------------------------------------+
int start() {
   int WeekOpenTime=iTime(NULL, PERIOD_W1,0);
   int CountBars=iBarShift(NULL, 0, WeekOpenTime);
   if (Time[CountBars]<WeekOpenTime) CountBars--;
   if (ObjectFind("Bars")==-1) {
      ObjectCreate("Bars", OBJ_LABEL, 0, 0, 0);// ???????? ???.
      ObjectSet("Bars", OBJPROP_CORNER, 0);    // ???????? ????
      ObjectSet("Bars", OBJPROP_XDISTANCE, 10);// ?????????? ?
      ObjectSet("Bars", OBJPROP_YDISTANCE, 15);// ?????????? Y
   }

   ObjectSetText("Bars",StringConcatenate("",CountBars+1), 12, "Tahoma", White);
   return(0);
  }
//+------------------------------------------------------------------+
int init()
  {
   return(0);
  }
//+------------------------------------------------------------------+
int deinit()
  {
   return(0);
  }
 
Vinin Ну а какая разница. Расскажи как индикатору или скрипту на истории правильно возвращать количество баров с начала недели?
 
Sys15975382:
Vinin Ну а какая разница. Расскажи как индикатору или скрипту на истории правильно возвращать количество баров с начала недели?

Пост выше поправил

Можно и на истории сделать, но цикл и его обработку не так трудно сделать. Только зачем

 
Sys15975382:
Vinin Ну а какая разница. Расскажи как индикатору или скрипту на истории правильно возвращать количество баров с начала недели?
bars_since_beginning_of_week = iBarShift(Symbol(),0,iTime(Symbol(),PERIOD_W1,0));

нет ничего проще.

Собственно, то же самое, что и у Vinin'a

 
Зачем так сложно? потому что не работает то что вы написали. Если вставить в советник все окей, а в теле скрипта или индикатора не пашет ни в какую. Скомпилируйте это в индикатор и прокатите по времени, убедитесь сами. Технически вы пишете правильные вещи, но на то он и баг что правильные вещи не работают.
 

в коде своего индикатора я изменил вот эту строчку:

int BarsM1=DayOfWeek()*1440-(24-Hour())*60-(60-Minute());

вот так: int BarsM1=DayOfWeek()*1440-(24-TimeHour(Time[0]))*60-(60-TimeMinute(Time[0]));

т.е. по сути делаю обходные пути.

Поведение при запуске в понедельник не изменилось. а вот если запускать со вторника то он работает успешно и на следующей недели и на любой другой.

 
Sys15975382:
Зачем так сложно? потому что не работает то что вы написали. Если вставить в советник все окей, а в теле скрипта или индикатора не пашет ни в какую.

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

И кстати. Для проверки моего кода (а это и есть индикатор) поставьте его на график и с понедельника смотрите его работу.

 
И тему неплохо было бы переименовать. Вариантов приводить не буду, но слово БАГ должно исчезнуть. Если переименую я, то эназвание может быть что-то типа "Баг. Кривые руки. "
Причина обращения: