Статья любопытная и для меня очень полезная. Однако, возник вопрос: а насколько корректно сравнение вещественных чисел в этом куске кода?
double AnnealingMethod::FindValue(double val,double step) { double buf=0; if(val==step) return val; if(step==1) return round(val);
Images\AnnealingMethod\back.bmp Images\AnnealingMethod\pause.bmp Images\AnnealingMethod\play.bmp Images\AnnealingMethod\stop.bmp Images\AnnealingMethod\forward.bmp
Спасибо за сообщение, поправили
AnnealingMethod.zip | Zip-файл с картинками для создания интерфейса плеера. Файлы нужно разместить в папке MQL5/Images/AnnealingMethod |
Хорошая статья получилась. Автору Спасибо!
Слабо разобрался еще, но хочется кое-что сказать по этому поводу
Несмотря на значительные преимущества, алгоритм метода отжига имеет следующие недостатки реализации:
- невозможность запуска алгоритма в облачном тестировании;
- сложность подключения к советнику и необходимость выбора параметров для получения наилучших результатов.
Предлагаю немного подкорректировать Статью, чтобы можно было подключать любой советник малыми телодвижениями.
Например, подключить стандартный Moving Average.mq5 к представленной реализации метода отжига можно так
//+------------------------------------------------------------------+ //| Moving Averages.mq5 | //| Copyright 2009-2017, MetaQuotes Software Corp. | //| http://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2009-2017, MetaQuotes Software Corp." #property link "http://www.mql5.com" #property version "1.00" #include <Trade\Trade.mqh> input double MaximumRisk = 0.02; // Maximum Risk in percentage input double DecreaseFactor = 3; // Descrease factor input int MovingPeriod = 12; // Moving Average period input int MovingShift = 6; // Moving Average shift // Вставить после всех input #include <AddAnnealingMethod.mqh> #define MaximumRisk Inputs[0] #define DecreaseFactor Inputs[1] #define MovingPeriod (int)Inputs[2] #define MovingShift (int)Inputs[3] //--- int ExtHandle=0; bool ExtHedging=false; CTrade ExtTrade; #define MA_MAGIC 1234501
И это все! Никаких больше манипуляций не требуется. Чтобы это заработало, пришлось немного изменить одну функцию
//функция для настройки параметров оптимизации uint AnnealingMethod::RunOptimization(string &InputParams[],int count,double F0,double T) { Input Mass[]; ArrayResize(Mass, ArraySize(InputParams)); ResetLastError(); bool Enable=false; double Start= 0; double Stop = 0; double Step = 0; double Value= 0; int j=0; Alg.HQRndRandomize(&state);//инициализация for(int i=0;i<ArraySize(InputParams);i++) { if(!ParameterGetRange(InputParams[i],Enable,Value,Start,Step,Stop)) return GetLastError(); // if(Enable) { // ArrayResize(Mass,ArraySize(Mass)+1); Mass[j].num=i; // Mass[j].Value=UniformValue(Start,Stop,Step); Mass[j].Value=Enable ? UniformValue(Start,Stop,Step) : Value; Mass[j].BestValue=Mass[j].Value; Mass[j].Start=Start; Mass[j].Stop=Stop; Mass[j].Step=Step; Mass[j].Temp=T*Distance(Start,Stop); j++; // if(!ParameterSetRange(InputParams[i],false,Value,Start,Stop,count)) if(Enable && !ParameterSetRange(InputParams[i],false,Value,Start,Step,Stop)) return GetLastError(); } // else // InputParams[i]=""; } if(j!=0) { if(!ParameterSetRange("iteration",true,1,1,1,count)) return GetLastError(); else return WriteData(Mass,F0,1); } return 0; }
И спрятать приличный кусок кода в AddAnnealingMethod.mqh.
Таким образом, алгоритм сверхбыстрого отжига — достойный конкурент ГА и при правильных настройках может показать лучший результат.
при каких таких "правильных" настройках?
смысл алгоритма оптимизации - уменьшение пространства поиска. если ведётся поиск - значит формула ФФ не известна (в противном случае экстремумы можно было бы вычислить по формуле на основе ФФ), а посему - не существует "правильных настроек".
алгоритм либо ищет лучше при прочих равных, либо хуже, невозможно быть чуть чуть беременной.
были реальные попытки сравнить на различных тестах штатный ГА и другие АО. боги сказали - не бывать единоборствам и аминь на этом.
ЗЫ. 1, 2 оптимизируемых параметра? это просто тьфу.... попробуйте оптить несколько сотен, тысяч параметров своим отжигом... глаза откроются
tester_file считывается только в том случае, если он существовал (содержимое не важно) на момент компиляции.
Если mq5 скомпилирован, когда не было соответствующего файла, то даже дальнейшее его наличие не будет восприниматься в EX5.
Поэтому если в OnTesterInit генерируете файл для tester_file, то убедитесь, что компилировали советник при наличии хотя бы пустого передаваемого файла.
@Renat Fatkhullin несколько ошибся в своем заявлении
Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий
Может ли советник без DLL функций отправить куда-нибудь данные?
Renat Fatkhullin, 2017.06.21 11:12
Не проверял, но предполагаю, этот файл можно сгенерировать прямо в OnTesterInit.
Нет, он не попадет в расчетный пакет данных в самом проходе.
В Статье показано, что OnTesterInit отлично формирует данные для передачи на Агентов в виде файла. Понятно, что эти данные могут быть и личного характера...
Автор проделал большую работу. Очень интересная статья.
Спасибо.
были реальные попытки сравнить на различных тестах штатный ГА и другие АО. боги сказали - не бывать единоборствам и аминь на этом.
ЗЫ. 1, 2 оптимизируемых параметра? это просто тьфу.... попробуйте оптить несколько сотен, тысяч параметров своим отжигом... глаза откроются
Статья ценна не алгоритмом Оптимизации (хоть он более, чем не безынтересен), а встроенной в штатный Оптимизатор реализацией. Реализация на данный момент очень нестандартна и даже противоречит некоторым заявлениям разработчиков. Но для понимания этого нужно исходники читать, которые не касаются самого алгоритма Отжига.
Ничто Вам не мешает подобным образом встроить свой же алгоритм и показать его плюсы/минусы прямо на советниках, как это сделал Автор.
Статья любопытная и для меня очень полезная. Однако, возник вопрос: а насколько корректно сравнение вещественных чисел в этом куске кода?
Да, вы правы так сравнивать нельзя. Справка по MQL5 предлагает воспользоваться следующей функцией:
bool CompareDoubles(double number1,double number2) { if(NormalizeDouble(number1-number2,8)==0) return(true); else return(false); }
Но даже, если сравнение будет выполнено неправильно, функция FindValue выдаст верный результат
Статья ценна не алгоритмом Оптимизации (хоть он более, чем не безынтересен), а встроенной в штатный Оптимизатор реализацией. Реализация на данный момент очень нестандартна и даже противоречит некоторым заявлениям разработчиков. Но для понимания этого нужно исходники читать, которые не касаются самого алгоритма Отжига.
Ничто Вам не мешает подобным образом встроить свой же алгоритм и показать его плюсы/минусы прямо на советниках, как это сделал Автор.
Это понятно, что статья ценна реализацией управления оптимизацией, но автор делает зачем то сравнение со штатным алгоритмом, да ещё и при мизерном количестве параметров - на это я и попытался сделать упор в своём посте, что со штатным оптимизатором бесполезно тягаться в достаточном для практических целей алготрейдеров диапазоне поискового пространства (количество параметров и их шаг).
А если мутить кастомную оптимизацию то точно не таким способом, потому что "узким горлышком" в скорости является сам тестер, а не АО, а про качество уже было сказано - штатный уже достаточно хорош.
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
Опубликована статья Управляемая оптимизация: метод отжига:
В тестере стратегий торговой платформы MetaTrader 5 есть только два варианта оптимизации: полный перебор параметров и генетический алгоритм. В этой статье предложен новый вариант оптимизации торговых стратегий — метод отжига. Приводится алгоритм метода, его реализация и способ подключения к любому советнику. Разработанный алгоритм протестирован на советнике Moving Average.
Для реализации алгоритма напишем два класса, которые необходимо подключить к оптимизируемому советнику:
Также для работы алгоритма требуется включить дополнительный код в функцию OnInit и добавить в код советника функции OnTester, OnTesterInit, OnTesterDeInit, OnTesterPass. Процесс подключения алгоритма к советнику показан на рис. 2.
Рис. 2. Подключение алгоритма к советнику
Автор: Aleksey Zinovik