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

 

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?

уровни предикторов
sell
buy
pval
concat
direction
121121
11
31
2.03E-03
121121
1
211112
3
15
4.68E-03
211112
1
222222
19
4
1.76E-03
222222
0
222311
8
0
4.68E-03
222311
0
321113
7
0
8.15E-03
321113
0
333332
53
19
6.15E-05
333332
0

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.

sample
correct sell correct buy total correct deals total deals share correct
1 37 10 47 85 0.5529412
2 26 7 33 65 0.5076923
3 30 9 39 80 0.4875
4 36 11 47 88 0.5340909
5 33 12 45 90 0.5
6 28 10 38 78 0.4871795
7 30 9 39 75 0.52
8 34 8 42 81 0.5185185
9 24 11 35 67 0.5223881
10 23 14 37 74 0.5
11 28 13 41 88 0.4659091
12 31 13 44 82 0.5365854
13 33 9 42 80 0.525
14 23 7 30 63 0.4761905
15 28 12 40 78 0.5128205
16 23 16 39 72 0.5416667
17 30 13 43 74 0.5810811
18 38 8 46 82 0.5609756
19 26 8 34 72 0.4722222
20 35 12 47 79 0.5949367
21 32 11 43 76 0.5657895
22 30 10 40 75 0.5333333
23 28 8 36 70 0.5142857
24 21 8 29 70 0.4142857
25 24 8 32 62 0.516129
26 34 15 49 83 0.5903614
27 24 9 33 63 0.5238095
28 26 14 40 66 0.6060606
29 35 6 41 84 0.4880952
30 28 8 36 74 0.4864865
31 26 14 40 79 0.5063291
32 31 15 46 88 0.5227273
33 35 14 49 93 0.5268817
34 35 19 54 85 0.6352941
35 27 8 35 64 0.546875
36 30 10 40 83 0.4819277
37 36 9 45 79 0.5696203
38 25 8 33 73 0.4520548
39 39 12 51 85 0.6
40 37 9 46 79 0.5822785
41 41 12 53 90 0.5888889
42 29 7 36 59 0.6101695
43 36 14 50 77 0.6493506
44 36 15 51 88 0.5795455
45 34 7 41 67 0.6119403
46 28 12 40 75 0.5333333
47 27 11 38 69 0.5507246
48 28 16 44 83 0.5301205
49 29 10 39 72 0.5416667
СОПРОВОЖДЕНИЕ ЭКСПЕРИМЕНТА ПО АНАЛИЗУ ДАННЫХ ФОРЕКСА: доказательство значимости предсказаний
СОПРОВОЖДЕНИЕ ЭКСПЕРИМЕНТА ПО АНАЛИЗУ ДАННЫХ ФОРЕКСА: доказательство значимости предсказаний
  • 2016.03.02
  • Alexey Burnakov
  • www.mql5.com
Начало по ссылкам: https://www.mql5.com/ru/blogs/post/659572 https://www.mql5.com/ru/blogs/post/659929 https://www.mql5.com/ru/blogs/post/660386 https://www.mql5.com/ru/blogs/post/661062
 

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.

 
SanSanych Fomenko:

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 es lo más importante. Nadie construye la pirámide al revés.
 
yerlan Imangeldinov:
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.
Y concretamente, ¿qué es lo que no veo?
 
yerlan Imangeldinov:
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.
Puede añadir información al sistema aparte del historial de precios. Pero todavía hay que formarse en la historia. O - Flair.
 

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.

entrada entrada_1 entrada_2 entrada_3 entrada_4 entrada_5 entrada_6 entrada_7 entrada_8 entrada_9 entrada_10 entrada_11 entrada_12 entrada_13 entrada_14 entrada_15 entrada_16 entrada_17 entrada_18 entrada_19 entrada_20
peso -186.905 7.954625 -185.245 14.88457 -206.037 16.03497 190.0939 23.05248 -182.923 4.268967 196.8927 16.43655 5.419367 8.76542 36.8237 5.940322 8.304859 8.176511 17.13691 -0.57317
subconjunto

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

Случайные леса предсказывают тренды
Случайные леса предсказывают тренды
  • 2014.09.29
  • СанСаныч Фоменко
  • www.mql5.com
В статье описано использование пакета Rattle для автоматического поиска паттернов, способных предсказывать "лонги" и "шорты" для валютных пар рынка Форекс. Статья будет полезна как новичкам, так и опытным трейдерам.
 
Dr.Trader:

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.

entrada entrada_1 entrada_2 entrada_3 entrada_4 entrada_5 entrada_6 entrada_7 entrada_8 entrada_9 entrada_10 entrada_11 entrada_12 entrada_13 entrada_14 entrada_15 entrada_16 entrada_17 entrada_18 entrada_19 entrada_20
peso -186.905 7.954625 -185.245 14.88457 -206.037 16.03497 190.0939 23.05248 -182.923 4.268967 196.8927 16.43655 5.419367 8.76542 36.8237 5.940322 8.304859 8.176511 17.13691 -0.57317
subconjunto

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.

Razón de la queja: