Пользовательские символы. Ошибки, баги, вопросы, предложения. - страница 27

 
Stanislav Korotky:

Добавление тиков "один в один" (в частности из EURUSD на MQ Demo) в пустой новый кастом-символ дает ошибку 5310 (не сразу, но в цикле прохода от произвольной даты).

Что не так? Как узнать, на какие именно тики ругается? Выводил массивы в лог - там нет нарушения хронологии.

Попробуйте вставить проверку для копирования тиков.
У меня в индикаторе на реал тайм данных в по тиковой обработке, при копировании CopyClose, иногда срабатывает ошибка копирования.
Пока не пойму в чём может быть причина. Может и в вашем случае появляется ошибка копирования.

И ещё, в CopyTicks вы копируете много тиков Limit, а потом ещё в цикле while пробегаетесь, то есть каждую итерацию копируете большой массив тиков.
И в CustomTicksAdd вы передаёте то же большое количество тиков array.
Попробуйте копировать один тик, и передавать один тик.
Вы же в цикле while бежите.

input int Limit = 10000;
input datetime Start = D'2020.06.01';

int fillArray(ulong &_start)
{
  MqlTick array[];
  int size = CopyTicks(_Symbol, array, COPY_TICKS_ALL, _start, Limit);

  if(size <= 0) 
  {
     Print("Ошибка копирования ценовых данных "+_Symbol+" "+(string)size+" ",GetLastError());
     return(size);
  }

  if(size > 0)
  {
    _start = array[size - 1].time_msc + 1;
    if(CustomTicksAdd(symbolName, array) == -1)
    {
      Print("Error:", GetLastError());
      return(-1);
    }
  }
  return(size);
}

...
{
  ulong startMsc = (ulong)Start * 1000;
  while(fillArray(startMsc) > 0);
}
Добавлено. Не относится к кастомным символам.
Только что отловил в индикаторе, в по тиковом реал тайм причину ошибки копирования функцией CopyClose с периодом M5.
Оборвалась связь интернета на несколько секунд, и после появления связи выскочила ошибка копирования 4401 Запрашиваемая история не найдена
Как то странно, за время отсутствия связи период M5 ещё не сменился на новый бар, а ошибка выскочила.
 
Roman:

Попробуйте вставить проверку для копирования тиков.
У меня в индикаторе на реал тайм данных в по тиковой обработке, при копировании CopyClose, иногда срабатывает ошибка копирования.
Пока не пойму в чём может быть причина. Может и в вашем случае появляется ошибка копирования.

И ещё, в CopyTicks вы копируете много тиков Limit, а потом ещё в цикле while пробегаетесь, то есть каждую итерацию копируете большой массив тиков.
И в CustomTicksAdd вы передаёте то же большое количество тиков array.
Попробуйте копировать один тик, и передавать один тик.

Ошибок копирования нет, в коде получается нормальное значение количества скопированных тиков (size), массив все время заполнен нормальными данными. Limit можно менять, но ошибка возникает при любом осмысленном значении от одной до нескольких тысяч. Копировать все тики сразу (как делается в некоторых кодах) - явно неправильно, потому что может вызвать ошибку выделения памяти и блокирует поток надолго без возможности показывать пользователю прогресс. Копирование же тиков мелкими пачками по 10 (не говоря уже об 1) - жутко замедляет весь процесс - неприемлемо.

Предложенный вариант - оптимальный. И даже если это для кого-то спорный момент, формально код корректен (или приведите, в чем моя ошибка) и текущее поведение - ошибка, т.е. тики должны добавляться без кода 5310.

Также по-прежнему осталась давняя проблема с очисткой базы тиков. Вызов CustomTicksDelete(symbolName, 0, LONG_MAX); не хочет удалять все тики и оставляет несколько (наблюдается не постоянно, а примерно через раз). Если перезапустить эксперт, тогда кастом-символ очищается полностью. Как и в случае CopyTicks - ошибок нет.

 
Если нужно писать тики без генерации еще OnTick-событий, то, возможно, лучше использовать иную функцию.
 
