Вопросы от начинающих MQL5 MT5 MetaTrader 5 - страница 530

 
-Aleks-:

Прошу помощи! (MQL4)

Надо получить время открытия Дня на чарте М15 с учетом каждого бара - для индикатора. 

Решил подсчитать в секундах с учетом текущего бара(0), но что то я ошибся, не могу понять где

D_Shift=(Open_time-pos*15*60-(Open_time-Open_timeTF))/1440*60; 

Если для индикатора, то:

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            temp_day;
   MqlDateTime    dt_struct;
   TimeToStruct(time[0],dt_struct);
   temp_day=dt_struct.day;

   for(int i=0;i<rates_total-1;i++)
     {
      TimeToStruct(time[i],dt_struct);
      if(dt_struct.day<temp_day)
        {
         Print("Start day ",time[i-1]);
         break;
        }
     }

//--- done
   return(rates_total);
  }

Но: этот код будет выполняться при каждом заходе в OnCalculate() - здесь уже в зависимости от Ваших нужд или добавить флаг bool или вынести код в отдельную функцию.

 
Karputov Vladimir:

Если для индикатора, то:

Но: этот код будет выполняться при каждом заходе в OnCalculate() - здесь уже в зависимости от Ваших нужд или добавить флаг bool или вынести код в отдельную функцию.

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

Open_timeTF  1454715900
Open_time 1454284800
Delta_1S 431100
Delta_M15 479

 

получается, что разница в 479 баров между первым баром дня и текущем баром - почему так? 

 
-Aleks-:

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

Open_timeTF  1454715900
Open_time 1454284800
Delta_1S 431100
Delta_M15 479

 

получается, что разница в 479 баров между первым баром дня и текущем баром - почему так? 

Я ведь указал, что я не экстрасенс и поэтому:

Но: этот код будет выполняться при каждом заходе в OnCalculate() - здесь уже в зависимости от Ваших нужд или добавить флаг bool или вынести код в отдельную функцию.

 
Karputov Vladimir:

Я ведь указал, что я не экстрасенс и поэтому:

А почему тут требуются экстрасенсорные способности? Выше в коде есть переменные, я показал что возвращают эти переменные в цифрах и задал вопрос, почему так, а не иначе - согласно коду.
 
Karputov Vladimir , не понимаю я Ваш код - ибо начинающий я в этом деле, ранее функцию OnCalculate вообще не использовал, поэтому не могу понять, что там рассчиталось rates_total, а главное куда это потом возвращать? Как это всё переделать в отдельную функцию так же пока не понимаю... без комментариев тяжело.
 
-Aleks-:
Karputov Vladimir , не понимаю я Ваш код - ибо начинающий я в этом деле, ранее функцию OnCalculate вообще не использовал, поэтому не могу понять, что там рассчиталось rates_total, а главное куда это потом возвращать? Как это всё переделать в отдельную функцию так же пока не понимаю... без комментариев тяжело.

Вот полный код MQL4 индикатора:

//+------------------------------------------------------------------+
//|                                                    Start day.mq4 |
//|                        Copyright 2016, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2016, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
#property indicator_chart_window
//--- input parameters
input int      timer=10; // seconds
//--- parameter
bool           IsDefineTime=true; // true -> you can define time
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   EventSetTimer(timer);
//---
   IsDefineTime=true;
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
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            temp_day;
   MqlDateTime    dt_struct;
   TimeToStruct(time[0],dt_struct);
   temp_day=dt_struct.day;

   if(IsDefineTime)
     {
      for(int i=0;i<rates_total-1;i++)
        {
         TimeToStruct(time[i],dt_struct);
         if(dt_struct.day<temp_day)
           {
            Print("Start day ",time[i-1]);
            IsDefineTime=false;
            break;
           }
        }
     }
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
//| Timer function                                                   |
//+------------------------------------------------------------------+
void OnTimer()
  {
//---
   IsDefineTime=true; // true -> you can define time
  }
//+------------------------------------------------------------------+

Алгоритм его работы: при старте индикатора Вы задаёте временной интервал таймера (например 10 секунд) - это означает, что каждые 10 секунд будет срабатывать таймер:

//+------------------------------------------------------------------+
//| Timer function                                                   |
//+------------------------------------------------------------------+
void OnTimer()
  {
//---
   IsDefineTime=true; // true -> you can define time
  }

и переменной IsDefineTime присваивается значение true. Для чего это нужно? Когда IsDefineTime=true мы можем в OnCalculate() зайти в цикл определения времени начала дня:

   if(IsDefineTime)
     {
      for(int i=0;i<rates_total-1;i++)
        {
         TimeToStruct(time[i],dt_struct);
         if(dt_struct.day<temp_day)
           {
            Print("Start day ",time[i-1]);
            IsDefineTime=false;
            break;
           }
        }
     }

В этом цикле Мы начинаем обход по массиву time[] (в этом массиве хранятся значениями времени открытия) с самого правого бара (его индекс равен "0"). Когда найдено начало дня, Мы распринтовываем его значение и присваиваем переменной IsDefineTime значение false - таким образом мы защищаемся от последующего входа в цикл определения времени начала дня, пока снова не сработает таймер.

Файлы:
Start_day.mq4  3 kb
 

Karputov Vladimir, спасибо за пояснения, однако, как это решает задачу?

Необходимо грубо говоря узнать бар текущего ТФ соответствующий бару начала дня. Узнать на каждом баре, и соотвествтенно сделать расчет и отрисовку индикатора. 

 
-Aleks-:

Karputov Vladimir, спасибо за пояснения, однако, как это решает задачу?

Необходимо грубо говоря узнать бар текущего ТФ соответствующий бару начала дня. Узнать на каждом баре, и соотвествтенно сделать расчет и отрисовку индикатора. 

Как спросили, так Вам и ответили :) . А если Вам нужно не время первого бара за этот день, а индекс этого бара - так это вот здесь, когда принтуете начало дня:

.
.
.
Print("Start day ",time[i-1]);
.
.
.

Вы используете индекс [i-1] - это и есть номер первого бара за день. 

 
Karputov Vladimir:

Как спросили, так Вам и ответили :) . А если Вам нужно не время первого бара за этот день, а индекс этого бара - так это вот здесь, когда принтуете начало дня:

Вы используете индекс [i-1] - это и есть номер первого бара за день. 

Согласен - спросил запутанно.

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

Прошу прощения за наглость, но может покажите, как объединить Ваш и мой код? 

 

-Aleks-:

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

как-то фсё запущено) Как-то так:

datetime Day00=86400*(TimeCurrent()/86400);//начало дня
int bar_shift=iBarShift(_Symbol,PERIOD_CURRENT,Day00);//индекс первого бара текущего дня
Причина обращения: