![MQL5 - Linguagem para estratégias de negociação inseridas no terminal do cliente MetaTrader 5](https://c.mql5.com/i/registerlandings/logo-2.png)
Você está perdendo oportunidades de negociação:
- Aplicativos de negociação gratuitos
- 8 000+ sinais para cópia
- Notícias econômicas para análise dos mercados financeiros
Registro
Login
Você concorda com a política do site e com os termos de uso
Se você não tem uma conta, por favor registre-se
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:
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.
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.
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 a mais importante. Ninguém está a construir uma pirâmide de cabeça para baixo.
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.
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.
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
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.
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.