N-ый открытый бар на определённом таймфрейме

 

Добрый день. В принципе, банальный вопрос, но я что-то призадумался. Как узнать данные бара, который открыт в сегодняшний день N-ым? Например, открыт график М15. Нужно узнать, какие цена открытия и закрытия бара М15 открытого первым, вторым или ещё каким на М15. Но, тут суть в том, что нужен способ не зависящий от таймфрейма. Чтобы он позволил находясь на любом таймфрейме получить данные открытия любого бара открытого N-ым в определённый день.

Я вижу один вариант. Создать 2 структуры. В них хранить данные типа MqlDateTime. Если день недели, например, изменился, значит запоминаем данные открытого бара. А дальше счётчик баров. И так каждый день будет происходить.

Есть ещё какие-то варианты?

Документация по MQL5: Константы, перечисления и структуры / Константы индикаторов / Ценовые константы
Документация по MQL5: Константы, перечисления и структуры / Константы индикаторов / Ценовые константы
  • www.mql5.com
Технические индикаторы требуют для своих расчетов указания значений цен и/или значений объемов, на которых они будут считаться. Существуют 7...
 
Виктор Демихов:

Добрый день. В принципе, банальный вопрос, но я что-то призадумался. Как узнать данные бара, который открыт в сегодняшний день N-ым? Например, открыт график М15. Нужно узнать, какие цена открытия и закрытия бара М15 открытого первым, вторым или ещё каким на М15. Но, тут суть в том, что нужен способ не зависящий от таймфрейма. Чтобы он позволил находясь на любом таймфрейме получить данные открытия любого бара открытого N-ым в определённый день.

Я вижу один вариант. Создать 2 структуры. В них хранить данные типа MqlDateTime. Если день недели, например, изменился, значит запоминаем данные открытого бара. А дальше счётчик баров. И так каждый день будет происходить.

Есть ещё какие-то варианты?

Да нет проблем, копируйте нужное количество баров и читайте структуру любого бара

int  CopyRates(
   string           symbol_name,       // имя символа
   ENUM_TIMEFRAMES  timeframe,         // период
   int              start_pos,         // откуда начнем 
   int              count,             // сколько копируем
   MqlRates         rates_array[]      // массив, куда будут скопированы данные
   );
Документация по MQL5: Доступ к таймсериям и индикаторам / CopyRates
Документация по MQL5: Доступ к таймсериям и индикаторам / CopyRates
  • www.mql5.com
Получает в массив rates_array исторические данные структуры MqlRates указанного символа-периода в указанном количестве. Отсчет элементов от...
 
Alexey Viktorov #:

Да нет проблем, копируйте нужное количество баров и читайте структуру любого бара

тут вопрос стоит N-бара узнать и из него взять данные, например сейчас 12 часов, а надо взять с 1 часа, тут пока только смотреть текущий час и отнимать iBarShift

 
Виктор Демихов:

Добрый день. В принципе, банальный вопрос, но я что-то призадумался. Как узнать данные бара, который открыт в сегодняшний день N-ым? Например, открыт график М15. Нужно узнать, какие цена открытия и закрытия бара М15 открытого первым, вторым или ещё каким на М15. Но, тут суть в том, что нужен способ не зависящий от таймфрейма. Чтобы он позволил находясь на любом таймфрейме получить данные открытия любого бара открытого N-ым в определённый день.

Я вижу один вариант. Создать 2 структуры. В них хранить данные типа MqlDateTime. Если день недели, например, изменился, значит запоминаем данные открытого бара. А дальше счётчик баров. И так каждый день будет происходить.

Есть ещё какие-то варианты?

Если речь идет об отсчете от начала дня, то можно так:

#property script_show_inputs
//--- input parameters
input int               numBar = 1;
input ENUM_TIMEFRAMES   TF     = PERIOD_H1;
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
{
   datetime timeStartDay = iTime(_Symbol, PERIOD_D1, 0);       //Дата/время начала текущего дня
   MqlRates rates[];
   CopyRates(_Symbol, TF, timeStartDay, iTime(_Symbol, TF, 0), rates);
   Print("Num bar=", numBar, " Time=", rates[numBar - 1].time, " Open=", rates[numBar - 1].open, " Close=", rates[numBar - 1].close);
}
 
lynxntech #:

тут вопрос стоит N-бара узнать и из него взять данные, например сейчас 12 часов, а надо взять с 1 часа, тут пока только смотреть текущий час и отнимать iBarShift

Да нет проблем. Берите по времени от и до

int  CopyRates(
   string           symbol_name,       // имя символа
   ENUM_TIMEFRAMES  timeframe,         // период
   datetime         start_time,        // с какой даты
   datetime         stop_time,         // по какую дату
   MqlRates         rates_array[]      // массив, куда будут скопированы данные
   );

Или с какой даты сколько штук…

int  CopyRates(
   string           symbol_name,       // имя символа
   ENUM_TIMEFRAMES  timeframe,         // период
   datetime         start_time,        // с какой даты
   int              count,             // сколько копируем
   MqlRates         rates_array[]      // массив, куда будут скопированы данные
   );

И что вы упираетесь в  iBarShift… Прям жить без него грустно…

 
Alexey Viktorov #:

Да нет проблем. Берите по времени от и до

Или с какой даты сколько штук…

И что вы упираетесь в  iBarShift… Прям жить без него грустно…

и потом все равно надо будет получить текущий час обычно, что-бы указать сколько нужно отнимать назад,

покажите простой пример как получить в 12 часов дня, данные индикатора или бара в 2 часа утра того-же дня,

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

Это я говорю о нормальных вариантах, можно нагородить отсчет от старта терминала и windows таймера, или в нициализации взять начальное время бара и простой математикой так же перемножать где-то, фантазий много.


без  iBarShift жить можно, но вот разработчики столько всего-нагородили, реально не нужного, многое функции задублировали, а вот что-бы получить час текущего бара, так же просто как и цену, надо городить структуру

и кто знает на сколько это затратно? когда они все меняют и ломают периодически, за то продвигают ООП, в котором ничего не должно ломаться, ведь он отвечает всегда за работу своей только функции...., лабуда.

 
Sergey Zhilinskiy #:

Если речь идет об отсчете от начала дня, то можно так:

Годное решение, чтобы получить значения на заданном баре. Всё, в принципе, чётко, но. есть один момент, который мне не нравится. Хорошо бы, как-то возвращать индекс найденного бара. Потому что если это применять в разных местах бота, получится этакий раздутый вездеход..))

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

 
lynxntech #:
но вот разработчики столько всего-нагородили, реально не нужного, многое функции задублировали, а вот что-бы получить час текущего бара, так же просто как и цену, надо городить структуру

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

Виктор Демихов #:

Годное решение, чтобы получить значения на заданном баре. Всё, в принципе, чётко, но. есть один момент, который мне не нравится. Хорошо бы, как-то возвращать индекс найденного бара. Потому что если это применять в разных местах бота, получится этакий раздутый вездеход..))

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

Да, нагородить можно много чего и оно будет работать, но хочется элегентного решения, чтобы не плодить дубликаты кода. Если код и так огромный, дубликаты только вероятность костыля могут привнести..

 

Я вижу это как-то так на вскидку. Только что придумал. Тоже не ООП, но..

   MqlRates rates[];

//===============================================================================================================================================================================================================================================================
// Возвращает индекс N-го бара таймфрейма tf ====================================================================================================================================================================================================================

void neededBarIndex(MqlRates& rates[], int index, ENUM_TIMEFRAMES tf = PERIOD_CURRENT) {
  datetime dayOpen = iTime(_Symbol, PERIOD_D1, 0);
  CopyRates(_Symbol, _Period, dayOpen, iTime(_Symbol, _Period, 0), rates);
}

Раз в день в 0.0 часов запускать код т.е. когда меняется день недели и сохранять таймсерию в rates[]. А дальше сутки работать с этими данными.

rates[] может быть либо методом класса, либо просто глобальной переменной.

Извратно, конечно, но.. другого способа инкапсулировать все данные внутри функции нет, видимо. По крайне мере, я это вижу так. Но, может кто что подскажет ещё.

 
Виктор Демихов #:

Решил я проверил то, что получилось.

Вот эта функция:

А вот как я её вызываю:

Вижу ошибку компиляции:

Функция же простая. Передал туда массив. 2 последних параметра вообще сейчас не применяются. Добавил т.к. позже понадобятся.  Почему ругается компилятор?

пока у меня в роботе самая затратная функция это проверка времени рабочего, которое нужно для покупок до 2 утра и в 22 вечера, общее потребление процессора около 0%

7 символов, каждый тик обработка с несколькими индикаторами

только это успокаивает


add самое затратное это проверка времени для торговли, но это ведь очень простая функция? по факту должны быть iCustom вызовы. В профилировщике. 

как может новый тик из шпиона быть с проверкой индикаторов, меньше, тупого проверки времени? Ответ - Профилировщик никакой.

 
Виктор Демихов #:
Извратно, конечно, но.. другого способа инкапсулировать все данные внутри функции нет, видимо. По крайне мере, я это вижу так. Но, может кто что подскажет ещё.

Как-то режет глаз, когда для получения данных одного бара приходится считывать целый массив. Не разумно с точки зрения производительности и потребления ресурсов. 
Лучше уж как-то так:

MqlRates neededBarIndex(int index, ENUM_TIMEFRAMES tf = PERIOD_CURRENT) {
  datetime dayOpen =  (TimeCurrent()/(24*60*60))*24*60*60;
  int shift = iBarShift(_Symbol,tf,dayOpen)-index;
  if (shift<0) shift = 0;
  MqlRates res[1];
  CopyRates(_Symbol,tf,shift,1,res);
  return res[0];
}

не проверял

Можно также вместо CopyRates использовать iOpen(), iClose(), iLow() ... по индексу бара, если не нужна полная заполненная структура MqlRates, т.к. она избыточна