Aprendizaje automático en el trading: teoría, práctica, operaciones y más - página 21

 
Dr.Trader:

También probé con la escala Y, R^2 en ambos casos (con y sin escala Y) salió igual (¡aunque usan paquetes diferentes!).

Supongo que la escala Y puede dar el mismo buen resultado con menos número de componentes principales. Pero, si incluso utilizando todos los componentes el resultado sigue sin ser satisfactorio (como en mi caso) - no hay diferencia. Además, funciona más rápido, lo que es más importante para mí ahora. Pero no he demostrado ni en la teoría ni en la práctica si este método es adecuado para la selección de predictores... Al principio tenía la idea de modelar los componentes principales en todos los predictores y seleccionar los predictores mirando los coeficientes de los componentes. Pero luego me di cuenta de que con la adición de basura - R^2 del modelo cae. Tiene sentido probar diferentes conjuntos de predictores y buscar los que tienen mayor R^2, pero es sólo una teoría.

Regularmente hago la siguiente sugerencia: si me destilas tu conjunto, compararemos mis resultados con los tuyos.

Para mí, lo ideal es .RData. Una trama en la que el objetivo es binario y los predictores son preferentemente números reales.

 
Dr.Trader:

Solía entrenar el bosque y devolver un error en una muestra de validación. En principio, funcionó: si el bosque se sobreentrena aunque sea un poco, el error tiende al 50%.

Ahora uso GetPCrsquared(), ese código de arriba. También tengo tu ejemplo de feature_selector_modeller.txt pero tengo que resolverlo y conseguir el fragmento de código necesario, así que aún no he comprobado mis datos.

Esto es lo que tienes que llevar allí:

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

En el marco de datos, la columna más a la derecha es la columna de destino.

TODAS las columnas deben ser categorías (ineteger, carácter o factor).

Y tienes que cargar todos los petos.

Un fragmento de código que muestra cómo traducir los números en variables categóricas:

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]

}

 

He encontrado esta interesante función en 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)

¿Quizá de esta forma el algoritmo reconozca mejor los datos? Pero hay un problema, la salida de la función es una variable "d" y tiene una matriz con dos columnas "x" e "y", una denota el precio y la segunda el tiempo curvado por el algoritmo, la cuestión es cómo convertir esta matriz en un vector para que no pierda sus propiedades

 
SanSanych Fomenko:

Regularmente hago la siguiente sugerencia: si me distribuye su conjunto, compararemos mis resultados con los suyos.

Para mí, lo ideal es un .RData. Una trama en la que el objetivo binario y los predictores son preferentemente números reales.

El apego es mi mejor conjunto de predictores. TrainData es D1 para eurusd para 2015, fronttestData es del 1 de enero de 2016 a junio. La prueba frontal es un poco larga, en el comercio real es poco probable que opere durante más de un mes con la misma configuración, sólo quería ver cuánto tiempo dura realmente la rentabilidad del modelo. FronttestData1, fronttestData2, fronttestData3 son cortes separados de fronttestData, sólo para enero, sólo para febrero, sólo para marzo. Sólo me interesa realmente bajar el error en fronttestData1, el resto es sólo para investigar. El conjunto de predictores contiene principalmente indicadores y diferentes cálculos entre ellos. Con el error de la red en el fronttest tengo un 30% en el fronttestData1, entrenando con control de iteración y ajustando el número de neuronas internas. Creo que el 30% aquí es sólo una cuestión de azar, el modelo captó alguna tendencia en el mercado de marzo2015 a febrero2016. Pero el hecho de que el resto de los períodos no se fusionen ya es bueno.

Aquí hay una imagen de mt5 tester 2014.01-2016.06, marqué período de entrenamiento con un marco. Ya está mejor que antes :). Por ahora este es mi límite, tengo que resolver muchos problemas con los indicadores, a saber, su configuración por defecto está estrictamente ligada a los marcos de tiempo, por ejemplo en H1 mi experiencia es completamente inútil, el mismo algoritmo para la selección de indicadores en H1 considera todo basura. Debería añadir un montón de sus variaciones con diferentes parámetros al conjunto inicial de indicadores o generar indicadores aleatorios de ohlc por mí mismo.

Archivos adjuntos:
 
Alexey Burnakov:

hay que tomar esto:

Eso tiene más sentido, gracias. Me parece que sólo 3 categorías por indicador no serán suficientes. Lógicamente, haría al menos 100 niveles, pero ¿es mejor o se pierde el sentido del algoritmo?

 
Dr.Trader:

Eso tiene más sentido, gracias. Me parece que sólo 3 categorías por indicador no serán suficientes. Lógicamente, haría al menos 100 niveles, pero ¿es mejor o hace que el algoritmo pierda su sentido?

El algoritmo perderá su sentido. El algoritmo cuenta el número total de niveles de las variables de entrada y se distribuye por estos niveles de respuesta. En consecuencia, si el número de valores de respuesta en cada uno de los niveles de entrada es muy bajo, será imposible evaluar la importancia estadística de la inclinación de la probabilidad.

Si haces 100 niveles, sí habrá muchas variables. Entonces el algoritmo devolverá una significación nula para cualquier subconjunto, lo que es razonable dado el tamaño limitado de la muestra.

El ejemplo es bueno.

niveles de entrada | número de observaciones

1 150

2 120

...

9 90

