L'Apprentissage Automatique dans le trading : théorie, modèles, pratique et trading algo - page 21

 
Dr. Trader:

J'ai aussi essayé l'échelle Y, le R^2 dans les deux cas (avec et sans échelle Y) est le même (même s'ils utilisent des paquets différents !).

Je suppose que l'échelle Y peut donner le même bon résultat avec un nombre inférieur de composantes principales. Mais, si même en utilisant tous les composants le résultat n'est toujours pas satisfaisant (comme dans mon cas) - il n'y a pas de différence. De plus, il fonctionne plus rapidement, ce qui est plus important pour moi maintenant. Mais je n'ai pas prouvé par la théorie ou par la pratique si cette méthode est adaptée à la sélection des prédicteurs... Au début, j'ai eu l'idée de modéliser les composantes principales sur tous les prédicteurs et de sélectionner les prédicteurs en regardant les coefficients des composantes. Mais ensuite j'ai remarqué qu'en ajoutant des déchets - le R^2 du modèle diminue. Il est logique d'essayer différents ensembles de prédicteurs et de rechercher ceux qui ont un R^2 plus élevé, mais ce n'est qu'une théorie.

Je fais régulièrement la suggestion suivante ici : si vous me faites parvenir votre jeu de distillation, nous comparerons mes résultats aux vôtres.

Pour moi, l'idéal est .RData. Une trame dans laquelle la cible est binaire et les prédicteurs sont de préférence des nombres réels.

 
Dr. Trader:

J'ai utilisé pour entraîner la forêt et renvoyer une erreur sur un échantillon de validation. En principe, cela a fonctionné - si la forêt se surentraîne, même un peu, l'erreur tend à 50%.

Maintenant, j'utilise GetPCrsquared(), le code ci-dessus. J'ai aussi votre exemple de feature_selector_modeller.txt mais je dois le comprendre et obtenir le fragment de code nécessaire, donc je n'ai pas encore vérifié mes données.

Voici ce que vous devez faire là-bas :

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

Dans le cadre de données, la colonne la plus à droite est la colonne cible.

TOUTES les colonnes doivent être des catégories (en nombre entier, en caractère ou en facteur).

Et vous devez charger tous les bibble.

Un morceau de code qui montre comment traduire des chiffres en variables catégorielles :

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]

}

 

J'ai trouvé cette fonction intéressante sur 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)

Peut-être que sous cette forme, l'algorithme reconnaîtra mieux les données ? Mais il y a un problème, la sortie de la fonction est une variable "d" et elle a une matrice avec deux colonnes "x" et "y", l'une dénote le prix et la seconde le temps courbé par l'algorithme, la question est de savoir comment transformer cette matrice en un vecteur afin qu'elle ne perde pas ses propriétés

 
SanSanych Fomenko:

Je fais régulièrement la suggestion suivante : si vous me distribuez votre jeu, nous comparerons mes résultats aux vôtres.

Pour moi, l'idéal est un .RData. Une trame dans laquelle la cible binaire et les prédicteurs sont de préférence des nombres réels.

L'attachement est mon meilleur ensemble de prédicteurs. TrainData est D1 pour eurusd pour 2015, fronttestData est du 1er janvier 2016 à juin. Le fronttest est un peu long, en trading réel il est peu probable que je trade plus d'un mois avec les mêmes paramètres, je voulais juste voir combien de temps la rentabilité du modèle dure réellement. FronttestData1, fronttestData2, fronttestData3 sont des coupes séparées de fronttestData, seulement pour janvier, seulement pour février, seulement pour mars. Je ne suis vraiment intéressé que par la réduction de l'erreur sur fronttestData1, le reste est juste pour la recherche. L'ensemble des prédicteurs contient principalement des indicateurs et différents calculs entre eux. Avec l'erreur nnet sur le fronttest, j'ai 30% sur le fronttestData1, l'entraînement avec le contrôle des itérations et l'ajustement du nombre de neurones internes. Je pense que les 30% ici sont juste une question de chance, le modèle a attrapé une certaine tendance sur le marché de mars2015 à février2016. Mais le fait que le reste des périodes ne fusionnent pas est déjà une bonne chose.

