Maschinelles Lernen im Handel: Theorie, Modelle, Praxis und Algo-Trading - Seite 21

 
Dr. Trader:

Ich habe auch die Y-Skala ausprobiert, R^2 war in beiden Fällen (mit und ohne Y-Skala) gleich (obwohl sie unterschiedliche Pakete verwenden!).

Ich vermute, dass die Y-Skala mit einer geringeren Anzahl von Hauptkomponenten das gleiche gute Ergebnis liefern kann. Aber wenn selbst bei Verwendung aller Komponenten das Ergebnis immer noch nicht zufriedenstellend ist (wie in meinem Fall), gibt es keinen Unterschied. Außerdem funktioniert es schneller, was für mich jetzt noch wichtiger ist. Aber ich habe weder in der Theorie noch in der Praxis bewiesen, ob diese Methode für die Auswahl der Prädiktoren geeignet ist... Zuerst hatte ich die Idee, die Hauptkomponenten auf alle Prädiktoren zu modellieren und die Prädiktoren anhand der Koeffizienten der Komponenten auszuwählen. Aber dann habe ich bemerkt, dass der R^2 des Modells sinkt, wenn man Müll hinzufügt. Es ist sinnvoll, verschiedene Gruppen von Prädiktoren auszuprobieren und nach denen mit einem höheren R^2 zu suchen, aber das ist nur eine Theorie.

Ich mache hier regelmäßig den folgenden Vorschlag: Wenn Sie mir Ihr Set destillieren, vergleichen wir meine Ergebnisse mit Ihren.

Für mich ist .RData das Ideal. Ein Frame, bei dem das Ziel binär ist und die Prädiktoren vorzugsweise reelle Zahlen sind.

 
Dr. Trader:

Ich habe den Wald trainiert und einen Fehler für eine Validierungsprobe zurückgegeben. Im Prinzip hat es funktioniert - wenn der Wald auch nur ein bisschen übertrainiert ist, tendiert der Fehler gegen 50%.

Jetzt verwende ich GetPCrsquared(), den obigen Code. Ich habe auch Ihr Beispiel aus feature_selector_modeller.txt, aber ich muss es herausfinden und das benötigte Codefragment bekommen, also habe ich meine Daten noch nicht überprüft.

Hier ist, was Sie dorthin mitnehmen müssen:

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

Im Datenrahmen ist die Spalte ganz rechts die Zielspalte.

ALLE Spalten sollten Kategorien sein (Ganzzahl, Zeichen oder Faktor).

Und Sie müssen alle Bibeln laden.

Ein Stück Code, das zeigt, wie man Zahlen in kategorische Variablen übersetzt:

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]

}

 

Ich habe diese interessante Funktion im Internet gefunden

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)

Vielleicht kann der Algorithmus in dieser Form die Daten besser erkennen? Aber es gibt ein Problem, die Ausgabe der Funktion ist eine Variable "d" und sie hat eine Matrix mit zwei Spalten "x" und "y", eine bezeichnet den Preis und die zweite die vom Algorithmus gebogene Zeit, die Frage ist, wie man diese Matrix in einen Vektor umwandelt, damit sie ihre Eigenschaften nicht verliert

 
SanSanych Fomenko:

Ich mache hier regelmäßig folgenden Vorschlag: Wenn Sie mir Ihr Set zur Verfügung stellen, werden wir meine Ergebnisse mit Ihren vergleichen.

Für mich ist das Ideal eine .RData. Ein Rahmen, in dem das binäre Ziel und die Prädiktoren vorzugsweise reelle Zahlen sind.

Die Anhänglichkeit ist mein bester Prädiktor. TrainData ist D1 für eurusd für 2015, fronttestData ist vom 1. Januar 2016 bis Juni. Der Fronttest ist ein bisschen lang, im realen Handel werde ich wahrscheinlich nicht länger als einen Monat mit den gleichen Einstellungen handeln, ich wollte nur sehen, wie lange die Rentabilität des Modells wirklich anhält. FronttestData1, fronttestData2, fronttestData3 sind separate Schnitte von fronttestData, nur für Januar, nur für Februar, nur für März. Ich bin nur wirklich daran interessiert, den Fehler auf fronttestData1 zu verringern, der Rest ist nur für die Forschung. Der Prädiktorensatz enthält hauptsächlich Indikatoren und verschiedene Berechnungen zwischen ihnen. Mit nnet error on fronttest habe ich 30% auf fronttestData1, Training mit Iterationskontrolle und passender Anzahl interner Neuronen. Ich denke, dass die 30% hier nur eine Frage des Zufalls sind, das Modell hat einen Trend auf dem Markt von März2015 bis Februar2016 aufgefangen. Aber die Tatsache, dass die anderen Zeiträume auch nicht verschmelzen, ist schon gut.

Hier ist ein Bild von mt5 tester 2014.01-2016.06, ich habe den Trainingszeitraum mit einem Rahmen markiert. Es ist schon besser als es war :). Für jetzt ist dies meine Grenze, ich habe viele Probleme mit Indikatoren zu lösen, nämlich ihre Standardeinstellungen sind streng auf Zeitrahmen gebunden, zum Beispiel auf H1 meine Erfahrung ist völlig nutzlos, der gleiche Algorithmus für Indikator Auswahl auf H1 hält alles Müll. Ich sollte entweder eine Reihe ihrer Variationen mit verschiedenen Parametern zum ursprünglichen Satz von Indikatoren hinzufügen oder selbst zufällige Indikatoren aus ohlc generieren.

Dateien:
 
Alexey Burnakov:

gibt es das hier zu nehmen:

Das macht mehr Sinn, danke. Meines Erachtens sind nur 3 Kategorien pro Indikator nicht ausreichend. Logischerweise würde ich mindestens 100 Levels machen, aber ist das besser oder geht der Sinn des Algorithmus verloren?

 
Dr. Trader:

Das macht mehr Sinn, danke. Meines Erachtens sind nur 3 Kategorien pro Indikator nicht ausreichend. Logischerweise würde ich mindestens 100 Stufen machen, aber ist das besser oder verliert der Algorithmus dadurch seinen Sinn?

Der Algorithmus wird seine Bedeutung verlieren. Der Algorithmus zählt die Gesamtzahl der Niveaus der Eingangsvariablen und verteilt sie auf diese Niveaus der Antwortstufen. Wenn die Anzahl der Antwortwerte auf jeder der Eingabestufen sehr gering ist, kann die statistische Signifikanz der Wahrscheinlichkeitsverzerrung nicht beurteilt werden.

Wenn Sie 100 Levels erstellen, wird es viele Variablen geben. Dann wird der Algorithmus für jede Teilmenge null Signifikanz liefern, was angesichts des begrenzten Stichprobenumfangs vernünftig ist.

Das ist ein gutes Beispiel.

Eingabeebenen | Anzahl der Beobachtungen

1 150

2 120

...

9 90

hier können wir die Signifikanz innerhalb einer Antwort schätzen

Das Beispiel ist ein schlechtes Beispiel.

Eingangspegel

112 5

...

357 2

...

1045 1

die Signifikanz innerhalb einer Antwort kann hier nicht geschätzt werden

 
Dr. Trader:

Die Anhänglichkeit ist mein bester Prädiktorensatz. TrainData ist D1 für eurusd für 2015, fronttestData ist vom 1. Januar 2016 bis Juni. Der Fronttest ist ein bisschen lang, im realen Handel werde ich wahrscheinlich nicht länger als einen Monat mit den gleichen Einstellungen handeln, ich wollte nur sehen, wie lange die Rentabilität des Modells wirklich anhält. FronttestData1, fronttestData2, fronttestData3 sind separate Schnitte von fronttestData, nur für Januar, nur für Februar, nur für März. Ich bin nur wirklich daran interessiert, den Fehler auf fronttestData1 zu verringern, der Rest ist nur für die Forschung. Der Prädiktorsatz enthält hauptsächlich Indikatoren und verschiedene Berechnungen zwischen ihnen. Mit nnet error on fronttest habe ich 30% auf fronttestData1, Training mit Iterationskontrolle und passender Anzahl interner Neuronen. Ich denke, dass die 30% hier nur eine Frage des Zufalls sind, das Modell hat einen Trend auf dem Markt von März2015 bis Februar2016 aufgefangen. Aber die Tatsache, dass die übrigen Zeiträume nicht zusammengelegt werden, ist schon gut.

Hier ist ein Bild von mt5 tester 2014.01-2016.06, ich habe den Trainingszeitraum mit einem Rahmen markiert. Es ist schon besser als es war :). Für jetzt ist dies meine Grenze, ich habe viele Probleme mit Indikatoren zu lösen, nämlich ihre Standardeinstellungen sind streng auf Zeitrahmen gebunden, zum Beispiel auf H1 meine Erfahrung ist völlig nutzlos, der gleiche Algorithmus für Indikator Auswahl auf H1 hält alles Müll. Ich muss entweder dem ursprünglichen Satz von Indikatoren eine Reihe von Variationen mit verschiedenen Parametern hinzufügen oder irgendwie zufällige Indikatoren aus ohlc generieren.

Nicht schlecht, aber die Zeiträume selbst außerhalb der Stichprobe sind klein.

Es ist auch nicht klar, wie viele Trades außerhalb der Stichprobe liegen. Es gibt Dutzende, Hunderte, wie lautet die Reihenfolge?

 
Dr. Trader:

Die Anhänglichkeit ist mein bester Prädiktor. TrainData ist D1 für eurusd für 2015, fronttestData ist vom 1. Januar 2016 bis Juni. Der Fronttest ist ein bisschen lang, im realen Handel werde ich wahrscheinlich nicht länger als einen Monat mit den gleichen Einstellungen handeln, ich wollte nur sehen, wie lange die Rentabilität des Modells wirklich anhält. FronttestData1, fronttestData2, fronttestData3 sind separate Schnitte von fronttestData, nur für Januar, nur für Februar, nur für März. Ich bin nur wirklich daran interessiert, den Fehler auf fronttestData1 zu verringern, der Rest ist nur für die Forschung. Der Prädiktorensatz enthält hauptsächlich Indikatoren und verschiedene Berechnungen zwischen ihnen. Mit nnet error on fronttest habe ich 30% auf fronttestData1, Training mit Iterationskontrolle und passender Anzahl interner Neuronen. Ich denke, dass die 30% hier nur eine Frage des Zufalls sind, das Modell hat einen Trend auf dem Markt von März2015 bis Februar2016 aufgefangen. Aber die Tatsache, dass die anderen Zeiträume auch nicht verschmelzen, ist schon gut.

Hier ist ein Bild von mt5 tester 2014.01-2016.06, ich markierte Trainingsperiode mit einem Rahmen. Es ist schon besser als es war :). Für jetzt ist dies meine Grenze, ich habe viele Probleme mit Indikatoren zu lösen, nämlich ihre Standardeinstellungen sind streng auf Zeitrahmen gebunden, zum Beispiel auf H1 meine Erfahrung ist völlig nutzlos, der gleiche Algorithmus für Indikator Auswahl auf H1 hält alles Müll. Ich muss entweder dem ursprünglichen Satz von Indikatoren eine Reihe von Variationen mit verschiedenen Parametern hinzufügen oder irgendwie zufällige Indikatoren aus ohlc generieren.

Ich habe es mir angesehen.

Habe ich richtig verstanden, dass der gesamte Datensatz 107 Zeilen (107 Beobachtungen) umfasst?

 
SanSanych Fomenko:

Angeschaut.

Habe ich richtig verstanden, dass der gesamte Datensatz 107 Zeilen (107 Beobachtungen) umfasst?

Nein, der Trainingssatz besteht aus etwa 250 Zeilen (Anzahl der Handelstage im Jahr 2015). Ich habe das Modell anhand der Tabelle trainData trainiert. Ich habe es mit fronttestData1 getestet. Alles andere ist für zusätzliche Kontrollen, die Sie ignorieren können.

trainData - das ganze Jahr 2015.
fronttestData1 - Januar 2016
fronttestData2 - Februar 2016
fronttestData3 - März 2016
fronttestDaten - Januar 2016 - Juni 2016

 
Dr. Trader:

Nein, der Trainingssatz besteht aus etwa 250 Zeilen (Anzahl der Handelstage im Jahr 2015). Ich habe das Modell mit der Tabelle trainData trainiert. Ich habe es mit fronttestData1 getestet. Alles andere ist für zusätzliche Kontrollen, die Sie ignorieren können.

trainData - das ganze Jahr 2015.
fronttestData1 - Januar 2016
fronttestData2 - Februar 2016
fronttestData3 - März 2016
fronttestDaten - Januar 2016 - Juni 2016

Für mich ist das sehr wenig - ich verwende Statistiken. Selbst für das aktuelle Fenster sind 107 Zeilen für mich sehr wenig. Ich verwende über 400 für das aktuelle Fenster.

Im Allgemeinen ist die Anzahl der Beobachtungen in Ihren Datensätzen mit der Anzahl der Prädiktoren vergleichbar. Es handelt sich um sehr spezifische Sets. Irgendwie habe ich gesehen, dass solche Sätze besondere Methoden erfordern. Keine Referenzen, da ich solche Probleme nicht habe.

Leider sind meine Methoden für Ihre Daten nicht geeignet.