Announcement

Collapse
No announcement yet.

funzione di fitness CUSTOM per le ottimizzazioni

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    funzione di fitness CUSTOM per le ottimizzazioni

    Dal 2014 Metatrader4

    permette di customizzare la funzione di fitness per le ottimizzazioni con il tester di Mt4
    . onTester_result1.png







    Per creare questa funzione di fitness si usa la funzione double OnTester()
    Ed il suo valore viene visualizzato nella lista dei risultati dell’ottimizzazione sotto il nome OnTester result

    Ad esempio, se voglio visualizzare, nei risultati dell’ottimizzazione, una colonna che contenga il valore di sintesi:
    Profit Factor + Profitto totale / DrawDown

    basta scrivere nel trading system la funzione double OnTester() che restituisca questo valore

    PHP Code:
    double OnTester()
      {
       
    double ProfitFactor     TesterStatistics(STAT_PROFIT_FACTOR);
       
    double TotalNetProfit   TesterStatistics(STAT_PROFIT);
       
    double MaximalDrawdown  TesterStatistics(STAT_EQUITY_DD);
       
    double miaFitness ProfitFactor TotalNetProfit/MaximalDrawdown;

       return(
    miaFitness);
      } 

    e la funzione OnTester() viene automaticamente richiamata al termine di ogni backtest sui dati storici.


    Quando ottimizziamo, nei risultati, troviamo per ogni backtest il valore double restituito dalla funzione, che viene visualizzata nel campo OnTester result onTester_result2.png




    La vita non è un giro di prova, cogli l’attimo..
    Realizzazione per Metatrader4 di trading system, indicatori, pattern grafici, Ottimizzazioni IS-OOS su Forex e CFD, Analisi di Portafoglio .

    #2
    Solo per amanti della funzione CUSTOM, e della programmazione in metaquote language4...

    la visualizzazione negli Optimization Results della DEVIAZIONE STANDARD, grazie alla funzione OnTester() con il seguente codice


    PHP Code:

    double OnTester
    ()
      {
       
    double DeviazioneStandard=0
       
    double totaleTrades TesterStatistics(STAT_TRADES);
       
    double expectedPayoff TesterStatistics(STAT_EXPECTED_PAYOFF);
       
    double profittoTrade=0;
       
    double scostamentoProfittodaExpPayoff=0;
       
    int ihstTotal=OrdersHistoryTotal();
       for(
    i=0i<hstTotali++)
         {
          if (
    OrderSelect(i,SELECT_BY_POS,MODE_HISTORY))
            {
             
    profittoTrade OrderProfit()+OrderCommission()+OrderSwap();
             
    scostamentoProfittodaExpPayoff scostamentoProfittodaExpPayoff MathPow(profittoTrade-expectedPayoff,2);  // Sommatoria (Xi - M)^2
            
    }
         }
       
    DeviazioneStandard MathSqrt(scostamentoProfittodaExpPayoff/totaleTrades);
      
       return(
    DeviazioneStandard);
      } 
    La vita non è un giro di prova, cogli l’attimo..
    Realizzazione per Metatrader4 di trading system, indicatori, pattern grafici, Ottimizzazioni IS-OOS su Forex e CFD, Analisi di Portafoglio .

    Comment


      #3
      Mi sarebbe veramente utile, ma purtroppo non saprei da dove iniziare. :-(
      Non ho neanche capito su quale file provare a metter mano.

      Comment


        #4
        dove codificare è di per se semplice ed intuitivo: dentro la funzione OnTester() da inserire in fondo a qualsiasi trading system...ma necessita di buona conoscenza dell linguaggio di programmazione metaquote language.
        La vita non è un giro di prova, cogli l’attimo..
        Realizzazione per Metatrader4 di trading system, indicatori, pattern grafici, Ottimizzazioni IS-OOS su Forex e CFD, Analisi di Portafoglio .

        Comment


          #5
          Grazie grazie grazie, ha funzionato alla perfezione.
          Di programmazione non ci capisco nulla, ma a copiare sono sempre stato forte. :-)

          Allego questo custum magari può tornar utile, spero di averlo scritto bene, a funzionare funziona ed anche il calcolo torna.


          double OnTester()
          {
          double ProfittoLordo = TesterStatistics(STAT_GROSS_PROFIT);
          double OperazioniConProfitto = TesterStatistics(STAT_PROFIT_TRADES);
          double MediaConProfitto = ProfittoLordo/OperazioniConProfitto ;
          double PerditaLorda = TesterStatistics(STAT_GROSS_LOSS);
          double OperazioniInPerdita = TesterStatistics(STAT_LOSS_TRADES);
          double MediaInPerdita = PerditaLorda/OperazioniInPerdita;
          double PercentualeProfitto = ((OperazioniConProfitto*100)/(OperazioniConProfitto+OperazioniInPerdita));
          double DivergenzaDiGuadagno = (PercentualeProfitto-(100/((MediaConProfitto/(MediaInPerdita*-1))+1)));
          return(DivergenzaDiGuadagno);
          }






          Comment


            #6
            Chiedo scusa in anticipo su come è scritto il codice, è la prima volta che scrivo qualcosa.
            Spero che questo progetto possa andare avanti e che qualcuno riscriva il codice in modo migliore. penso ci voglia veramente poco :-)

            Scritto male e forse funzionante!!! :-(

            L'idea è questa trovare dei custom più o meno giusti e scriverli in un unico codice, scegliendo la custom preferita all'interno del set dell'EA.
            Trovare un sistema in modo da poter con il tempo implementare nuovi custom ed agganciarli nella maniera più facile possibile.
            Visto che non tutti i parametri sono visualizzabili ed ordinabili nella schermata Risultati dell'ottimizzazione come spiegato molto bene da Umberto qui: https://www.forexdream.net/forum/trad...ottimizzazione
            si potrebbe pensare di far scartare alcuni valori durante un ottimizzazione.


            Ecco il codice forse questa volta funziona :-(:


            PHP Code:
            extern string StringCustom_1 "-----Inizio Parametri Custom----------";
            extern string StringCustom_2 "1=FitnessUmberto - 2 Deviazione Standard - 3 Divergenza di Guadagno - 4 AltraFitness";
            extern int ScegliCustom =1// Sarebbe bello un menù a tendina ma non sono capace
            extern double MaxProfictFactor =100;
            extern double MinProfictFactor =-100;
            extern double MaxGrandeOperazioneInPerdita =1000;
            extern double MaxMediaOperazioneInPerdita =1000;
            extern double MaxStrisciaOperazioneInPerdita =10000;
            extern int MaxNumeroOperazioneInPerdita =100;
            double FitnessCustom=0;
            extern string StringCustom_3 "-----Fine Parametri Custom----------";

            double OnTester()
              {
               if (
            ScegliCustom == 1)
                 {
                  
            double ProfitFactor1 TesterStatistics(STAT_PROFIT_FACTOR);
                  
            double TotalNetProfit1 TesterStatistics(STAT_PROFIT);
                  
            double MaximalDrawdown1 TesterStatistics(STAT_EQUITY_DD);
                  
            double FitnessCustom1 ProfitFactor1 TotalNetProfit1/MaximalDrawdown1;
                  
                  if (
            TesterStatistics(STAT_PROFIT_FACTOR)> MaxProfictFactor && FitnessCustom1 )FitnessCustom1 1;
                  if (
            TesterStatistics(STAT_PROFIT_FACTOR)< MinProfictFactor && FitnessCustom1 )FitnessCustom1 1;
                  if (
            TesterStatistics(STAT_MAX_LOSSTRADE)*-1MaxGrandeOperazioneInPerdita && FitnessCustom1 )FitnessCustom1 1;
                  if (((
            TesterStatistics(STAT_GROSS_LOSS)*-1)/(TesterStatistics(STAT_LOSS_TRADES)))> MaxMediaOperazioneInPerdita && FitnessCustom1 )FitnessCustom1 1;
                  if (
            TesterStatistics(STAT_CONLOSSMAX)*-1MaxStrisciaOperazioneInPerdita && FitnessCustom1 )FitnessCustom1 1;
                  if (
            TesterStatistics(STAT_CONLOSSMAX_TRADES)> MaxNumeroOperazioneInPerdita && FitnessCustom1 )FitnessCustom1 1;
                  
                  if (
            TesterStatistics(STAT_PROFIT)< && FitnessCustom1 )FitnessCustom1 0;
                  
            FitnessCustom=FitnessCustom1;
                  return(
            FitnessCustom);
               }
               
               if (
            ScegliCustom == 2)
                 {
                  
            double FitnessCustom2=0;
                  
            double totaleTrades2 TesterStatistics(STAT_TRADES);
                  
            double expectedPayoff2 TesterStatistics(STAT_EXPECTED_PAYOFF);
                  
            double profittoTrade2=0;
                  
            double scostamentoProfittodaExpPayoff2=0;
                  
            int ihstTotal2=OrdersHistoryTotal();
                  for(
            i=0i<hstTotal2i++)
                    {
                     if (
            OrderSelect(i,SELECT_BY_POS,MODE_HISTORY))
                       {
                        
            profittoTrade2 OrderProfit()+OrderCommission()+OrderSwap();
                        
            scostamentoProfittodaExpPayoff2 scostamentoProfittodaExpPayoff2 MathPow(profittoTrade2-expectedPayoff2,2); // Sommatoria (Xi - M)^2
                       
            }
                    }

                  
            FitnessCustom2 MathSqrt(scostamentoProfittodaExpPayoff2/totaleTrades2);
                  if (
            TesterStatistics(STAT_PROFIT_FACTOR)> MaxProfictFactor && FitnessCustom2 )FitnessCustom2 1;
                  if (
            TesterStatistics(STAT_PROFIT_FACTOR)< MinProfictFactor && FitnessCustom2 )FitnessCustom2 1;
                  if (
            TesterStatistics(STAT_MAX_LOSSTRADE)*-1MaxGrandeOperazioneInPerdita && FitnessCustom2 )FitnessCustom2 1;
                  if (((
            TesterStatistics(STAT_GROSS_LOSS)*-1)/(TesterStatistics(STAT_LOSS_TRADES)))> MaxMediaOperazioneInPerdita && FitnessCustom2 )FitnessCustom2 1;
                  if (
            TesterStatistics(STAT_CONLOSSMAX)*-1MaxStrisciaOperazioneInPerdita && FitnessCustom2 )FitnessCustom2 1;
                  if (
            TesterStatistics(STAT_CONLOSSMAX_TRADES)> MaxNumeroOperazioneInPerdita && FitnessCustom2 )FitnessCustom2 1;
                  
                  if (
            TesterStatistics(STAT_PROFIT)< && FitnessCustom2 )FitnessCustom2 0;
                  
            FitnessCustom=FitnessCustom2;
                  return(
            FitnessCustom);
                 }
               
               if (
            ScegliCustom == 3)
                 {
                  
            double ProfittoLordo3 TesterStatistics(STAT_GROSS_PROFIT);
                  
            double OperazioniConProfitto3 TesterStatistics(STAT_PROFIT_TRADES);
                  
            double MediaConProfitto3 ProfittoLordo3/OperazioniConProfitto3 ;
                  
            double PerditaLorda3 TesterStatistics(STAT_GROSS_LOSS);
                  
            double OperazioniInPerdita3 TesterStatistics(STAT_LOSS_TRADES);
                  
            double MediaInPerdita3 PerditaLorda3/OperazioniInPerdita3;
                  
            double PercentualeProfitto3 = ((OperazioniConProfitto3*100)/(OperazioniConProfitto3+OperazioniInPerdita3));
                  
            double FitnessCustom3 = (PercentualeProfitto3-(100/((MediaConProfitto3/(MediaInPerdita3*-1))+1)));
                  
                  if (
            TesterStatistics(STAT_PROFIT_FACTOR)> MaxProfictFactor && FitnessCustom3 )FitnessCustom3 1;
                  if (
            TesterStatistics(STAT_PROFIT_FACTOR)< MinProfictFactor && FitnessCustom3 )FitnessCustom3 1;
                  if (
            TesterStatistics(STAT_MAX_LOSSTRADE)*-1MaxGrandeOperazioneInPerdita && FitnessCustom3 )FitnessCustom3 1;
                  if (((
            TesterStatistics(STAT_GROSS_LOSS)*-1)/(TesterStatistics(STAT_LOSS_TRADES)))> MaxMediaOperazioneInPerdita && FitnessCustom3 )FitnessCustom3 1;
                  if (
            TesterStatistics(STAT_CONLOSSMAX)*-1MaxStrisciaOperazioneInPerdita && FitnessCustom3 )FitnessCustom3 1;
                  if (
            TesterStatistics(STAT_CONLOSSMAX_TRADES)> MaxNumeroOperazioneInPerdita && FitnessCustom3 )FitnessCustom3 1;
                  
                  if (
            TesterStatistics(STAT_PROFIT)< && FitnessCustom3 )FitnessCustom3 0;
                  
            FitnessCustom=FitnessCustom3;
                  return(
            FitnessCustom);
                 }
               
               if (
            ScegliCustom == 4)
                 {
                  
            double ProfitFactor4 TesterStatistics(STAT_PROFIT_FACTOR);
                  
            double TotalNetProfit4 TesterStatistics(STAT_PROFIT);
                  
            double MaximalDrawdown4 TesterStatistics(STAT_EQUITY_DD);
                  
            double ProfittoLordo4 TesterStatistics(STAT_GROSS_PROFIT);
                  
            double OperazioniConProfitto4 TesterStatistics(STAT_PROFIT_TRADES);
                  
            double MediaConProfitto4 ProfittoLordo4/OperazioniConProfitto4 ;
                  
            double PerditaLorda4 TesterStatistics(STAT_GROSS_LOSS);
                  
            double OperazioniInPerdita4 TesterStatistics(STAT_LOSS_TRADES);
                  
            double MediaInPerdita4 PerditaLorda4/OperazioniInPerdita4;
                  
            double PercentualeProfitto4 = ((OperazioniConProfitto4*100)/(OperazioniConProfitto4+OperazioniInPerdita4));
                  
            double DivergenzaDiGuadagno4 = (PercentualeProfitto4-(100/((MediaConProfitto4/(MediaInPerdita4*-1))+1)));
                  
            double miaFitness4 TotalNetProfit4/MaximalDrawdown4;
                  
            double FitnessCustom4 ProfitFactor4 ProfitFactor4 miaFitness4 DivergenzaDiGuadagno4;
                  
                  if (
            TesterStatistics(STAT_PROFIT_FACTOR)> MaxProfictFactor && FitnessCustom4 )FitnessCustom4 1;
                  if (
            TesterStatistics(STAT_PROFIT_FACTOR)< MinProfictFactor && FitnessCustom4 )FitnessCustom4 1;
                  if (
            TesterStatistics(STAT_MAX_LOSSTRADE)*-1MaxGrandeOperazioneInPerdita && FitnessCustom4 )FitnessCustom4 1;
                  if (((
            TesterStatistics(STAT_GROSS_LOSS)*-1)/(TesterStatistics(STAT_LOSS_TRADES)))> MaxMediaOperazioneInPerdita && FitnessCustom4 )FitnessCustom4 1;
                  if (
            TesterStatistics(STAT_CONLOSSMAX)*-1MaxStrisciaOperazioneInPerdita && FitnessCustom4 )FitnessCustom4 1;
                  if (
            TesterStatistics(STAT_CONLOSSMAX_TRADES)> MaxNumeroOperazioneInPerdita && FitnessCustom4 )FitnessCustom4 1;
                  
                  if (
            TesterStatistics(STAT_PROFIT)< && FitnessCustom4 )FitnessCustom4 0;
                  
            FitnessCustom=FitnessCustom4;
                  return(
            FitnessCustom);
                 }

               else return(
            0);

              } 
            Last edited by PieTra; 04-12-2015, 23:22.

            Comment


              #7
              ottimo lavoro Pierluigi :012.WAsmile:
              La vita non è un giro di prova, cogli l’attimo..
              Realizzazione per Metatrader4 di trading system, indicatori, pattern grafici, Ottimizzazioni IS-OOS su Forex e CFD, Analisi di Portafoglio .

              Comment


                #8
                Grazie Umberto.
                Sarebbe utile implementare quelle che possono essere calcolate da questo ottimo treand
                https://www.forexdream.net/forum/main...=1449238217132
                oltre che aggiungere come da te consigliato il minimo numero di operazioni da far scartare durante l'ottimizzazione, ma questo potrei farlo anche io!!! :03.bigsmile_80_anim
                Last edited by PieTra; 04-12-2015, 23:23.

                Comment


                  #9
                  Siete dei grandi !!

                  Comment


                    #10
                    Nella mia veloce lettura del thread mi sembra manchi una considerazione: il risultato della funzione custom di bontà di un backtest è naturalmente orientato nel verso dei numeri naturali (cioè più alto è meglio è). Ora vi sono dei fattori (ad esempio il drawdown) che invece sono naturalmente orientati nel verso opposto (più basso è meglio è) con delle singolarità assai insidiose (ad esempio il DD 0% parrebbe eccellente ma probabilmente è indice di pochissime trade e quindi di dati di dubbio valore statistico). La formula generale di bontà che andiamo a considerare per l'event OnCustom deve tenere conto di queste cose e deve anche tenere conto della gestione dei segni + e - di eventuali rapporti: il punto è che se la nostra formula contiene una funzione razionale e capita (magari raramente ma capita) che il numeratore e il denominatore siano numeri negativi ecco che il risultato finale sarà positivo, cosa assolutamente deleteria. Queste particolarità sono assai insidiose e magari possono essere aggirabili da analisi visuali dei risultati, ma se uno sviluppa magari un sistema di ottimizzazione automatica che processa una certa serie di risultati c'è il rischio di mettere al lavoro dei set di parametri assolutamente pessimi credendoli eccellenti.
                    La statistica è l'unica scienza esatta!

                    Comment


                      #11
                      certamente, sta al bravo sviluppatore considerare tutte le situazioni, come ad esempio

                      PHP Code:
                      if (TesterStatistics(STAT_TRADES)==0)   return(0);
                      else       
                      DeviazioneStandard MathMax(1,MathSqrt(scostamentoProfittodaExpPayoff/totaleTrades));
                      return(
                      expectedPayoff/DeviazioneStandard
                      La vita non è un giro di prova, cogli l’attimo..
                      Realizzazione per Metatrader4 di trading system, indicatori, pattern grafici, Ottimizzazioni IS-OOS su Forex e CFD, Analisi di Portafoglio .

                      Comment


                        #12
                        Non mi è chiaro come calcoli il valore di scostamentoProfittodaExpPayoff. Così, a senso, sembrerebbe una differenza tra due valori "profitto" e "expected payoff" ma il primo è riferito all'intero backtest mentre il secondo è riferito alla singola trade. E' esatto?
                        La statistica è l'unica scienza esatta!

                        Comment


                          #13
                          è descritto qui, al post numero 2: https://www.forexdream.net/forum/trad...=2018#post2018

                          è la classica formula della deviazione standard, collaudata e verificata nel suo calcolo
                          La vita non è un giro di prova, cogli l’attimo..
                          Realizzazione per Metatrader4 di trading system, indicatori, pattern grafici, Ottimizzazioni IS-OOS su Forex e CFD, Analisi di Portafoglio .

                          Comment


                            #14
                            Ok, ho capito come viene calcolata.
                            Ora il punto è che tu poi la dividi ulteriormente per il numero di trade fatte, cioè meno trade sono fatte più probabile è che quel valore venga alto (e quindi sia maggiore di 1).

                            Il rischio è che, a parità di altri fattori, un BT con 20 trade passi avanti nella classifica della bontà di uno con 200 e questo personalmente mi sembra un azzardo.
                            La statistica è l'unica scienza esatta!

                            Comment


                              #15
                              Certamente il numero minimo di trade è statisticamente fondamentale.
                              Ma quella che ho scritto non è la mia funzione di fitness che uso, è solo una formula di calcolo della deviazione standard.

                              In questo thread ci sono solo esempi di come si può costruire una funzione Custom per le proprie ottimizzazioni.
                              Io uso una mia formula che unisce insieme diversi parametri di sintesi.

                              Riguardo al numero di trades minimi io faccio restituire -1 alla funzione OnTester() se il il numero di trades del backtest non supera un numero mimimo che decido con una variabile esterna, così da poterla variare a piacere a seconda dell'EA usato, timeframe, ecc.
                              La vita non è un giro di prova, cogli l’attimo..
                              Realizzazione per Metatrader4 di trading system, indicatori, pattern grafici, Ottimizzazioni IS-OOS su Forex e CFD, Analisi di Portafoglio .

                              Comment

                              Working...
                              X