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

 
Dr.Trader:

Ho provato anche la scala Y, R^2 in entrambi i casi (con e senza scala Y) è uscito lo stesso (anche se usano pacchetti diversi!).

Immagino che la scala Y possa dare lo stesso buon risultato con un minor numero di componenti principali. Ma, se anche usando tutti i componenti il risultato non è ancora soddisfacente (come nel mio caso) - non c'è differenza. Inoltre funziona più velocemente, il che è più importante per me ora. Ma non ho provato né con la teoria né con la pratica se questo metodo è adatto alla selezione dei predittori... All'inizio ho avuto l'idea di modellare le componenti principali su tutti i predittori e selezionare i predittori guardando i coefficienti delle componenti. Ma poi ho notato che con l'aggiunta di spazzatura - R^2 del modello scende. Ha senso provare diversi set di predittori e cercare quelli con un R^2 più alto, ma è solo una teoria.

Qui faccio regolarmente il seguente suggerimento: se mi distillate il vostro set, confrontiamo i miei risultati con i vostri.

Per me, l'ideale è .RData. Un frame in cui il target è binario e i predittori sono preferibilmente numeri reali.

 
Dr.Trader:

Ho usato per addestrare la foresta e restituire un errore su un campione di convalida. In linea di principio, ha funzionato - se la foresta si sovrallena anche solo un po', l'errore tende al 50%.

Ora uso GetPCrsquared(), quel codice sopra. Ho anche il tuo esempio da feature_selector_modeller.txt ma devo capirlo e ottenere il frammento di codice necessario, quindi non ho ancora controllato i miei dati.

Ecco cosa devi portare lì:

library(infotheo) # measured in nats, converted to bits

library(scales)

library(GenSA)


#get data

sampleA <- read.table('C:/Users/aburnakov/Documents/Private/dummy_set_features.csv'

, sep= ','

, header = T)




#calculate parameters

predictor_number <- dim(sampleA)[2] - 1

sample_size <- dim(sampleA)[1]

par_v <- runif(predictor_number, min = 0, max = 1)

par_low <- rep(0, times = predictor_number)

par_upp <- rep(1, times = predictor_number)



#load functions to memory

shuffle_f_inp <- function(x = data.frame(), iterations_inp, quantile_val_inp){

mutins <- c(1:iterations_inp)

for (count in 1:iterations_inp){

xx <- data.frame(1:dim(x)[1])

for (count1 in 1:(dim(x)[2] - 1)){

y <- as.data.frame(x[, count1])

y$count <- sample(1 : dim(x)[1], dim(x)[1], replace = F)

y <- y[order(y$count), ]

xx <- cbind(xx, y[, 1])

}

mutins[count] <- multiinformation(xx[, 2:dim(xx)[2]])

}

quantile(mutins, probs = quantile_val_inp)

}



shuffle_f <- function(x = data.frame(), iterations, quantile_val){

height <- dim(x)[1]

mutins <- c(1:iterations)

for (count in 1:iterations){

x$count <- sample(1 : height, height, replace = F)

y <- as.data.frame(c(x[dim(x)[2] - 1], x[dim(x)[2]]))

y <- y[order(y$count), ]

x[dim(x)[2]] <- NULL

x[dim(x)[2]] <- NULL

x$dep <- y[, 1]

rm(y)

receiver_entropy <- entropy(x[, dim(x)[2]])

received_inf <- mutinformation(x[, 1 : dim(x)[2] - 1], x[, dim(x)[2]])

corr_ff <- received_inf / receiver_entropy

mutins[count] <- corr_ff

}

quantile(mutins, probs = quantile_val)

}


############### the fitness function

