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

Está perdiendo oportunidades comerciales:
- Aplicaciones de trading gratuitas
- 8 000+ señales para copiar
- Noticias económicas para analizar los mercados financieros
Registro
Entrada
Usted acepta la política del sitio web y las condiciones de uso
Si no tiene cuenta de usuario, regístrese
Aclararé las condiciones del premio en metálico:
5 créditos a la primera persona que resuelva el problema
Fecha límite para las soluciones: 30 de junio de 2016
Hay un ejemplo de aplicación de un algoritmo de selección de rasgos informativos para aplicar una estrategia de negociación.
Seguro que has leído mis blogs sobre el Gran Experimento: https://www.mql5.com/ru/blogs/post/661895
Y aquí hay una imagen como esta:
Intenté encontrar un patrón para cinco pares y detectar el porcentaje de tratos adivinados correctamente en una muestra de validación de 25 años más o menos. No funcionó de inmediato. No alcancé la precisión deseada para ningún horizonte de previsión.
A continuación, tomemos sólo un par, el eurusd. Encontré una dependencia del movimiento de los precios con 3 horas de antelación en un subconjunto de mis predictores.
Reduje los predictores a una forma categórica y comencé mi función de búsqueda de predictores significativos. Lo hice ahora mismo, mientras estaba en el trabajo, en 20 minutos.
[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"
No conseguí una convergencia tan rápida, pero obtuve algún resultado al nivel del uno y medio por ciento de poder explicativo.
El gráfico de convergencia (minimización).
Lo siguiente es la construcción del modelo.
Tenemos varios predictores categóricos. Construimos un "libro de reglas" o qué tipo de relación hay entre los predictores y la salida, larga o corta en un horizonte temporal de 3 horas.
¿Qué aspecto tiene el resultado?
Vemos la asimetría del número de compras y ventas en cada línea y el valor correspondiente del valor p del criterio chi-cuadrado para que coincida con la distribución 50/50. Seleccionamos sólo las filas en las que la probabilidad es inferior a 0,01.
Y el código de todo el experimento, a partir del momento en que las entradas ya han sido seleccionadas:
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)
A continuación, hay 49 muestras de validación, cada una de las cuales abarca 5 años aproximadamente. Validemos el modelo con ellos y contemos el porcentaje de direcciones comerciales adivinadas correctamente.
Veamos el porcentaje de operaciones acertadas por muestras y el histograma de este valor:
Y contar cuánto en total adivinamos la dirección de la operación en todas las muestras:
> sum(correct_validation_results$`total correct deals`) / sum(correct_validation_results$`total deals`)
[1] 0.5361318
Alrededor del 54%. Pero sin tener en cuenta que hay que superar la distancia entre Ask & Bid. Es decir, el umbral según el gráfico anterior es de aproximadamente el 53%, suponiendo que el spread = 1 pip.
Es decir, hemos inventado un modelo sencillo en 30 minutos, que es fácil de carodear en el terminal, por ejemplo. Y ni siquiera es un comité. Y he estado buscando dependencias durante 20 minutos en lugar de 20 horas. En definitiva, hay algo.
Y todo gracias a la correcta selección de atributos informativos.
Y estadísticas detalladas para cada muestra válida.
Todos los datos en bruto están disponibles en los enlaces del blog.
Y este modelo no es muy rentable. MO está en el nivel de medio punto. Pero esa es la dirección que estoy tomando.
Siempre aprendiendo del pasado.
Miramos durante siglos un gráfico. Ambos sobre y vemos "tres soldados", luego vemos "cabeza y hombros". Cuántas de estas cifras ya las hemos visto y creemos en ellas, comerciamos...
Y si la tarea se establece así:
1. encontrar automáticamente esas cifras, no a todos los gráficos, sino a un par de divisas en particular, las que se produjeron recientemente, no hace tres siglos en el comercio de arroz japonés.
2) Los datos iniciales sobre los que buscamos automáticamente esas figuras - patrones.
Para responder a la primera pregunta, consideremos el algoritmo llamado "bosque aleatorio". El algoritmo toma como datos de entrada para su funcionamiento las cotizaciones de una o varias divisas, los indicadores, los incrementos de precios... todo lo inventado por el ser humano. 10-5-100-200 ... variables de entrada. A continuación, toma todo el conjunto de valores de las variables referidas a un punto del tiempo correspondiente a una barra y busca la combinación de estas variables de entrada que correspondería en los datos históricos a un resultado bastante determinado, por ejemplo, una orden de compra. Y otra serie de combinaciones para otra orden - VENDER. A cada uno de estos conjuntos le corresponde un árbol distinto. La experiencia demuestra que para un conjunto de entrada de 18000 barras (unos 3 años) el algoritmo encuentra entre 200 y 300 árboles. Este es el conjunto de patrones, casi análogos de "cabezas y hombros", y bocas enteras de soldados.
El problema de este algoritmo es que dichos árboles pueden recoger algunas particularidades que no se encuentran en el futuro. Esto se llama "superfitting" aquí en el foro, en el aprendizaje de máquinas "overfitting". Sabemos que todo un gran conjunto de variables de entrada puede dividirse en dos partes: las relacionadas con la variable de salida y las no relacionadas con el ruido. Por ello, Burnakov trata de eliminar las que son irrelevantes para el resultado.
PS.
¡Al construir una tendencia TS (COMPRA, VENTA) cualquier variedad de vagones está relacionada con el ruido!
Lo que se ve es una pequeña parte del mercado y no la más importante. Nadie está construyendo una pirámide al revés.
Lo que se ve es una pequeña parte del mercado y no la más importante. Nadie está construyendo una pirámide al revés.
Intenté entrenar la neurona con los datos de entrada y luego miré los pesos. Si los datos de entrada tienen pesos bajos, parece que no son necesarios. Lo hice con R (Rattle), gracias a SanSanych por su artículo https://www.mql5.com/ru/articles/1165.
No he probado este enfoque en la práctica, me pregunto si ha funcionado o no. Tomaría input_1 input_3 input_5 input_7 input_9 input_11
Intenté entrenar la neurona con los datos de entrada y luego miré los pesos. Si los datos de entrada tienen pesos bajos, parece que no son necesarios. Lo hice con R (Rattle), gracias a SanSanych por su artículo https://www.mql5.com/ru/articles/1165.
No he probado este enfoque en la práctica, me pregunto si ha funcionado o no. Tomaría input_1 input_3 input_5 input_7 input_9 input_11
) hmm. muy interesante.
Pregunta aclaratoria. ¿Por qué no incluye entonces algunas entradas más en las que el peso sea pequeño, por ejemplo, 13, 14, 16? ¿Podría mostrar un diagrama de entradas y pesos ordenados por peso?
Lo siento, no lo entendí al principio. Sí, las entradas especificadas tienen un gran peso de módulo, como debe ser.
Visualmente, todos los pesos se dividen en dos grupos. Si quieres dividirlos según su importancia/no importancia, entonces 5,11,7,1,3,9 destacan claramente, este conjunto creo que es suficiente.