Нулевой буфер старшего ТФ на первом тике

 

Всем привет! Решена ли проблема получения данных индикатора старшего ТФ на нулевом баре на первом тике? У меня пока получается получить данные только со второго тика. Т.е я обращаюсь к примеру с индикатора на М1 к индикатору на М3 и на новом баре М3 на первом тике я хочу получить данные индикатора на М3 - не получается! Только на втором тике.....


запускаю этот индикатор на М1 :

//+------------------------------------------------------------------+
//|                                              testindicatorM1.mq5 |
//|                                  Copyright 2023, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2023, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property indicator_chart_window

int handle;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   handle=iCustom(NULL,PERIOD_M3,"testindicatorM3");
//---
   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[])
  {
//---
   if(time[rates_total-1]==D'2025.05.30 00:09') {
      double value[1];
      CopyBuffer(handle,0,time[rates_total-1],1,value);
      Print(TimeCurrent()," ",value[0]);
   }
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+

Вызываю этот индикатор 

//+------------------------------------------------------------------+
//|                                                testindicator.mq5 |
//|                                  Copyright 2023, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2023, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots   1
//--- plot Label1
#property indicator_label1  "Label1"
#property indicator_type1   DRAW_ARROW
#property indicator_color1  clrBlue
#property indicator_style1  STYLE_SOLID
#property indicator_width1  2
//--- indicator buffers
double         Label1Buffer[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit() {
//--- indicator buffers mapping
   SetIndexBuffer(0,Label1Buffer,INDICATOR_DATA);
//--- setting a code from the Wingdings charset as the property of PLOT_ARROW
   PlotIndexSetInteger(0,PLOT_ARROW,159);
   PlotIndexSetDouble(0, PLOT_EMPTY_VALUE, EMPTY_VALUE);
   ArrayInitialize(Label1Buffer,EMPTY_VALUE);
//---
   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[]) {
//---
  // -- Единственное значение индикатора, только для теста...
   if(time[rates_total-1]==D'2025.05.30 00:09')
         Label1Buffer[rates_total-1]=open[rates_total-1];
   else Label1Buffer[rates_total-1]=EMPTY_VALUE;
//--- return value of prev_calculated for next call
   return(rates_total);
}
//+------------------------------------------------------------------+

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

в чем может быть проблема?

 

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

Ошибки, баги, вопросы

Slava, 2021.05.29 18:16

Хочу напомнить.

1. Для каждого символа, для которого открыт хоть один график, работает отдельный поток для обработки пришедших тиков. Может быть открыто несколько графиков по какому-то символу, но поток будет всё равно один.

2. Поток символа обрабатывает не графики, а таймсерии. То есть, те самые массивы данных, которые отдаются на запрос CopyRates

3. Бесполезно спрашивать у своего символа в OnTick или OnCalculate, синхронизирован ли он. Конечно, да!

4. Все таймсерии обрабатываются по порядку, от младшей к старшей. Сначала применение тика, потом расчёт всех индикаторов, созданных на данной таймсерии. Если вы из индикатора, работающего на M1, спрашиваете данные для этого же символа H1, то вы никогда не получите данных с применённым тиком. Данные всегда будут на один тик назад, какие бы ухищрения вы не применяли. Потому что один поток на символ с последовательной обработкой таймфреймов.

5. Предыдущее утверждение не касается экспертов и скриптов, потому что эксперты и скрипты работают каждый в своём отдельном потоке.


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

Ошибки, баги, вопросы

Anton, 2021.06.01 09:40

4. Все таймсерии обрабатываются по порядку, от младшей к старшей. Сначала применение тика, потом расчёт всех индикаторов, созданных на данной таймсерии. Если вы из индикатора, работающего на M1, спрашиваете данные для этого же символа H1, то вы никогда не получите данных с применённым тиком. Данные всегда будут на один тик назад, какие бы ухищрения вы не применяли. Потому что один поток на символ с последовательной обработкой таймфреймов.

Утверждение получилось немного двусмысленное. На всякий случай уточняю. Да, при обработке тика все таймсерии обрабатываются по порядку, от младшей к старшей. Каждый тик добавляется к данным каждой таймсерии, затем производится расчет индикаторов на каждой таймсерии, по порядку. Т.е. для индикатора в OnCalculate() данные самих таймсерий (всех) безусловно обновленные, но данные индикаторов старших таймфреймов еще не пересчитаны.

 
Включите по условию пользовательское событие и в OnChartEvent() по этому событию получите значения. Где-то это долго обсуждалось. Даже с примерами.
 
Alexey Viktorov #:
Включите по условию пользовательское событие и в OnChartEvent() по этому событию получите значения. Где-то это долго обсуждалось. Даже с примерами.

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

 
Tango_X #:

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

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

Нулевой буфер старшего ТФ на первом тике

Alexey Viktorov, 2025.06.01 06:00

Включите по условию пользовательское событие и в OnChartEvent() по этому событию получите значения. Где-то это долго обсуждалось. Даже с примерами.

Повторяю: Это уже обсуждалось. Результат положительный. Ищите это обсуждение и будет вам счастье.

Вам повезло. Я быстро смог найти, но это не начало обсуждения

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

Ошибки, баги, вопросы

Alexey Viktorov, 2024.06.25 13:59

Так вот это очень полезно оказалось. Я не так просто упоминал свойства графического объекта сразу после создания его. Точно так же и с массивом индикатора. Обновлённый массив будет доступен только после выхода из функции обработки этого массива. Следовательно надо что-то сделать чтобы была возможность почитать этот буфер(массив) между выходом из OnCalculate() и вторым тиком. В этом поможет этот самый CHARTEVENT_CUSTOM.