Все тормоза, похоже, когда в CopyTicks входной from не нулевой.
Похоже, очень кривая реализация CopyTicks в таком режиме, даже если запрашиваются тики со времени последнего вызова. Казалось бы, должно летать, ан нет.
Получилось локализовать один из багов, вызывающий расхождения в индикаторе. Дело снова в CopyTicks.
Оказывается, если собирать тиковую историю по частям, то она может не совпадать с реальной историей. Советник это показывает
#include <TypeToBytes.mqh> // https://www.mql5.com/ru/code/16280long LastTime = 0; // time_msc-время последнего тика (самого свежего), полученного из историиint Count = 0; // Количество тиков в последенем запросе, у которых time_msc == LastTime// Возвращает следующие тики (после предыдущего вызова)int GetFreshTicks( MqlTick &Ticks[], constuint flags = COPY_TICKS_TRADE, constuint count = 100000 )
{
int Res = 0;
MqlTick NewTicks[];
constint NewAmount = CopyTicks(Symbol(), NewTicks, flags, LastTime, count);
if ((NewAmount > 0) && (Count < NewAmount))
{
Res = ArrayCopy(Ticks, NewTicks, 0, Count);
// Взяли крайнее время из текущей истории
LastTime = Ticks[Res - 1].time_msc;
Count = 1;
// Находим (Count) в текущей истории количество тиков со временем LastTimefor (int i = Res - 2; i >= 0; i--)
{
if (Ticks[i].time_msc < LastTime)
break;
Count++;
}
}
return(ArrayResize(Ticks, Res));
}
// Сравнение двух массивовtemplate <typename T>
bool ArrayEqual( const T &Array1[], const T &Array2[] )
{
constint Amount = MathMin(ArraySize(Array1), ArraySize(Array2));
bool Res = (Amount > 0);
if (Res)
for (int i = 0; i < Amount; i++)
if (_R(Array1[i]) != Array2[i]) // https://www.mql5.com/ru/code/16280
{
Res = false;
ExpertRemove();
break;
}
return(Res);
}
voidOnTick()
{
// возьмем тики с начала утренней сессии
Count = 0;
LastTime = (TimeCurrent() - (TimeCurrent() % (24 * 3600))) * 1000;
MqlTick Ticks[]; // История, собранная по частямMqlTick NewTicks[]; // массив для следующей части тиков// Собираем историю по частям while (GetFreshTicks(NewTicks, COPY_TICKS_TRADE, 100000) > 0)
ArrayCopy(Ticks, NewTicks, ArraySize(Ticks));
if (ArraySize(Ticks) > 0)
{
// Взяли ВСЮ историю тиковPrint(CopyTicks(_Symbol, NewTicks, COPY_TICKS_TRADE, Ticks[0].time_msc, 10000000)); // 10000000 - большое число, чтобы все выкачать.// Проверка на совпадение собранной по частям истории с самой историейPrint(ArrayEqual(NewTicks, Ticks) ? "Equal" : "Not Equal");
}
}
Результат
2016.09.3016:02:54.661 Test (Si-12.16,M1) Not Equal
2016.09.3016:02:54.661 Test (Si-12.16,M1) ExpertRemove() function called2016.09.3016:02:54.621 Test (Si-12.16,M1) 3337402016.09.3016:02:54.121 Test (Si-12.16,M1) Equal
2016.09.3016:02:54.071 Test (Si-12.16,M1) 3337362016.09.3016:02:53.791 Test (Si-12.16,M1) Equal
2016.09.3016:02:53.741 Test (Si-12.16,M1) 333723
Этот советник еще показывает слабенький баг. Выяснил, что в собранной по частям истории могут отсутствовать куски, длительностью в несколько минут. Только лаконичное и понятное воспроизведение в виде кода не придумал. А выкладывать сложное - нет смысла, т.к. никто даже смотреть не будет.
В общем, никак не победить баги CopyTicks. И заметьте, советник работает в режиме ленты (COPY_TICKS_TRADE). Т.е. даже с лентой не получается работать.
Сегодня обещают новый билд на демо. Поэтому пока ждемс.
Надеюсь, CopyTicks() поправят.
Кстати, еще с момента появления CopyTicks() просил разработчиков, чтобы добавили перегрузу функции, как у других Copy...() функций. Сказали - добавят. И... тишина...
Кстати, еще с момента появления CopyTicks() просил разработчиков, чтобы добавили перегрузу функции, как у других Copy...() функций. Сказали - добавят. И... тишина...
Если нужна ТОЛЬКО лента (COPY_TICKS_TRADE - time_msc, last, volume и flags), то данное решение полностью подходит - баги не выявлены.
Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий
Загадочный биржевой индикатор
fxsaber, 2016.09.27 18:32
Все тормоза, похоже, когда в CopyTicks входной from не нулевой.
Похоже, очень кривая реализация CopyTicks в таком режиме, даже если запрашиваются тики со времени последнего вызова. Казалось бы, должно летать, ан нет.
Подождите беты на этой неделе, где мы ряд улучшений в тиках и обновлениях стакана сделали.
1432 - много багов решено. Спасибо!
Но не все.
Если дописываемую историю сравнивать с фактической, то есть расхождения в режиме COPY_TICKS_ALL (TRADE и INFO - нет проблем). Советник
Результат
Но не все.
Если дописываемую историю сравнивать с фактической, то есть расхождения в режиме COPY_TICKS_ALL (TRADE и INFO - нет проблем). Советник
Результат
Сильно залогировал код выше и выяснил причины. Если CopyTicks (from > 0) получает тики до самого свежего, то он может пропускать некоторые.
Пример.
Запросил тики с from = 2016.09.29 11:05:55.564. Получил в ответ три тика
Спустя какое-то время запрашиваю тиковую историю издалека и вижу тик, который CopyTicks пропустил ранее
Вот такой баг!
Похоже, какой-то конфликт параллельной записи в базу тиков и считывания из нее.
Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий
Загадочный биржевой индикатор
fxsaber, 2016.09.30 15:09
Получилось локализовать один из багов, вызывающий расхождения в индикаторе. Дело снова в CopyTicks.
Оказывается, если собирать тиковую историю по частям, то она может не совпадать с реальной историей. Советник это показывает
Результат
Этот советник еще показывает слабенький баг. Выяснил, что в собранной по частям истории могут отсутствовать куски, длительностью в несколько минут. Только лаконичное и понятное воспроизведение в виде кода не придумал. А выкладывать сложное - нет смысла, т.к. никто даже смотреть не будет.
В общем, никак не победить баги CopyTicks. И заметьте, советник работает в режиме ленты (COPY_TICKS_TRADE). Т.е. даже с лентой не получается работать.
Еще один баг, теперь уже во всех режимах COPY_TICKS_*
А Вы пробовали тики получать и начиная с определенного момента, и определенное, например, фиксированное количество?
По коду похоже, что определенное количество (100000) с последнего момента. А если просто N тиков получить. Тоже пропуски будут?
Сразу скажу, сам, пока, не сильно экспериментировал с тиками...
А Вы пробовали тики получать и начиная с определенного момента, и определенное, например, фиксированное количество?
По коду похоже, что определенное количество (100000) с последнего момента. А если просто N тиков получить. Тоже пропуски будут?
Сразу скажу, сам, пока, не сильно экспериментировал с тиками...
Пробовал.
Сегодня обещают новый билд на демо. Поэтому пока ждемс.
Пробовал.
Сегодня обещают новый билд на демо. Поэтому пока ждемс.
Надеюсь, CopyTicks() поправят.
Кстати, еще с момента появления CopyTicks() просил разработчиков, чтобы добавили перегрузу функции, как у других Copy...() функций. Сказали - добавят. И... тишина...
Кстати, еще с момента появления CopyTicks() просил разработчиков, чтобы добавили перегрузу функции, как у других Copy...() функций. Сказали - добавят. И... тишина...