
Um exemplo de uma estratégia de negociação baseada na diferença de fuso horário em diferentes continentes
Introdução
Eu tive um pouco de tempo livre e estava claro que desta vez eu o passaria estudando os mercado e pesquisando a divergência de ciclos econômicos e indicadores técnicos. Você pode ver os resultados da pesquisa no seguinte artigo Criando um indicado com opções de controle gráfico. Mas estas não foram as únicas constatações! Descobri um fenômeno de uma escala ainda maior, mas para entender, vejamos nosso mundo em termos de fusos horários (Fig. 1).
Figura 1. Fusos horários
Como podemos ver, o dia começa diferente em cada país e continua com vários horários, enquanto vemos nosso grande vasto país expandido em quase 10 fusos, enquanto o Oceano Atlântico só se estende por mais 6 fusos horários.
Qual é o padrão aqui? Vamos olhar para a ordem da abertura dos mercados nos seguintes países: Japão, Austrália, China, Rússia. No momento que os funcionários na Rússia chegam em seus escritórios e começam as operações de negócio, na ásia já é de tarde e quando a sessão na Europa é aberta, eles já fecharam.
é aqui que a diversão começa. Uma vez o mercado é aberto, os corretores europeus e gerentes de hedge fund colocam seus ativos no mercado e tomam ações especulativas ou simultâneas com os interesses dos seus investidores. Não, é muito cedo para a parte mais interessante, que começa com o amanhecer em Chicago, em conexão com a menor extensão do Oceano Atlântico, chega uma hora em que os gerentes do mercado de ações de Chicago abrem seus terminais de negociação e começam a gerenciar seu capital.
Vamos parar por um momento, em conexão com a menor extensão do Oceano Atlântico. A sessão europeia ainda não terminou (Fig. 1). Londres é separada de Chicago em 8 zonas horárias, se presumirmos que o dia de trabalho tenha 8 horas + 45 minutos de pausa e uma hora a mais, o que prolonga o tempo em outras 1 hora e meia ou duas (aqueles que trabalham em escritório sabem disso).
Este é o momento que ganhamos os ativos de mercado dos gerentes europeus e americanos. Tenho medo de listar todos os zeros dos ativos a esse ponto, os gerentes americanos e europeus começam seu esforço pelo preço das bolsas e, neste ponto, é um fenômeno, como mostra a Figura 2.
Figura 2. Pulso do Mercado
Batalhas financeiras enchem o mercado, ativos mudam de dono a cada segundo, mas não é nisso em que o mercado termina! Depois que este período acaba, um movimento quieto se inicia na direção da tendência atual. Neste ponto, a faixa estende seus limites e depois os estreita mais uma vez e continua adiante a mover na direção da tendência principal.
Estou certo de que você percebeu que o preço de mercado pode subir ou descer, mas sempre se move em direção à direita.
2. Fluxogramas como método principal de desenvolvimento de um algoritmo
O primeiro bloco do programa "Iniciar-Parar" é demonstrado na Figura 3:
Figura 3. Bloco "Iniciar-Parar"
Este bloco é utilizado para denotar o início do programa, o início e o fim de uma função ou outro procedimento, como uma inicialização e finalização. O próximo bloco que olharemos é classificado como "Dados" e é representado na Figura 4.
Figura 4. Bloco "dados"
O bloco "dados" é utilizado para determinar os parâmetros especificados na inicialização do programa ou as variáveis de saída no caso do MQL5. A unidade também serve de função de destinação das variáveis globais.
A seguir, levamos em consideração um bloco comumente utilizado (99% dos programas em MQL utilizam este método) - está descrito em duas partes, que marcam os limites de um ciclo. Considere a Fig. 5:
Figura 5. Blocos de ciclos
Processos como atribuição ou contabilidade geralmente ocorrem dentro destes ciclos, exemplos dos quais estão descritos na Figura 6.
Figura 6. Ações
E não devemos esquecer sobre os blocos lógicos - a Fig. 7 mostra o bloco "solução".
Figura 7. O bloco "solução"
O bloco "solução" também pode ter mais de dois resultados se estiver localizado dentro do operador do "botão, o que depende do número de tipo de localizações. Esta unidade terá um número de saídas correspondentes.
O próximo bloco induz funções pré-definidas como iMACD ou iRSA, assim como funções personalizadas, definidas em outro lugar do programa ou na biblioteca (Fig. 8).
Figura 8. Função
E os dois últimos blocos implementam apenas funções de serviço - como comentários e a quebra (Fig. 9).
Figura 9. Blocos de serviço
Estes são todos os tipos de blocos que podem ser usados para descrever qualquer programa escrito para uma máquina; eles são todos claros, simples e fáceis de usar, no primeiro estágio de desenvolvimento, eles também revelam os pontos fracos do sistema e inventam métodos para eliminá-los.
Agora você está familiarizado com este método, no entanto, não estou pedindo para que você aja precisamente de acordo com estes esquemas, mas simplesmente conheça o valor inicial dos fluxogramas, é fácil o suficiente para entender alguns tipos de métodos de cálculo. Este método me ajuda a facilmente formular uma ideia, que havia rapidamente disparado no hemisfério esquerdo do meu cérebro, pronto para escapar do hemisfério direito.
3. Construção do algoritmo
E então, vamos seguir para a preparação do Conselheiro Especialista com base na estratégia do fluxograma.
O primeiro bloco estará requisitando os parâmetros de entrada. Conforme nós determinamos, é de vital importância esperar até o momento das batalhas principais, ou seja, duas horas depois da sessão de abertura dos Estados Unidos, quando os mercados europeus fecham. Observaremos isto no relógio global, ou seja, no horário do terminal e então calcularemos a hora de abertura por conta própria.
Então, determinaremos o tamanho das posições e os níveis de lucro e perda, o que no futuro têm o potencial de otimização. Será dada atenção especial ao parâmetro do número mágico, já que será usado por nosso Conselheiro Especialista para determinar sua ordem e abrir negociações. Mais adiante, faremos um limite móvel (trailing stop) para limitar o risco de nossas posições, em relação às nossas observações.
Existe outro parâmetro interessante que precisaremos - um nível seguro de acordo com o que veremos, a presença de notícias econômicas significantes no momento, e se elas impõe ou não uma ameaça, considerando que o pânico principal nos mercados surge dentro destas duas horas.
Figura 10. Parâmetros de entrada
//--- input parameters input int America=16; input double Lots=0.1; input int TakeProfit=500; input long MagicNumber=665; input int Limited=600; input int TrailingStop=100;
Vamos prosseguir até a próxima parte da formação da estratégia.
Precisamos determinar se a sessão foi um cruzamento e se as ordens foram ou estão sendo definidas. (Fig. 11)
Figura 11. Hora de negociar
Como você pode ver, o algorítimo dado é um programa fechado com parâmetros de entrada, cálculos completos e resultados de saída. Tais mini programas são chamados de funções e são protegidos do programa principal pela encapsulação.
O encapsulamento é uma barreira entre os programas ou partes do programa, que é separado por métodos, como o Get e Set (get e set) para evitar que eles atravessem o território de outros "gets e sets". A essência deste processo reside no fato de que os nomes das variáveis podem ser os mesmo entre as funções e dentro do programa principal, mas quando o método Get tenta tirar de uma célula com um nome variável, ele enfrentará o encapsulamento, que apenas o dará acesso a setor particular das células de memória, alocadas para esta função ou programa.
O mesmo se aplica ao método Set, mas ao contrário do Get. Ele ajusta o valor na memória da célula para o nome da variável e se os nomes das variáveis dentro do programa ou dentro da função coincidirem, então o encapsulamento não permitirá que o método Set atribua os valores das variáveis dentro de outro programa ou função.
bool time2trade(int TradeHour,int Number) { MqlDateTime time2trade; TimeTradeServer(time2trade); if(time2trade.hour!=TradeHour) return(false); time2trade.hour= 0; time2trade.min = 0; time2trade.sec = 1; for(int ii=OrdersTotal()-1;ii>=0;ii--) { OrderGetTicket(ii); long ordmagic=OrderGetInteger(ORDER_MAGIC); if(Number==ordmagic) return(false); } HistorySelect(StructToTime(time2trade),TimeTradeServer()); for(int ii=HistoryOrdersTotal()-1;ii>=0;ii--) { long HistMagic=HistoryOrderGetInteger(HistoryOrderGetTicket(ii),ORDER_MAGIC); if(Number==HistMagic) return(false); } return(true); }
Nós identificamos a sessão exigida e determinamos se definimos as ordens ou não. Vamos levar em consideração o que deve ser feito a seguir.
Anteriormente, notamos que as maiores flutuações ocorrem 2 horas após a abertura da sessão nos Estados Unidos Temos 9 barras de 15 minutos após a abertura da sessão americana. Encontramos o maior intervalo para este período e o levamos em consideração com cuidado - se esta variação for grande o suficiente, então, mais provavelmente, há um pânico amplamente disseminado no mercado e as tendências futuras são difíceis de prever. Portanto, precisaremos de um pouco de restrição aqui.
Quando o mercado está calmo, a sessão aumentará sua volatilidade. Isto nos dará a oportunidade de determinar o desvio máximo da tendência principal e colocar as armadilhas de ordem a uma distância segura, que funcionará por que a tendência principal continuará. Conforme observamos antes, o preço pode tanto subir como cair, mas ele sempre muda para a direita. (Fig. 12)
Figura 12. Algorítimo de ajuste de ordem
Modulando o código do programa, atente ao fato de que o terminal de negócio do MetaTrader 5 não permite a configuração de um fechamento de ordem ao preço da última transação. Se neste momento o preço atrai uma nova mínima ou máxima, defenderemos nossa posição recuando a uma distância mínima do preço da última transação, para uma determinação confiável de uma ordem. Além disso, definiremos o período de duração de nossas ordens antes do final do dia, já que posteriormente elas não serão mais eficazes.
void OnTick() { //--- if(time2trade(America+2,MagicNumber)) { int i; double Highest = 0; double Lowest = 0; MqlRates Range[]; CopyRates(Symbol(),15,0,9,Range); Lowest=Range[1].low; for(i=0; i<9;i++) { if(Highest<Range[i].high) Highest=Range[i].high;//MathMax(,Highest); if(Lowest>Range[i].low) Lowest=Range[i].low; } long StopLevel=SymbolInfoInteger(Symbol(),SYMBOL_TRADE_STOPS_LEVEL); Highest=Highest+StopLevel*Point(); // add to the current prices parameters of the minimum distance possible for the setting of orders Lowest=Lowest-StopLevel*Point(); // to ensure the maximum probability of the acceptance of our order 30> if((Higest-Lowest)/Point()<Limited) { MqlTradeRequest BigDogBuy; MqlTradeRequest BigDogSell; BigDogBuy.action=TRADE_ACTION_PENDING; // Set the pending order BigDogBuy.magic = MagicNumber; BigDogBuy.symbol=Symbol(); BigDogBuy.price=Highest; //Price by which the order will be set BigDogBuy.volume=Lots; BigDogBuy.sl=Lowest; //if the stop loss is not set, then set by the strategy /s39> BigDogBuy.tp=Highest+TakeProfit*Point(); //set the take profit/s41> BigDogBuy.deviation=dev; //minimum deviation from the requested price, //in other words, by how much the executed price can differ from the specified price BigDogBuy.type=ORDER_TYPE_BUY_STOP; //order type, which is executed based on the specified price or by a higher than specified price //in this case the order is set to a higher or equal amount to the specified price //if the order type was buy_limit, then it would be executed //by the specified price, or prices lower than the specified price BigDogBuy.type_filling=ORDER_FILLING_AON; //the given parameter demonstrates how the order acts //with partial execution of the scope BigDogBuy.expiration=TimeTradeServer()+6*60*60; //by the strategy text the order life span only for the current work day //since it has been 2 hours since the opening of the American market, and the work day is 8 hours, we have 8-2 = 6 BigDogSell.action=TRADE_ACTION_PENDING; // Set the pending order BigDogSell.magic = MagicNumber; BigDogSell.symbol=Symbol(); BigDogSell.price=Lowest; //Price, by which the order will be set BigDogSell.volume=Lots; BigDogSell.sl=Highest; //Stop loss set by the strategy BigDogSell.tp=Lowest-TakeProfit*Point(); //set the take profit BigDogSell.deviation=dev; //Minimum deviation from the requested price, //in other words, by how much the executed price can differ from the specified price BigDogSell.type=ORDER_TYPE_SELL_STOP; //order type, which is executed based on the specified price or by a higher than specified price //in this case the order is set to a higher or equal amount to the specified price //if the order type was buy_limit, then it would be executed //by the specified price, or prices lower than the specified price BigDogSell.type_filling=ORDER_FILLING_AON; //the given parameter demonstrates how the order acts ///with partial execution of the scope BigDogSell.expiration=TimeTradeServer()+6*60*60; //by the strategy text the order life span only for the current work day //since it has been 2 hours since the opening of the American market, and the work day is 8 hours, we have 8-2 = 6 MqlTradeResult ResultBuy,ResultSell; OrderSend(BigDogBuy,ResultBuy); OrderSend(BigDogSell,ResultSell); } }
As ordens são posicionadas, as armadilhas definidas - agora é hora de cuidar de reduzir os riscos de nossas posições, vamos aplicar a tecnologia de limite móvel (trailing stop).
Para identificar nossa posição, usaremos o número mágico (MagicNumber), e mudar o nível de stop-loss quando ele alcançar um determinado nível de lucro com mínimas mudanças de preço. (Figura 13)
Figura 13. Implementação do limite móvel
Para as diferentes estratégias, o limite móvel é implementado utilizando o método mais simples, embora em algumas estratégias, recomenda-se não utilizar um limite móvel, de modo a não evitar que o preço alcance seu objetivo ou utilizar tal mecanismo apenas para a transferência de posições para sem perdas. Mas nesta estratégia, aplicamos o mecanismo clássico para mover a parada de proteção, em caso de alteração de preço, em nossa direção para um certo número mínimo de alterações de preço.
//--- trailing implementation int PosTotal=PositionsTotal(); for(int i=PosTotal-1; i>=0; i--) { //--- go through open positions and see if there are positions created by this Expert Advisor. if(PositionGetSymbol(i)==Symbol()) { if(MagicNumber==PositionGetInteger(POSITION_MAGIC)) { MqlTick lasttick; SymbolInfoTick(Symbol(),lasttick); if(PositionGetInteger(POSITION_TYPE)==0) { //--- buy if(TrailingStop>0 &&(((lasttick.bid-PositionGetDouble(POSITION_PRICE_OPEN))/Point())>TrailingStop) && ((lasttick.bid-PositionGetDouble(POSITION_SL))/Point())>TrailingStop) { MqlTradeRequest BigDogModif; ZeroMemory(BigDogModif); BigDogModif.action= TRADE_ACTION_SLTP; BigDogModif.symbol= Symbol(); BigDogModif.sl = lasttick.bid - TrailingStop*Point(); BigDogModif.tp = PositionGetDouble(POSITION_TP); BigDogModif.deviation=3; MqlTradeResult BigDogModifResult; ZeroMemory(BigDogModifResult); OrderSend(BigDogModif,BigDogModifResult); } } if(PositionGetInteger(POSITION_TYPE)==1) {//--- sell if(TrailingStop>0 && ((PositionGetDouble(POSITION_PRICE_OPEN)-lasttick.ask)/Point()>TrailingStop) && (PositionGetDouble(POSITION_SL)==0 || (PositionGetDouble(POSITION_SL)-lasttick.ask)/Point()>TrailingStop)) { MqlTradeRequest BigDogModif; ZeroMemory(BigDogModif); BigDogModif.action= TRADE_ACTION_SLTP; BigDogModif.symbol= Symbol(); BigDogModif.sl = lasttick.ask + TrailingStop*Point(); BigDogModif.tp = PositionGetDouble(POSITION_TP); BigDogModif.deviation=3; MqlTradeResult BigDogModifResult; ZeroMemory(BigDogModifResult); OrderSend(BigDogModif,BigDogModifResult); } } } } } }
A seguir, obtemos o nosso algorítimo. (Fig. 14)
Fig. 14. Montando um algorítimo
//+------------------------------------------------------------------+ //| BigDog_By_CoreWinTT.mq5 | //| Copyright 2010, MetaQuotes Software Corp. | //| http://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "2010, MetaQuotes Software Corp." #property link "http://www.mql5.com" #property version "1.00" //--- input parameters input int America=16; input double Lots=0.1; input int TakeProfit=500; input long MagicNumber=665; input int Limited=600; input int TrailingStop=100; int dev=30; //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- return(0); } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { //--- } //+------------------------------------------------------------------+ bool time2trade(int TradeHour,int Number) { MqlDateTime time2trade; TimeTradeServer(time2trade); if(time2trade.hour!=TradeHour) return(false); time2trade.hour= 0; time2trade.min = 0; time2trade.sec = 1; for(int ii=OrdersTotal()-1;ii>=0;ii--) { OrderGetTicket(ii); long ordmagic=OrderGetInteger(ORDER_MAGIC); if(Number==ordmagic) return(false); } HistorySelect(StructToTime(time2trade),TimeTradeServer()); for(int ii=HistoryOrdersTotal()-1;ii>=0;ii--) { long HistMagic=HistoryOrderGetInteger(HistoryOrderGetTicket(ii),ORDER_MAGIC); if(Number==HistMagic) return(false); } return(true); } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { //--- if(time2trade(America+2,int(MagicNumber))) { int i; double Highest= 0; double Lowest = 0; MqlRates Range[]; CopyRates(Symbol(),15,0,9,Range); Lowest=Range[1].low; for(i=0; i<9;i++) { if(Highest<Range[i].high) Highest=Range[i].high; if(Lowest>Range[i].low) Lowest=Range[i].low; } long StopLevel=SymbolInfoInteger(Symbol(),SYMBOL_TRADE_STOPS_LEVEL); Highest=Highest+StopLevel*Point(); //--- add to the current prices the parameters of a minimum possible distance for the order set. Lowest=Lowest-StopLevel*Point(); //--- to ensure the maximum probability of the acceptance of our order. if((Highest-Lowest)/Point()<Limited) { MqlTradeRequest BigDogBuy; MqlTradeRequest BigDogSell; ZeroMemory(BigDogBuy); ZeroMemory(BigDogSell); BigDogBuy.action=TRADE_ACTION_PENDING; //--- set the pending order BigDogBuy.magic = MagicNumber; BigDogBuy.symbol=Symbol(); BigDogBuy.price=Highest; //--- Price by which the order will be set BigDogBuy.volume=Lots; BigDogBuy.sl=Lowest; //--- if the stop loss is not established, then we set by the strategy BigDogBuy.tp=Highest+TakeProfit*Point(); //--- set the take profit BigDogBuy.deviation=dev; //--- Minimum deviation from the requested price, //--- in other words, by how much the executed price can differ from the specified price BigDogBuy.type=ORDER_TYPE_BUY_STOP; //--- order type, which is executed based on the specified price or by a higher than specified price //--- in this case the order is set to a higher or equal amount to the specified price //--- if the order type was buy_limit, then it would be executed //--- by the specified price, or prices lower than the specified price BigDogBuy.type_filling=ORDER_FILLING_FOK; //--- the given parameter demonstrates how the order acts //--- with partial execution of the scope BigDogBuy.expiration=TimeTradeServer()+6*60*60; //--- by the strategy text the order life span only for the current work day //--- since it has been 2 hours since the opening of the American market, //--- and the work day is 8 hours, we have 8-2 = 6 BigDogSell.action=TRADE_ACTION_PENDING; //-- Set the pending order BigDogSell.magic = MagicNumber; BigDogSell.symbol=Symbol(); BigDogSell.price=Lowest; //--- Price by which the order will be set BigDogSell.volume=Lots; BigDogSell.sl=Highest; //-- Stop loss set by the strategy BigDogSell.tp=Lowest-TakeProfit*Point(); //--- Set take profit BigDogSell.deviation=dev; //--- Minimum deviation from the requested price, //--- in other words, by how much the executed price can differ from the specified price BigDogSell.type=ORDER_TYPE_SELL_STOP; //--- order type, which is executed based on the specified price or by a higher than specified price //--- in this case the order is set to a higher or equal amount to the specified price //--- if the order type was buy_limit, then it would be executed //--- by the specified price, or prices lower than the specified price BigDogSell.type_filling=ORDER_FILLING_FOK; //--- the given parameter demonstrates how the order acts //--- with partial execution of the scope BigDogSell.expiration=TimeTradeServer()+6*60*60; //-- by the strategy text the order life span only for the current work day //--- since it has been 2 hours since the opening of the American market, //--- and the work day is 8 hours, we have 8-2 = 6 MqlTradeResult ResultBuy,ResultSell; ZeroMemory(ResultBuy); ZeroMemory(ResultSell); OrderSend(BigDogBuy,ResultBuy); OrderSend(BigDogSell,ResultSell); } } //--- trailing implementation int PosTotal=PositionsTotal(); for(int i=PosTotal-1; i>=0; i--) { //--- go through open positions and see if there are positions created by this Expert Advisor. if(PositionGetSymbol(i)==Symbol()) { if(MagicNumber==PositionGetInteger(POSITION_MAGIC)) { MqlTick lasttick; SymbolInfoTick(Symbol(),lasttick); if(PositionGetInteger(POSITION_TYPE)==0) { //--- buy if(TrailingStop>0 &&(((lasttick.bid-PositionGetDouble(POSITION_PRICE_OPEN))/Point())>TrailingStop) && ((lasttick.bid-PositionGetDouble(POSITION_SL))/Point())>TrailingStop) { MqlTradeRequest BigDogModif; ZeroMemory(BigDogModif); BigDogModif.action= TRADE_ACTION_SLTP; BigDogModif.symbol= Symbol(); BigDogModif.sl = lasttick.bid - TrailingStop*Point(); BigDogModif.tp = PositionGetDouble(POSITION_TP); BigDogModif.deviation=3; MqlTradeResult BigDogModifResult; ZeroMemory(BigDogModifResult); OrderSend(BigDogModif,BigDogModifResult); } } if(PositionGetInteger(POSITION_TYPE)==1) {//--- sell if(TrailingStop>0 && ((PositionGetDouble(POSITION_PRICE_OPEN)-lasttick.ask)/Point()>TrailingStop) && (PositionGetDouble(POSITION_SL)==0 || (PositionGetDouble(POSITION_SL)-lasttick.ask)/Point()>TrailingStop)) { MqlTradeRequest BigDogModif; ZeroMemory(BigDogModif); BigDogModif.action= TRADE_ACTION_SLTP; BigDogModif.symbol= Symbol(); BigDogModif.sl = lasttick.ask + TrailingStop*Point(); BigDogModif.tp = PositionGetDouble(POSITION_TP); BigDogModif.deviation=3; MqlTradeResult BigDogModifResult; ZeroMemory(BigDogModifResult); OrderSend(BigDogModif,BigDogModifResult); } } } } } } //+------------------------------------------------------------------+
Conclusão
Existem muitos fenômenos de mercado que ocorrem periodicamente e de maneira regular e, quando pesquisados, podem nos conceder certa vantagem. Além disso, talvez, negociantes mais experientes perceberam alguma sobreposição com a estratégia conhecida "BigDog", o artigo não o menciona, e fiz isso de propósito - para que o leitor pense sobre como eles realmente são preparados.
Na internet você pode se familiarizar com diferentes variações desta estratégia, este artigo trata apenas do fenômeno, no qual esta estratégia está baseada.
Traduzido do russo pela MetaQuotes Ltd.
Artigo original: https://www.mql5.com/ru/articles/59





- 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