
Modelagem de Apostas como meio de desenvolver "Intuição de Mercado"
Introdução
Este artigo trata sobre um mecanismo simples de modelagem de apostas em tempo real. Então, o que é uma Aposta? Aposta financeira - previsão sobre a continuação do movimento (para cima ou para baixo) de um título e obtenção de dinheiro caso a previsão se torne realidade. (Traduzido para o inglês da Wikipédia Russa por MetaQuotes Software Corp.)
Na verdade, nas apostas estamos interessados em uma coisa: se o título vai subir ou descer. O volume deste movimento não é importante para nós.
Se usarmos apostas na forma de um jogo em pequenos intervalos de tempo, podemos desenvolver a nossa "intuição de mercado". Podemos aprender a "prever" se um par irá para cima ou para baixo. Isto será discutido neste artigo.
Concepção
Dizem que conhecer análise técnica, análise fundamental, regras de gestão financeira etc. é muito importante para um operador. Sem dúvida, tudo isso é muito importante. Mas há também a chamada "intuição de mercado" - quando um operador olha para um gráfico absolutamente claro sem quaisquer indicadores e pode ver em que direção o título se moverá. Naturalmente, esta previsão não é sempre exata, mas em cada abordagem de trading podem ocorrer erros. Ainda assim, a capacidade de "prever" o mercado é muito útil, especialmente quando é preciso estimar rapidamente a situação do mercado.
Normalmente, a "intuição de mercado" é resultante de muita experiência, numerosas experiências. Muitas vezes, o custo dessas "experiências" são milhares de dólares norte-americanos.
Mas eu acredito que há maneiras de desenvolver essa intuição que requerem menos tempo e dinheiro. Uma das maneiras é a criação de um jogo, com o objetivo de prever a direção do movimento de um título. O jogo será ainda melhor se ele estiver conectado com as condições reais de trading. Ele também pode ser conduzido em conjunto com o trading real.
Sem dúvida, as habilidades humanas podem ser exercitadas e desenvolvidas. Podemos aprender a desenhar, cantar, tocar instrumentos musicais diferentes. Estou certo de que, da mesma maneira, alguém pode aprender a "ver" o mercado. Podemos jogar jogos de computador. Da mesma forma, podemos jogar o jogo "prever a direção". Mas o que devemos saber aqui é como começar e como desenvolver essa habilidade. Primeiro, precisamos do jogo.
Definição da tarefa
Do que precisamos? Precisamos de um jogo que possa ser jogado em um gráfico real em tempo real. E o jogo deve ter regras muito simples e de fácil implementação. E o jogo deve fornecer o máximo de atenção no mercado e não nas operações executadas. Além disso, o jogo não deve distrair muita atenção do possível trading real.
As apostas parecem satisfazer todos estes requisitos. Mas na vida real não são muito convenientes. Não são muitas as corretoras que oferecem essa oportunidade. Mesmo se você conseguir encontrar uma empresa deste tipo, você pode enfrentar alguns inconvenientes. Por exemplo, as contas de demonstração podem distrair sua atenção do trading real. E o jogo é muito arriscado para uma conta real. E, geralmente, você não pode apostar por um período inferior a uma hora.
Sendo assim, esta variante não atende plenamente a nossa tarefa. Consequentemente, temos de escrever um programa separado para este jogo, um programa sem essas limitações. O MQL4 serve para nossa proposta.
Implementação
Vamos começar com uma pergunta simples: Como ele deve ser? Obviamente, um usuário deve selecionar uma das duas variantes dadas - para cima ou para baixo (sua previsão sobre o futuro comportamento de um título). Depois disso, o programa adiciona um ponto se a suposição for correta e subtrai um ponto se for incorreta.
A implementação da seleção é melhor realizada através de objetos - SYMBOL_ARROWDOWN e SYMBOL_ARROWUP. O usuário pode colocar a seta necessária em um gráfico. Mas desenhá-las e escrever assinaturas levaria muito tempo e atenção. Portanto, esta variante não se acomoda à situação.
Mais uma variante é colocar automaticamente duas setas no início de um novo castiçal. O usuário deve excluir uma seta e a restante deve indicar a sua suposição. Depois disso, no início de um novo castiçal, um Expert Advisor deve verificar se a previsão estava correta. E a pontuação total e o número de previsões corretas e incorretas serão contadas. Para este propósito, será utilizada a gravação em um arquivo externo.
Parece fácil. E isto pode ser implementado facilmente.
//+------------------------------------------------------------------+ //| trener.mq4 | //| Copyright © 2008, FXRaider | //| | //+------------------------------------------------------------------+ #property copyright "Copyright © 2008, FXRaider" //+------------------------------------------------------------------+ //| expert initialization function | //+------------------------------------------------------------------+ extern int gap=5; int init() { //---- //---- return(0); } //+------------------------------------------------------------------+ //| expert deinitialization function | //+------------------------------------------------------------------+ int deinit() { //---- //---- return(0); } //+------------------------------------------------------------------+ //| expert start function | //+------------------------------------------------------------------+ int start() { //------------------------------ string solution="none"; int point, point_neg, point_pos; //------------------------------ //+---------------------------------------------------------------+ //| "up" choice searching | if( ObjectGet("up", OBJPROP_PRICE1)==Open[1]+gap*Point &&iBarShift(NULL,0,ObjectGet("up",OBJPROP_TIME1))==1 &&ObjectFind("down") != 0 &&ObjectFind("up") == 0 ) { solution="up"; } //| "up" choice searching | //+---------------------------------------------------------------+ //+---------------------------------------------------------------+ //| "down" choice searching | if( ObjectGet("down", OBJPROP_PRICE1)==Open[1]-gap*Point &&iBarShift(NULL,0,ObjectGet("down",OBJPROP_TIME1))==1 &&ObjectFind("up") != 0 &&ObjectFind("down") == 0 ) { solution="down"; } //| "down" choice searching | //+---------------------------------------------------------------+ //+---------------------------------------------------------------+ //| counting points at a positive answer | if((solution=="up"&&Open[1]<Close[1]) ||(solution=="down"&&Open[1]>Close[1])) { point=1; point_pos=1; point_neg=0; } //| counting points at a positive answer | //+---------------------------------------------------------------+ //+---------------------------------------------------------------+ //| counting points at a negative answer | if((solution=="up"&&Open[1]>Close[1]) ||(solution=="down"&&Open[1]<Close[1])) { point=-1; point_pos=0; point_neg=1; } //| counting points at a negative answer | //+---------------------------------------------------------------+ //+----------------------------------------------------------------------------------+ //| working with an external file | int handle; double points, //total score points_pos, //score of positive answers points_neg; //score of negative answers handle=FileOpen("trener_"+Symbol()+"_"+Period()+".csv", FILE_CSV|FILE_WRITE|FILE_READ,";"); if(handle>0) //if there is a file, read it { points=NormalizeDouble(StrToDouble(FileReadString(handle)),Digits); points_pos=NormalizeDouble(StrToDouble(FileReadString(handle)),Digits); points_neg=NormalizeDouble(StrToDouble(FileReadString(handle)),Digits); FileClose(handle); } if(solution!="none") //if a choice is made { handle=FileOpen("trener_"+Symbol()+"_"+Period()+".csv", FILE_CSV|FILE_WRITE|FILE_READ,";"); FileWrite(handle ,points+point); //write the total score FileWrite(handle ,points_pos+point_pos); //write the score of positive answers FileWrite(handle ,points_neg+point_neg); //write the score of negative answers FileClose(handle); } //| working with an external file | //+----------------------------------------------------------------------------------+ //+------------------------------------------------------------------------------------+ //| working with objects | if(iBarShift(NULL,0,ObjectGet("down",OBJPROP_TIME1))>0 ||ObjectGet("down",OBJPROP_PRICE1)!=Open[0]-gap*Point) { ObjectDelete("down"); } if(iBarShift(NULL,0,ObjectGet("up",OBJPROP_TIME1))>0 ||ObjectGet("up",OBJPROP_PRICE1)!=Open[0]+gap*Point) { ObjectDelete("up"); } if(ObjectFind("down") != 0&&ObjectFind("up") != 0) //if no object { ObjectCreate("down", OBJ_ARROW, 0, Time[0], Open[0]-gap*Point); //draw a down arrow ObjectSet("down", OBJPROP_STYLE, STYLE_DOT); ObjectSet("down", OBJPROP_ARROWCODE, SYMBOL_ARROWDOWN); ObjectSet("down", OBJPROP_COLOR, Red); ObjectCreate("up", OBJ_ARROW, 0, Time[0], Open[0]+gap*Point); //draw an up arrow ObjectSet("up", OBJPROP_STYLE, STYLE_DOT); ObjectSet("up", OBJPROP_ARROWCODE, SYMBOL_ARROWUP); ObjectSet("up", OBJPROP_COLOR, Blue); } //| working with objects | //+------------------------------------------------------------------------------------+ Comment("Score: ", points," (",points_pos,"/",points_neg, //show the score ") | Time: ", Hour(),":", Minute(),":", Seconds());//show time (for convenience) //---- return(0); } //+------------------------------------------------------------------+
O código contém comentários.
Depois de anexá-los em gráfico, temos o seguinte resultado:
Vemos duas setas na última barra - para cima e para baixo. No canto superior esquerdo, vemos o resultado do jogo e do tempo terminal do último crédito. A contagem é apresentada em três figuras: a primeira é a pontuação total, a segunda (a primeiro entre colchetes) é o número de respostas positivas (previsão correta), a terceira (a segunda entre colchetes) é o número de respostas negativas (previsão incorreta). E o tempo é exibido para a conveniência da operação em modo de tela cheia (F11).
Agora, esperamos o início da próxima barra. Se a previsão estiver correta, a "Pontuação" terá a seguinte forma: "Pontuação: 1(1/0)". Se a previsão estiver incorreta, a "Pontuação" terá a seguinte forma: "Pontuação: -1(0/1)". E se o preço de fechamento for igual ao preço de abertura, a pontuação não vai mudar. No nosso exemplo, a previsão estava errada:
Melhoria
Nossa tarefa está cumprida. Mas há uma desvantagem de tal implementação: você pode fazer a sua escolha durante todo o castiçal, incluindo os últimos segundos. E isso parece injusto. Seria melhor, se fosse possível fazer a escolha nos primeiros 30 segundos. Para este fim, vamos introduzir a variável externa int - "time_limit". O seu valor será igual ao número de segundos durante o qual a escolha deve ser feita. Se um usuário não consegue fazer a seleção dentro deste período de tempo, as setas serão apagadas a partir do gráfico e aparecerão apenas no próximo castiçal.
As mudanças vão aparecer na parte de "trabalhar com objetos" (explicação nos comentários). Aqui está o código:
//+------------------------------------------------------------------+ //| trener.mq4 | //| Copyright © 2008, FXRaider | //| | //+------------------------------------------------------------------+ #property copyright "Copyright © 2008, FXRaider" //+------------------------------------------------------------------+ //| expert initialization function | //+------------------------------------------------------------------+ extern int gap=5; extern int time_limit=30; int init() { //---- //---- return(0); } //+------------------------------------------------------------------+ //| expert deinitialization function | //+------------------------------------------------------------------+ int deinit() { //---- //---- return(0); } //+------------------------------------------------------------------+ //| expert start function | //+------------------------------------------------------------------+ int start() { //------------------------------ string solution="none"; int point, point_neg, point_pos; //------------------------------ //+---------------------------------------------------------------+ //| "up" choice searching | if( ObjectGet("up", OBJPROP_PRICE1)==Open[1]+gap*Point &&iBarShift(NULL,0,ObjectGet("up",OBJPROP_TIME1))==1 &&ObjectFind("down") != 0 &&ObjectFind("up") == 0 ) { solution="up"; } //| "up" choice searching | //+---------------------------------------------------------------+ //+---------------------------------------------------------------+ //| "down" choice searching | if( ObjectGet("down", OBJPROP_PRICE1)==Open[1]-gap*Point &&iBarShift(NULL,0,ObjectGet("down",OBJPROP_TIME1))==1 &&ObjectFind("up") != 0 &&ObjectFind("down") == 0 ) { solution="down"; } //| "down" choice searching | //+---------------------------------------------------------------+ //+---------------------------------------------------------------+ //| counting points at a positive answer | if((solution=="up"&&Open[1]<Close[1]) ||(solution=="down"&&Open[1]>Close[1])) { point=1; point_pos=1; point_neg=0; } //| counting points at a positive answer | //+---------------------------------------------------------------+ //+---------------------------------------------------------------+ //| counting points at a negative answer | if((solution=="up"&&Open[1]>Close[1]) ||(solution=="down"&&Open[1]<Close[1])) { point=-1; point_pos=0; point_neg=1; } //| counting points at a negative answer | //+---------------------------------------------------------------+ //+----------------------------------------------------------------------------------+ //| working with an external file | int handle; double points, //total score points_pos, //score of positive answers points_neg; //score of negative answers handle=FileOpen("trener_"+Symbol()+"_"+Period()+".csv", FILE_CSV|FILE_WRITE|FILE_READ,";"); if(handle>0) //if there is a file, read it { points=NormalizeDouble(StrToDouble(FileReadString(handle)),Digits); points_pos=NormalizeDouble(StrToDouble(FileReadString(handle)),Digits); points_neg=NormalizeDouble(StrToDouble(FileReadString(handle)),Digits); FileClose(handle); } if(solution!="none") //if a choice is made { handle=FileOpen("trener_"+Symbol()+"_"+Period()+".csv", FILE_CSV|FILE_WRITE|FILE_READ,";"); FileWrite(handle ,points+point); //write the total score FileWrite(handle ,points_pos+point_pos); //write the score of positive answers FileWrite(handle ,points_neg+point_neg); //write the score of negative answers FileClose(handle); } //| working with an external file | //+----------------------------------------------------------------------------------+ //+------------------------------------------------------------------------------------+ //| working with objects | if(iBarShift(NULL,0,ObjectGet("down",OBJPROP_TIME1))>0 ||ObjectGet("down",OBJPROP_PRICE1)!=Open[0]-gap*Point) { ObjectDelete("down"); } if(iBarShift(NULL,0,ObjectGet("up",OBJPROP_TIME1))>0 ||ObjectGet("up",OBJPROP_PRICE1)!=Open[0]+gap*Point) { ObjectDelete("up"); } int sec_lim; if(!time_limit) { sec_lim=0; } else { sec_lim=TimeCurrent()-time_limit; } if(sec_lim>ObjectGet("up",OBJPROP_TIME1) &&sec_lim>ObjectGet("down",OBJPROP_TIME1) &&ObjectFind("down") == 0&&ObjectFind("up") == 0 &&iBarShift(NULL,0,ObjectGet("down",OBJPROP_TIME1))==0 &&iBarShift(NULL,0,ObjectGet("up",OBJPROP_TIME1))==0) { ObjectDelete("up"); ObjectDelete("down"); } if((ObjectFind("down") != 0&&ObjectFind("up") != 0) //if no objects &&sec_lim<Time[0]) { ObjectCreate("down", OBJ_ARROW, 0, Time[0], Open[0]-gap*Point); //draw a down arrow ObjectSet("down", OBJPROP_STYLE, STYLE_DOT); ObjectSet("down", OBJPROP_ARROWCODE, SYMBOL_ARROWDOWN); ObjectSet("down", OBJPROP_COLOR, Red); ObjectCreate("up", OBJ_ARROW, 0, Time[0], Open[0]+gap*Point); //draw an up arrow ObjectSet("up", OBJPROP_STYLE, STYLE_DOT); ObjectSet("up", OBJPROP_ARROWCODE, SYMBOL_ARROWUP); ObjectSet("up", OBJPROP_COLOR, Blue); } //| working with objects | //+------------------------------------------------------------------------------------+ Comment("Score: ", points," (",points_pos,"/",points_neg, //show the score ") | Time: ", Hour(),":", Minute(),":", Seconds());//Show time (for convenience) //---- return(0); } //+------------------------------------------------------------------+
Sendo assim, temos duas variáveis mutáveis nos parâmetros de entrada:
O parâmetro "vão" indica o número de pontos - a distância entre as setas e o preço de abertura do castiçal. A variável "time_limit" indica o número de segundos durante o usuário deve fazer sua escolha. Se o valor for "0", não haverá nenhuma limitação no tempo, isto é, uma opção pode ser feita ao longo de todo o castiçal.
Conclusão
Assim, implementamos uma versão simples de modelar apostas financeiras usando a linguagem MQL4. Este jogo pode ajudar muito no desenvolvimento da sua capacidade de "prever" o mercado, bem como pode ajudá-lo a aprender muitas regularidades na movimentação de títulos. A versão é implementado de forma que a atenção do leitor é maximamente concentrada no gráfico de preço. As operações executadas por um operador exigem pouco tempo e são fáceis de entender.
Eu gostaria de compartilhar meus próprios resultados do jogo. Eu consegui fazer previsões corretas para 5-10 castiçais em sucessão (em um gráfico de cinco minutos).
Usando este jogo, um operador pode aprender a responder uma das questões mais importantes: Para onde um título vai se mover? Ainda assim, há uma série de outras questões importantes, como a fixação do lucro, a fixação das perdas, a escolha do volume de um trade de abertura, etc. Apenas saber como responder a todas estas perguntas pode traze um resultado estável para o operador.
Uma das outras questões importantes é o tempo de descanso de um operador. Este jogo pode ser muito mais útil do que qualquer outro jogo existente no mercado de entretenimento.
Traduzido do russo pela MetaQuotes Ltd.
Artigo original: https://www.mql5.com/ru/articles/1505





- Aplicativos de negociação gratuitos
- 8 000+ sinais para cópia
- Notícias econômicas para análise dos mercados financeiros
Você concorda com a política do site e com os termos de uso