L'apprendimento automatico nel trading: teoria, modelli, pratica e algo-trading - pagina 7

 
Dr.Trader:

Grazie, ho provato. Vedo che hai fatto molto per selezionare i predittori, perché la neuronica si è addestrata facilmente su di essi, e ha memorizzato il risultato anche sul dataset di test.

I risultati seguenti si riferiscono alla formazione su R1.F3

1) C'è un risultato divertente con Rattle. HH con la configurazione standard ha mostrato errori di formazione/convalida/prova del 30%/29%/33%. L'errore su R2.F3 è del 35%. Ma tutto questo è solo un caso fortunato in realtà, in un'altra configurazione avrebbe facilmente sotto- o sovra-allenato, qui ha solo avuto fortuna.

2) Poi ho preso un semplice approccio grezzo con apprendimento non supervisionato, 200 neuroni nascosti, la rete è stata addestrata fino a quando ha smesso di migliorare. Errori di formazione/convalida/test/R2.F3 - 2%/30%/27%/45%. Chiaramente, la rete viene riqualificata.

3) Apprendimento supervisionato. Questo è diverso dagli alberi, ma si dovrebbe sempre fare così con un neurone per non sovrallenarlo. L'essenza è mettere in pausa l'allenamento una volta ogni tanto e controllare i risultati dell'allenamento/validazione/test. Non conosco la regola d'oro della collazione dei risultati, ma è un approccio abbastanza normale per allenarsi sul set di dati del treno, poi cercare gli errori nei set di dati di convalida e test, fermare l'allenamento quando gli errori nella convalida/test smettono di cadere. Questo dà una sorta di garanzia contro il sovrallenamento. R2.F3 è considerato indisponibile durante tutto questo processo, e il test viene fatto solo dopo la fine dell'allenamento. In questo caso gli errori di treno/validazione/test/R2.F3 sono 27%/30%/31%/37%. Anche qui c'è sovrallenamento, ma non molto. Avresti potuto fermare il processo di apprendimento in anticipo dopo che l'errore del treno fosse diventato sensibilmente più piccolo degli errori di convalida/test, ma questo è tirare a indovinare... potrebbe aver aiutato o meno.

La variabile target "R1.F1" ha tre valori, Rattle non può farlo con i neuroni e devi scrivere il tuo codice in R, ho saltato questo dataset.

"R1.F4" "R1.F5" "R1.F6" ha dato circa gli stessi risultati per tutti e 4 gli errori in Rattle neuronka, penso che un approccio adeguato con neuronka darà anche circa gli stessi risultati, non li ho trattati ulteriormente.

Ho numeri simili per Forest e Ada.

Ora, se torniamo ai nostri "arieti" - come scartare il rumore da una lista arbitraria di predittori? Ho un algoritmo empirico che ha selezionato i miei 27 predittori su 170. L'ho anche usato per analizzare i set di predittori di altre persone e anche con successo. Sulla base di questa esperienza, sostengo che tutti i metodi di R che usano variabili di "importanza" nei loro algoritmi non possono eliminare il set di predittori dal rumore.

Faccio appello a tutti i lettori del thread: sono disposto a fare l'analisi appropriata se i dati grezzi sono presentati come RData o un file Excel che non richiede elaborazione.

A parte questo.

In allegato allego una serie di articoli che presumibilmente risolvono il problema di ripulire l'insieme originale dei predittori dal rumore, e con una qualità molto migliore. Purtroppo non ho tempo di provarlo al momento. Forse qualcuno proverà a postare il risultato?

 
SanSanych Fomenko:

In allegato ci sono una serie di articoli che presumibilmente risolvono il problema di ripulire l'insieme originale dei predittori dal rumore, e con una qualità molto maggiore. Purtroppo non ho tempo di provarlo al momento. Forse qualcuno farà una prova e pubblicherà il risultato?

Grazie, ho sfogliato il documento, ma non ho trovato quello che mi serve. Sto cercando di allenare il mio modello per il forex, da qualche parte tra M15 e H4. Non mi basta prendere semplicemente i dati dell'ultima barra, ho bisogno di prenderli per decine di barre contemporaneamente e metterli uno dopo l'altro in un lungo array per gli input del modello. Per esempio (open_bar1, close_bar1, hh_bar1, open_bar2, close_bar2, hh_bar2, open_bar3, close_bar3, hh_bar3,...). Se qualche metodo di selezione mi dirà di rimuovere il tempo della seconda barra, non mi aiuterà, il metodo dovrebbe dirmi di rimuovere per esempio tutti i dati sul tempo (indici 3,6,9...).

Ho capito bene, nel tuo file ALL_cod.RData, puoi usare anche Rat_DF1 per la formazione (specificando il target necessario) e poi usare Rat_DF2 e Rat_DF3 per il controllo? Ho allegato il mio codice in R per chi è interessato, implementa l'addestramento delle reti neurali controllato dagli errori. Per selezionare un'altra variabile di destinazione, potete semplicemente sostituire "Short_Long.75" nel file con qualcosa tra "Short_Long.35", "Flet_Long", "Short_Flet", "Flet_In". È più conveniente che sostituire diverse serie di dati.

File:
 
Dr.Trader:
Sto cercando di addestrare il mio modello per il forex, da qualche parte nella gamma M15-H4. Non mi basta prendere i dati dell'ultima barra, ho bisogno di prenderli per decine di barre in una volta, e metterli uno dopo l'altro in un lungo array per gli input del modello. Per esempio (open_bar1, close_bar1, hh_bar1, open_bar2, close_bar2, hh_bar2, open_bar3, close_bar3, hh_bar3,...). Se qualche metodo di selezione mi dirà che devo rimuovere il tempo della seconda barra, non mi aiuterà, il metodo dovrebbe dirmi che posso rimuovere per esempio tutti i dati temporali (indici 3,6,9...).

mmm I dati temporali possono essere necessari, poiché i mercati funzionano in modo diverso a seconda della sessione.

Guarda il mio set di funzioni forex:

> names(sampleA)

  [1] "lag_diff_2"        "lag_diff_3"        "lag_diff_4"        "lag_diff_6"        "lag_diff_8"        "lag_diff_11"       "lag_diff_16"     

  [8] "lag_diff_23"       "lag_diff_32"       "lag_diff_45"       "lag_diff_64"       "lag_diff_91"       "lag_diff_128"      "lag_diff_181"    

 [15] "lag_diff_256"      "lag_diff_362"      "lag_diff_512"      "lag_diff_724"      "lag_mean_diff_2"   "lag_mean_diff_3"   "lag_mean_diff_4" 

 [22] "lag_mean_diff_6"   "lag_mean_diff_8"   "lag_mean_diff_11"  "lag_mean_diff_16"  "lag_mean_diff_23"  "lag_mean_diff_32"  "lag_mean_diff_45"

 [29] "lag_mean_diff_64"  "lag_mean_diff_91"  "lag_mean_diff_128" "lag_mean_diff_181" "lag_mean_diff_256" "lag_mean_diff_362" "lag_mean_diff_512"

[36] "lag_mean_diff_724" "lag_max_diff_2"    "lag_max_diff_3"    "lag_max_diff_4"    "lag_max_diff_6"    "lag_max_diff_8"    "lag_max_diff_11" 

 [43] "lag_max_diff_16"   "lag_max_diff_23"   "lag_max_diff_32"   "lag_max_diff_45"   "lag_max_diff_64"   "lag_max_diff_91"   "lag_max_diff_128"

 [50] "lag_max_diff_181"  "lag_max_diff_256"  "lag_max_diff_362"  "lag_max_diff_512"  "lag_max_diff_724"  "lag_min_diff_2"    "lag_min_diff_3"  

 [57] "lag_min_diff_4"    "lag_min_diff_6"    "lag_min_diff_8"    "lag_min_diff_11"   "lag_min_diff_16"   "lag_min_diff_23"   "lag_min_diff_32" 

 [64] "lag_min_diff_45"   "lag_min_diff_64"   "lag_min_diff_91"   "lag_min_diff_128"  "lag_min_diff_181"  "lag_min_diff_256"  "lag_min_diff_362"

 [71] "lag_min_diff_512"  "lag_min_diff_724"  "lag_sd_2"          "lag_sd_3"          "lag_sd_4"          "lag_sd_6"          "lag_sd_8"        

 [78] "lag_sd_11"         "lag_sd_16"         "lag_sd_23"         "lag_sd_32"         "lag_sd_45"         "lag_sd_64"         "lag_sd_91"       

 [85] "lag_sd_128"        "lag_sd_181"        "lag_sd_256"        "lag_sd_362"        "lag_sd_512"        "lag_sd_724"        "lag_range_2"     

 [92] "lag_range_3"       "lag_range_4"       "lag_range_6"       "lag_range_8"       "lag_range_11"      "lag_range_16"      "lag_range_23"    

 [99] "lag_range_32"      "lag_range_45"      "lag_range_64"      "lag_range_91"      "lag_range_128"     "lag_range_181"     "lag_range_256"   

[106] "lag_range_362"     "lag_range_512"     "lag_range_724"     "symbol"            "month"             "day"               "week_day"        

[113] "hour"              "minute"            "future_lag_2"      "future_lag_3"      "future_lag_4"      "future_lag_6"      "future_lag_8"    

[120] "future_lag_11"     "future_lag_16"     "future_lag_23"     "future_lag_32"     "future_lag_45"     "future_lag_64"     "future_lag_91"   

[127] "future_lag_128"    "future_lag_181"    "future_lag_256"    "future_lag_362"    "future_lag_512"    "future_lag_724"

Prendo sia i dati delle medie mobili, sia i massimi e i minimi, sia gli spread dei prezzi nella finestra. E il tempo, e i giorni e anche i mesi).

I miei algoritmi possono realisticamente lasciare 10 o anche 5 predittori su 114. Questo è normale. In tali dati c'è una forte correlazione tra i PREDICATORI e quindi c'è una forte ridondanza.

 

Vi darò una breve panoramica del mio metodo per selezionare le caratteristiche informative. Il codice è allegato.

Ci sono due lati della questione - come selezionare i sottoinsiemi e come misurare la rilevanza dei predittori selezionati per la variabile di uscita.

La prima domanda. Lo risolvo con l'enumerazione stocastica delle combinazioni di predittori usando il metodo Simulated Annealing. Simile nei risultati alla genetica e alla discesa a gradiente non deterministica. Il lato positivo è che seleziona dai minimi locali e funziona secondo il principio che è in natura. Può funzionare con una superficie di errore non liscia, ma qui tutto è condizionato.

Per molti problemi i sostenitori del metodo lo considerano migliore della genetica, per esempio. È implementato attraverso un pacchetto in R come standard quasi. Il trucco è che è per dati continui, e ho indici di predittori, quindi faccio un vettore continuo di lunghezza in numero totale di predittori e quando qualsiasi scalare rompe la soglia data l'indice del predittatore diventa uno.

La seconda domanda è ancora più sottile. Funzione di fitness.

