Aprendizado de máquina no trading: teoria, prática, negociação e não só - página 2

 

Vou esclarecer as condições para o prémio em dinheiro:

5 créditos para a primeira pessoa a resolver o problema

Data limite para as soluções: 30 de Junho de 2016

 

Há um exemplo de aplicação de um algoritmo de seleção de traços informativos para implementar uma estratégia de negociação.

Você provavelmente já leu os meus blogs sobre a Grande Experiência: https://www.mql5.com/ru/blogs/post/661895

E aqui está uma foto como esta:

Tentei encontrar um padrão para cinco pares e detectar a percentagem de negócios correctamente adivinhados numa amostra de validação de cerca de 25 anos. Não resultou de imediato. Eu não alcancei a precisão desejada para qualquer horizonte de previsão.

A seguir, vamos levar só um par, eurusd. Eu encontrei uma dependência do movimento de preços 3 horas à frente de um subconjunto dos meus preditores.

Reduzi os preditores a uma forma categórica e comecei a minha função de procurar preditores significativos. Fi-lo agora mesmo, enquanto eu estava no trabalho, em 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"   

Não consegui a convergência tão rapidamente, mas obtive algum resultado ao nível do poder explicativo de um por cento e meio.

O gráfico de convergência (minimização).

A seguir é a construção do modelo.

Nós temos vários preditores categóricos. Construímos um "livro de regras" ou que tipo de relação existe entre os preditores e a produção - longa ou curta num horizonte temporal de 3 horas.

Como é que é o 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 a inclinação do número de compra e venda em cada linha e o valor correspondente do p-valor do critério qui-quadrado para corresponder à distribuição 50/50. Selecionamos apenas aquelas linhas em que a probabilidade é inferior a 0,01.

E o código de toda a experiência, a partir do momento em que as entradas já foram selecionadas:

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 seguir, há 49 amostras de validação, cada uma cobrindo aproximadamente 5 anos. Vamos validar o modelo neles e contar a percentagem de direcções comerciais correctamente adivinhadas.

Vejamos a percentagem de negócios correctamente adivinhados por amostras e o histograma deste valor:

E contar quanto no total adivinhámos a direcção do negócio em todas as amostras:

> sum(correct_validation_results$`total correct deals`) / sum(correct_validation_results$`total deals`)

[1] 0.5361318

Cerca de 54%. Mas sem ter em conta que precisamos de ultrapassar a distância entre o Ask & Bid. Ou seja, o limiar de acordo com o gráfico acima é de cerca de 53%, assumindo que o spread = 1 pip.

Ou seja, nós concebemos um modelo simples em 30 minutos, que é fácil de codificar no terminal, por exemplo. E nem sequer é um comité. E eu estou à procura de dependências há 20 minutos em vez de 20 horas. Em suma, há qualquer coisa.

E tudo graças à seleção correta de atributos informativos.

E estatísticas detalhadas para cada amostra 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 os dados em bruto estão disponíveis nos links do blog.

E este modelo não é muito rentável. O MO está ao nível de meio ponto. Mas é essa a direcção que estou a tomar.

 
SanSanych Fomenko:

Sempre a aprender com o passado.

Procuramos durante séculos num gráfico. Ambos sobre e vemos "três soldados", depois vemos "cabeça e ombros". Quantos destes números já vimos e acreditamos neles, nós trocamos...

E se a tarefa for definida assim:

1. encontrar automaticamente tais números, não para todos os gráficos, mas para um determinado par de moedas, os que ocorreram recentemente, não há três séculos atrás, no comércio do arroz japonês.

2) Os dados iniciais sobre os quais procuramos automaticamente tais números - padrões.

Para responder à primeira pergunta, consideremos o algoritmo chamado "floresta aleatória". O algoritmo toma cotações de uma ou várias moedas, indicadores, incrementos de preço - tudo o que foi humanamente inventado, como dados de entrada para o seu funcionamento. 10-5-100-200 ... variáveis de entrada. Em seguida, ele pega todo o conjunto de valores das variáveis referentes a um ponto no tempo correspondente a uma barra e procura por uma combinação dessas variáveis de entrada que corresponderia nos dados do histórico a um determinado resultado, por exemplo, uma ordem de compra. E outro conjunto de combinações para outra encomenda - SELL. Uma árvore separada corresponde a cada um desses conjuntos. A experiência mostra que para um conjunto de entrada de 18000 barras (cerca de 3 anos), o algoritmo encontra 200-300 árvores. Este é o conjunto de padrões, quase análogos de "cabeças e ombros", e bocas inteiras de soldados.

O problema com este algoritmo é que tais árvores podem captar algumas especificidades que não são encontradas no futuro. Isto é chamado de "superfitting" aqui no fórum, na aprendizagem de máquinas "overfitting". Sabemos que todo um grande conjunto de variáveis de entrada pode ser dividido em duas partes: as relacionadas com a variável de saída e as não relacionadas com o ruído. Então Burnakov tenta eliminar os que são irrelevantes para a saída.

PS.

Ao construir uma tendência TS (BUY, SELL) quaisquer variedades de vagões estão relacionadas com o ruído!

O que você vê é uma pequena parte do mercado e não é o mais importante. Ninguém constrói a pirâmide de cabeça para baixo.
 
yerlan Imangeldinov:
O que você vê é uma pequena parte do mercado e não a mais importante. Ninguém está a construir uma pirâmide de cabeça para baixo.
E especificamente, o que é que eu não vejo?
 
yerlan Imangeldinov:
O que você vê é uma pequena parte do mercado e não a mais importante. Ninguém está a construir uma pirâmide de cabeça para baixo.
Você pode adicionar informações ao sistema, além do histórico de preços. Mas ainda tens de treinar em história. Ou - Flair.
 

Tentei treinar o neurónio sobre os dados de entrada, depois olhei para os pesos. Se os dados de entrada tiverem pesos baixos, parece que não são necessários. Fi-lo com R (Rattle), graças ao SanSanych pelo seu artigo https://www.mql5.com/ru/articles/1165.

entrada input_1 input_2 input_3 input_4 input_5 input_6 input_7 input_8 input_9 input_10 input_11 input_12 input_13 input_14 input_15 input_16 input_17 input_18 input_19 input_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 sim sim sim sim sim sim

Ainda não testei esta abordagem na prática, pergunto-me se funcionou ou não. Eu aceitaria input_1 input_3 input_5 input_7 input_9 input_11

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

Tentei treinar o neurónio nos dados de entrada, depois olhei para os pesos. Se os dados de entrada tiverem pesos baixos, parece que não são necessários. Fi-lo com R (Rattle), graças ao SanSanych pelo seu artigo https://www.mql5.com/ru/articles/1165.

entrada input_1 input_2 input_3 input_4 input_5 input_6 input_7 input_8 input_9 input_10 input_11 input_12 input_13 input_14 input_15 input_16 input_17 input_18 input_19 input_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 sim sim sim sim sim sim

Ainda não testei esta abordagem na prática, pergunto-me se funcionou ou não. Eu aceitaria input_1 input_3 input_5 input_7 input_9 input_11

) hmm. Muito interessante.

Pergunta esclarecedora. Porque não inclui mais alguns inputs onde o peso é pequeno, por exemplo, 13, 14, 16? Você poderia mostrar um diagrama de entradas e pesos ordenados por peso?

Desculpa, no início não percebi. Sim, as entradas especificadas têm um grande peso modulo, como devem ser.

 

Visualmente, todos os pesos estão divididos em dois grupos. Se você quiser dividi-los de acordo com o significado/não-significado, então 5,11,7,1,3,9 claramente se destacam, este conjunto eu acho que é suficiente.