Провёл небольшое стресс-тестирование. Выключил интернет, запустил индикатор с панелью на график. Параметры уже предоставил выше. Потом включил интернет, получил такой результат:
CL 022:29:43.402 TestMSTFMovingAverages (EURUSD,M15) CMSTFIndicators::AddNewMA: MA(10) indicator (handle 10) added to the collection
OS 022:29:43.402 TestMSTFMovingAverages (EURUSD,M15) CMSTFIndicators::AddNewMA: MA(EURUSD,H1:10) indicator (handle 11) added to the collection
DQ 022:29:43.439 TestMSTFMovingAverages (EURUSD,M15) CIndMSTF::Calculate::MA(10): Waiting for data to sync...
QL 022:29:43.439 TestMSTFMovingAverages (EURUSD,M15) CMSTFIndicators::Calculate::MA(10): Error in indicator calculation: Data is not synchronized
IO 022:29:43.439 TestMSTFMovingAverages (EURUSD,M15) CIndMSTF::Calculate::MA(EURUSD,H1:10): Waiting for data to sync...
PQ 022:29:43.439 TestMSTFMovingAverages (EURUSD,M15) CMSTFIndicators::Calculate::MA(EURUSD,H1:10): Error in indicator calculation: Data is not synchronized
LN 022:29:43.439 TestMSTFMovingAverages (EURUSD,M15) CMSTFIndicators::Calculate: Not all indicators have been calculated successfully. It is necessary to recalculate the buffers of all indicators
KE 022:29:43.443 TestMSTFMovingAverages (EURUSD,M15) CIndMSTF::Calculate::MA(10): Waiting for data to sync...
JH 022:29:43.443 TestMSTFMovingAverages (EURUSD,M15) CMSTFIndicators::Calculate::MA(10): Error in indicator calculation: Data is not synchronized
RK 022:29:43.443 TestMSTFMovingAverages (EURUSD,M15) CIndMSTF::Calculate::MA(EURUSD,H1:10): Waiting for data to sync...
OD 022:29:43.443 TestMSTFMovingAverages (EURUSD,M15) CMSTFIndicators::Calculate::MA(EURUSD,H1:10): Error in indicator calculation: Data is not synchronized
CR 022:29:43.443 TestMSTFMovingAverages (EURUSD,M15) CMSTFIndicators::Calculate: Not all indicators have been calculated successfully. It is necessary to recalculate the buffers of all indicators
GE 022:30:04.495 TestMSTFMovingAverages (EURUSD,M15) CIndMSTF::OnTimer::MA(EURUSD,H1:10): Tick emulation. Attempt 1 of 3 ...
II 022:30:34.092 TestMSTFMovingAverages (EURUSD,M15) CIndMSTF::Calculate::MA(10): Waiting for data to sync...
LD 022:30:34.092 TestMSTFMovingAverages (EURUSD,M15) CMSTFIndicators::Calculate::MA(10): Error in indicator calculation: Data is not synchronized
DH 022:30:34.092 TestMSTFMovingAverages (EURUSD,M15) CIndMSTF::Calculate::MA(EURUSD,H1:10): Waiting for data to sync...
NH 022:30:34.093 TestMSTFMovingAverages (EURUSD,M15) CMSTFIndicators::Calculate::MA(EURUSD,H1:10): Error in indicator calculation: Data is not synchronized
RG 022:30:34.093 TestMSTFMovingAverages (EURUSD,M15) CMSTFIndicators::Calculate: Not all indicators have been calculated successfully. It is necessary to recalculate the buffers of all indicators
JM 022:30:35.539 TestMSTFMovingAverages (EURUSD,M15) CIndMSTF::Calculate::MA(10): Waiting for data to sync...
KP 022:30:35.539 TestMSTFMovingAverages (EURUSD,M15) CMSTFIndicators::Calculate::MA(10): Error in indicator calculation: Data is not synchronized
CD 022:30:35.539 TestMSTFMovingAverages (EURUSD,M15) CIndMSTF::Calculate::MA(EURUSD,H1:10): Waiting for data to sync...
FL 022:30:35.539 TestMSTFMovingAverages (EURUSD,M15) CMSTFIndicators::Calculate::MA(EURUSD,H1:10): Error in indicator calculation: Data is not synchronized
RK 022:30:35.539 TestMSTFMovingAverages (EURUSD,M15) CMSTFIndicators::Calculate: Not all indicators have been calculated successfully. It is necessary to recalculate the buffers of all indicators
OM 022:30:37.935 TestMSTFMovingAverages (EURUSD,M15) CIndMSTF::Calculate::MA(EURUSD,H1:10): Waiting for a new tick and when the indicator will be calculated...
PI 022:30:37.935 TestMSTFMovingAverages (EURUSD,M15) CMSTFIndicators::Calculate::MA(EURUSD,H1:10): Error in indicator calculation: Calculation not completed
ND 022:30:37.935 TestMSTFMovingAverages (EURUSD,M15) CMSTFIndicators::Calculate: Not all indicators have been calculated successfully. It is necessary to recalculate the buffers of all indicators
PN 222:30:39.604 TestMSTFMovingAverages (EURUSD,M15) array out of range in'TestMSTFMovingAverages.mq5' (211,34)
Если посмотрим на график USDCHF, а вернее на красную кривую индикатора МА(USDCHF, H1), то за последние 7 часов переход на следующее значение происходил в 00 минут 5 раз. Выделил красными вертикалями. И только последние 2 часа всё нормально. Синие вертикали. Имхо, явный косяк с заполнением буферов...
Провёл небольшое стресс-тестирование. Выключил интернет, запустил индикатор с панелью на график. Параметры уже предоставил выше. Потом включил интернет, получил такой результат:
Если посмотрим на график USDCHF, а вернее на красную кривую индикатора МА(USDCHF, H1), то за последние 7 часов переход на следующее значение происходил в 00 минут 5 раз. Выделил красными вертикалями. И только последние 2 часа всё нормально. Синие вертикали. Имхо, явный косяк с заполнением буферов...
Провёл небольшое стресс-тестирование. Выключил интернет, запустил индикатор с панелью на график. Параметры уже предоставил выше. Потом включил интернет, получил такой результат:
Индикатор вылетел.
В строке 211 в позиции курсора 34 идёт обращение к предопределённому массиву time[]:
DrawData(mouse_bar_index,time[mouse_bar_index]);
Выходит, что индекс в массив передан некорректный.
Больше rates_total-1 он вряд ли может быть, скорее всего равен -1, так как получает свои значения в обработчике OnChartEvent функцией iBarShift(), которая может вернуть -1:
voidOnChartEvent(constint id,
constlong &lparam,
constdouble &dparam,
conststring &sparam)
{
//--- Работа с панелью//--- Вызываем обработчик событий панели
panel.OnChartEvent(id,lparam,dparam,sparam);
//--- Если курсор перемещается или щелчок по графикуif(id==CHARTEVENT_MOUSE_MOVE || id==CHARTEVENT_CLICK)
{
//--- Объявляем переменные для записи в них координат времени и ценыdatetime time=0;
double price=0;
int wnd=0;
//--- Если координаты курсора преобразованы в дату и времяif(ChartXYToTimePrice(ChartID(),(int)lparam,(int)dparam,wnd,time,price))
{
//--- записываем индекс бара, где расположен курсор в глобальную переменнуюmouse_bar_index=iBarShift(Symbol(),PERIOD_CURRENT,time);//--- Выводим данные бара под курсором на панель
DrawData(mouse_bar_index,time);
}
}
//--- Если получили пользовательское событие - выводим об этом сообщение в журналif(id>CHARTEVENT_CUSTOM)
{
//--- Здесь может быть обработка щелчка по кнопке закрытия на панелиPrintFormat("%s: Event id=%ld, object id (lparam): %lu, event message (sparam): %s",__FUNCTION__,id,lparam,sparam);
}
}
В функции DrawData() некорректное значение индекса обрабатывается при вызове CopyRates(), которая не получит данных при отрицательном индексе, и после этого будет осуществлён выход из DrawData():
//--- Если данные бара по указанному индексу получить не удалось - уходимif(CopyRates(Symbol(),PERIOD_CURRENT,index,1,rates)!=1)
return;
Значит - перед обращением к массиву time[] нужно проверять индекс бара, передаваемый в массив (в строке 211):
//--- Выводим на панель данные бара под курсором (либо текущий бар, если курсор за пределами графика)if(mouse_bar_index>WRONG_VALUE && mouse_bar_index<rates_total)
DrawData(mouse_bar_index,time[mouse_bar_index]);
В общем - теория. Не тестировал, так как занят разработкой продолжения темы (цветные буферы мульти- индикаторов и такое прочее). После публикации очередной статьи по этой теме, буду проверять и тестировать (если Вы раньше меня не протестируете с внесением изменений в стр.211)
В строке 211 в позиции курсора 34 идёт обращение к предопределённому массиву time[]:
Выходит, что индекс в массив передан некорректный.
Больше rates_total-1 он вряд ли может быть, скорее всего равен -1, так как получает свои значения в обработчике OnChartEvent функцией iBarShift(), которая может вернуть -1:
В функции DrawData() некорректное значение индекса обрабатывается при вызове CopyRates(), которая не получит данных при отрицательном индексе, и после этого будет осуществлён выход из DrawData():
Значит - перед обращением к массиву time[] нужно проверять индекс бара, передаваемый в массив (в строке 211):
В общем - теория. Не тестировал, так как занят разработкой продолжения темы (цветные буферы мульти- индикаторов и такое прочее). После публикации очередной статьи по этой теме, буду проверять и тестировать (если Вы раньше меня не протестируете с внесением изменений в стр.211)
Артём, индекс бара может быть и текущий, iBarShift() возвращает 0. А вот в CopyRates() меньше 1 засунуть нельзя. Поэтому, наверное надо писать iBarShift()+1 в любом варианте, так-как номер бара и количество баров не равны.
Артём, индекс бара может быть и текущий, iBarShift() возвращает 0. А вот в CopyRates() меньше 1 засунуть нельзя. Поэтому, наверное надо писать iBarShift()+1 в любом варианте, так-как номер бара и количество баров не равны.
Артём, индекс — да, он может быть и нулю равен. Но количество копируемых элементов
intCopyRates(
string symbol_name, // имя символа ENUM_TIMEFRAMES timeframe, // период int start_pos, // откуда начнем int count, // сколько копируемMqlRates rates_array[] // массив, куда будут скопированы данные
);
нулю не может быть равно.
Точно так-же как количество позиций и индекс в списке позиций…
...После публикации очередной статьи по этой теме, буду проверять и тестировать (если Вы раньше меня не протестируете с внесением изменений в стр.211)
Чтобы что-то тестировать, нужно быть в парадигме происходящего ))
Я понял, что мне легче свою версию набросать, т.к. мне не близок текущий подход. В частности, мне кажется, что класс CIndMSTF какой-то супер класс. Потом на его базе создаётся куча индикаторных классов. Жуть - файл IndMSTF.mqh на 4 тыс. строк кода )) Я пошёл по пути использования в качестве индикаторной коллекции экземпляр класса CIndicators. Очень удобно. Не нужно изобретать велосипед...
Потом зачем в классе CIndMSTF хранить данные по буферам (SBuffer m_buffers[])? Один раз обсчитали их в OnCalculate() и хватит. Т.е. приняли как параметр по ссылке, посчитали и отдали...
Напишу ещё попозже о том, с чем не согласен, как закончу свою версию...
Да, понравилось, что есть вот этот механизм:
...При работе с данными не текущего графика для исключения "освобождения" таймсерии, необходимо не реже. чем раз в две минуты обращаться к этой таймсерии. В этом случае будет происходить "удержание" таймсерии, что ускорит к ней обращение (не нужно будет каждый раз дожидаться синхронизации данных)...
Артём, ещё такой момент. Если статьи пишутся как пособие, к-рое есть желание изучать, то имхо, не хватает схем взаимоотношений тех, классов, к-рые разработчик создаёт...
Потом, зачем выкладывать код всех индикаторов в материал статьи? Я о б этом разделе - "Полный список всех классов-наследников базового класса мультисимвольного мультипериодного индикатора". Специально посмотрел, сколько строк кода там.
Провёл небольшое стресс-тестирование. Выключил интернет, запустил индикатор с панелью на график. Параметры уже предоставил выше. Потом включил интернет, получил такой результат:
Индикатор вылетел.
Ещё заметил странности. График М15 на USDCHF.
Если посмотрим на график USDCHF, а вернее на красную кривую индикатора МА(USDCHF, H1), то за последние 7 часов переход на следующее значение происходил в 00 минут 5 раз. Выделил красными вертикалями. И только последние 2 часа всё нормально. Синие вертикали. Имхо, явный косяк с заполнением буферов...
Провёл небольшое стресс-тестирование. Выключил интернет, запустил индикатор с панелью на график. Параметры уже предоставил выше. Потом включил интернет, получил такой результат:
Индикатор вылетел.
Ещё заметил странности. График М15 на USDCHF.
Если посмотрим на график USDCHF, а вернее на красную кривую индикатора МА(USDCHF, H1), то за последние 7 часов переход на следующее значение происходил в 00 минут 5 раз. Выделил красными вертикалями. И только последние 2 часа всё нормально. Синие вертикали. Имхо, явный косяк с заполнением буферов...
Провёл небольшое стресс-тестирование. Выключил интернет, запустил индикатор с панелью на график. Параметры уже предоставил выше. Потом включил интернет, получил такой результат:
Индикатор вылетел.
В строке 211 в позиции курсора 34 идёт обращение к предопределённому массиву time[]:
DrawData(mouse_bar_index,time[mouse_bar_index]);Выходит, что индекс в массив передан некорректный.
Больше rates_total-1 он вряд ли может быть, скорее всего равен -1, так как получает свои значения в обработчике OnChartEvent функцией iBarShift(), которая может вернуть -1:
В функции DrawData() некорректное значение индекса обрабатывается при вызове CopyRates(), которая не получит данных при отрицательном индексе, и после этого будет осуществлён выход из DrawData():
Значит - перед обращением к массиву time[] нужно проверять индекс бара, передаваемый в массив (в строке 211):
В общем - теория. Не тестировал, так как занят разработкой продолжения темы (цветные буферы мульти- индикаторов и такое прочее). После публикации очередной статьи по этой теме, буду проверять и тестировать (если Вы раньше меня не протестируете с внесением изменений в стр.211)
В строке 211 в позиции курсора 34 идёт обращение к предопределённому массиву time[]:
Выходит, что индекс в массив передан некорректный.
Больше rates_total-1 он вряд ли может быть, скорее всего равен -1, так как получает свои значения в обработчике OnChartEvent функцией iBarShift(), которая может вернуть -1:
В функции DrawData() некорректное значение индекса обрабатывается при вызове CopyRates(), которая не получит данных при отрицательном индексе, и после этого будет осуществлён выход из DrawData():
Значит - перед обращением к массиву time[] нужно проверять индекс бара, передаваемый в массив (в строке 211):
В общем - теория. Не тестировал, так как занят разработкой продолжения темы (цветные буферы мульти- индикаторов и такое прочее). После публикации очередной статьи по этой теме, буду проверять и тестировать (если Вы раньше меня не протестируете с внесением изменений в стр.211)
Артём, индекс бара может быть и текущий, iBarShift() возвращает 0. А вот в CopyRates() меньше 1 засунуть нельзя. Поэтому, наверное надо писать iBarShift()+1 в любом варианте, так-как номер бара и количество баров не равны.
Артём, индекс бара может быть и текущий, iBarShift() возвращает 0. А вот в CopyRates() меньше 1 засунуть нельзя. Поэтому, наверное надо писать iBarShift()+1 в любом варианте, так-как номер бара и количество баров не равны.
В данном контексте: индекс - и есть номер бара
В данном контексте: индекс - и есть номер бара
Артём, индекс — да, он может быть и нулю равен. Но количество копируемых элементов
нулю не может быть равно.
Точно так-же как количество позиций и индекс в списке позиций…
Артём, индекс — да, он может быть и нулю равен. Но количество копируемых элементов
нулю не может быть равно.
Точно так-же как количество позиций и индекс в списке позиций…
Вот здесь:
куда указывает index ?
Вот здесь:
куда указывает index ?
Всё, умолкаю. Я не смотрел код функции DrawData(mouse_bar_index,time); потому и ошибался…
Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий
Обсуждение статьи "Готовим мультисимвольные мультипериодные индикаторы"
Artyom Trishkin, 2023.11.01 04:46
...После публикации очередной статьи по этой теме, буду проверять и тестировать (если Вы раньше меня не протестируете с внесением изменений в стр.211)
Чтобы что-то тестировать, нужно быть в парадигме происходящего ))
Я понял, что мне легче свою версию набросать, т.к. мне не близок текущий подход. В частности, мне кажется, что класс CIndMSTF какой-то супер класс. Потом на его базе создаётся куча индикаторных классов. Жуть - файл IndMSTF.mqh на 4 тыс. строк кода )) Я пошёл по пути использования в качестве индикаторной коллекции экземпляр класса CIndicators. Очень удобно. Не нужно изобретать велосипед...
Потом зачем в классе CIndMSTF хранить данные по буферам (SBuffer m_buffers[])? Один раз обсчитали их в OnCalculate() и хватит. Т.е. приняли как параметр по ссылке, посчитали и отдали...
Напишу ещё попозже о том, с чем не согласен, как закончу свою версию...
Да, понравилось, что есть вот этот механизм:
...При работе с данными не текущего графика для исключения "освобождения" таймсерии, необходимо не реже. чем раз в две минуты обращаться к этой таймсерии. В этом случае будет происходить "удержание" таймсерии, что ускорит к ней обращение (не нужно будет каждый раз дожидаться синхронизации данных)...
Артём, ещё такой момент. Если статьи пишутся как пособие, к-рое есть желание изучать, то имхо, не хватает схем взаимоотношений тех, классов, к-рые разработчик создаёт...
Потом, зачем выкладывать код всех индикаторов в материал статьи? Я о б этом разделе - "Полный список всех классов-наследников базового класса мультисимвольного мультипериодного индикатора". Специально посмотрел, сколько строк кода там.
Вот начало:
А вот конец:
Почти 2 тыс. Ошалеть!