Ошибка " invalid bar .. <= .." при выполнении CustomRatesUpdate() и CustomRatesReplace()

 
При выполнении CustomRatesUpdate() и CustomRatesReplace() добавляется только последний по времени бар. На остальные выводятся сообщения в журнал вида " invalid bar 2018.03.30 08:32 (1) <= 2018.03.30 09:52 (0)". Просьба откликнуться, кто сталкивался: как удалось победить?
 

Посмотрите Rates.mqh, там идет формирование MqlRates[] из MqlTick[].

Если у Вас уже есть готовый проблемный MqlRates[], запишите его через FileSave и прикрепите сюда. А так же скиньте json-файл пользовательского символа.

ThirdPartyTicks
ThirdPartyTicks
  • голосов: 12
  • 2018.03.16
  • fxsaber
  • www.mql5.com
Исторически сложилось, что для MetaTrader 4 пользуются популярностью сторонние приложения, позволяющие получать тиковую историю из различных источников. Как правило, ее используют в Тестере Стратегий как полигон для проверки советников, а также для исследований (машинное обучение и т.д.). Некоторые источники котировок в обсуждениях стали почти...
 
Из MqlTick[] не подходит - надо именно бары закачать. Файлы прикрепил
Файлы:
Files.zip  10 kb
 
Ivan Titov:
Из MqlTick[] не подходит - надо именно бары закачать. Файлы прикрепил

Rates-массив нужно перевернуть (время должно быть по-возрастанию). А вот после появится такое

'BTC.EXANTE' invalid bar 2018.03.30 07:34 (2), close price 6673.29000000 is much bigger than open price 6647.13500000 [delta: 2615500000]

на такую запись

                   [time]     [open]     [high]      [low]    [close] [tick_volume] [spread] [real_volume]
[  2] 2018.03.30 07:34:00 6647.13500 6673.68500 6644.69000 6673.29000             4        0             4


И это, похоже, уже баг MT5 - такое логирование. Сами бары успешно запишутся.

 
Большое спасибо! В документации о порядке баров в  массиве ни слова. А от ошибки "is much bigger" удалось избавиться настройкой свойств символа (прилагаю)
Файлы:
 

Ivan Titov:
Большое спасибо! В документации о порядке баров в  массиве ни слова.

Да, в Документации это описано только в части тиков.

А от ошибки "is much bigger" удалось избавиться настройкой свойств символа (прилагаю)

Как раз показательна здесь другая ошибка MT5. Например, стираю полностью Ваш символ. И создаю на основе исправленного json-файла его же. Попытка записать бары при этом выдаст все ту же ошибку. Потому что где-то в кешах хранятся старые настройки - удаленного символа. И ничего не сделать.

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

 
Ivan Titov:
от ошибки "is much bigger" удалось избавиться настройкой свойств символа (прилагаю)

Вы не заметили подводный камень. Импорт цен осуществляется на основе заданного значения Digits-поля. Если он изменен с 8-ми на 2-ку, то цены обрежутся при импорте.

 
fxsaber:

Вы не заметили подводный камень. Импорт цен осуществляется на основе заданного значения Digits-поля. Если он изменен с 8-ми на 2-ку, то цены обрежутся при импорте.

Согласен, но в данном случае достаточно - биржа дает цены с точностью до 2-х знаков.

fxsaber:

Как раз показательна здесь другая ошибка MT5. Например, стираю полностью Ваш символ. И создаю на основе исправленного json-файла его же. Попытка записать бары при этом выдаст все ту же ошибку. 

После удаления создаю символ программно функцией CustomSymbolCreate(). Вроде такой ошибки не замечал.

 
Ivan Titov:

После удаления создаю символ программно функцией CustomSymbolCreate(). Вроде такой ошибки не замечал.

Без разницы, вручную или через MQL. Баг хорошо можно ощутить, если гонять кастомный символ в Тестере.

Ivan Titov:

Согласен, но в данном случае достаточно - биржа дает цены с точностью до 2-х знаков.

В исходных данных три знака


Лучше всего определять программно

  static int GetDigits( double Price )
  {
    int Res = 0;

    while ((bool)(Price = ::NormalizeDouble(Price - (int)Price, 8)))
    {
      Price *= 10;

      Res++;
    }

    return(Res);
  }

  static int GetDigits( const MqlTick &Tick )
  {
    return(::MathMax(TICKS::GetDigits(Tick.bid), TICKS::GetDigits(Tick.ask)));
  }

  int GetDigits( void ) const
  {
    int Res = 0;

    const uint Size = this.GetAmount();

    for (uint i = 0; _CS(i < Size); i++)
    {
      const int digits = TICKS::GetDigits(this.Data[i]);

      if (digits > Res)
        Res = digits;
    }

    return(Res);
  }

и перед имортом менять свойство SYMBOL_DIGITS на вычисленное.

 
fxsaber:

В исходных данных три знака

Лучше всего определять программно

и перед имортом менять свойство SYMBOL_DIGITS на вычисленное.

Хм.., действительно. Биржа дает цены для BTC.EXANTE с 3 знаками после запятой, а в параметре "Minimum possible increment of symbol price" возвращает 0.01. Буду определять по факту, спасибо.

Причина обращения: