Разъясните пожалуйста что в этой функции может быть не так? - страница 4

 
Alexey Viktorov:

Владимир, но ведь в тестере проблема не возникает... Откуда такая беда??? Или от того, что в тестере только один советник?

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

В тестере всё торговое окружение готовится заранее. Всё на блюдечке. Никаких забот. В реале - по другому, при нестандартном поведении (работе на чужом таймфрейме и/или чужом символе) нужно самостоятельно заботится о актуальности торгового окружения.
 
Karputov Vladimir:
В одном терминале (на периоде М15 стояли советники) на  одном символе не сработало - я на 99% процентов уверен, что проблема в том, что при использовании чужого таймфрейма нужно всё время "поддёргивать" историю. Думаю это лучше делать через CopyTime().
А CopyRates() дёргает эту самую историю??? Там ведь в структуре время присутствует...
 
Karputov Vladimir:

Это не ошибка. Вы работаете на чужом таймфрейме. В таком случае нужно самостоятельно заботится о том, чтобы данные по чужому таймфрейму были актуальными.

Альтернатив, лично я, не вижу. 

Не факт, неизвестно как SERIES_LASTBAR_DATE работает. Очень может быть, что ничего обновлять не надо, потому-что время последнего бара можно рассчитать используя TimeCurrent() указанного символа. Поинтересоваться бы у разработчиков.  

 Но так же пока четким неоспоримым фактом остается то, что если двум переменных присвоено тру, то вместе (при проверке &&) эти переменные тоже дадут тру.  

 

Проблема с отпаданием кэша других инструментов/ТФ действительно существует.

При чем, проверка на ошибки и ожидание подгрузки в цикле помогает не всегда. Мы в сервис-деске общались, но со стороны MQ ни каких подвижек не было, только одна подсказка:

Support Team 2016.02.29 11:45

Подозрение такое, что исторические данные выгружаются по таймауту.

Есть 2 решения:

1. обращаться к данным чаще,чем 1 раз в 3 минуты

2. навесить на данные какой-нибудь очень простой индикатор. Volume, например. Там никакого расчёта нет, занят всего один буфер. Наличие индикатора удержит исторический кеш в памяти вне зависимости от частоты обращения

 2-й совет не работает, индикаторы вызываются постоянно, но в какой-то момент кэш отваливается и данные получить становится невозможно.

 

Andrey Khatimlianskii 2016.03.18 13:41

Решил проблему вот таким костылем - вызываю каждые 150 секунд вот такой код для всех задействованных инструментов/ТФ:

bool CheckTimeSeries( string symbol, ENUM_TIMEFRAMES period )
{
   double array[];
   if ( CopyClose( symbol, period, 1, 1, array ) <= 0 )
   {
                int err = GetLastError();
                Print( " * Can't refresh timeseries (", symbol, ", ", period, ")! ERROR #", err, "!!!" );
                return(false);
   }
   return(true);
}

Работает достаточно быстро, ошибка 4806 после этого апдейта вроде бы пропала.

 

Прошу вас прокомментировать ещё одну непонятку.

Bars

Возвращает количество баров в истории по соответствующему символу периоду. Существует 2 варианта функции.


Интересует только второй вариант.

Запросить количество баров на заданном интервале
int  Bars(
   string           symbol_name,     // имя символа
   ENUM_TIMEFRAMES  timeframe,       // период
   datetime         start_time,      // с какой даты
   datetime         stop_time        // по какую дату
   );

Текст советника

/*******************Expert initialization function*******************/
int OnInit()
{
   return(INIT_SUCCEEDED);
}/*******************************************************************/

/************************Expert tick function************************/
void OnTick()
{
  datetime dtarr[], date = D'2016.06.22';
  ArraySetAsSeries(dtarr, true);
  CopyTime(_Symbol, PERIOD_D1, 0, 5, dtarr);
  Print(dtarr[0]);
  Print(" ", Bars(_Symbol, PERIOD_D1, date, dtarr[0]));
  Print(" ", Bars(_Symbol, PERIOD_D1, date+1, dtarr[0]));
   
}/*******************************************************************/

/******************Expert deinitialization function******************/
void OnDeinit(const int reason)
{
}/*******************************************************************/

Я так понимаю, что время 00:00:00 принадлежит наступившим суткам точно так-же как и время 00:00:01

Но ... предложенные принты не согласны с этим.

2016.06.24 22:18:56.450 TestTime (EURUSD,M15)    2
2016.06.24 22:18:56.450 TestTime (EURUSD,M15)    3
2016.06.24 22:18:56.450 TestTime (EURUSD,M15)   2016.06.24 00:00:00

Получается что между 2016.06.22 00:00:00 и 2016.06.24 00:00:00 ТРИ дневных бара, а между 2016.06.22 00:00:01 и 2016.06.24 00:00:00 всего ДВА...

Или я чего-то не так понимаю???

Файлы:
TestTime.mq5  2 kb
 

А если к времени текущего бара прибавить по секунде

  Print(" ", Bars(_Symbol, PERIOD_D1, date, dtarr[0]+1));
  Print(" ", Bars(_Symbol, PERIOD_D1, date+1, dtarr[0]+1));

то получается вот что

2016.06.24 22:26:48.602 TestTime (EURUSD,M15)    3
2016.06.24 22:26:48.602 TestTime (EURUSD,M15)    4
2016.06.24 22:26:48.602 TestTime (EURUSD,M15)   2016.06.24 00:00:00

Вроде как время 2016.06.24 00:00:01 принадлежит уже следующему бару что-ли???

 
Верхняя граница времени не входит в интервал в котором определяется количество баров.
 
Dmitry Fedoseev:
Верхняя граница времени не входит в интервал в котором определяется количество баров.

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

Слушайте, а не это-ли является причиной такого поведения SeriesInfoInteger(_Symbol, PERIOD_D1, SERIES_LASTBAR_DATE); ? Новый бар появился, тик имеется код выполняется, а время пока не учитывается???

 

Ну вот и барабашка сдулся...И от него пошёл полный игнор...

Владимир, хоть на этот вопрос можете ответить???

Alexey Viktorov:
А CopyRates() дёргает эту самую историю??? Там ведь в структуре время присутствует...
 
Alexey Viktorov:

Ну вот и барабашка сдулся...И от него пошёл полный игнор...

Владимир, хоть на этот вопрос можете ответить???

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