Stanislav Korotky:

Может, на стыке пачек попадаются тики с одинаковой мс и это считается ошибкой?

Просто догадка

 
Andrey Khatimlianskii:

Может, на стыке пачек попадаются тики с одинаковой мс и это считается ошибкой?

Просто догадка

По коду видно, что идут дубли тиков. В таком случае элементарно флаги тиков могут не соответствовать.

 
fxsaber:
Если нужно писать тики без генерации еще OnTick-событий, то, возможно, лучше использовать иную функцию.

Согласен. Попробую. Но не вижу причин, почему текущий способ не должен работать.

 
Stanislav Korotky:

Ошибок копирования нет, в коде получается нормальное значение количества скопированных тиков (size), массив все время заполнен нормальными данными. Limit можно менять, но ошибка возникает при любом осмысленном значении от одной до нескольких тысяч. Копировать все тики сразу (как делается в некоторых кодах) - явно неправильно, потому что может вызвать ошибку выделения памяти и блокирует поток надолго без возможности показывать пользователю прогресс. Копирование же тиков мелкими пачками по 10 (не говоря уже об 1) - жутко замедляет весь процесс.

Предложенный вариант - оптимальный. И даже если это для кого-то спорный момент, формально код корректен (или приведите, в чем моя ошибка) и текущее поведение - ошибка, т.е. тики должны добавляться без кода 5310.

Также по-прежнему осталась давняя проблема с очисткой базы тиков. Вызов CustomTicksDelete(symbolName, 0, LONG_MAX); не хочет удалять все тики и оставляет несколько (наблюдается не постоянно, а примерно через раз). Если перезапустить эксперт, тогда кастом-символ очищается полностью. Как и в случае CopyTicks - ошибок нет.

ERR_CUSTOM_TICKS_WRONG_ORDER

5310

Не упорядоченный по времени массив тиков


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

По поводу очистки базы тиков, не нравится мне константа LONG_MAX в данном случае.
Справка функции CustomTicksDelete говорит,  Время последнего тика в ценовой истории из указанного диапазона, подлежащего удалению. Время в миллисекундах с 01.01.1970.
А LONG_MAX куда больше этой разрядности. То есть передаётся большее значение, на которое не рассчитан данный параметр.
Попробуйте использовать число соответствующее разрядности миллисекундам, то есть 13 значений.

 
fxsaber:

По коду видно, что идут дубли тиков. В таком случае элементарно флаги тиков могут не соответствовать.

Дубли тиков в приемном массиве CopyTicks? Каким образом понятно, что это дубли тиков а не идентичные тики (у тиков ведь нет уникальных идентификаторов)? Даже если дубли, по идее тики с равными отсечками не нарушают последовательность. Наконец, возникает вопрос - каким образом дубли образуются?

 
Roman:

ERR_CUSTOM_TICKS_WRONG_ORDER

5310

Не упорядоченный по времени массив тиков


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

Про удаление речи нет, ничего не перезаписывается. Итерации идут по времени без пересечений. Всегда в пустой кастом-символ - либо новый, либо после успешного удаления всех тиков.

 
Stanislav Korotky:

Дубли тиков в приемном массиве CopyTicks? Каким образом понятно, что это дубли тиков а не идентичные тики (у тиков ведь нет уникальных идентификаторов)? Даже если дубли, по идее тики с равными отсечками не нарушают последовательность. Наконец, возникает вопрос - каким образом дубли образуются?

Посмотрел код внимательнее. Вы пропускаете тики при получении порциями. Возможна ситуация Ticks[Limit - 1].time_msc == Ticks[Limit + k], k >= 0.

Соответственно, когда дописываете с пропуском, то флаги могут не соответствовать.


Делайте так, чтобы в конце порции были все исторические тики с одним временем. Т.е. чтобы начало следующей порции было с уже другим временем. Иначе даже при записи в кастомный будут потери.

Если хочется именно через CopyTicks, то проще всего отбросить из полученной пачки самые крайние тики с наибольшим временем. И _start делать равным этому времени.
Причина обращения: