Первый бар видимой истории, как?

 

Добрый день, коллеги.

Столкнулся со странной проблемой, может кто подскажет, как решить.

Задача: в любой момент времени в индикаторе определять дату первого (самого старого) бара видимой в окне истории.

Допустим в настройках терминала ставлю "Макс. баров в окне" = 50000.

Пробую получить дату первого бара скриптом для начала:

   int      bars     =  0;
   int      tryCount =  0;
   datetime dt;
   datetime Time[]; // массив для получения данных time   
   
   while ((bars == 0) && (tryCount < 10)) {
      bars  =  Bars(_Symbol, _Period);
      tryCount++;
   }
   
   CopyTime (_Symbol, _Period, 0, bars, Time);
   dt =  Time[0];
   Print(TimeToString(dt));
   
   dt =  (datetime)SeriesInfoInteger(_Symbol, _Period, SERIES_FIRSTDATE);
   Print(TimeToString(dt));

Обе распечатки дают одну и ту же дату, например "2023.04.27 17:11", и она правильная, но только по началу.

Работаю на таймфрейме М1. Жду 10 минут. Запускаю тот же скрипт еще раз.

Результат выдается тот же. НО: за 10 минут окно видимой истории сместилось на 10 баров вправо, и реально видимый 1-й бар уже не 17:11, а 17:21.

Перезапускаю терминал - все равно тот же результат.

Второй вариант: хелп MQL5 уверяет, что метод iBars возвращает "Количество истории по соответствующему символу и периоду, но не более чем задано в настройках платформы параметром "Макс. баров в окне" ("Max bars in chart").

Поправляю скрипт (расчет bars одной строкой через iBars). Запускаю - тот же результат (при этом bars получается больше 50 тыс несмотря на уверения хелпа).

Третий вариант: можно переместить график в начало с помощью ChartNavigate() и узнать номер первого видимого бара (CHART_FIRST_VISIBLE_BAR)

   ChartNavigate(ChartID(), CHART_BEGIN);
   int   fistBar  =  (int)ChartGetInteger(ChartID(), CHART_FIRST_VISIBLE_BAR);
  
   Print("firstBar: " + IntegerToString(fistBar));

При этом firstBar так же получается больше 50 тыс, хотя в настройках, как я писал выше, стоит значение 50 тыс. Т.е. опять пролет.

Перезапуск терминала тоже не помогает.

-----------------------------------------------------

P.S. Если бы настройку терминала  "Макс. баров в окне" можно было получить из кода, вопрос решился бы, но такого в хелпе MQL5 не нашел.

В итоге сломал голову, но не придумал, как решить вопрос.

Какие идеи?

 
Время самого старого бара в индикаторе всегда time[0]… И зачем ещё как-то изгаляться пытаясь получить уже известное?
 
Alexey Viktorov #:
Время самого старого бара в индикаторе всегда time[0]… И зачем ещё как-то изгаляться пытаясь получить уже известное?

Всмысле в индикаторе коды, что я приводил выше, будут работать не так, как в скрипте?

 
satorifx #:

Всмысле в индикаторе коды, что я приводил выше, будут работать не так, как в скрипте?

В смысле в индикаторе это вообще не нужно

/****************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[])
 {

//--- return value of prev_calculated for next call
  return(rates_total);
 }/******************************************************************/
 
Alexey Viktorov #:

В смысле в индикаторе это вообще не нужно

Интересная идея, но тоже не работает.

//+------------------------------------------------------------------+
//| 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[])
{
//---
   datetime cur         =  time[0];
   static datetime prev =  0;   
   
   if (prev_calculated == 0) {prev  =  cur; Print(TimeToString(cur));}
   
   if (prev != cur) {
      Print(TimeToString(cur));
      prev  =  cur;
   }
//--- return value of prev_calculated for next call
   return(rates_total);
}

Если бы при появлении нового бара time[0] изменялся, я бы получил распечатку нового time[0] каждый раз, когда появлялся бы новый бар.

А результат кода выше - при появлении новых баров ничего не распечатывается.

 
satorifx #:

Интересная идея, но тоже не работает.

Если бы при появлении нового бара time[0] изменялся, я бы получил распечатку нового time[0] каждый раз, когда появлялся бы новый бар.

А результат кода выше - при появлении новых баров ничего не распечатывается.

Это вы просто заработались уже.

time[0] не должен меняться при появлении нового бара. Меняется (увеличивается) количество баров в истории, а первый бар так и остаётся первым.

 
satorifx #:

Интересная идея, но тоже не работает.

Если бы при появлении нового бара time[0] изменялся, я бы получил распечатку нового time[0] каждый раз, когда появлялся бы новый бар.

А результат кода выше - при появлении новых баров ничего не распечатывается.

Так вы сначала определитесь в своих желаниях…

satorifx:

………

НО: за 10 минут окно видимой истории сместилось на 10 баров вправо, и реально видимый 1-й бар уже не 17:11, а 17:21.

………

какое время вы хотите видеть при появлении нового бара¿¿¿

И вот это условие 

   if (prev != cur)

совершенно не верно… Если хотите получать распечатку на каждом баре поставьте условие

if(rates_total > prev_calculated)
 
Alexey Viktorov #:

совершенно не верно… Если хотите получать распечатку на каждом баре поставьте условие

Вы правда не понимаете, что это ничего не изменит?

Поставил ваше условие. Теперь при появлении каждого нового бара идет распечатка, но распечатывается всегда одно и то же значение какого-то там 1-го бара, а не 1-го бара, видимого на чарте, который мне нужен, и который должен меняться.

 
satorifx #:

Вы правда не понимаете, что это ничего не изменит?

Поставил ваше условие. Теперь при появлении каждого нового бара идет распечатка, но распечатывается всегда одно и то же значение какого-то там 1-го бара, а не 1-го бара, видимого на чарте, который мне нужен, и который должен меняться.

Свойства графиков
//+------------------------------------------------------------------+ 
//| Функция получает номер первого видимого бара на графике.         | 
//| Индексация как в таймсерии, последние бары имеют меньшие индексы.| 
//+------------------------------------------------------------------+ 
int ChartFirstVisibleBar(const long chart_ID=0) 
  { 
//--- подготовим переменную для получения значения свойства 
   long result=-1; 
//--- сбросим значение ошибки 
   ResetLastError(); 
//--- получим значение свойства 
   if(!ChartGetInteger(chart_ID,CHART_FIRST_VISIBLE_BAR,0,result)) 
     { 
      //--- выведем сообщение об ошибке в журнал "Эксперты" 
      Print(__FUNCTION__+", Error Code = ",GetLastError()); 
     } 
//--- вернем значение свойства графика 
   return((int)result); 
  }
Документация по MQL5: Константы, перечисления и структуры / Константы графиков / Примеры работы с графиком
Документация по MQL5: Константы, перечисления и структуры / Константы графиков / Примеры работы с графиком
  • www.mql5.com
Примеры работы с графиком - Константы графиков - Константы, перечисления и структуры - Справочник MQL5 - Справочник по языку алгоритмического/автоматического трейдинга для MetaTrader 5
 
satorifx #:

Вы правда не понимаете, что это ничего не изменит?

Поставил ваше условие. Теперь при появлении каждого нового бара идет распечатка, но распечатывается всегда одно и то же значение какого-то там 1-го бара, а не 1-го бара, видимого на чарте, который мне нужен, и который должен меняться.

Бары в 5ке наоборот. Нулевой в 4ке это последний в 5ке. Нулевой в 5ке это первый бар начала истории. Поэтому не перевернув индексацию 1 и 2й бар и следующий в 5ке не меняются. Это что бы не пересчитывать сделано.
 
satorifx #:

Вы правда не понимаете, что это ничего не изменит?

Поставил ваше условие. Теперь при появлении каждого нового бара идет распечатка, но распечатывается всегда одно и то же значение какого-то там 1-го бара, а не 1-го бара, видимого на чарте, который мне нужен, и который должен меняться.

Ну и формулируете вы вопрос………

При каких делах тут

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

Первый бар видимой истории, как?

satorifx, 2023.06.19 08:17

Добрый день, коллеги.

Столкнулся со странной проблемой, может кто подскажет, как решить.

Задача: в любой момент времени в индикаторе определять дату первого (самого старого) бара видимой в окне истории.

Допустим в настройках терминала ставлю "Макс. баров в окне" = 50000.

Пробую получить дату первого бара скриптом для начала:

   int      bars     =  0;
   int      tryCount =  0;
   datetime dt;
   datetime Time[]; // массив для получения данных time   
   
   while ((bars == 0) && (tryCount < 10)) {
      bars  =  Bars(_Symbol, _Period);
      tryCount++;
   }
   
   CopyTime (_Symbol, _Period, 0, bars, Time);
   dt =  Time[0];
   Print(TimeToString(dt));
   
   dt =  (datetime)SeriesInfoInteger(_Symbol, _Period, SERIES_FIRSTDATE);
   Print(TimeToString(dt));

Обе распечатки дают одну и ту же дату, например "2023.04.27 17:11", и она правильная, но только по началу.

Работаю на таймфрейме М1. Жду 10 минут. Запускаю тот же скрипт еще раз.

Результат выдается тот же. НО: за 10 минут окно видимой истории сместилось на 10 баров вправо, и реально видимый 1-й бар уже не 17:11, а 17:21.

Перезапускаю терминал - все равно тот же результат.

Второй вариант: хелп MQL5 уверяет, что метод iBars возвращает "Количество истории по соответствующему символу и периоду, но не более чем задано в настройках платформы параметром "Макс. баров в окне" ("Max bars in chart").

Поправляю скрипт (расчет bars одной строкой через iBars). Запускаю - тот же результат (при этом bars получается больше 50 тыс несмотря на уверения хелпа).

Третий вариант: можно переместить график в начало с помощью ChartNavigate() и узнать номер первого видимого бара (CHART_FIRST_VISIBLE_BAR)

   ChartNavigate(ChartID(), CHART_BEGIN);
   int   fistBar  =  (int)ChartGetInteger(ChartID(), CHART_FIRST_VISIBLE_BAR);
  
   Print("firstBar: " + IntegerToString(fistBar));

При этом firstBar так же получается больше 50 тыс, хотя в настройках, как я писал выше, стоит значение 50 тыс. Т.е. опять пролет.

Перезапуск терминала тоже не помогает.

-----------------------------------------------------

P.S. Если бы настройку терминала  "Макс. баров в окне" можно было получить из кода, вопрос решился бы, но такого в хелпе MQL5 не нашел.

В итоге сломал голову, но не придумал, как решить вопрос.

Какие идеи?


Правильно сформулированный вопрос уже половина ответа…