Обсуждение статьи "Управляемая оптимизация: метод отжига"

 

Опубликована статья Управляемая оптимизация: метод отжига:

В тестере стратегий торговой платформы MetaTrader 5 есть только два варианта оптимизации: полный перебор параметров и генетический алгоритм. В этой статье предложен новый вариант оптимизации торговых стратегий — метод отжига. Приводится алгоритм метода, его реализация и способ подключения к любому советнику. Разработанный алгоритм протестирован на советнике Moving Average.

Для реализации алгоритма напишем два класса, которые необходимо подключить к оптимизируемому советнику:

  • класс AnnealingMethod.mqh — содержит набор методов, реализующих отдельные этапы алгоритма;
  • класс FrameAnnealingMethod.mqh — содержит методы для работы графического интерфейса, отображаемого в окне графика терминала.

Также для работы алгоритма требуется включить дополнительный код в функцию OnInit и добавить в код советника функции OnTester, OnTesterInit, OnTesterDeInit,  OnTesterPass. Процесс подключения алгоритма к советнику показан на рис. 2.


Рис. 2. Подключение алгоритма к советнику

Автор: Aleksey Zinovik

 

Статья любопытная и для меня очень полезная. Однако, возник вопрос: а насколько корректно сравнение вещественных чисел в этом куске кода?

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

fxsaber:

Не проверял, но предполагаю, этот файл можно сгенерировать прямо в OnTesterInit.

Нет, он не попадет в расчетный пакет данных в самом проходе.


В Статье показано, что OnTesterInit отлично формирует данные для передачи на Агентов в виде файла. Понятно, что эти данные могут быть и личного характера...

 

Автор проделал большую работу. Очень интересная статья.

Спасибо.

 
Andrey Dik:

были реальные попытки сравнить на различных тестах штатный ГА и другие АО. боги сказали - не бывать единоборствам и аминь на этом.

ЗЫ. 1, 2 оптимизируемых параметра? это просто тьфу.... попробуйте оптить несколько сотен, тысяч параметров своим отжигом... глаза откроются

Статья ценна не алгоритмом Оптимизации (хоть он более, чем не безынтересен), а встроенной в штатный Оптимизатор реализацией. Реализация на данный момент очень нестандартна и даже противоречит некоторым заявлениям разработчиков. Но для понимания этого нужно исходники читать, которые не касаются самого алгоритма Отжига.

Ничто Вам не мешает подобным образом встроить свой же алгоритм и показать его плюсы/минусы прямо на советниках, как это сделал Автор.

 
Sergey Pavlov:

Статья любопытная и для меня очень полезная. Однако, возник вопрос: а насколько корректно сравнение вещественных чисел в этом куске кода?

Да, вы правы так сравнивать нельзя. Справка по MQL5 предлагает воспользоваться следующей функцией:

bool CompareDoubles(double number1,double number2) 
  { 
   if(NormalizeDouble(number1-number2,8)==0) return(true); 
   else return(false); 
  } 

Но даже, если сравнение будет выполнено неправильно, функция FindValue выдаст верный результат 

 
fxsaber:

Статья ценна не алгоритмом Оптимизации (хоть он более, чем не безынтересен), а встроенной в штатный Оптимизатор реализацией. Реализация на данный момент очень нестандартна и даже противоречит некоторым заявлениям разработчиков. Но для понимания этого нужно исходники читать, которые не касаются самого алгоритма Отжига.

Ничто Вам не мешает подобным образом встроить свой же алгоритм и показать его плюсы/минусы прямо на советниках, как это сделал Автор.

Это понятно, что статья ценна реализацией управления оптимизацией, но автор делает зачем то сравнение со штатным алгоритмом, да ещё и при мизерном количестве параметров - на это я и попытался сделать упор в своём посте, что со штатным оптимизатором бесполезно тягаться в достаточном для практических целей алготрейдеров диапазоне поискового пространства (количество параметров и их шаг).

А если мутить кастомную оптимизацию то точно не таким способом, потому что "узким горлышком" в скорости является сам тестер, а не АО, а про качество уже было сказано - штатный уже достаточно хорош.