Otimize um EA e obtenha o melhor dos otimizados. - página 41

 

Sinal livre - reoptimizado.

Existem atualmente 6 League TS em funcionamento, que me parecem ser as mais otimizadas.

Os resultados atuais dos favoritos da Liga CU estão nas páginas anteriores.

TCs atuais para uma otimização excessiva:

Símbolo Sistema Motivo
1 EURCHF ChnTrendDTS Novo
2 EURCHF ChnTrendSAR Novo
3 EURCHF ChnTrendSP Novo
4 EURCHF ChnFlatSP Novo
5 EURCHF ChnFlatSAR Novo
6 EURCHF ChnFlatRTS Novo
7 EURCHF ChnTrendRTS Novo
8 EURCHF ChnFlatDTS Novo
9 GBPUSD ChnTrendSAR Não permitido SL
10 CADJPY ChnFlatSAR Não permitido SL
11 CHFJPY EMAFlatRTS Grande DD
12 USDJPY EMAFlatDTS Long Max Wait


Eu coloquei USDJPY EMAFlatDTS

Período de otimização 4.05.17 - 4.15.18, em diante a partir de 4.10.17

(Como eu otimizo demais - eu corrigirei este posto, e re-otimizarei os TCs, começando com os últimos, para os primeiros)

 
Georgiy Merts:

Sinal livre - reaberto.

Atualmente há 6 TCs da Liga trabalhando lá, o que me parece ser o mais ideal.

Talvez você ainda possa tornar possível escrever resultados de otimização no arquivo? Apenas indicadores padrão não me dão, e eu acho que outros não dão muito.

Aqui está meu conjunto de dados, o que dá o otimizador, mas planejo expandi-lo também.

 
Aleksey Vyazmikin:

Talvez você ainda possa tornar possível a gravação de resultados de otimização em um arquivo? É só que eu, e acho que outros, não me saio muito dos indicadores padrão.

Aqui está meu conjunto de dados fornecido pelo otimizador, mas planejo expandi-lo também.


É claro que tenho todos esses dados dentro de meu consultor especializado. Você sugere que após cada passe eu gere um arquivo desse tipo e o coloque na área de arquivo?

Mas tenho certeza de que muitas pessoas vão olhar para isso?


Mas, digamos, em seu arquivo - eu pessoalmente não percebo esta figura - apenas "não consigo ver a floresta para as árvores". Eu olho apenas para as colunas "Fator de Recuperação", e "Falha".

Todos os outros dados são supérfluos para mim, eles não me dizem nada de novo. Creio que é necessário ter o menor número possível de parâmetros em especialistas e o menor número possível de indicadores para avaliação. Eu colocaria tudo em um parâmetro "qualidade", mas vejo que outro parâmetro "sustentabilidade" é necessário.


Você diz "estes são os parâmetros que eu tenho de saída, e eu pretendo expandir este conjunto" - qual é o objetivo?

Mostre-me um exemplo mais concreto - onde você usaria pelo menos um terço dessas colunas, que você produz? Você é exatamente como o participante de um tópico vizinho, que escreveu um maravilhoso motor de tela, que exibe efeitos visuais maravilhosos no gráfico... Mas ele não pensou sobre o uso prático dessas características. A obtenção de quaisquer dados deve ser de alguma utilidade particular, deve ser parte de uma metodologia particular de seleção ou operação de TC. E "só para ter"... Estes recursos são melhor gastos na re-optimização adicional de sistemas externos ou de novos sistemas.

Em idéia, é claro, é possível se preocupar com a saída do arquivo. Bem, se haverá pelo menos mais alguns votos de que os três parâmetros - qualidade, sorteio e fila SL não são suficientes - bem, faça tal arquivo, e exibirá seus dados nos relatórios.

 

TCs atuais para uma otimização excessiva:

Símbolo Sistema Motivo
1 EURCHF ChnTrendSAR Novo
2 EURCHF ChnTrendSP Novo
3 EURCHF ChnFlatSP Novo
4 EURCHF ChnFlatSAR Novo
5 EURCHF ChnFlatRTS Novo
6 EURCHF ChnTrendRTS Novo
7 EURCHF ChnFlatDTS Novo
8 GBPUSD ChnTrendSAR Não permitido SL
9 EURCHF EMATrendSP Muitos SL
10 GBPAUD EMAFlatRTS Grande DD
11 CADJPY ChnFlatSAR Não permitido SL
12 CHFJPY EMAFlatRTS Grande DD
13 GBPNZD EMAFlatSAR Long Max Wait


Eu tenho um GBPNZD EMAFlatSAR

Período 5.05.17 - 5.05.18, em diante a partir de 5.10.17

 

Situação atual sobre os favoritos

(Todos os TCs trabalham em demonstração sem MM, com lotes mínimos)

Top 20 por qualidade:

Tabela dos 10 melhores em qualidade:

Melhor 20 por equilíbrio:

Os 10 melhores gráficos por balanço:

Apenas um lembrete, o Trading Systems League Expert (versões tanto para MT4 como MT5) está no disco Yandex. No arquivo também foi anexada uma breve descrição dos princípios da Liga e uma lista de TS, trabalhando nela.

Por padrão, a Liga trabalha com um TS (EURUSD ChnTrendSAR, magik 220141) sem nenhuma restrição.

Outros trabalhos de TS somente no testador de estratégia. Para seu trabalho em uma demonstração ou códigos reais de registro de conta são necessários. Os códigos de registro, válidos por 3 meses com um link para o número da conta, são emitidos para otimizar os sistemas individuais da Liga (2-5 horas em um quad-core Core i5).

EALeague
EALeague
  • yadi.sk
View and download from Yandex.Disk
 
Georgiy Merts:


É claro que tenho todos estes dados dentro do Expert Advisor. Você está sugerindo gerar tal arquivo após cada passe, e jogá-lo na área de arquivo?

Mas tenho certeza de que muitas pessoas vão olhar para isso?

Você diz: "estes são os parâmetros que exibo, e ainda pretendo expandir este conjunto" - qual é o propósito?

Mostre-me um exemplo mais concreto - onde você usaria pelo menos um terço das colunas que você produz?

Em teoria, é claro, a saída do arquivo é possível. Bem, se haverá pelo menos mais alguns votos de que os três parâmetros - qualidade, subsidência e fila SL não são suficientes - bem, faça tal arquivo, e exibirá seus dados nos relatórios.

Deixe-me colocar desta forma: de repente fiquei curioso para ver que tipo de Expert Advisors eu estava otimizando, mas sem conhecer seu algoritmo exato, decidi focar em seu desempenho e de repente percebi que não podia avaliar os resultados devido à escassez de indicadores estatísticos.

Você diz que os participantes do projeto devem fazer a seleção eles mesmos, mas isto não é realista com base nos dados disponíveis.

Agora estou trabalhando em um sistema de avaliação mecânica - a idéia principal é equilibrar todos os indicadores, não apenas seu valor absoluto, o que, naturalmente, é igualmente importante.

Por exemplo, uso freqüentemente a fórmula "Rendimento"-"Lucro Máximo Contínuo "*3-"Despesa"-"Perda Máxima Contínua "*3 para estimar lucros, e se ainda estivermos no "plus", olhamos mais além, mas também nesta fase podemos peneirar muito.

E, o drawdown só percebo em termos naturais, pois a porcentagem depende dos lucros acumulados no momento do drawdown, mas isto não pode dizer nada, pois não há garantia de que da próxima vez este drawdown também ocorrerá, somente após os lucros acumulados. Por exemplo, um drawdown de 10% com um capital inicial de 1000 é de 10 unidades, e se 10% com um lucro de 2000, já são 30 unidades, concordam que os números não são comparáveis. O significado da porcentagem somente se a retirada de fundos a cada dia, mas se você implementá-la, então outros indicadores são rastejantes, que são calculados automaticamente, então você tem a cada número por si mesmo, o que é problemático.

Posso lhe dar meu código para escrever dados em um arquivo, se você ainda não o fez antes.

 
Aleksey Vyazmikin:

Posso lhe dar meu código para escrever dados em um arquivo, se você ainda não o fez antes.

Você não deveria ter desistido do Skype. Você poderia ter olhado para o código e ter trabalhado a melhor maneira de fazer isso.

Vá lá, de que indicadores você precisa?

E em que momento deve ser produzido pelo consultor especializado? Como eu entendo - na função OnTester()? Eu farei de você uma função assim. Ele emitirá um arquivo CSV, que pode ser facilmente aberto em Excel.


E de que Expert Advisor estamos falando, o principal Expert Advisor da Liga, ou EAs separados para TS diferentes?

 
Georgiy Merts:

Você não deveria ter desistido do Skype. Você poderia ter olhado para o código e pensado na melhor maneira de fazer isso.

Vá lá, de que indicadores você precisa?

E em que momento deve ser produzido pelo Consultor Especialista? Como eu entendo - na função OnTester ()? farei com que você seja um especialista.


Ah, e de que EA estamos falando aqui - o principal Conselheiro Especialista da Liga, ou EAs separados para TS diferentes?

Tenho-o organizado desta forma

//--- Кол-во показателей для записи в файл
#define  STAT_VALUES_COUNT 21
double stat_values[STAT_VALUES_COUNT]; // Массив для показателей теста


//+------------------------------------------------------------------+
//| Начало оптимизации                                               |
//+------------------------------------------------------------------+
void OnTesterInit()
  {
      //FileWrite(Statistic,"typeMAH","pMAH","pipsXH","pMAT_Sell","CalcPlan","FinRezultatTotalSell","avrMassSell","MaxOrdersSell","N_Sell","ProcTotalSell","Вершин Sell","FinRezultatTotalBuy","avrMassBuy","MaxOrdersBuy","N_Buy","ProcTotalBuy","Вершин Buy");
      //Printer.Write("OnTesterInit");

      string TimeF=TimeToString(TimeLocal(),TIME_DATE|TIME_MINUTES);
      StringSetCharacter(TimeF,13,'_');    
      Statistic=Printer.FileCreate(Symbol()+"_"+TimeF+"_S&G","S&G\\Test",false,false,EvryTick); //Создание файла для записи     
      Printer.Write("N",
      "Депо",
      "Прибыль",
      "Доход",
      "Расход",
      "Прибыльность",
      "Фактор вост.",
      "Мат ож",
      "К.Ш.",
      "Макс ДД баланса",
      "Макс ДД средств",
      "N сделок",
      "N трейдов",
      "N + трейдов",
      "N - трейдов",
      "Sell трейдов",
      "Buy трейдов",
      "Sell + трейдов",
      "Buy + трейдов",
      "Avr + трейдов",
      "Avr - трейдов",
      "% Sell от прибыльных",
      "% Buy от прибыльных",
      "% Sell от всех",
      "% Buy от всех",      
      "% + от всех",
      "Custom"            
      );
  }
//+------------------------------------------------------------------+
//| Обработчик события окончания тестирования                        |
//+------------------------------------------------------------------+
double OnTester()
  {

  
      //--- Заполним массив показателями теста
      GetTestStatistics(stat_values);
      //--- Создадим фрейм
      FrameAdd("Statistics",1,0,stat_values);

   double custom_Pokazatel_01=CustomPokazatelf(1);

  // return(0.0);
   return(custom_Pokazatel_01);

  }
//+------------------------------------------------------------------+
//| Пользовательские функции                                         |
//+------------------------------------------------------------------+
double CustomPokazatelf(int VariantPokazatel)
{

     double  profit = TesterStatistics(STAT_PROFIT);
     double  max_dd = TesterStatistics(STAT_BALANCE_DD);
   //  double  RecoveryF = TesterStatistics(STAT_RECOVERY_FACTOR);  
     double  Mat_Ojidanie = TesterStatistics(STAT_EXPECTED_PAYOFF);  
     
   double custom_Pokazatel=0;
   //=ЕСЛИ(C3-40000>0;(C3-40000)*(3000-J3);-1)
   //if (profit-40000>0)custom_Pokazatel_01=(profit-40000)*(3000-max_dd);
   //=ЕСЛИ(И(C3-40000>0;3000-J3>0);(C3-40000)*СТЕПЕНЬ(3000-J3;1,5)*H3;0)

   if (VariantPokazatel==1)
      {
      if (profit-Find_Profit>0 && Find_MaxDD-max_dd>0)custom_Pokazatel=(profit-Find_Profit)*MathPow((Find_MaxDD-max_dd),1.5)*Mat_Ojidanie/(Find_Profit+max_dd);
      else custom_Pokazatel=-1;
      }
   return(custom_Pokazatel);
}
//+------------------------------------------------------------------+
//| Очередной проход оптимизации                                     |
//+------------------------------------------------------------------+
void OnTesterPass()
  {

      string name ="";  // Публичное имя/метка фрейма
      ulong  pass =0;   // Номер прохода в оптимизации, на котором добавлен фрейм
      long   id   =0;   // Публичный id фрейма
      double val  =0.0; // Одиночное числовое значение фрейма
      //---
      FrameNext(pass,name,id,val,stat_values);
      //---
     // Print(__FUNCTION__,"(): pass: "+IntegerToString(pass)+"; STAT_PROFIT: ",DoubleToString(stat_values[0],2));
     // double a=stat_values[0];
     // Print ("a=",a);
     // Print(DotToComma(DoubleToString(stat_values[0],2)));
      
      double SellPribl_from_Pribl=0.0;//Процент прибыльных позиций Sell из всех прибыльных
      double BuyPribl_from_Pribl=0.0;//Процент прибыльных позиций Buy из всех прибыльных
      double SellPribl_from_All=0.0;//Процент прибыльных позиций Sell из всех проторгованных
      double BuyPribl_from_All=0.0;//Процент прибыльных позиций Buy из всех проторгованных
      double Pribl_from_All=0.0;//Процент прибыльных позиций из всех проторгованных
      if (stat_values[12]>0) SellPribl_from_Pribl=stat_values[16]/stat_values[12]*100.0;
      if (stat_values[12]>0) BuyPribl_from_Pribl=stat_values[17]/stat_values[12]*100.0;
      if (stat_values[11]>0) SellPribl_from_All=stat_values[16]/stat_values[11]*100.0;
      if (stat_values[11]>0) BuyPribl_from_All=stat_values[17]/stat_values[11]*100.0;
      if (stat_values[11]>0) Pribl_from_All=stat_values[12]/stat_values[11]*100.0;
      
      /*if (pass>0)*/ Printer.Write(IntegerToString(pass),
                              stat_values[0],
                              stat_values[1],
                              stat_values[2],
                              stat_values[3],
                              DoubleToString(stat_values[4],2),
                              DoubleToString(stat_values[5],2),
                              DoubleToString(stat_values[6],2),
                              DoubleToString(stat_values[7],2),
                              stat_values[8],
                              stat_values[9],
                              stat_values[10],
                              stat_values[11],
                              stat_values[12],
                              stat_values[13],
                              stat_values[14],
                              stat_values[15],
                              stat_values[16],
                              stat_values[17],
                              stat_values[18],
                              stat_values[19],      
                              DoubleToString(SellPribl_from_Pribl,2),
                              DoubleToString(BuyPribl_from_Pribl,2),  
                              DoubleToString(SellPribl_from_All,2),
                              DoubleToString(BuyPribl_from_All,2),
                              DoubleToString(Pribl_from_All,2),
                              DoubleToString(stat_values[20],2)
                              );


//--- Если включена запись результатов оптимизации
//      CreateOptimizationReport();

/*

  Print("OnTesterPass");
         Printer.Write("OnTesterPass");
*/

  }
//+------------------------------------------------------------------+
//| Завершение оптимизации                                           |
//+------------------------------------------------------------------+
void OnTesterDeinit()
  {



      FileClose(Statistic);

  }
//+------------------------------------------------------------------+
//| Заполняет массив результатами теста                              |
//+------------------------------------------------------------------+
void GetTestStatistics(double &stat_array[])
  {


stat_array[0]=     TesterStatistics(STAT_INITIAL_DEPOSIT);      //      Значение начального депозита
stat_array[1]=     TesterStatistics(STAT_PROFIT);                //     Чистая прибыль по окончании тестирования, сумма STAT_GROSS_PROFIT и STAT_GROSS_LOSS (STAT_GROSS_LOSS всегда меньше или равно нулю)
stat_array[2]=     TesterStatistics(STAT_GROSS_PROFIT);    //   Общая прибыль, сумма всех прибыльных (положительных) трейдов. Значение больше или равно нулю
stat_array[3]=     TesterStatistics(STAT_GROSS_LOSS);         //        Общий убыток, сумма всех убыточных (отрицательных) трейдов. Значение меньше или равно нулю
stat_array[4]=     TesterStatistics(STAT_PROFIT_FACTOR);           //   Прибыльность – отношение STAT_GROSS_PROFIT/STAT_GROSS_LOSS. Если STAT_GROSS_LOSS=0, то прибыльность принимает значение DBL_MAX
stat_array[5]=     TesterStatistics(STAT_RECOVERY_FACTOR);      //      Фактор восстановления – отношение STAT_PROFIT/STAT_BALANCE_DD
stat_array[6]=     TesterStatistics(STAT_EXPECTED_PAYOFF);      //      Математическое ожидание выигрыша
stat_array[7]=     TesterStatistics(STAT_SHARPE_RATIO);    //   Коэффициент Шарпа
stat_array[8]=     TesterStatistics(STAT_BALANCE_DD);         //        Максимальная просадка баланса в деньгах. В процессе торговли баланс может испытать множество просадок, берется наибольшее значение.
stat_array[9]=     TesterStatistics(STAT_EQUITY_DD);          //        Максимальная просадка средств в деньгах. В процессе торговли средства могут испытать множество просадок, берется наибольшее значение.
stat_array[10]= TesterStatistics(STAT_DEALS);               //  Количество совершенных сделок
stat_array[11]= TesterStatistics(STAT_TRADES);           //     Количество трейдов
stat_array[12]= TesterStatistics(STAT_PROFIT_TRADES);      //   Прибыльные трейды
stat_array[13]= TesterStatistics(STAT_LOSS_TRADES);           //        Убыточные трейды
stat_array[14]= TesterStatistics(STAT_SHORT_TRADES);       //   Короткие трейды
stat_array[15]= TesterStatistics(STAT_LONG_TRADES);              //     Длинные трейды 
stat_array[16]= TesterStatistics(STAT_PROFIT_SHORTTRADES);   // Короткие прибыльные трейды
stat_array[17]= TesterStatistics(STAT_PROFIT_LONGTRADES);          //   Длинные прибыльные трейды
stat_array[18]= TesterStatistics(STAT_PROFITTRADES_AVGCON);  // Средняя длина прибыльной серии трейдов
stat_array[19]= TesterStatistics(STAT_LOSSTRADES_AVGCON);          //   Средняя длина убыточной серии трейдов
//stat_array[20]=       TesterStatistics(STAT_CUSTOM_ONTESTER);    //   Custom
stat_array[20]= CustomPokazatelf(1);       //   Custom

  }

Há uma falha no código, ou talvez não no código - às vezes o último frame não vem de todos, mas nem sempre, e às vezes a numeração pode coincidir. Em geral, acho que é uma falha de programa, mas se você vir um bug no código, me diga!


E em que EAs - sim, você pode, e em tudo o que está sujeito a otimização.

 

Hmmm...

Você salva cada teste executado não apenas no arquivo de estatísticas, mas também nos quadros do arquivo MQD? Fiz bem?

Também - eu me pergunto como essa saída para um arquivo irá funcionar no OnTesterPass(), se o passe do testador estiver em Cloud? Em um quadro será escrito, mas em um arquivo, eu suspeito, não.

Alexey, você vai se afogar no fluxo de dados.


Mas, se é tão importante para você - eu posso colocar seu código na TC League.

Seu código é bastante transparente e inteligente, então ele se encaixará quase sem mudanças, só precisarei de algumas pequenas modificações, para que todas as estruturas estejam dentro de minhas classes OOP.

Bem... Farei isso, hoje ou amanhã colocarei seu código na Liga... Mas não vejo como isso possa ser muito útil. Há muitos números, e não podemos ver a floresta para as árvores.

 
Georgiy Merts:

Hmmm...

Você salva cada teste executado não apenas no arquivo de estatísticas, mas também nos quadros do arquivo MQD? Fiz bem?

Alexey, você vai se afogar no fluxo de dados.


Mas, se é tão importante para você - eu posso colocar seu código na TC League.

Seu código é bastante transparente e inteligente, por isso ele se encaixará quase sem mudanças, só vou precisar de alguns ajustes, para que todas as estruturas estejam dentro de minhas classes OOP.

Bem... Farei isso, hoje ou amanhã colocarei seu código na Liga... No entanto, não vejo grande utilidade nisso. Há muitos números, e não podemos ver a floresta para as árvores.

São necessárias molduras para que tudo se recolha da rede - otimizadores (agentes), não estou usando um computador. E assim o código não é meu do zero - eu o eviscerei parcialmente do artigo sobre otimização e o adaptei às minhas necessidades.

No Expert Advisor, você pode fazer uma variável externa, de acordo com a qual as estatísticas serão escritas ou não.

E, você tem poucas variáveis externas em seu EA, ao contrário do meu monstro, então você pode (precisa) escrever o valor das variáveis de uma só vez - ele adicionará algumas linhas no arquivo final, mas permitirá trabalhar com ele em um nível diferente. Agora estou apenas adicionando estes valores ao arquivo à mão, ou seja, estou otimizando em fragmentos.

Razão: