L'apprendimento automatico nel trading: teoria, modelli, pratica e algo-trading - pagina 2
Ti stai perdendo delle opportunità di trading:
- App di trading gratuite
- Oltre 8.000 segnali per il copy trading
- Notizie economiche per esplorare i mercati finanziari
Registrazione
Accedi
Accetti la politica del sito e le condizioni d’uso
Se non hai un account, registrati
Chiarirò le condizioni per il premio in denaro:
5 crediti alla prima persona che risolve il problema
Termine ultimo per le soluzioni: 30 giugno 2016
C'è un esempio di applicazione di un algoritmo di selezione di tratti informativi per implementare una strategia di trading.
Probabilmente avete letto i miei blog sul Grande Esperimento: https://www.mql5.com/ru/blogs/post/661895
Ed ecco una foto come questa:
Ho cercato di trovare un modello per cinque coppie e rilevare la percentuale di accordi indovinati correttamente su un campione di convalida di 25 anni circa. Non ha funzionato subito. Non ho raggiunto la precisione desiderata per qualsiasi orizzonte di previsione.
Poi, prendiamo solo una coppia, eurusd. Ho trovato una dipendenza del movimento dei prezzi 3 ore avanti su un sottoinsieme dei miei predittori.
Ho ridotto i predittori a una forma categorica e ho iniziato la mia funzione di ricerca di predittori significativi. L'ho fatto proprio ora, mentre ero al lavoro, in 20 minuti.
[1] "1.51%"
> final_vector <- c((sao$par >= threshold), T)
> names(sampleA)[final_vector]
[1] "lag_diff_45_var" "lag_diff_128_var" "lag_max_diff_8_var" "lag_max_diff_11_var" "lag_max_diff_724_var" "lag_sd_362_var"
[7] "output"
Non ho ottenuto la convergenza così rapidamente, ma ho ottenuto qualche risultato al livello dell'uno e mezzo per cento di potere esplicativo.
Il grafico di convergenza (minimizzazione).
Il prossimo passo è la costruzione del modello.
Abbiamo diversi predittori categorici. Costruiamo un "libro di regole" o che tipo di relazione c'è tra i predittori e l'output - lungo o corto in un orizzonte temporale di 3 ore.
Che aspetto ha come risultato:
Vediamo l'asimmetria del numero di acquisti e vendite in ogni linea e il valore corrispondente del p-value del criterio chi-quadro per la corrispondenza della distribuzione 50/50. Selezioniamo solo le righe in cui la probabilità è inferiore a 0,01.
E il codice di tutto l'esperimento, a partire dal momento in cui gli ingressi sono già stati selezionati:
dat_test <- sampleA[, c("lag_diff_45_var"
, "lag_diff_128_var"
, "lag_max_diff_8_var"
, "lag_max_diff_11_var"
, "lag_max_diff_724_var"
, "lag_sd_362_var"
, "output")]
dat_test$concat <- do.call(paste0, dat_test[1:(ncol(dat_test) - 1)])
x <- as.data.frame.matrix(table(dat_test$concat
, dat_test$output))
x$pval <- NA
for (i in 1:nrow(x)){
x$pval[i] <- chisq.test(x = c(x$`0`[i], x$`1`[i])
, p = c(0.5, 0.5))$p.value
}
trained_model <- subset(x
, x$pval < 0.01)
trained_model$concat <- rownames(trained_model)
trained_model$direction <- NA
trained_model$direction [trained_model$`1` > trained_model$`0`] <- 1
trained_model$direction [trained_model$`0` > trained_model$`1`] <- 0
### test model
load('C:/Users/aburnakov/Documents/Private/big_experiment/many_test_samples.R')
many_test_samples_eurusd_categorical <- list()
for (j in 1:49){
dat <- many_test_samples[[j]][, c(1:108, 122)]
disc_levels <- 3
for (i in 1:108){
naming <- paste(names(dat[i]), 'var', sep = "_")
dat[, eval(naming)] <- discretize(dat[, eval(names(dat[i]))], disc = "equalfreq", nbins = disc_levels)[,1]
}
dat$output <- NA
dat$output [dat$future_lag_181 > 0] <- 1
dat$output [dat$future_lag_181 < 0] <- 0
many_test_samples_eurusd_categorical[[j]] <- subset(dat
, is.na(dat$output) == F)[, 110:218]
many_test_samples_eurusd_categorical[[j]] <- many_test_samples_eurusd_categorical[[j]][(nrow(dat) / 5):(2 * nrow(dat) / 5), ]
}
correct_validation_results <- data.frame()
for (i in 1:49){
dat_valid <- many_test_samples_eurusd_categorical[[i]][, c("lag_diff_45_var"
, "lag_diff_128_var"
, "lag_max_diff_8_var"
, "lag_max_diff_11_var"
, "lag_max_diff_724_var"
, "lag_sd_362_var"
, "output")]
dat_valid$concat <- do.call(paste0, dat_valid[1:(ncol(dat_valid) - 1)])
y <- as.data.frame.matrix(table(dat_valid$concat
, dat_valid$output))
y$concat <- rownames(y)
valid_result <- merge(x = y, y = trained_model[, 4:5], by.x = 'concat', by.y = 'concat')
correct_sell <- sum(subset(valid_result
, valid_result$direction == 0)[, 2])
correct_buys <- sum(subset(valid_result
, valid_result$direction == 1)[, 3])
correct_validation_results[i, 1] <- correct_sell
correct_validation_results[i, 2] <- correct_buys
correct_validation_results[i, 3] <- sum(correct_sell
, correct_buys)
correct_validation_results[i, 4] <- sum(valid_result[, 2:3])
correct_validation_results[i, 5] <- correct_validation_results[i, 3] / correct_validation_results[i, 4]
}
hist(correct_validation_results$V5, breaks = 10)
plot(correct_validation_results$V5, type = 's')
sum(correct_validation_results$V3) / sum(correct_validation_results$V4)
Poi, ci sono 49 campioni di convalida, ognuno dei quali copre circa 5 anni. Convalidiamo il modello su di loro e contiamo la percentuale di direzioni commerciali indovinate correttamente.
Vediamo la percentuale di operazioni indovinate correttamente per campioni e l'istogramma di questo valore:
E contare quanto in totale abbiamo indovinato la direzione del trade su tutti i campioni:
> sum(correct_validation_results$`total correct deals`) / sum(correct_validation_results$`total deals`)
[1] 0.5361318
Circa il 54%. Ma senza considerare che dobbiamo superare la distanza tra Ask & Bid. Cioè, la soglia secondo il grafico di cui sopra è circa il 53%, supponendo che lo spread = 1 pip.
Cioè, abbiamo inventato un modello semplice in 30 minuti, che è facile da codificare nel terminale, per esempio. E non è nemmeno un comitato. E ho cercato dipendenze per 20 minuti invece di 20 ore. Tutto sommato, c'è qualcosa.
E tutto grazie alla giusta selezione di attributi informativi.
E statistiche dettagliate per ogni campione valido.
Tutti i dati grezzi sono disponibili ai link del blog.
E questo modello non è molto redditizio. MO è a livello di mezzo punto. Ma questa è la direzione che sto prendendo.
Sempre imparando dal passato.
Guardiamo per secoli un grafico. Sia su e vediamo 'tre soldati', poi vediamo 'testa e spalle'. Quante di queste cifre abbiamo già visto e crediamo in queste cifre, commerciamo...
E se il compito è impostato in questo modo
1. trovare automaticamente tali figure, non a tutti i grafici, ma a una coppia di valute particolare, quelle che si sono verificate di recente, non tre secoli fa nel commercio del riso giapponese.
2) I dati iniziali su cui cerchiamo automaticamente tali figure - modelli.
Per rispondere alla prima domanda, consideriamo l'algoritmo chiamato "foresta casuale". L'algoritmo prende le quotazioni di una o più valute, indicatori, incrementi di prezzo - tutto ciò che è stato inventato dall'uomo, come dati di input per il suo funzionamento. 10-5-100-200 ... variabili di input. Poi prende l'insieme dei valori delle variabili che si riferiscono a un punto nel tempo corrispondente a una barra e cerca una combinazione di queste variabili di input che corrisponderebbe sui dati storici a un certo risultato, per esempio, un ordine BUY. E un'altra serie di combinazioni per un altro ordine - VENDERE. Un albero separato corrisponde a ciascuno di questi insiemi. L'esperienza mostra che per un set di input di 18000 barre (circa 3 anni) l'algoritmo trova 200-300 alberi. Questo è l'insieme dei modelli, quasi analoghi di "teste e spalle", e bocche intere di soldati.
Il problema con questo algoritmo è che tali alberi possono raccogliere alcune specificità che non si incontrano in futuro. Questo è chiamato "superfitting" qui nel forum, nell'apprendimento automatico "overfitting". Sappiamo che tutto un grande insieme di variabili di input può essere diviso in due parti: quelle legate alla variabile di output e quelle non legate al rumore. Così Burnakov cerca di eliminare quelli che sono irrilevanti per l'uscita.
PS.
Quando si costruisce un TS di tendenza (COMPRA, VENDI) qualsiasi varietà di vagoni è legata al rumore!
Quello che vedete è una piccola parte del mercato e non la più importante. Nessuno sta costruendo una piramide al contrario.
Quello che vedete è una piccola parte del mercato e non la più importante. Nessuno sta costruendo una piramide al contrario.
Ho provato ad addestrare il neurone sui dati di input, poi ho guardato i pesi. Se i dati di input hanno un peso basso, sembra che non sia necessario. L'ho fatto con R (Rattle), grazie a SanSanych per il suo articolo https://www.mql5.com/ru/articles/1165.
Non ho testato questo approccio nella pratica, mi chiedo se ha funzionato o no. Prenderei l'input_1 input_3 input_5 input_7 input_9 input_11
Ho provato ad addestrare il neurone sui dati di input, poi ho guardato i pesi. Se i dati di input hanno pesi bassi, sembra che non siano necessari. L'ho fatto con R (Rattle), grazie a SanSanych per il suo articolo https://www.mql5.com/ru/articles/1165.
Non ho testato questo approccio nella pratica, mi chiedo se ha funzionato o no. Prenderei l'input_1 input_3 input_5 input_7 input_9 input_11
) hmm. molto interessante.
Domanda chiarificatrice. Perché allora non includete qualche altro ingresso dove il peso è piccolo, per esempio 13, 14, 16? Potresti mostrare un diagramma degli ingressi e dei pesi ordinati per peso?
Scusa, non avevo capito all'inizio. Sì, gli ingressi specificati hanno un grande peso modulo, come dovrebbe essere.
Visivamente, tutti i pesi sono divisi in due gruppi. Se volete dividerli secondo la significatività/non significatività, allora 5,11,7,1,3,9 spiccano chiaramente, questo insieme penso sia sufficiente.