Торговые системы: Эксперты на основе популярных торговых систем и алхимия оптимизации торгового робота (Продолжение)
период оптимизации в месяцах
Спасибо Вам огромное за труд, интересные предложения и доходчивые пояснения.
Очень понравилась предлагаемая схема оптимизации советника. И реализация таймсерий оптимизации - хорошая и интересная. Честно-говоря не знал, что такое возможно.
Но есть ряд вопросов.
В частности не совсем понятно - зачем оптимизировать по переменной Opt_Number? На мой взгляд сравниваются соверешенно несвязанные данные, ведь советник на одних и тех же параметрах на разных периодах может дать совершенно разные результаты, а сравнение при оптимизации ведётся по результатам. Так как же можно сравнивать результаты работы советника, да ещё на разных периодах, да ещё при разных параметрах? А если ещё оптимизация ведётся с включением функции ГА - это по крайней мере некорректно и нерезультанивно. Разброс параметров и результатов будет очень большой.
Я ещё не очень глубоко разобрался в MQ-4, поэтому и хотел бы узнать Ваше мнение.
А возможна ли реализация автоматическая-циклическая реализация бэк-тэстинга? Т.е. есть такая идея. Попробую описать.
1-й цикл - Идёт обычная оптимизация по 0-му периоду (т.е. по периоду оптимизации - 3 мес. как это реализовано у Вас). После его окончания - автоматически запускается 2-й цикл.
2-й цикл - Идёт вторичная оптимизация, но уже по периоду тестирования (4-й и 5-й месяцы), и параметры берутся не огульно по ГА, а из результатов первой оптимизации.
Т.е. получится как бы двойной прогон на одних и тех же параметрах.
Возможна ли реализация в MQ-4 такой задачи?
1. В частности не могу понять зачем установлена проверка Timeframe ? Насколько я понимаю этот параметр устанавливается при инициализации советника и в дальнейшем вообще не изменяется, только проверяется. Для чего эта проверка? Почему выбраны именно такие значения этого параметра? Насколько я понял этот параметр связын с периодом валютной пары, на котором работает советник (М1, М5, М30...).
2. При реализации функций открытия ордеров Вы исключили параметр - "коментарии". Видимо Вы этот параметр просто никогда не используете. У меня МТС реализована на основе нескольких торговых логик и мне интересно которая из них сработала, поэтому ордера приходится подписывать. Поэтому я дописал в ваших функциях ещё один параметр - string Name_Order. Мне кажется, что в этом я не одинок.
SouthAlex писал(а):
период оптимизации в месяцах
а можно задавать период оптимизации, а также тестирования и сдвиг в днях?
Вот код, который позволяет задавать параметры в днях, для этого необходимо переменную Opt_Period сделать отрицательной, это уже исправленный вариант кода:
//+X================================================================X+ //| IsBackTestingTime.mqh | //| Copyright © 2008, Nikolay Kositsin | //| Khabarovsk, farria@mail.redcom.ru | //+X================================================================X+ //---- Объявления внешних переменных для бэктестинга extern datetime Start_Time = D'2007.01.01'; // время старта нулевой //оптимизации extern int Opt_Period = 3; // период оптимизации в месяцах, если //значение периода меньше нуля, то все параметры измеряются в днях extern int Test_Period = 2; // период тестирования в месяцах extern int Period_Shift = 1; //шаг сдвига периода оптимизации в //месяцах extern int Opt_Number = 0; // номер оптимизации //+X================================================================X+ //| IsBackTestingTime() | //+X================================================================X+ bool IsBackTestingTime() { //----+ //---- Объявления статических переменных времени static datetime OptStart_Time, OptEnd_Time, TestEnd_Time; //---- Объявления статических логических переменных static bool SecondStart; if (!SecondStart) { //----+ БЭКТЕСТИНГ ДЛЯ ДНЕВНЫХ ИНТЕРВАЛОВ if (Opt_Period > 0) { //----+ ИНИЦИАЛИЗАЦИЯ КОНСТАНТ ДЛЯ БЭКТЕСТИНГА int newmonth, newyear; string StartTime, OptDay; //--- StartTime = TimeToStr(Start_Time, TIME_DATE); OptDay = StringSubstr(StartTime, 8, 9); newyear = StrToInteger(StringSubstr(StartTime, 0, 4)); newmonth = StrToInteger(StringSubstr(StartTime, 5, 6)); //--- newmonth += Opt_Number * Period_Shift; OptStart_Time = CountTime(newmonth, newyear, OptDay); //---- newmonth += MathAbs(Opt_Period); OptEnd_Time = CountTime(newmonth, newyear, OptDay); //---- newmonth += Test_Period; TestEnd_Time = CountTime(newmonth, newyear, OptDay); SecondStart = true; } //----+ БЭКТЕСТИНГ ДЛЯ ЧАСОВЫХ ИНТЕРВАЛОВ if (Opt_Period < 0) { //----+ ИНИЦИАЛИЗАЦИЯ КОНСТАНТ ДЛЯ БЭКТЕСТИНГА OptStart_Time = Start_Time + Opt_Number * Period_Shift * 3600 * 24; OptEnd_Time = OptStart_Time + MathAbs(Opt_Period) * 3600 * 24; TestEnd_Time = OptEnd_Time + Test_Period * 3600 * 24; SecondStart = true; } } //----+ ПРОВЕРКА ВЫПОЛНЕНИЯ УСЛОВИЙ БЭКТЕСТИНГА //----+ +--------------------------------------------------------+ datetime TimeCar = TimeCurrent(); if (IsOptimization()) if (TimeCar < OptStart_Time || TimeCar > OptEnd_Time) return(false); if (!IsOptimization() && IsTesting()) if (TimeCar < OptEnd_Time || TimeCar > TestEnd_Time) return(false); //----+ +--------------------------------------------------------+ return(true); //----+ } //+X================================================================X+ //| CountTime() // Вспомогательная функция для IsBackTestingTime() | //+X================================================================X+ datetime CountTime(int& newmonth, int&newyear, string OptDay) { //----+ string sResaltTime; datetime dResaltTime; //--- if (newmonth > 12) { newyear += MathFloor(newmonth / 12.0); newmonth = MathMod(newmonth, 12); } //--- if (newmonth > 9) sResaltTime = StringConcatenate (newyear, ".", newmonth, ".", OptDay); else sResaltTime = StringConcatenate (newyear, ".0", newmonth, ".", OptDay); //--- dResaltTime = StrToTime(sResaltTime); return(dResaltTime); //----+ } //----+ +---------------------------------------------------------------+
Вот нашёл ошибку.
Пытался варировать с переменной Opt_Number, сдвигая периоды начала оптимизации. Начало выдавать какую-то абракадабру, т.е. периоды скакали как сумасшедшие, совсем не так как описывал автор.
Внимательно проанализировал код функции. Действительно - ошибка. Оказалась, что логику функции не реализовывает следующая запись:
newmonth += Opt_Number * Opt_Period * Period_Shift;
...
Если подставить в вышеприведённые формулы абсолютные значения, то получатся следующие результаты.
Первоначальные, установленные автором значения переменных:
//---- Объявления внешних переменных для бэктестинга extern datetime Start_Time = D'2007.01.01'; // время старта нулевой оптимизации extern int Opt_Period = 3; // период оптимизации в месяцах extern int Test_Period = 2; // период тестирования в месяцах extern int Period_Shift = 1; // сдвиг периодрв оптимизации и тестирования в месяцах extern int Opt_Number = 0; // номер оптимизацииПодставляем их в вышепреведённые формулы. Получается:
newmonth += Opt_Number * Opt_Period * Period_Shift;
newmonth = 0 + 0*3*1 = 0 , // т.е. номер начального месяца оптимизации = 0, т.е. 2007.01.01
Теперь попробуем посмотреть оптимизацию под номером 1, т.е. сдвинуть начало оптимизационного периода на один месяц, т.е. параметр Opt_Number = 1 , не меняя при этом остальных параметров. Что получается?
newmonth += Opt_Number * Opt_Period * Period_Shift;
newmonth = 0 + 1*3*1 = 3 , // т.е. номер начального месяца оптимизации = 3, т.е. 2007.03.01
Т.е. начальный месяц у нас сдвинулся не на 1 месяц, а на 3. И т.д. (Opt_Number = 2, newmonht = 6 ...).
Такая же история происходит и при попытказ изменения сдвигов Period_Shift. Т.е. до тех пор пока параметр Opt_Number будет равен нулю оптимизация неизменно будет начинаться с даты "2007.01.01". Если же установить параметр Opt_Number в какое-нибудь другое значение, не равное 0, периоды сразу скачут на величину Opt_Number * Opt_Period * Period_Shift. В общем Данная задача нереализована.
Далее, возвнащаясь к самой схеме бэк-тестирования. Идея делать временной сдвиг, т.е. проецировать так сказать будующее в прошлое, т.е. разделять периоды оптимизации и тестирования на исторических данных - великолепна. Но крайне непонятна идея проводить много уровневая оптимизация. Сам принцип и методы его реализации - понятны, а вот результат - не понятен. Что мы получаем в итоге всех этих действий? Думаю даже достойный ответ - может ли работать советник на реале - и то не получим. Автор упоминал в первой статье, что написать советник и подогнать его под историю, получив при этом просто замечательные результаты - не составляет особого труда. Так что же мы получаем в итоге всех этих манипуляций.
Попробуем проанализировать. При оптимизации система выдаёт разброванные по параметрам результаты. В периоде тестирования - можно найти достойные параметры, которые неплохо работали и на периоде оптимизации и на периоде тестирования. И что сделать с этими параметрами?
На следующем уровне оптимизации - система выдаёт совершенно другие параметры. При включённой функции ГА вероятность совпадений крайне мала, а если оптимизируемых параметров более 2-х - вероятность вообще почти сводится к нулю.
Т.е. получается, что при первом прогоне мы получили одни данные параметров, при втором - другие, при третьем - третьи и т.д. На каждом последующем этапе мы будем получать какие-то результаты и параметры - совершенно не связанные с предыдущими этапами.
В чём смысл этих манипуляций? Что мы хотим в итоге получить от этих действий? Ответим ли мы на вопрос - способен ли наш советник реально работать в реальном времени в будущем
Данная технология, на мой взгляд, может ответить только на один вопрос - действительно ли советник полностью убыточен или всё же существует возможность подогнать его под какие-то оптеделённые параметры в надежде, что он всё же будет работать в будущем. Т.е. данная технология может отловить только тот советник, который строго подогнан под оптределённый период времени, исторические данные, и на других периодах он просто работать не может. Если же советник имеет возможность рабоать на разных поведениях рынка и способен подганяться под параметны - то данная технология покажет, что он способен подганяться, но нужно каждый раз подганять.
В данном контексте и возвращаясь к работе вышеприведённой функции считаю, что параметр Period_Shift вообще не существенен. Не нужен он. Невозможно сравнивать результаты работы советника на разных периодах при разных параметрах. Это просто непоказательно
Поэтому предлагаю заменить ошибочную строку в процедуре на простую и понятную.
newmonth = Opt_Number;
либо
newmonth = Period_Shift;
Данная технология, на мой взгляд, может ответить только на один вопрос - действительно ли советник полностью убыточен или всё же существует возможность подогнать его под какие-то оптеделённые параметры в надежде, что он всё же будет работать в будущем. Т.е. данная технология может отловить только тот советник, который строго подогнан под оптределённый период времени, исторические данные, и на других периодах он просто работать не может. Если же советник имеет возможность рабоать на разных поведениях рынка и способен подганяться под параметны - то данная технология покажет, что он способен подганяться, но нужно каждый раз подганять.
А в принципе думаю на это и расчитана эта технология. Т.е. ответить на вопрос действительно ли советник полная лажа или он ещё способен подгоняться под некие параметры.
В общем я благодарен Вам, Николай!
Заставили очень сильно и о многом задуматься.
И ещё одну закавыку в функции нашёл.
Период тестирования в функции должен находиться внутри периода, установленного на тестере. Т.е. сли на тестере будет установлен период 2008.01.01-2008.04.03, а мы попытаемся функцией протестировать период - 2007.01.01-2007.06.01 - результатов не будет. Выдаст - 0.
Kadet! Это просто несерьёзно! Вы только начали изучать язык MQL, по большому счёту его ещё и не понимаете как следует, а абсолютно впустую пытаетесь судить о вешах, которые не понимаете абсолютно и при этом тратите своё и чужое время! Вот код, к которому у вас претензии:
newmonth = StrToInteger(StringSubstr(StartTime, 5, 6)); //--- newmonth += Opt_Number *MathAbs(Opt_Period) * Period_Shift;
Попытаюсь вам его расшифровать (знак равенства стоял с плюсом!!!!!):
newmonth = StrToInteger(StringSubstr(StartTime, 5, 6)); //--- newmonth = newmonth + Opt_Number *MathAbs(Opt_Period) * Period_Shift;Вы смотрите внимательней на код и проверяйте каждую мелочь! Убирайте ваш словесный хлам, он никому не нужен, вы не правы!
Kadet! Это просто несерьёзно! Вы только начали изучать язык MQL, по большому счёту его ещё и не понимаете как следует,
...
Вы смотрите внимательней на код и проверяйте каждую мелочь! Убирайте ваш словесный хлам, он никому не нужен, вы не правы!
Попробуйте вручную поменяйте значение переменной Opt_Number и проведите оптимизацию. А затем проверте результаты на тестировании. Особое внимане обратите на даты ордеров. Надеюсь Вы, уважаемый Николай, заметите, что: - при значении Opt_Number = 0, ордера на тестировании выставляются начиная с 2007.04.01, - при Opt_Number = 1, ордера на тестировании выставляются начиная с 2007.07.01, - при Opt_Number = 2, ордера на тестировании выставляются начиная с 2007.10.01, - при Opt_Number = 3, ордера на тестировании выставляются начиная с 2008.01.01, - при Opt_Number = 4, ордера на тестировании вообще не вытавляются, потому что тестирование проводится на ещё не существующем периоде истории, т.е. в будущем. Т.е. функция сдвигает начало оптимизации на 3 месяца, а по описанию - сдвиг должен быть только на 1 месяц. При сдвиге на 3 месяца очень трудно подобрать значения переменных таким образом, чтобы дата окончания тестирования - была текущим месяцем. Поробуйте, может тогда поймёте о чём это я. Формула - некорректна. Или так было задумано? Я у себя убрал лишние заморочки - заработал корректно.
С MQ-4 я действительно знаком недавно, зато осмелюсь Вам доложить, что с другими языками и программированием вцелом я знаком очень давно и не по наслышке, так, что о работе программных функций судить могу и записи типа - +=, -=, != и т.д. для меня не в диковинку. В абсолютных значениях я расшифровал как - newmonth = 0 + 1*3*1 = 3 , где первый "0", извините, действительно ошибочен. Там будет соять "1" (т.е. январь 2007).
А возможна ли реализация автоматическая-циклическая реализация бэк-тэстинга? Т.е. есть такая идея. Попробую описать.
1-й цикл - Идёт обычная оптимизация по 0-му периоду (т.е. по периоду оптимизации - 3 мес. как это реализовано у Вас). После его окончания - автоматически запускается 2-й цикл.
2-й цикл - Идёт вторичная оптимизация, но уже по периоду тестирования (4-й и 5-й месяцы), и параметры берутся не огульно по ГА, а из результатов первой оптимизации.
Т.е. получится как бы двойной прогон на одних и тех же параметрах.
Возможна ли реализация в MQ-4 такой задачи?
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
New article Эксперты на основе популярных торговых систем и алхимия оптимизации торгового робота (Продолжение) has been published:
Author: Nikolay Kositsin