fitness_f <- function(par){

indexes <- c(1:predictor_number)

for (i in 1:predictor_number){

if (par[i] >= threshold) {

indexes[i] <- i

} else {

indexes[i] <- 0

}

}

local_predictor_number <- 0

for (i in 1:predictor_number){

if (indexes[i] > 0) {

local_predictor_number <- local_predictor_number + 1

}

}

if (local_predictor_number > 1) {

sampleAf <- as.data.frame(sampleA[, c(indexes[], dim(sampleA)[2])])

pred_entrs <- c(1:local_predictor_number)

for (count in 1:local_predictor_number){

pred_entrs[count] <- entropy(sampleAf[count])

}

max_pred_ent <- sum(pred_entrs) - max(pred_entrs)

pred_multiinf <- multiinformation(sampleAf[, 1:dim(sampleAf)[2] - 1])

pred_multiinf <- pred_multiinf - shuffle_f_inp(sampleAf, iterations_inp, quantile_val_inp)

if (pred_multiinf < 0){

pred_multiinf <- 0

}

pred_mult_perc <- pred_multiinf / max_pred_ent

inf_corr_val <- shuffle_f(sampleAf, iterations, quantile_val)

receiver_entropy <- entropy(sampleAf[, dim(sampleAf)[2]])

received_inf <- mutinformation(sampleAf[, 1:local_predictor_number], sampleAf[, dim(sampleAf)[2]])

if (inf_corr_val - (received_inf / receiver_entropy) < 0){

fact_ff <- (inf_corr_val - (received_inf / receiver_entropy)) * (1 - pred_mult_perc)

} else {

fact_ff <- inf_corr_val - (received_inf / receiver_entropy)

}

} else if (local_predictor_number == 1) {

sampleAf<- as.data.frame(sampleA[, c(indexes[], dim(sampleA)[2])])

inf_corr_val <- shuffle_f(sampleAf, iterations, quantile_val)

receiver_entropy <- entropy(sampleAf[, dim(sampleAf)[2]])

received_inf <- mutinformation(sampleAf[, 1:local_predictor_number], sampleAf[, dim(sampleAf)[2]])

fact_ff <- inf_corr_val - (received_inf / receiver_entropy)

} else  {

fact_ff <- 0

}

return(fact_ff)

}



########## estimating threshold for variable inclusion


iterations = 5

quantile_val = 1


iterations_inp = 1

quantile_val_inp = 1


levels_arr <- numeric()

for (i in 1:predictor_number){

levels_arr[i] <- length(unique(sampleA[, i]))

}


mean_levels <- mean(levels_arr)

optim_var_num <- log(x = sample_size / 100, base = round(mean_levels, 0))


if (optim_var_num / predictor_number < 1){

threshold <- 1 - optim_var_num / predictor_number

} else {

threshold <- 0.5

}



#run feature selection


start <- Sys.time()


sao <- GenSA(par = par_v, fn = fitness_f, lower = par_low, upper = par_upp

     , control = list(

      #maxit = 10

        max.time = 1200

        , smooth = F

        , simple.function = F))


trace_ff <- data.frame(sao$trace)$function.value

plot(trace_ff, type = "l")

percent(- sao$value)

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

names(sampleA)[final_vector]

final_sample <- as.data.frame(sampleA[, final_vector])


Sys.time() - start

Nel dataframe, la colonna più a destra è la colonna di destinazione.

TUTTE le colonne devono essere categorie (ineteger, carattere o fattore).

E devi caricare tutte le bibbie.

Un pezzo di codice che mostra come tradurre i numeri in variabili categoriche:

disc_levels <- 3 # сколько равночастотных уровней переменной создается


for (i in 1:56){

naming <- paste(names(dat[i]), 'var', sep = "_")

dat[, eval(naming)] <- discretize(dat[, eval(names(dat[i]))], disc = "equalfreq", nbins = disc_levels)[,1]

}

 

Ho trovato questa interessante funzione su internet

data_driven_time_warp <- function (y) {
  cbind(
    x = cumsum(c(0, abs(diff(y)))),
    y = y
  )
}


y <- cumsum(rnorm(200))+1000
i <- seq(1,length(y),by=10)
op <- par(mfrow=c(2,1), mar=c(.1,.1,.1,.1))
plot(y, type="l", axes = FALSE)
abline(v=i, col="grey")
lines(y, lwd=3)
box()
d <- data_driven_time_warp(y)
plot(d, type="l", axes=FALSE)
abline(v=d[i,1], col="grey")
lines(d, lwd=3)
box()
par(op)

Forse in questa forma l'algoritmo riconoscerà meglio i dati? Ma c'è un problema, l'output della funzione è una variabile "d" e ha una matrice con due colonne "x" e "y", una denota il prezzo e la seconda il tempo percorso dall'algoritmo, la questione è come trasformare questa matrice in un vettore in modo che non perda le sue proprietà

 
SanSanych Fomenko:

Qui faccio regolarmente il seguente suggerimento: se mi trasferisci il tuo set, confronteremo i miei risultati con i tuoi.

Per me, l'ideale è un .RData. Un frame in cui il target binario e i predittori sono preferibilmente numeri reali.

L'ataccamento è il mio miglior set di predittori. TrainData è D1 per eurusd per il 2015, fronttestData è dal 1 gennaio 2016 a giugno. Il fronttest è un po' lungo, nel trading reale è improbabile che io faccia trading per più di un mese con le stesse impostazioni, volevo solo vedere quanto dura davvero la redditività del modello. FronttestData1, fronttestData2, fronttestData3 sono tagli separati da fronttestData, solo per gennaio, solo per febbraio, solo per marzo. Sono davvero interessato solo ad abbassare l'errore su fronttestData1, il resto è solo per la ricerca. Il set di predittori contiene principalmente indicatori e diversi calcoli tra di loro. Con nnet error su fronttest ho il 30% su fronttestData1, formazione con controllo dell'iterazione e numero di neuroni interni adeguato. Penso che il 30% qui sia solo una questione di caso, il modello ha catturato qualche tendenza nel mercato da marzo 2015 a febbraio 2016. Ma il fatto che il resto dei periodi non si unisca è già buono.

Ecco un'immagine da mt5 tester 2014.01-2016.06, ho segnato il periodo di formazione con una cornice. È già meglio di prima :). Per ora questo è il mio limite, devo risolvere molti problemi con gli indicatori, cioè le loro impostazioni di default sono strettamente legate ai timeframe, per esempio su H1 la mia esperienza è completamente inutile, lo stesso algoritmo di selezione degli indicatori su H1 considera tutto spazzatura. Dovrei aggiungere un mucchio di loro variazioni con parametri diversi al set iniziale di indicatori o generare indicatori casuali da ohlc da solo.

 
Alexey Burnakov:

c'è questo da prendere:

Questo ha più senso, grazie. Mi sembra che solo 3 categorie per indicatore non bastino. Logicamente, farei almeno 100 livelli, ma è meglio o si perde il senso dell'algoritmo?

 
Dr.Trader:

Questo ha più senso, grazie. Mi sembra che solo 3 categorie per indicatore non bastino. Logicamente, farei almeno 100 livelli, ma è meglio o fa perdere il senso dell'algoritmo?

L'algoritmo perderà il suo significato. L'algoritmo conta il numero totale di livelli di variabili di input e distribuisce per questi livelli di livelli di risposta. Di conseguenza, se il numero di valori di risposta a ciascuno dei livelli di ingresso è molto basso, sarà impossibile valutare la significatività statistica della distorsione di probabilità.

Se fai 100 livelli, sì, ci saranno molte variabili. Allora l'algoritmo restituirà significatività zero per qualsiasi sottoinsieme, che è ragionevole data la dimensione limitata del campione.

L'esempio è buono.

livelli di ingresso | numero di osservazioni

1 150

2 120

...

9 90

qui possiamo stimare la significatività all'interno di una risposta

L'esempio è pessimo.

livelli di ingresso

112 5

...

357 2

...

1045 1

la significatività all'interno di una risposta non può essere stimata qui

 
Dr.Trader:

L'ataccamento è il mio miglior set di predittori. TrainData è D1 per eurusd per il 2015, fronttestData è dal 1 gennaio 2016 a giugno. Il fronttest è un po' lungo, nel trading reale è improbabile che io faccia trading per più di un mese con le stesse impostazioni, volevo solo vedere quanto dura davvero la redditività del modello. FronttestData1, fronttestData2, fronttestData3 sono tagli separati da fronttestData, solo per gennaio, solo per febbraio, solo per marzo. Sono davvero interessato solo ad abbassare l'errore su fronttestData1, il resto è solo per la ricerca. Il set di predittori contiene principalmente indicatori e diversi calcoli tra di loro. Con nnet error su fronttest ho il 30% su fronttestData1, addestramento con controllo dell'iterazione e numero di neuroni interni adeguato. Penso che il 30% qui sia solo una questione di caso, il modello ha catturato qualche tendenza nel mercato da marzo 2015 a febbraio 2016. Ma il fatto che il resto dei periodi non si unisca è già buono.

