Нормализация даты и времени или в чем подвох?

 

Задача нарисовать сеть линий с заданного периода до макс. и мин. цен с заданным шагом.

Проблема. На дате по умолчанию рисует линии только на больших таймфреймах от D1 и выше. на малых не хочет

меняю дату на пару дней вперед и все рисует даже на малых.

в чем прикол? где собака порыла? Нормализация даты и времени нужна или что?

подскажите плиз а то уже третий час бошку ломаю. 

ошибок не выдает! 

//+------------------------------------------------------------------+
//|                                                      Prognoz.mq4 |
//|                               Copyright 2016, Vladimir Gribachev |
//|                      https://www.mql5.com/ru/users/moneystrategy |
//+------------------------------------------------------------------+
#property copyright "Copyright 2016, Vladimir Gribachev"
#property link      "https://www.mql5.com/ru/users/moneystrategy"
#property version   "1.00"
#property strict

input datetime  Inp_StartDateTime  = D'2016.01.01 00:05'; //Дата и время старта
input int       Inp_GMTTerminal    = 2;                  //Часовой пояс терминала
//---
input  int      Inp_LineStep=30;                  //Шаг установки сетки
//---
input  int      Inp_MagicNum  = 12345;
input  string   Inp_EaComment = "Prognoz";

int inp_step;
datetime start_time;
datetime start_date;
datetime bar_time;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   start_time=Inp_StartDateTime-Inp_GMTTerminal*60*60;

   inp_step=Inp_LineStep;
//---
   if(Digits==3 || Digits==5)
     {
      inp_step*=10;
     }
//---
   Print("Лондонское время ",TimeToStr(TimeCurrent()-Inp_GMTTerminal*60*60,TIME_MINUTES));

   EventSetTimer(1);
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   del_object();
   EventKillTimer();
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {

  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnTimer()
  {
//--- найдем цену и бар для старта
   int bar_shift=iBarShift(_Symbol,0,start_time);//количество баров назад до старта
   double price_start=iClose(_Symbol,0,bar_shift);//находим цену последнего бара для начала расчетов
   //start_time = TimeToStr(start_time,TIME_DATE);
  
//--- отрисуем первые линии и коммент
   line(" line start",start_time,price_start,start_time+_Period*240,price_start,clrRed);
   line(" line time",start_time,0,start_time,10000,clrRed);
   //label(" label",MathMax(start_time,Time[(int)(ChartGetInteger(0,CHART_FIRST_VISIBLE_BAR)-3)]),price_start,clrRed," старт "+(string)Inp_StartDateTime+" по цене "+DoubleToStr(price_start,Digits)+" с шагом "+(string)inp_step+" пунктов",ANCHOR_LEFT_LOWER);

//--- найдем необходимое количество линий
   int max_up_line=0,max_dn_line=0;
   max_up_line =(int)((get_highest_price(bar_shift)-price_start)/Point)/inp_step;//максимальное количество линий вверх
   max_dn_line = (int)((price_start-get_lowest_price(bar_shift))/Point)/inp_step;//максимальное количество линий вниз

//--- рисуем линии выше цены старта
   if(count_up_line()<max_up_line)//если количество линий меньше максимального
     {
      double price_up=price_start+(inp_step*(count_up_line()+1)*Point);//находим цену открытия следующей линии сверху
      line(" line up "+(string)count_up_line(),start_time,price_up,start_time+_Period*240,price_up,clrYellow);//рисуем линию
     }

//--- рисуем линии ниже цены старта
   if(count_dn_line()<max_dn_line)//если количество линий меньше максимального
     {
      double price_dn=price_start-(inp_step*(count_dn_line()+1)*Point);//находим цену открытия следующей линии снизу
      line(" line dn "+(string)count_dn_line(),start_time,price_dn,start_time+_Period*240,price_dn,clrYellow);//рисуем линию
     }

  }
//+------------------------------------------------------------------+
//| Рисуем линии                                                     |
//+------------------------------------------------------------------+
void line(string name,datetime time1,double price1,datetime time2,double price2,color _color)
  {
   string line=Inp_EaComment+name;
   ResetLastError();
   if(ObjectFind(line)<0)
     {
      if(!ObjectCreate(line,OBJ_TREND,0,time1,price1,time2+_Period*240,price2))
        {
         Print(__FUNCTION__," ",__LINE__," error: ",GetLastError());
         return;
        }
     }
   ObjectSetInteger(0,line,OBJPROP_COLOR,_color);
   ObjectSetInteger(0,line,OBJPROP_TIME1,time1);
   ObjectSetInteger(0,line,OBJPROP_TIME2,time2);
   ObjectSetDouble(0,line,OBJPROP_PRICE1,price1);
   ObjectSetDouble(0,line,OBJPROP_PRICE2,price2);
   ObjectSetInteger(0,line,OBJPROP_WIDTH,1);
   ObjectSetInteger(0,line,OBJPROP_STYLE,STYLE_SOLID);
   ObjectSetInteger(0,line,OBJPROP_SELECTABLE,false);
   ObjectSetInteger(0,line,OBJPROP_SELECTED,false);
   ObjectSetInteger(0,line,OBJPROP_HIDDEN,true);
   ChartRedraw();
  }
//+------------------------------------------------------------------+
//| Рисуем метки                                                     |
//+------------------------------------------------------------------+
void label(string name,datetime time,double price,color _color,string text,ENUM_ANCHOR_POINT anchor)
  {
   string label=Inp_EaComment+name;
   ResetLastError();
   if(ObjectFind(label)<0)
     {
      if(!ObjectCreate(label,OBJ_TEXT,0,time,price,time+_Period*240,price))
        {
         Print(__FUNCTION__," ",__LINE__," error: ",GetLastError());
         return;
        }
     }
   ObjectSetInteger(0,label,OBJPROP_COLOR,_color);
   ObjectSetString(0,label,OBJPROP_TEXT,text);
   ObjectSetDouble(0,label,OBJPROP_PRICE,0,price);
   ObjectSetInteger(0,label,OBJPROP_TIME,0,time);
   ObjectSetInteger(0,label,OBJPROP_FONTSIZE,9);
   ObjectSetInteger(0,label,OBJPROP_ANCHOR,anchor);
   ObjectSetInteger(0,label,OBJPROP_SELECTABLE,false);
   ObjectSetInteger(0,label,OBJPROP_SELECTED,false);
   ObjectSetInteger(0,label,OBJPROP_HIDDEN,true);
   ChartRedraw();
  }
//+------------------------------------------------------------------+
//| Удаление созданных объектов                                      |
//+------------------------------------------------------------------+
void del_object()
  {
   for(int i=0;i<ObjectsTotal();i++)
     {
      string name=ObjectName(i);
      if(StringFind(name,Inp_EaComment,0)>=0)
        {
         ObjectDelete(name);
         i--;
        }
     }
  }
//+------------------------------------------------------------------+
//| Подсчитываем линии выше старта                                   |
//+------------------------------------------------------------------+
int count_up_line()
  {
   int count = 0;
   for(int i = ObjectsTotal()-1; i>=0; i--)
     {
      string name=ObjectName(i);
      if(StringFind(name,Inp_EaComment+" line up",0)>=0)
        {
         count++;
        }
     }
   return (count);
  }
//+------------------------------------------------------------------+
//| Подсчитываем линии ниже старта                                   |
//+------------------------------------------------------------------+
int count_dn_line()
  {
   int count = 0;
   for(int i = ObjectsTotal()-1; i>=0; i--)
     {
      string name=ObjectName(i);
      if(StringFind(name,Inp_EaComment+" line dn",0)>=0)
        {
         count++;
        }
     }
   return (count);
  }
//+------------------------------------------------------------------+
//| Находим максимальную цену от старта                              |
//+------------------------------------------------------------------+
double get_highest_price(int bars)
  {
   double highest=0;
   for(int i=1; i<=bars; i++)
     {
      double price=iHigh(_Symbol,0,i);
      if(price>highest)highest=price;
     }
   return (highest);
  }
//+------------------------------------------------------------------+
//| Находим минимальную цену от старта                               |
//+------------------------------------------------------------------+
double get_lowest_price(int bars)
  {
   double lowest=1000000;
   for(int i=1; i<=bars; i++)
     {
      double price=iLow(_Symbol,0,i);
      if(price<lowest)lowest=price;
     }
   return (lowest);
  }
//+------------------------------------------------------------------+


 

 

Вы не совсем продуманно задаете второе время для г.объектов.
Вместо _Period*240, надо _Period*60*60.

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnTimer()
  {
//--- найдем цену и бар для старта
   int bar_shift=iBarShift(_Symbol,0,start_time);//количество баров назад до старта
   double price_start=iClose(_Symbol,0,bar_shift);//находим цену последнего бара для начала расчетов
   //start_time = TimeToStr(start_time,TIME_DATE);
  
//--- отрисуем первые линии и коммент
   line(" line start",start_time,price_start,start_time+_Period*60*60,price_start,clrRed);
   line(" line time",start_time,0,start_time,10000,clrRed);
   //label(" label",MathMax(start_time,Time[(int)(ChartGetInteger(0,CHART_FIRST_VISIBLE_BAR)-3)]),price_start,clrRed," старт "+(string)Inp_StartDateTime+" по цене "+DoubleToStr(price_start,Digits)+" с шагом "+(string)inp_step+" пунктов",ANCHOR_LEFT_LOWER);

//--- найдем необходимое количество линий
   int max_up_line=0,max_dn_line=0;
   max_up_line =(int)((get_highest_price(bar_shift)-price_start)/Point)/inp_step;//максимальное количество линий вверх
   max_dn_line = (int)((price_start-get_lowest_price(bar_shift))/Point)/inp_step;//максимальное количество линий вниз

//--- рисуем линии выше цены старта
   if(count_up_line()<max_up_line)//если количество линий меньше максимального
     {
      double price_up=price_start+(inp_step*(count_up_line()+1)*Point);//находим цену открытия следующей линии сверху
      line(" line up "+(string)count_up_line(),start_time,price_up,start_time+_Period*60*60,price_up,clrYellow);//рисуем линию
     }

//--- рисуем линии ниже цены старта
   if(count_dn_line()<max_dn_line)//если количество линий меньше максимального
     {
      double price_dn=price_start-(inp_step*(count_dn_line()+1)*Point);//находим цену открытия следующей линии снизу
      line(" line dn "+(string)count_dn_line(),start_time,price_dn,start_time+_Period*60*60,price_dn,clrYellow);//рисуем линию
     }

  }
//+------------------------------------------------------------------+
//| Рисуем линии                                                     |
//+------------------------------------------------------------------+
void line(string name,datetime time1,double price1,datetime time2,double price2,color _color)
  {
   string line=Inp_EaComment+name;
   ResetLastError();
   if(ObjectFind(line)<0)
     {
      if(!ObjectCreate(line,OBJ_TREND,0,time1,price1,time2+_Period*60*60,price2))
        {
         Print(__FUNCTION__," ",__LINE__," error: ",GetLastError());
         return;
        }
     }
   ObjectSetInteger(0,line,OBJPROP_COLOR,_color);
   ObjectSetInteger(0,line,OBJPROP_TIME1,time1);
   ObjectSetInteger(0,line,OBJPROP_TIME2,time2);
   ObjectSetDouble(0,line,OBJPROP_PRICE1,price1);
   ObjectSetDouble(0,line,OBJPROP_PRICE2,price2);
   ObjectSetInteger(0,line,OBJPROP_WIDTH,1);
   ObjectSetInteger(0,line,OBJPROP_STYLE,STYLE_SOLID);
   ObjectSetInteger(0,line,OBJPROP_SELECTABLE,false);
   ObjectSetInteger(0,line,OBJPROP_SELECTED,false);
   ObjectSetInteger(0,line,OBJPROP_HIDDEN,true);
   ChartRedraw();
  }
//+------------------------------------------------------------------+
//| Рисуем метки                                                     |
//+------------------------------------------------------------------+
void label(string name,datetime time,double price,color _color,string text,ENUM_ANCHOR_POINT anchor)
  {
   string label=Inp_EaComment+name;
   ResetLastError();
   if(ObjectFind(label)<0)
     {
      if(!ObjectCreate(label,OBJ_TEXT,0,time,price,time+_Period*60*60,price))
        {
         Print(__FUNCTION__," ",__LINE__," error: ",GetLastError());
         return;
        }
     }
   ObjectSetInteger(0,label,OBJPROP_COLOR,_color);
   ObjectSetString(0,label,OBJPROP_TEXT,text);
   ObjectSetDouble(0,label,OBJPROP_PRICE,0,price);
   ObjectSetInteger(0,label,OBJPROP_TIME,0,time);
   ObjectSetInteger(0,label,OBJPROP_FONTSIZE,9);
   ObjectSetInteger(0,label,OBJPROP_ANCHOR,anchor);
   ObjectSetInteger(0,label,OBJPROP_SELECTABLE,false);
   ObjectSetInteger(0,label,OBJPROP_SELECTED,false);
   ObjectSetInteger(0,label,OBJPROP_HIDDEN,true);
   ChartRedraw();
  }


 

 

могу ошибиться

line(" line start",start_time,price_start,start_time+_Period*240,price_start,clrRed);


  line(" line start",start_time,price_start,

start_time+

_Period*240 // если 1 час то 60*60   но 240 это что за фрагмент времени ? при днее 1440*60 при 2х то 2880+240 отрисовка будет при меньшем таймфреме нет 

,price_start,clrRed);

 
Marat Sultanov:

Вы не совсем продуманно задаете второе время для г.объектов.
Вместо _Period*240, надо _Period*60*60

Спасибо. Все заработало!

ЗЫ. Натупил изначально, а потом всю голову себе сломал переделками, глаза замылил так, что потом не чего не видел. А такая маленькая ошибка :) жесть.

Спасибо камрады за помощь. 

Новичкам код можно использовать для нанесения сетки или еще чегонить, пригодится вообщем. (берите и используйте)

поторопился

теперь пашет все что выше 4х часов включительно. 

 
Vladimir Gribachev:

Спасибо. Все заработало!

ЗЫ. Натупил изначально, а потом всю голову себе сломал переделками, глаза замылил так, что потом не чего не видел. А такая маленькая ошибка :) жесть.

Спасибо камрады за помощь. 

Новичкам код можно использовать для нанесения сетки или еще чегонить, пригодится вообщем. (берите и используйте)

поторопился

теперь пашет все что выше 4х часов включительно. 

_Period  возвращает минуты то есть в нашем случае должно быть так  _Period*60  
 
Vladimir Pastushak:
_Period  возвращает минуты то есть в нашем случае должно быть так  _Period*60  

решилось все так 

PeriodSeconds(PERIOD_D1)*240 вместо  _Period*60 *60

 
Vladimir Gribachev:

решилось все так 

PeriodSeconds(PERIOD_D1)*240 вместо  _Period*60 *60

не есть хорошо 

PeriodSeconds(PERIOD_D1) == 1440*60

И вы получаете в итоге  1440*60*240 что не есть правильно

 
Vladimir Pastushak:
_Period  возвращает минуты то есть в нашем случае должно быть так  _Period*60  

Абсолютно, верно!

Vladimir Gribachev:

решилось все так 

PeriodSeconds(PERIOD_D1)*240 вместо  _Period*60 *60

Да, согласен, использовать PeriodSeconds() - более рациональный способ, чем умножать на 60, т.к. значения периода в enum не обязательно должно совпадать с количеством минут периода. Но правда, желательно лучше тогда совсем ни на что не умножать (выше это уже указали)...

--- 

Ну, самое главное это то, что мы выяснили где нужно было концентрировать внимание :) Я так думаю!

 
Marat Sultanov:

Ну, самое главное это то, что мы выяснили где нужно было концентрировать внимание :) Я так думаю!

да, главное что вопрос решен.

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