aquí podemos estimar la significación dentro de una respuesta

El ejemplo es malo.

niveles de entrada

112 5

...

357 2

...

1045 1

la significación dentro de una respuesta no puede ser estimada aquí

 
Dr.Trader:

El apego es mi mejor conjunto de predictores. TrainData es D1 para eurusd para 2015, fronttestData es del 1 de enero de 2016 a junio. La prueba frontal es un poco larga, en el comercio real es poco probable que opere durante más de un mes con la misma configuración, sólo quería ver cuánto tiempo dura realmente la rentabilidad del modelo. FronttestData1, fronttestData2, fronttestData3 son cortes separados de fronttestData, sólo para enero, sólo para febrero, sólo para marzo. Sólo me interesa realmente bajar el error en fronttestData1, el resto es sólo para investigar. El conjunto de predictores contiene principalmente indicadores y diferentes cálculos entre ellos. Con el error de la red en el fronttest tengo un 30% en el fronttestData1, entrenando con control de iteración y ajustando el número de neuronas internas. Creo que el 30% aquí es sólo una cuestión de azar, el modelo captó alguna tendencia en el mercado de marzo2015 a febrero2016. Pero el hecho de que el resto de los períodos no se fusionen ya es bueno.

Aquí hay una imagen de mt5 tester 2014.01-2016.06, marqué período de entrenamiento con un marco. Ya está mejor que antes :). Por ahora este es mi límite, tengo que resolver muchos problemas con los indicadores, a saber, su configuración por defecto está estrictamente ligada a los marcos de tiempo, por ejemplo en H1 mi experiencia es completamente inútil, el mismo algoritmo para la selección de indicadores en H1 considera todo basura. Necesito o bien añadir al conjunto original de indicadores un montón de variaciones con diferentes parámetros, o bien generar de alguna manera indicadores aleatorios desde ohlc.

No está mal, pero los períodos propios fuera de la muestra son pequeños.

Tampoco está claro cuántas operaciones quedan fuera de la muestra. Hay docenas, cientos, ¿cuál es el orden?

 
Dr.Trader:

El apego es mi mejor conjunto de predictores. TrainData es D1 para eurusd para 2015, fronttestData es del 1 de enero de 2016 a junio. La prueba frontal es un poco larga, en el comercio real es poco probable que opere durante más de un mes con la misma configuración, sólo quería ver cuánto tiempo dura realmente la rentabilidad del modelo. FronttestData1, fronttestData2, fronttestData3 son cortes separados de fronttestData, sólo para enero, sólo para febrero, sólo para marzo. Sólo me interesa realmente bajar el error en fronttestData1, el resto es sólo para investigar. El conjunto de predictores contiene principalmente indicadores y diferentes cálculos entre ellos. Con el error de la red en el fronttest tengo un 30% en el fronttestData1, entrenando con control de iteración y ajustando el número de neuronas internas. Creo que el 30% aquí es sólo una cuestión de azar, el modelo captó alguna tendencia en el mercado de marzo2015 a febrero2016. Pero el hecho de que el resto de los períodos no se fusionen ya es bueno.

Aquí hay una imagen de mt5 tester 2014.01-2016.06, marqué período de entrenamiento con un marco. Ya está mejor que antes :). Por ahora este es mi límite, tengo que resolver muchos problemas con los indicadores, a saber, su configuración por defecto está estrictamente ligada a los marcos de tiempo, por ejemplo en H1 mi experiencia es completamente inútil, el mismo algoritmo para la selección de indicadores en H1 considera todo basura. Necesito o bien añadir al conjunto original de indicadores un montón de variaciones con diferentes parámetros, o bien generar de alguna manera indicadores aleatorios desde ohlc.

Lo he mirado.

¿He entendido bien que hay 107 líneas (107 observaciones) en el conjunto de datos?

 
SanSanych Fomenko:

Mirado.

¿He entendido bien que el conjunto de datos tiene 107 filas (107 observaciones)?

No, el conjunto de entrenamiento tiene 250 y pico filas (número de días de negociación en 2015). He entrenado el modelo en la tabla trainData. Lo he probado en fronttestData1. Todo lo demás es para comprobaciones adicionales, puedes ignorarlas

trainData - todo el año 2015.
fronttestData1 - Enero 2016
fronttestData2 - Febrero 2016
fronttestData3 - Marzo 2016
fronttestData - Enero 2016 - Junio 2016

 
Dr.Trader:

No, el conjunto de entrenamiento tiene 250 y pico filas (número de días de negociación en 2015). He entrenado el modelo en la tabla trainData. Lo he probado en fronttestData1. Todo lo demás es para controles adicionales, puedes ignorarlos.

trainData - todo el año 2015.
fronttestData1 - Enero 2016
fronttestData2 - Febrero 2016
fronttestData3 - Marzo 2016
fronttestData - Enero 2016 - Junio 2016

Para mí, esto es muy poco: utilizo las estadísticas. Incluso para la ventana actual 107 filas es muy pequeño para mí. Utilizo más de 400 para la ventana actual.

Por lo general, en sus conjuntos el número de observaciones es comparable al número de predictores. Son conjuntos muy específicos. De alguna manera he visto que tales conjuntos requieren métodos especiales. No hay referencias porque no tengo esos problemas.

Lamentablemente, mis métodos no son adecuados para sus datos.