Ecco un'immagine da mt5 tester 2014.01-2016.06, ho segnato il periodo di formazione con una cornice. È già meglio di prima :). Per ora questo è il mio limite, devo risolvere molti problemi con gli indicatori, cioè le loro impostazioni di default sono strettamente legate ai timeframe, per esempio su H1 la mia esperienza è completamente inutile, lo stesso algoritmo di selezione degli indicatori su H1 considera tutto spazzatura. Ho bisogno o di aggiungere al set originale di indicatori un mucchio di variazioni con parametri diversi, o in qualche modo generare indicatori casuali da ohlc.

Non male, ma i periodi stessi fuori dal campione sono piccoli.

Non è nemmeno chiaro quanti scambi cadano fuori dal campione. Ce ne sono decine, centinaia, qual è l'ordine?

 
Dr.Trader:

L'ataccamento è il mio miglior set di predittori. TrainData è D1 per eurusd per il 2015, fronttestData è dal 1 gennaio 2016 a giugno. Il fronttest è un po' lungo, nel trading reale è improbabile che io faccia trading per più di un mese con le stesse impostazioni, volevo solo vedere quanto dura davvero la redditività del modello. FronttestData1, fronttestData2, fronttestData3 sono tagli separati da fronttestData, solo per gennaio, solo per febbraio, solo per marzo. Sono davvero interessato solo ad abbassare l'errore su fronttestData1, il resto è solo per la ricerca. Il set di predittori contiene principalmente indicatori e diversi calcoli tra di loro. Con nnet error su fronttest ho il 30% su fronttestData1, formazione con controllo dell'iterazione e numero di neuroni interni adeguato. Penso che il 30% qui sia solo una questione di caso, il modello ha catturato qualche tendenza nel mercato da marzo 2015 a febbraio 2016. Ma il fatto che il resto dei periodi non si unisca è già buono.

Ecco un'immagine da mt5 tester 2014.01-2016.06, ho segnato il periodo di formazione con una cornice. È già meglio di prima :). Per ora questo è il mio limite, devo risolvere molti problemi con gli indicatori, cioè le loro impostazioni di default sono strettamente legate ai timeframe, per esempio su H1 la mia esperienza è completamente inutile, lo stesso algoritmo di selezione degli indicatori su H1 considera tutto spazzatura. Ho bisogno o di aggiungere al set originale di indicatori un mucchio di variazioni con parametri diversi, o in qualche modo generare indicatori casuali da ohlc.

L'ho guardato.

Ho capito bene che ci sono 107 linee (107 osservazioni) nel dataset totale?

 
SanSanych Fomenko:

Guardato.

Ho capito bene che il dataset totale ha 107 righe (107 osservazioni)?

No, il set di allenamento ha 250-qualcosa righe (numero di giorni di trading nel 2015). Ho addestrato il modello sulla tabella trainData. L'ho testato su fronttestData1. Tutto il resto è per i controlli aggiuntivi, puoi ignorarli

trainData - l'intero anno 2015.
fronttestData1 - gennaio 2016
fronttestData2 - febbraio 2016
fronttestData3 - marzo 2016
fronttestData - gennaio 2016 - giugno 2016

 
Dr.Trader:

No, il set di allenamento ha 250-qualcosa righe (numero di giorni di trading nel 2015). Ho addestrato il modello sulla tabella trainData. L'ho testato su fronttestData1. Tutto il resto è per i controlli extra, potete ignorarli.

trainData - l'intero anno 2015.
fronttestData1 - gennaio 2016
fronttestData2 - febbraio 2016
fronttestData3 - marzo 2016
fronttestData - gennaio 2016 - giugno 2016

Per me questo è molto poco - uso le statistiche. Anche per la finestra attuale 107 righe è molto piccolo per me. Io uso più di 400 per la finestra attuale.

Generalmente nei vostri set il numero di osservazioni è paragonabile al numero di predittori. Questi sono set molto specifici. In qualche modo ho visto che tali insiemi richiedono metodi speciali. Nessun riferimento perché non ho questi problemi.

Purtroppo i miei metodi non sono adatti ai tuoi dati.