Voici une image de mt5 tester 2014.01-2016.06, j'ai marqué la période de formation avec un cadre. C'est déjà mieux qu'avant :). Pour l'instant, c'est ma limite, je dois résoudre de nombreux problèmes avec les indicateurs, à savoir que leurs paramètres par défaut sont strictement liés aux horizons temporels, par exemple sur H1 mon expérience est complètement inutile, le même algorithme de sélection des indicateurs sur H1 considère tout comme de la merde. Je devrais soit ajouter un tas de leurs variations avec différents paramètres à l'ensemble initial d'indicateurs, soit générer moi-même des indicateurs aléatoires à partir d'ohlc.

Dossiers :
 
Alexey Burnakov:

il y a ça à prendre :

C'est plus logique, merci. Il me semble que seulement 3 catégories par indicateur ne suffiront pas. Logiquement, je ferais au moins 100 niveaux, mais est-ce mieux ou est-ce que cela perd le sens de l'algorithme ?

 
Dr. Trader:

C'est plus logique, merci. Il me semble que seulement 3 catégories par indicateur ne suffiront pas. Logiquement, je ferais au moins 100 niveaux, mais est-ce mieux ou cela fait-il perdre son sens à l'algorithme ?

L'algorithme perdra son sens. L'algorithme compte le nombre total de niveaux de variables d'entrée et distribue par ces niveaux des niveaux de réponse. Par conséquent, si le nombre de valeurs de réponse à chacun des niveaux d'entrée est très faible, il sera impossible d'évaluer la signification statistique de l'asymétrie de probabilité.

Si vous faites 100 niveaux, oui, il y aura beaucoup de variables. L'algorithme renverra alors une signification nulle pour tout sous-ensemble, ce qui est raisonnable étant donné la taille limitée de l'échantillon.

L'exemple est bon.

niveaux d'entrée | nombre d'observations

1 150

2 120

...

9 90

ici nous pouvons estimer la signification dans une réponse

L'exemple est mauvais.

niveaux d'entrée

112 5

...

357 2

...

1045 1

l'importance au sein d'une réponse ne peut pas être estimée ici

 
Dr. Trader:

L'attachement est mon meilleur ensemble de prédicteurs. TrainData est D1 pour eurusd pour 2015, fronttestData est du 1er janvier 2016 à juin. Le fronttest est un peu long, en trading réel il est peu probable que je trade plus d'un mois avec les mêmes paramètres, je voulais juste voir combien de temps la rentabilité du modèle dure réellement. FronttestData1, fronttestData2, fronttestData3 sont des coupes séparées de fronttestData, seulement pour janvier, seulement pour février, seulement pour mars. Je ne suis vraiment intéressé que par la réduction de l'erreur sur fronttestData1, le reste est juste pour la recherche. L'ensemble des prédicteurs contient principalement des indicateurs et différents calculs entre eux. Avec l'erreur nnet sur le fronttest, j'ai 30% sur le fronttestData1, l'entraînement avec le contrôle des itérations et l'ajustement du nombre de neurones internes. Je pense que les 30% ici sont juste une question de chance, le modèle a attrapé une certaine tendance sur le marché de mars2015 à février2016. Mais le fait que le reste des périodes ne fusionnent pas est déjà une bonne chose.

Voici une image de mt5 tester 2014.01-2016.06, j'ai marqué la période de formation avec un cadre. C'est déjà mieux qu'avant :). Pour l'instant, c'est ma limite, je dois résoudre de nombreux problèmes avec les indicateurs, à savoir que leurs paramètres par défaut sont strictement liés aux horizons temporels, par exemple sur H1 mon expérience est complètement inutile, le même algorithme de sélection des indicateurs sur H1 considère tout comme de la merde. J'ai besoin soit d'ajouter à l'ensemble original d'indicateurs une série de variations avec différents paramètres, soit de générer d'une manière ou d'une autre des indicateurs aléatoires à partir d'ohlc.

Pas mal, mais les périodes elles-mêmes en dehors de l'échantillon sont petites.

On ne sait pas non plus combien de transactions tombent en dehors de l'échantillon. Il y en a des dizaines, des centaines, quel est l'ordre ?

 
Dr. Trader:

L'attachement est mon meilleur ensemble de prédicteurs. TrainData est D1 pour eurusd pour 2015, fronttestData est du 1er janvier 2016 à juin. Le fronttest est un peu long, en trading réel il est peu probable que je trade plus d'un mois avec les mêmes paramètres, je voulais juste voir combien de temps la rentabilité du modèle dure réellement. FronttestData1, fronttestData2, fronttestData3 sont des coupes séparées de fronttestData, seulement pour janvier, seulement pour février, seulement pour mars. Je ne suis vraiment intéressé que par la réduction de l'erreur sur fronttestData1, le reste est juste pour la recherche. L'ensemble des prédicteurs contient principalement des indicateurs et différents calculs entre eux. Avec l'erreur nnet sur le fronttest, j'ai 30% sur le fronttestData1, l'entraînement avec le contrôle des itérations et l'ajustement du nombre de neurones internes. Je pense que les 30% ici sont juste une question de chance, le modèle a attrapé une certaine tendance sur le marché de mars2015 à février2016. Mais le fait que le reste des périodes ne fusionnent pas est déjà une bonne chose.

Voici une image de mt5 tester 2014.01-2016.06, j'ai marqué la période de formation avec un cadre. C'est déjà mieux qu'avant :). Pour l'instant, c'est ma limite, je dois résoudre de nombreux problèmes avec les indicateurs, à savoir que leurs paramètres par défaut sont strictement liés aux horizons temporels, par exemple sur H1 mon expérience est complètement inutile, le même algorithme de sélection des indicateurs sur H1 considère tout comme de la merde. J'ai besoin soit d'ajouter à l'ensemble original d'indicateurs une série de variations avec différents paramètres, soit de générer d'une manière ou d'une autre des indicateurs aléatoires à partir d'ohlc.

Je l'ai examiné.

Ai-je bien compris qu'il y a 107 lignes (107 observations) dans l'ensemble des données ?

 
SanSanych Fomenko:

Regardé.

Ai-je bien compris que le jeu de données total comporte 107 lignes (107 observations) ?

Non, l'ensemble d'entraînement comporte quelque 250 lignes (nombre de jours de bourse en 2015). J'ai entraîné le modèle sur la table trainData. Je l'ai testé sur fronttestData1. Tout le reste est pour des contrôles supplémentaires, vous pouvez les ignorer.

trainData - toute l'année 2015.
fronttestData1 - janvier 2016
fronttestData2 - février 2016
fronttestData3 - mars 2016
fronttestData - janvier 2016 - juin 2016

 
Dr. Trader:

Non, l'ensemble d'entraînement comporte quelque 250 lignes (nombre de jours de bourse en 2015). J'ai entraîné le modèle sur la table trainData. Je l'ai testé sur fronttestData1. Tout le reste est pour des contrôles supplémentaires, vous pouvez les ignorer.

trainData - toute l'année 2015.
fronttestData1 - janvier 2016
fronttestData2 - février 2016
fronttestData3 - mars 2016
fronttestData - janvier 2016 - juin 2016

Pour moi, c'est très peu - j'utilise les statistiques. Même pour la fenêtre actuelle, 107 rangées, c'est très peu pour moi. J'en utilise plus de 400 pour la fenêtre actuelle.

Généralement, dans vos ensembles, le nombre d'observations est comparable au nombre de prédicteurs. Ce sont des ensembles très spécifiques. D'une manière ou d'une autre, j'ai vu que de tels ensembles nécessitent des méthodes spéciales. Aucune référence car je n'ai pas de tels problèmes.

Malheureusement, mes méthodes ne sont pas adaptées à vos données.