Come misurare che il predittore (e l'insieme dei predittori) influenza l'output. La dipendenza può essere non lineare. La regressione standard può ottenere grandi ritardi su alcuni problemi non lineari. Non sto parlando di formazione in scatola nera e di usare uno stimatore d'importanza incorporato. Sto parlando di un metodo separato.

Bisogna capire che la dipendenza può essere molto complessa e comportare interazioni, ridondanze, di nuovo non linearità. Tutte queste cose possono essere applicate sia ai dati categorici che a quelli numerici.

Ho optato per i dati categorici, dato che ci sono buoni strumenti di teoria dell'informazione per questo. Per dirla in modo semplice: c'è un input e un output. Se lo stato dell'output dipende almeno un po' dall'input (probabilisticamente), allora sono dipendenti. C'è una cosa chiamata informazione reciproca. Misura questo.

Ora vai più a fondo. VI misura qualcosa sulla distribuzione osservata su un campione di dimensioni finite. Questa è ovviamente una stima puntuale.

Quindi abbiamo bisogno di stimare i limiti statistici dell'informazione nel caso di una coppia input-output indipendente. Questo viene fatto da una funzione scritta in proprio utilizzando metodi numerici.

Ancora più in profondità. Se abbiamo due o più predittori - cosa fare con loro?

In primo luogo, essi stessi possono essere correlati e più sono correlati, maggiore sarà la ridondanza nel loro insieme. Questa ridondanza è misurata dalla cosiddetta multi-informazione. Ma la multinformazione è anche una stima puntuale su un campione. Per esso il quantile della distribuzione è anche calcolato numericamente attraverso un'altra funzione autoscritta.

In secondo luogo, il numero di livelli di categorie di predittori può essere così grande (diciamo, 2 ^ 15) che non si può dire nulla sulla dipendenza a questi livelli. Ci sono pochissime osservazioni per livello.

Infine, quando tutto questo è fatto e messo insieme, possiamo misurare qualsiasi tipo di dipendenza su un numero arbitrario di predittori e uscite, su una dimensione arbitraria del campione con significatività statistica predeterminata. Le funzioni sottostanti sono prese dal pacchetto Information Theory.

È tutto nel file allegato. Certo, non è facile capirlo senza 100 grammi. C'è anche il codice completo per la creazione di regole di trading e la loro convalida. Tutto per la vostra informazione e per approfondire la vostra conoscenza.

Fondamentalmente, il risultato è il solito:

[1] "1.69%"

> final_vector <- c((sao$par >= threshold), T)

> names(sampleA)[final_vector]

 [1] "lag_diff_23"      "lag_diff_45"      "lag_mean_diff_2"  "lag_mean_diff_8"  "lag_max_diff_11"  "lag_max_diff_181" "lag_min_diff_3"   "lag_min_diff_724"

 [9] "lag_sd_724"       "lag_range_32"     "symbol" "future_lag_181"  

Dopo un giorno e mezzo di lavoro e l'enumerazione di decine di migliaia di combinazioni di predittori, la funzione emette un valore di funzione fitness - questa è un'informazione reciproca significativa penalizzata per la ridondanza nel set di predittori. E gli stessi predittori.

Tutto questo, ripeto, è categorico e permette la costruzione di regole leggibili dall'uomo. Permette l'interpretazione del modello trovato.

Per esempio, sopra ho l'1,7% di determinismo completo (che non è male per il Forex) e un sacco di input che insieme significativamente al livello di confidenza 0,1 (ho messo l'esperimento in questo modo) determinano lo stato di uscita (binario). Cioè, chiaramente le informazioni nei dati forex sono presenti. La questione è sperimentalmente provata.

Dopo di che possiamo valutare la redditività della convalida e codificare il sistema di trading.

Alexey

 
Dr.Trader:


Ho capito bene che nel tuo file ALL_cod.RData puoi anche usare Rat_DF1 per la formazione (specificando il target desiderato) e poi usare Rat_DF2 e Rat_DF3 per il controllo? Ho allegato il mio codice in R per chi è interessato, implementa l'addestramento delle reti neurali controllato dagli errori. Per selezionare un'altra variabile di destinazione, potete semplicemente sostituire "Short_Long.75" nel file con qualcosa tra "Short_Long.35", "Flet_Long", "Short_Flet", "Flet_In". Questo è più conveniente che sostituire diverse serie di dati.

Sì. Esattamente per la comodità del sonaglio.

Un'altra sfumatura.

Tutte le variabili obiettivo sono derivate da due ZZ: ZZ(35) e ZZ(25). Ed ecco una sfumatura molto sgradevole che risuona con la vostra.

La variabile obiettivo è una sequenza di 0 e 1, che corrisponde al braccio ZZ. Ma noi prevediamo SEMPRE un singolo elemento del braccio ZZ, non il braccio stesso. Quindi non è corretto dire che stiamo prevedendo delle tendenze. È corretto dire che stiamo prevedendo un elemento di una tendenza. E se si sommano tutti gli elementi di tendenza previsti, la tendenza probabilmente non funzionerà.

 

Grazie per feature_selector_modeller.zip, ci darò un'occhiata.

SanSanych Fomenko:

Mi rivolgo a tutti i lettori del ramo: sono pronto a fare l'analisi corrispondente, se i dati iniziali saranno presentati sotto forma di RData o file Excel, che non richiede elaborazione.

Ho allegato il file, è una serie di dati da forex. All'interno di RData con due set di dati, per la formazione e per la convalida. Fisicamente i dati nei due set di dati corrono uno dietro l'altro, sono divisi in due file solo per la comodità di testare il modello. Il modello su questo dataset può essere addestrato, ho setacciato manualmente i predittori e ho addestrato il neurone, alla fine l'errore minimo sul dataset di validazione è stato del 46%, che non è proprio redditizio. Si può pensare a un vero profitto se l'errore scende sotto il 40%. Prova a setacciare i predittori da questo file per favore.

SanSanych Fomenko:

La variabile obiettivo è una sequenza di 0 e 1, che corrisponde alla leva ZZ. Ma noi prevediamo SEMPRE un singolo elemento del braccio ZZ, non il braccio stesso. Quindi non è corretto dire che stiamo prevedendo delle tendenze. È corretto dire che stiamo prevedendo un elemento di una tendenza. E se sommate tutti gli elementi di tendenza previsti, probabilmente non otterrete nemmeno una tendenza.

Ho provato diverse variabili di destinazione. Da un lato, si può prevedere il prezzo una barra prima e poi la variabile target sarà 1 o 0 a seconda che il prezzo della prossima barra sia al rialzo o al ribasso. Non ho mai ottenuto alcun risultato sui piccoli timeframe, sembra che il prezzo di chiusura sia un numero piuttosto casuale su di essi. Ma su H1 e oltre c'è già qualche risultato positivo.

Un'altra variante è lo zigzag o altri indicatori di tendenza. Ho ottenuto alcuni risultati positivi con esso, ma a condizione di passare il risultato attraverso il filtro. Per esempio, prendere la media dei risultati delle ultime barre o usare i risultati solo al di sopra di un certo valore di soglia. Secondo me, non vale la pena applicare tutto questo, sono più congetture che calcoli precisi. Il problema è che il modello è tenuto a dare solo segnali di acquisto per le prossime 10-20 barre, mentre a volte dà segnali di vendita tra di loro. In tal caso l'affare viene invertito, la commissione e lo spread vengono pagati, e così via diverse volte per tendenza. Pertanto, dovremmo ottenere un'alta precisione o smussare i risultati per evitare tali inversioni su una sola barra. Cioè, come hai detto tu, solo un elemento di una tendenza è previsto; la tendenza stessa non può essere composta da tali elementi.

File:
set56.RData.zip  525 kb
 
Dr.Trader:


Ho provato diverse variabili di destinazione. Da un lato, si può prevedere il prezzo una barra prima e poi la variabile target sarà 1 o 0 a seconda che il prezzo della barra successiva sia salito o sceso. Non ho mai ottenuto alcun risultato sui piccoli timeframe, il prezzo di chiusura sembra essere un numero piuttosto casuale su di essi. Ma su H1 e oltre c'è già qualche risultato positivo.


I miei risultati sono costantemente l'opposto. Posso facilmente prevedere il movimento dei prezzi qualche minuto prima (fino a un'ora) con una precisione del 55% (Ask to Ask). Miglior risultato per 23 minuti. È una classificazione binaria su campioni di convalida.

E man mano che l'orizzonte di previsione aumenta, la precisione scende lentamente fino al 51% a 12 ore avanti. E questa dipendenza è presente in tutta la storia. Ma la precisione deve essere ancora maggiore per arrivare al lato positivo (per superare la distanza Ask - Bid).

Ne parleremo più tardi.

 
Dr.Trader:

Grazie per il feature_selector_modeller.zip, lo esaminerò.

Ho allegato il file, è un set di dati forex. All'interno di RData con due set di dati, per la formazione e per la convalida. Fisicamente i dati nei due set di dati si susseguono, sono divisi in due file solo per la comodità di testare il modello. Il modello su questo dataset può essere addestrato, ho setacciato manualmente i predittori e ho addestrato il neurone, alla fine l'errore minimo sul dataset di validazione è stato del 46%, che non è proprio redditizio. Si può pensare a un vero profitto se l'errore scende sotto il 40%. Prova a setacciare i predittori da questo file per favore.


Non ho trovato un singolo predittore - sono tutti rumori. I tuoi predittori non hanno potere predittivo per la tua variabile obiettivo. Alcuni suggerimenti 54,55,56. Potresti essere in grado di ottenere qualcosa da loro... Altrimenti, per quanto mi riguarda, tutto può essere buttato via.
 
Capisco, grazie, cercherò altri input.
 
Dr.Trader:
Capisco, grazie, cercherò altri dati grezzi.

Aspettate. Controllerò anche i tuoi dati per le dipendenze.

Una domanda prima di iniziare. I tuoi dati includono tutte le barre in una riga, o c'è stato uno sfoltimento delle barre prima di fare i campioni?

Motivazione: