I vostri simboli e i vostri flussi di dati in Metatrader 5 - pagina 11

 

Aggiungerò un'altra funzione di test che contiene due plateau pari di valori massimi:

z = abs(tanh(x) + tanh(y))

z = abs(tanh(x) + tanh(y))

Se si cambia X,Y da -20 a +20 con passo 0,1, l'iterazione completa richiede 160801 iterazioni.

Nel test, entrambi i plateau sono visti in 1400 iterazioni, che è meno dell'uno per cento della ricerca completa.

Qualcuno lo eseguirà su GA? Interessante da confrontare.

 
event:

Aggiungerò un'altra funzione di test contenente due plateau di valori massimi pari:

z = abs(tanh(x) + tanh(y))

Se si cambia X,Y da -20 a +20 con passo 0,1, l'iterazione completa richiede 160801 iterazioni.

Nel test, entrambi i plateau sono visti in 1400 iterazioni, che è meno dell'uno per cento della ricerca completa.

Qualcuno lo eseguirà su GA? Interessante da confrontare.

Non stai cercando con GA?

Lavorare con due argomenti di una funzione ottimizzata non è affatto indicativo. Non solo perché lo spazio di ricerca è piccolo, ma anche perché possono apparire le proprietà "cattive" dell'algoritmo di ricerca stesso.

Convertite la formula in una forma con almeno 10 argomenti e tutte le proprietà positive e negative dell'algoritmo appariranno.

 
joo:

Non stai cercando con i GA?

Lavorare con due argomenti di una funzione ottimizzata non è affatto indicativo. Non solo perché lo spazio di ricerca è piccolo, ma anche perché possono apparire le proprietà "cattive" dell'algoritmo di ricerca stesso.

Convertire la formula in una forma che sarebbe di almeno 10 argomenti - tutte le proprietà positive e negative dell'algoritmo appariranno in una volta sola.

Questo non è GA, c'è un link all'articolo nel thread.

Sopra ho postato un esempio con sei parametri. La difficoltà di visualizzare molti parametri.

Se suggerite una funzione con più parametri - farò un test.

 
event:

Se suggerite una funzione con più parametri - farò un test.

Y=a+b;

dove:

a=Skin(x1, y1)+Skin(x2, y2)+Skin(x3, y3)+Skin(x4, y4)+Skin(x5, y5);

b=Skin(x6, y6)+Skin(x7, y7)+Skin(x8, y8)+Skin(x9, y9)+Skin(x10, y10);

Sapete già dove cercare la funzione Skin.

Quindi ci sono 20 variabili, e la funzione Y è molto facile da visualizzare. Potete usare questo principio per costruire una funzione con un numero illimitato di argomenti, ma essere ancora in grado di visualizzarla.

E di conseguenza, il risultato finale è controllato come Y*2/n contro il valore noto dell'estremo, dove n è il numero totale di argomenti.

 
Laryx:

E puoi farmi un esempio di un algoritmo dove in un "sottosterzo" un sovrasterzo completo è in una dozzina di ore e in MT è in mesi?

È anche realistico avere una ricerca completa più veloce dell'euristica di ottimizzazione. Un attacco di forza bruta completo in MT è rappresentato come un insieme di esecuzioni indipendenti. Infatti è sempre possibile considerare l'ottimizzazione come un unico problema computazionale e applicarvi l'ottimizzazione algoritmica.

In questo approccio la sequenza dei passaggi è di grande importanza, poiché quasi tutti i calcoli sono memorizzati nella cache. Per quasi tutti i parametri di input (tutti indipendenti) di TC ci sono sempre buffer globali nell'ottimizzatore che memorizzano i valori dei passaggi precedenti.

Per esempio, si usa il MA MA e PriceChannel. Per ognuno di questi indicatori hanno i loro parametri di input indipendenti. È per questo che per ogni indicatore si prescrive (poche righe in realtà, con OOP dovrebbe essere ancora più bello) la funzione per riempire il suo buffer globale. Poi confrontiamo l'intensità delle risorse di ogni indicatore (PriceChannel è più pesante di MA). I parametri di input degli indicatori più pesanti cominciano ad essere enumerati nel ciclo esterno (primo for), quelli semplici - nel ciclo interno (in for annidati).

È qui che otteniamo un enorme guadagno. Inoltre, c'è il C++, i calcoli interi e il nostro sistema di ordini senza controlli inutili. È così che si ottiene il risultato. Di conseguenza, le corse singole sono almeno un ordine di grandezza più veloci della MT. E l'ottimizzazione è ordini di grandezza più veloce.

Ciò che manca a MT-optimizer è la funzione OnOptimization che fornirebbe un accesso completo alla matrice ottenuta dei risultati di ottimizzazione. Lì eseguo varie analisi della matrice ottenuta: filtraggio, combinazione di passaggi di un ordine che non si sovrappongono per tempo di scambio, ecc. Ma ciò che è ancora più utile è il calcolo dei coefficienti di peso per ciascuno dei passaggi per comporre un meta-TS sotto forma di un portafoglio appropriato. OnOptimization ha un vettore-Equity per ciascuno dei passaggi non "senza speranza" per questo scopo.

Ma il sottotester non viene inventato nella fase di ricerca di un TS funzionante, ma quando è già stato trovato, purtroppo. La ricerca stessa è una fase completamente diversa: senza una descrizione.
 
event:

Qualcuno lo eseguirà su GA? Interessante da confrontare.

 
joo:

Y=a+b;

dove:

a=Skin(x1, y1)+Skin(x2, y2)+Skin(x3, y3)+Skin(x4, y4)+Skin(x5, y5);

b=Skin(x6, y6)+Skin(x7, y7)+Skin(x8, y8)+Skin(x9, y9)+Skin(x10, y10);

Sapete già dove cercare la funzione Skin.

Quindi ci sono 20 variabili, e la funzione Y è molto facile da visualizzare. Potete usare questo principio per costruire una funzione con un numero illimitato di argomenti, ma essere ancora in grado di visualizzarla.

E di conseguenza, il risultato finale è controllato come Y*2/n contro il valore noto dell'estremo, dove n è il numero totale di argomenti.

cosa spaventosa...)) E puoi spiegare come"la funzione Y è molto facile da visualizzare"?
 
Serj_Che:
Quanti passaggi e a che passo variabile è il calcolo?
 
event:
Quanti passaggi e con quale passo di variabili è il calcolo?

Chi se ne frega se non ti piace la foto?

Il GA a 64 bit in MT5 è molto buono, risolve qualsiasi problema, la cosa principale è formulare il problema correttamente.

Non so di che tipo di nerd state parlando in questo thread su GA.

Non credo che il problema sia con il GA, ma il tester stesso è inutile, soprattutto nello scambio a causa della memorizzazione sbagliata della storia delle quotazioni e l'impossibilità di salvare la propria storia.

Spero che questo problema venga risolto, ma temo che dovrò aspettare 3-5 anni.

 
zaskok:

Per esempio, si usa la MA e PriceChannel. Ognuno di questi indicatori ha i suoi parametri di input indipendenti. Quindi, per ogni indicatore c'è una funzione scritta (poche righe in realtà, con OOP deve essere ancora più bella) che riempie il suo buffer globale corrispondente. Poi confrontiamo l'intensità delle risorse di ogni indicatore (PriceChannel è più pesante di MA). I parametri di input degli indicatori più pesanti cominciano ad essere enumerati sul ciclo esterno (primo for), quelli semplici - sul ciclo interno (nel for annidato).

Qualcosa mi dice che questo approccio potrebbe essere fatto facilmente anche sotto GA. La quantità di lavoro è circa la stessa. Il "ciclo interno" viene rielaborato ad ogni passaggio...

Ma, soprattutto, quanta domanda ci sarebbe? Come sospetto, non tutti usano anche la semplice funzione personalizzata OnTester(). Ma questo è uno strumento di ottimizzazione molto potente.

Ecco, per esempio, una delle mie implementazioni:

double CDoublePeakBottomAdvisorPartsFactory::MyOnTester(CMyExpertT* pmeExpert)
{
   ulong ulTickedTime = pmeExpert.GetTickedTime();
   uint  uiTotalNumberOfSL = pmeExpert.GetNumOfLosePositions();

   double dDDPercent = TesterStatistics(STAT_EQUITY_DDREL_PERCENT);
   double dStartBalance = TesterStatistics(STAT_INITIAL_DEPOSIT);
   double dProfit = TesterStatistics(STAT_PROFIT);
   double dNumOfTrades = TesterStatistics(STAT_TRADES);
   double dNumOfProfitTrades = TesterStatistics(STAT_PROFIT_TRADES);
   double dMaxNumOfSL = TesterStatistics(STAT_MAX_CONLOSS_TRADES);
   double dRecoveryFactor = TesterStatistics(STAT_RECOVERY_FACTOR);
   double dProfitTradesPerWeek = dNumOfProfitTrades/ulTickedTime*SECS_IN_WEEK;
   double dProfitPerDay = dProfit/ulTickedTime*SECS_IN_DAY;
  

   Print("Ticked time (days): ",DoubleToString(ulTickedTime/SECS_IN_DAY,2));

   Print("Number Of Trades: ",DoubleToString(dNumOfTrades,1));

   if(dNumOfTrades == 0)
      {
      Print("Ни одного трейда !");
      return(-100000);
      };


   if(dMaxNumOfSL > uiIMaxNumOfSeqSL)
      return(-10000 - dMaxNumOfSL*100 + dProfit/1000);
  
   
   double dBarsPerTrade = ((double)ulTickedTime/PeriodSeconds(m_didData.m_etTimeFrame))/dNumOfTrades;

   if((bILongAllow == false) || (bIShortAllow == false))
      dBarsPerTrade /= 2;
   
   if(dBarsPerTrade < MIN_BARS_PER_TRADE)
      return(dBarsPerTrade-MIN_BARS_PER_TRADE + dRecoveryFactor);

   Print("Max number Of SL: ",DoubleToString(dMaxNumOfSL,1));

   if(iIMaxNumOfSeqSLForQualify > 0 && dMaxNumOfSL > iIMaxNumOfSeqSLForQualify)
      {
      Print("Слишком много СЛ подряд !");
      return(dRecoveryFactor - (dMaxNumOfSL-iIMaxNumOfSeqSLForQualify)*1000)-10000;
      };

   Print("Bars Per Trade (half): ",DoubleToString(dBarsPerTrade,1));
        
   if(dBarsPerTrade > MAX_BARS_PER_TRADE)
      {
      Print("Слишком редкие трейды !");
      return(dRecoveryFactor - dBarsPerTrade/100);
      };
     

   Print("Profit: ",DoubleToString(dProfit,3));
   Print("Profit per day: ",DoubleToString(dProfitPerDay,3));
   Print("Число СЛ: ",IntegerToString(uiTotalNumberOfSL));


   Print("Приемлемая торговля.");
   
   return(dRecoveryFactor + (1-(uiTotalNumberOfSL/dNumOfTrades))*100);
};

Qui si basa sul fattore di recupero, ma evidenzia le corse con un numero minimo di SL successivi e con scambi abbastanza frequenti.

Tuttavia, per come la vedo io, la maggior parte usa le opzioni standard.