Загрузка графика перед стартом индикатора - страница 2

 
peterlogin:

Либо что-то не так делаю, либо это не работает:

if (IsTFDataReady(ENUM_TIMEFRAMES(Period())))
{
        // История загружена
}

Если флаг FirstRUN нужен только для проверки подкачки истории, то его можно убрать вовсе. Проверять график на предмет подкачки стоит на каждом тике. Вдруг был дисконнект?

 
Ihor Herasko:

Если флаг FirstRUN нужен только для проверки подкачки истории, то его можно убрать вовсе. Проверять график на предмет подкачки стоит на каждом тике. Вдруг был дисконнект?

FirstRUN можно убрать, но для отладки пока оставил.

Проблема осталась. Как проверяю:
В окне терминала стоит индикатор. Из окна с парами просто кидаю пару на график, соответственно индикатор перегружается. Так вот в ряде случаев получаю следующее:

2019.03.21 13:02:45.930 ptr_Area EURJPY.I,H1: Initialization is complete. Time index bar (10038) = 2017.01.23 09:00 / 2018.09.04 10:00

2019.03.21 13:02:45.930 ptr_Area EURJPY.I,H1: History initialization...

2019.03.21 13:02:45.930 ptr_Area EURJPY.I,H1: initialized


т.к. ошибки нет, а история не подгружена до конца. Индикатор отрабатывает неверно.

bool IsTFDataReady(ENUM_TIMEFRAMES eTF)

{

   bool res = false;

   ResetLastError();

   datetime dt1 = iTime(Symbol(), eTF, Bars-1);

   datetime dt2 = iTime(Symbol(), eTF, 1);

   if (GetLastError() == ERR_NO_ERROR)

   {

      Print("Initialization is complete. Time index bar (", Bars, ") = ", TimeToStr(dt1), " / ", TimeToStr(dt2));

      res = true;

   } 

   else

      Print("Initialization error: ", GetLastError()) ;

   return(res);

}

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 (FirstRUN)

   {

      Print("History initialization...");

   

      if (!IsTFDataReady(ENUM_TIMEFRAMES(Period())))

      {

         return(0);

      }

   }

FirstRUN = false;

}


 
peterlogin:

FirstRUN можно убрать, но для отладки пока оставил.

Проблема осталась. 

После этого используете значения prev_calculated и rates_total. Если их разность более, чем 1, значит, произошла подгрузка данных. В этом случае полностью перерисовываете индикатор. 

 

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

#property strict
#property indicator_chart_window

bool isload = false;

int OnInit()
{
   
   return(INIT_SUCCEEDED);
}

bool IsTFDataReady(ENUM_TIMEFRAMES eTF)
{
   bool res = false;
   ResetLastError();
   datetime dt1 = iTime(Symbol(), eTF, Bars-1);
   datetime dt2 = iTime(Symbol(), eTF, 1);
   if (GetLastError() == ERR_NO_ERROR)
   {
      if (!isload)
         Print("IsTFDataReady: bar total=", Bars, "  Time(Bars)=", TimeToStr(dt1), "  Time(1)=", TimeToStr(dt2));
      res = true;
   } 
   else
   {
      isload = false;
      Print("IsTFDataReady error: ", GetLastError()) ;
   }   
   return(res);
}

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 (!isload)
      Print("OnCalculate -> Bars=", Bars, " rates_total=", rates_total, " prev_calculated=", prev_calculated, " counted_bars=", IndicatorCounted());

   if (!IsTFDataReady(ENUM_TIMEFRAMES(Period())))
   {
      isload = false;   
      return(rates_total);
   }

   if (MathAbs(rates_total - prev_calculated) > 1)
   
   {
      Print("OnCalculate history error: (rates_total - prev_calculated)=", rates_total - prev_calculated);
      isload = false;
      return(rates_total);
   }

   if (!isload)
      Print("History - OK");
   
   isload = true;  
   return(rates_total);
}
 

на минутке удалось сгенерировать ошибку 4051. Но проблема в том что, сравнение rates_total и  prev_calculated -  не дает признака окончания загрузки истории:

ВРЕМЯ: 2019.03.21 15:48:20.389

2019.03.21 15:48:20.559 _test_histoty GLDUSD.I,M1: History - OK
2019.03.21 15:48:20.559 _test_histoty GLDUSD.I,M1: IsTFDataReady: bar total=2048  Time(Bars)=2019.03.20 03:41  Time(1)=2019.03.21 14:47
2019.03.21 15:48:20.559 _test_histoty GLDUSD.I,M1: OnCalculate -> Bars=2048 rates_total=2048 prev_calculated=2048 counted_bars=2047
2019.03.21 15:48:20.435 _test_histoty GLDUSD.I,M1: OnCalculate history ERROR: (rates_total - prev_calculated)=2048
2019.03.21 15:48:20.435 _test_histoty GLDUSD.I,M1: IsTFDataReady: bar total=2048  Time(Bars)=2019.03.20 03:41  Time(1)=2019.03.21 14:47
2019.03.21 15:48:20.435 _test_histoty GLDUSD.I,M1: OnCalculate -> Bars=2048 rates_total=2048 prev_calculated=0 counted_bars=0
2019.03.21 15:48:20.433 _test_histoty GLDUSD.I,M1: OnCalculate history ERROR: (rates_total - prev_calculated)=1536

2019.03.21 15:48:20.389 _test_histoty GLDUSD.I,M1: History - OK <- ПРИЗНАК ПОЛНОЙ ЗАГРУЗКИ НЕ СООТВЕТСТВУЕТ ДЕЙСТВИТЕЛЬНОСТИ

2019.03.21 15:48:20.389 _test_histoty GLDUSD.I,M1: IsTFDataReady: bar total=1024  Time(Bars)=2019.03.20 20:46  Time(1)=2019.03.21 14:47
2019.03.21 15:48:20.389 _test_histoty GLDUSD.I,M1: OnCalculate -> Bars=1024 rates_total=1024 prev_calculated=1024 counted_bars=1023
2019.03.21 15:48:20.389 _test_histoty GLDUSD.I,M1: OnCalculate history ERROR: (rates_total - prev_calculated)=1024
2019.03.21 15:48:20.389 _test_histoty GLDUSD.I,M1: IsTFDataReady: bar total=1024  Time(Bars)=2019.03.20 20:46  Time(1)=2019.03.21 14:47
2019.03.21 15:48:20.389 _test_histoty GLDUSD.I,M1: OnCalculate -> Bars=1024 rates_total=1024 prev_calculated=0 counted_bars=0
2019.03.21 15:48:20.130 _test_histoty GLDUSD.I,M1: OnCalculate history ERROR: (rates_total - prev_calculated)=512
2019.03.21 15:48:20.130 _test_histoty GLDUSD.I,M1: IsTFDataReady: bar total=512  Time(Bars)=2019.03.21 06:17  Time(1)=2019.03.21 14:47
2019.03.21 15:48:20.130 _test_histoty GLDUSD.I,M1: OnCalculate -> Bars=512 rates_total=512 prev_calculated=0 counted_bars=0
2019.03.21 15:48:20.060 _test_histoty GLDUSD.I,M1: IsTFDataReady ERROR: 4051
2019.03.21 15:48:20.060 _test_histoty GLDUSD.I,M1: OnCalculate -> Bars=1 rates_total=1 prev_calculated=1 counted_bars=0
2019.03.21 15:48:19.453 _test_histoty GLDUSD.I,M1: IsTFDataReady ERROR: 4051
2019.03.21 15:48:19.453 _test_histoty GLDUSD.I,M1: OnCalculate -> Bars=1 rates_total=1 prev_calculated=0 counted_bars=0
2019.03.21 15:48:19.289 _test_histoty GLDUSD.I,M1: initialized
2019.03.21 15:48:19.289 _test_histoty XAUUSD.I,M1: uninit reason 3
 
peterlogin:

Но проблема в том что, сравнение rates_total и  prev_calculated -  не дает признака окончания загрузки истории:

Они дают признак подкачки истории. Это главное. Как только история докачалась, нужно заново пересчитать показатели индикатора.

 
Ihor Herasko:

Они дают признак подкачки истории. Это главное. Как только история докачалась, нужно заново пересчитать показатели индикатора.

да так и буду делать. спасибо

 
Ihor Herasko:

Обращение к таймсерии приводит к запросу истории с сервера, если последний запрос был "давно" (что подразумевается под давно точно сказать не могу). При этом генерируется ошибка 4066. Следующие обращения к таймсерии будут генерировать уже другие ошибки (не помню уже, какие) до тех пор, пока вся доступная история не будет закачана. Как только загрузка окончена, обращение к таймсерии не будет вызывать ошибку, обращения к серверу прекратятся.

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

Поэтому для окончания загрузки просто жду несколько секунд.

 
secret:

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

Поэтому для окончания загрузки просто жду несколько секунд.

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

 
Ihor Herasko:

После этого используете значения prev_calculated и rates_total. Если их разность более, чем 1, значит, произошла подгрузка данных. В этом случае полностью перерисовываете индикатор. 

произошла подгрузка данных это prev_calculated = 0.

prev_calculated - rates_total = 1, появился новый бар.

prev_calculated - rates_total > 1 , после последнего расчета индикатора имеется такое количество не посчитанных (новых)баров. Такая ситуация возникает в тестере на максимальной скорости при ценах открытия и контрольных точках. Наверно возможно и в реале.