Lite_EXPERT2.mqh: Exemplos da implementação do Expert Advisor
Introdução
Em meu artigo anterior intitulado "Lite_EXPERT2.mqh: Kit Funcional para Desenvolvedores de Expert Advisors", eu familiarizei os leitores com as funções do Lite_EXPERT2.mqh. Neste artigo, vou dar exemplos reais de implementação do Expert Advisor que usam essas funções. Eu acredito que a operação das funções de negociação não é materialmente
OpenBuyOrder1_() OpenSellOrder1_() OpenBuyOrder2_() OpenSellOrder2_() OpenBuyLimitOrder1_() OpenBuyStopOrder1_() OpenSellLimitOrder1_() OpenSellStopOrder1_() Make_BuyTrailingStop_() Make_SellTrailingStop_()
diferente das funções semelhantes fornecidas no arquivo Lite_EXPERT1.mqh,
É improvável que cause qualquer confusão a inicialização de mais algumas variáveis externas (ver Exp_0_1.mq4 e Exp_0.mq4; Exp_1.mq4 e EXP_1_1.mq4). Portanto, não há absolutamente nenhuma necessidade de voltar a elas mais uma vez. Vou prosseguir diretamente aos exemplos construídos, utilizando as funções de negociação que usam valores absolutos dos níveis de preços do gráfico como variáveis externas para ordens pendentes.
ddOpenBuyOrder1_() dOpenSellOrder1_() dOpenBuyOrder2_() dOpenSellOrder2_() dOpenBuyLimitOrder1_() dOpenBuyStopOrder1_() dOpenSellLimitOrder1_() dOpenSellStopOrder1_() dModifyOpenBuyOrder_() dModifyOpenSellOrder_() dModifyOpenBuyOrderS() dModifyOpenSellOrderS() dMake_BuyTrailingStop_() dMake_SellTrailingStop_()
As estratégias de negociação que serão discutidas neste artigo são baseadas no indicador Average True Range, então é com este assunto que eu vou começar este artigo.
Usando o Indicador Average True Range em Sistemas Mecânicos de Negociação
O indicador Average True Range (doravante - ATR) foi desenvolvido por Welles Wilder e introduzido pela primeira vez no seu livro "Novos conceitos em Sistemas Técnicos de Negociação" em 1978. Este indicador tornou-se bastante popular e ainda é incluído em muitos pacotes de software de análise técnica. O indicador ATR em si não indica direções da tendência atual, mas fornece uma imagem gráfica de volatilidade ou atividade do mercado em questão.
Essencialmente este indicador pode ser usado em sistemas de negociação mecânicas através de duas variantes:
1. Sinais de filtragem do sistema de negociação para a identificação das condições de tendências e falta de tendências no mercado.
Neste caso, a direção de tendência e sinais de entradas são recebidos a partir de outros indicadores, enquanto o indicador de ATR somente proporciona uma condição de entrada adicional. Por exemplo, tal condição adicional pode ser o rompimento do valor médio do indicador pelo próprio indicador. Para obter o valor médio ATR é conveniente usar a linha média do sinal com base no ATR.
2. Ordens pendentes adaptativas.
O valor absoluto deste indicador determina as distâncias a partir da abertura dos preços das barras, fora da qual, muito provavelmente, as flutuações fortes de preços irão iniciar. Por isso é muito prático de usar esses níveis para definir ordens pendentes de abertura de posições e níveis de Stop Loss. Neste caso, temos a oportunidade de usar o indicador ATR para definir ordens a uma certa distância em relação ao preço, se adaptando à volatilidade do mercado atual em cada negócio. A distância fixa definida nas condições reais do mercado é visto como um velho general de exército, sempre de prontidão ao combate referente a uma guerra que há muito tempo se tornou história. Isso geralmente resulta num interessante desempenho do sistema de negociação no real, com as condições do mercado em constante mudança. De forma muito semelhante, você pode usar a distância ATR para mover níveis de Trailing Stop ao preço em cada mudança de barra.
Agora, podemos prosseguir para o desenvolvimento de Expert Advisors usando o arquivo Lite_EXPERT2.mqh. A melhor maneira de fazer isso é começar com a modernização da construção dos Expert Advisors com base no Lite_EXPERT1.mqh, a fim de conseguir maior flexibilidade na negociação.
Sistema de Negociação que Usa Mudanças na Direção da MA como Sinais de Entrada e Saída no Mercado
Já tenho uma descrição detalhada de um sistema deste tipo no meu artigo intitulado "Expert Advisors Baseados em Sistemas Populares de Negociação e Alquímia de Otimização de Robô de Negociação", dedicada a sistemas de negociação muito básicos.
É hora de torná-los mais complexos. Um sistema de negociação quase semelhante com base nas funções do Lite_EXPERT2.mqh foi desenvolvido no Expert Advisor Exp_1_1.mq4 (original Exp_1.mq4). Nós apenas precisamos substituir o Stop Loss e Take Profit fixados pelos recalculados em unidades ATR e adicionar os níveis semelhantes de Trailing Stop que irão deslocar uma vez em cada barra alterada. Este é melhor implementado em duas etapas. Nós primeiro substituimos o Stop Loss e Take Profit (Expert Advisor Exp_17_A.mq4 Expert), e depois checamos os erros no código e estando em conformidade com a estratégia de negociação selecionada, somamos os níveis de Trailing Stop (o Expert Advisor Exp_17.mq4). No artigo, eu somente fonecerei a versão final com descrições mais detalhadas sobre as alterações feitas no código.
//+X==================================================================X+ //| Exp_17.mq4 | //| Copyright © 2009, Nikolay Kositsin | //| Khabarovsk, farria@mail.redcom.ru | //+X==================================================================X+ #property copyright "Copyright © 2009, Nikolay Kositsin" #property link "farria@mail.redcom.ru" //+--------------------------------------------------------------------+ //| PARÂMETROS DE ENTRADA DO EXPERT ADVISOR PARA POSIÇÕES COMPRADAS | //+--------------------------------------------------------------------+ extern bool Test_Up = true; // filtro da direção de cálculo da posição extern int Timeframe_Up = 240; extern double Money_Management_Up = 0.1; extern int Length_Up = 4; // profundidade de suavização extern int Phase_Up = 100; // parâmetro que varia dentro do intervalo (-100 .. + 100), impacta a qualidade do processo de transição; extern int IPC_Up = 0; extern int ATR_Period_Up = 14; // período do ATR extern int LevMinimum_Up = 40; // valor mínimo em pontos abaixo // quais os valores de ordens pendentes não podem falhar extern int STOPLOSS_Up = 100; // Stop Loss expresso em percentagem do ATR extern int TAKEPROFIT_Up = 200; // Take Profit expresso em percentagem do ATR extern int TRAILINGSTOP_Up = 100; // Trailing stop expresso em percentagem do ATR extern bool ClosePos_Up = true; // Permissão para forçar o fechamento de uma posição //+--------------------------------------------------------------------+ //| PARÂMETROS DE ENTRADA DO EXPERT ADVISOR PARA POSIÇÕES VENDIDAS | //+--------------------------------------------------------------------+ extern bool Test_Dn = true; // filtro da direção de cálculo da posição extern int Timeframe_Dn = 240; extern double Money_Management_Dn = 0.1; extern int Length_Dn = 4; // Profundidade de suavização extern int Phase_Dn = 100; // parâmetro que varia dentro do intervalo (-100 .. + 100), impacta a qualidade do processo de transição; extern int IPC_Dn = 0; extern int ATR_Period_Dn = 14; // período do ATR ]extern int LevMinimum_Up = 40; // Valor mínimo em pontos abaixo // quais os valores de ordens pendentes não podem falhar extern int STOPLOSS_Dn = 100; // Stop Loss expresso em percentagem do ATR extern int TAKEPROFIT_Dn = 200; // Take Profit expresso em percentagem do ATR extern int TRAILINGSTOP_Dn = 100; // Trailing Stop expresso em percentagem do ATR extern bool ClosePos_Dn = true; // Permissão para forçar o fechamento de uma posição //+--------------------------------------------------------------------+ //---- Declaração de variáveis inteiras para cálculo mínimo das barras int MinBar_Up, MinBar_Dn; //---- Declaração de variáveis inteiras para o timeframe do gráfico em segundos int Period_Up, Period_Dn; //---- declaração de variáveis de ponto flutuante para ordens pendentes double _STOPLOSS_Up, _TAKEPROFIT_Up, _LevMinimum_Up, _TRAILINGSTOP_Up; double _STOPLOSS_Dn, _TAKEPROFIT_Dn, _LevMinimum_Dn, _TRAILINGSTOP_Dn; //+X==================================================================X+ //| Funções personalizada do Expert | //+X==================================================================X+ #include <Lite_EXPERT2.mqh> //+X==================================================================X+ //| Função personalizada de inicialização do Expert | //+X==================================================================X+ int init() { // ---- Checar a correção do valor da variável Timeframe_Up TimeframeCheck("Timeframe_Up", Timeframe_Up); // ---- Checar a correção do valor da variável Timeframe_Dn TimeframeCheck("Timeframe_Dn", Timeframe_Dn); // ---- Inicialização das variáveis MinBar_Up = 4 + 39 + 30;// Quatro barras para entrada de sinais + comprimento do filtro FATL + comprimento do filtro JMA MinBar_Up = MathMax(MinBar_Up, ATR_Period_Up + 1); MinBar_Dn = 4 + 39 + 30;// Quatro barras para entrada de sinais + comprimento do filtro FATL + comprimento do filtro JMA MinBar_Dn = MathMax(MinBar_Dn, ATR_Period_Dn + 1); //---- Period_Up = Timeframe_Up * 60; // timeframe do gráfico para posições compradas em segundos Period_Dn = Timeframe_Dn * 60; // timeframe gráfico para posições curtas em segundos //---- Conversão de porcentagem para fração _STOPLOSS_Up = STOPLOSS_Up / 100.0; _TAKEPROFIT_Up = TAKEPROFIT_Up / 100.0; _TRAILINGSTOP_Up = TRAILINGSTOP_Up / 100.0; //---- Conversão de porcentagem para fração _STOPLOSS_Dn = STOPLOSS_Dn / 100.0; _TAKEPROFIT_Dn = TAKEPROFIT_Dn / 100.0; _TRAILINGSTOP_Dn = TRAILINGSTOP_Dn / 100.0; // ---- Conversão dos pontos mínimos para a distância mínima do preço _LevMinimum_Up = LevMinimum_Up * Point; _LevMinimum_Dn = LevMinimum_Dn * Point; // ---- inicialização completa return(0); } //+X==================================================================X+ //| Função de desinicialização do expert | //+X==================================================================X+ int deinit() { // ---- + Excluindo variáveis globais após testes e otimizações TimeLevelGlobalVariableDel(Symbol(), 1); TimeLevelGlobalVariableDel(Symbol(), 2); //---- desinicialização completa do Expert Advisor return(0); //----+ } //+X==================================================================X+ //| Função personalizada de iteração do Expert | //+X==================================================================X+ int start() { //----+ //----+ Declaração de variáveis locais int bar; double Mov[3], dMov12, dMov23, ATR, Level, open; //----+ Declaração de variáveis estáticas static datetime TradeTimeLevel_Up, TradeTimeLevel_Dn; //---- static bool BUY_Sign, BUY_Stop, SELL_Sign, SELL_Stop; static bool TrailSignal_Up, TrailSignal_Dn; //---- static double dStopLoss_Up, dTakeProfit_Up, dTrailingStop_Up; static double dStopLoss_Dn, dTakeProfit_Dn, dTrailingStop_Dn; //+-------------------------------+ //|CÓDIGO PARA POSIÇÕES COMPRADAS | //+-------------------------------+ if (Test_Up) if (MinBarCheck(Symbol(), Timeframe_Up, MinBar_Up)) { if (IsNewBar(0, Symbol(), Timeframe_Up)) { //----+ Zerar sinais de negociação BUY_Sign = false; BUY_Stop = false; //---- Obtendo o prazo limite para desativação // a próxima operação de negociação TradeTimeLevel_Up = iTime(NULL, Timeframe_Up, 0); if (TradeTimeLevel_Up == 0) return(-1); TradeTimeLevel_Up += Period_Up; //----+ CALCULANDO E CARREGANDO VALORES PARA BUFFERS DO INDICADOR for(bar = 1; bar <= 3; bar++) Mov[bar - 1]= iCustom(NULL, Timeframe_Up, "JFatl", Length_Up, Phase_Up, 0, IPC_Up, 0, bar); //----+ DETERMINANDO SINAIS PARA OPERAÇÕES dMov12 = Mov[0] - Mov[1]; dMov23 = Mov[1] - Mov[2]; //---- Conseguindo um sinal para abrir uma posição if (dMov23 < 0) if (dMov12 > 0) BUY_Sign = true; //---- Conseguindo um sinal para fechar uma posição if (dMov12 < 0) if (ClosePos_Up) BUY_Stop = true; //----+ CALCULANDO ORDENS PENDENTES PARA POSIÇÕES COMPRADAS // Faz cálculo de ordem apenas se o sinal de negociação está disponível if (BUY_Sign) { //---- Obtendo o valor inicial ATR ATR = iATR(NULL, Timeframe_Up, ATR_Period_Up, 1); //---- Obtendo o preço atual open = iOpen(Symbol(), Timeframe_Up, 0); //---- Calculando a distância ao Stop Loss Level = ATR * _STOPLOSS_Up; //---- Verificando a distância ao Stop Loss contra o valor mínimo if (Level < _LevMinimum_Up) Level = _LevMinimum_Up; //---- Determinando o valor absoluto do Stop Loss dStopLoss_Up = open - Level; //---- Calculando a distância ao Take Profit Level = ATR * _TAKEPROFIT_Up; //---- Verificando a distância ao Take Profit contra o valor mínimo if (Level < _LevMinimum_Up) Level = _LevMinimum_Up; //---- Determinando o valor absoluto do Take Profit dTakeProfit_Up = open + Level; //---- Corrigindo os valores de ordens pendente, // tendo em conta a direção da negociação dGhartVelueCorrect(OP_BUY, dStopLoss_Up); dGhartVelueCorrect(OP_BUY, dTakeProfit_Up); } //----+ CALCULANDO OS TRAILING STOPS PARA POSIÇÕES COMPRADAS dTrailingStop_Up = 0; TrailSignal_Up = false; //---- if (TRAILINGSTOP_Up > 0) // Calcula o Trailing Stop apenas se a posição necessária existir if (OrderSelect_(Symbol(), OP_BUY, 1, MODE_TRADES)) // Move Trailing Stop se a posição é aberta sobre uma barra diferente de zero if (iBarShift(NULL, Timeframe_Up, OrderOpenTime(), false) > 0) { TrailSignal_Up = true; //---- Obtendo o valor inicial ATR ATR = iATR(NULL, Timeframe_Up, ATR_Period_Up, 1); //---- Obtendo o preço atual open = iOpen(Symbol(), Timeframe_Up, 0); //---- Calculando a distância ao Stop Loss Level = ATR * _TRAILINGSTOP_Up; //---- Verificando a distância ao Stop Loss contra o valor mínimo if (Level < _LevMinimum_Up) Level = _LevMinimum_Up; //---- Obtendo o valor absoluto do Trailing Stop dTrailingStop_Up = open - Level; //---- Corrigindo o valor absoluto do Trailing Stop, // de acordo com a direção da negociação ( a posição // das funções de modificação do valor da variável cmd é inversa!) dGhartVelueCorrect(OP_SELL, dTrailingStop_Up); } } //----+ EXECUÇÃO DE OPERAÇÃO if (!dOpenBuyOrder1_(BUY_Sign, 1, TradeTimeLevel_Up, Money_Management_Up, 5, dStopLoss_Up, dTakeProfit_Up)) return(-1); //---- if (!CloseBuyOrder1_(BUY_Stop, 1)) return(-1); //---- if (!dMake_BuyTrailingStop_(TrailSignal_Up, 1, TradeTimeLevel_Up, dTrailingStop_Up)) return(-1); } //+-------------------------------+ //| CÓDIGO PARA POSIÇÕES VENDIDAS | //+-------------------------------+ if (Test_Dn) if (MinBarCheck(Symbol(), Timeframe_Dn, MinBar_Dn)) { if (IsNewBar(1, Symbol(), Timeframe_Dn)) { //----+ Zerar sinais de negociação SELL_Sign = false; SELL_Stop = false; //---- Obtendo o prazo limite para desativação // a próxima operação de negociação TradeTimeLevel_Dn = iTime(NULL, Timeframe_Dn, 0); if (TradeTimeLevel_Dn == 0) return(-1); TradeTimeLevel_Dn += Period_Dn; //----+ CALCULANDO E CARREGANDO VALORES PARA BUFFERS DO INDICADOR for(bar = 1; bar <= 3; bar++) Mov[bar - 1]= iCustom(NULL, Timeframe_Dn, "JFatl", Length_Dn, Phase_Dn, 0, IPC_Dn, 0, bar); //----+ DETERMINANDO SINAIS PARA OPERAÇÕES dMov12 = Mov[0] - Mov[1]; dMov23 = Mov[1] - Mov[2]; //---- Conseguindo um sinal para abrir uma posição if (dMov23 > 0) if (dMov12 < 0) SELL_Sign = true; //---- Conseguindo um sinal para fechar uma posição if (dMov12 > 0) if (ClosePos_Dn) SELL_Stop = true; //----+ CALCULANDO ORDENS PENDENTES PARA POSIÇÕES VENDIDAS // Faz cálculo de ordem apenas se o sinal de negociação está disponível if (SELL_Sign) { //---- Obtendo o valor inicial ATR ATR = iATR(NULL, Timeframe_Dn, ATR_Period_Dn, 1); //---- Obtendo o preço atual open = iOpen(Symbol(), Timeframe_Dn, 0); //---- Calculando a distância ao Stop Loss Level = ATR * _STOPLOSS_Dn; //---- Verificando a distância ao Stop Loss contra o valor mínimo if (Level < _LevMinimum_Dn) Level = _LevMinimum_Dn; //---- Determinando o valor absoluto do Stop Loss dStopLoss_Dn = open + Level; //---- Calculando a distância ao Take Profit Level = ATR * _TAKEPROFIT_Dn; //---- Verificando a distância ao Take Profit contra o valor mínimo if (Level < _LevMinimum_Dn) Level = _LevMinimum_Dn; //---- Determinando o valor absoluto do Take Profit dTakeProfit_Dn = open - Level; //---- Corrigindo os valores das ordens pendente, tendo em conta a direção da negociação dGhartVelueCorrect(OP_SELL, dStopLoss_Dn); dGhartVelueCorrect(OP_SELL, dTakeProfit_Dn); } //----+ CALCULANDO OS TRAILING STOPS PARA POSIÇÕES VENDIDAS dTrailingStop_Dn = 0; TrailSignal_Dn = false; //---- if (TRAILINGSTOP_Dn > 0) // Calcula o Trailing Stop apenas se a posição necessária existir if (OrderSelect_(Symbol(), OP_SELL, 2, MODE_TRADES)) // Move Trailing Stop se a posição é aberta sobre uma barra diferente de zero if (iBarShift(NULL, Timeframe_Dn, OrderOpenTime(), false) > 0) { TrailSignal_Dn = true; //---- Obtendo o valor inicial ATR ATR = iATR(NULL, Timeframe_Dn, ATR_Period_Dn, 1); //---- Obtendo o preço atual open = iOpen(Symbol(), Timeframe_Dn, 0); //---- Calculando a distância ao Stop Loss Level = ATR * _TRAILINGSTOP_Dn; //---- Verificando a distância ao Stop Loss contra o valor mínimo if (Level < _LevMinimum_Dn) Level = _LevMinimum_Dn; //---- Obtendo o valor absoluto do Trailing Stop dTrailingStop_Dn = open + Level; //---- Corrigindo o valor absoluto do Trailing Stop, // de acordo com a direção da negociação ( a posição // das funções de modificação do valor da variável cmd é inversa!) dGhartVelueCorrect(OP_BUY, dTrailingStop_Dn); } } //----+ EXECUÇÃO DE OPERAÇÃO if (!dOpenSellOrder1_(SELL_Sign, 2, TradeTimeLevel_Dn, Money_Management_Dn, 5, dStopLoss_Dn, dTakeProfit_Dn)) return(-1); //---- if (!CloseSellOrder1_(SELL_Stop, 2)) return(-1); //---- if (!dMake_SellTrailingStop_(TrailSignal_Dn, 2, TradeTimeLevel_Dn, dTrailingStop_Dn)) return(-1); } return(0); //----+ } //+X----------------------+ <<< Fim >>> +-----------------------X+
Então, nós temos um novo par de variáveis no bloco de variáveis externas do Expert Advisor - ATR_Period_Up e ATR_Period_Dn, podem ser usadas para alterar os valores do indicador ATR envolvidos no cálculo das ordens pendentes. Agora, o significado lógico de valores das variáveis externas para o Stop Loss, Take Profit e Trailing Stop é um pouco diferente. Os valores usados para representar a distância relativa em pontos da ordem ao preço atual, representam a porcentagem de valor do indicador ATR na primeira barra. Em outras palavras, para calcular a ordem tomamos o percentual do indicador ATR e adicionamos ao valor do preço de abertura da barra zero. A melhor maneira de converter o percentual ao valor de ponto flutuante é usar o bloco init() do Expert Advisor, onde estes cálculos serão feitos uma única vez e os valores calculados serão salvos para as variáveis declaradas com um alcance global.
Devido ao novo indicador ATR disponivel, as fórmulas para a inicialização das variáveis LevMinimum_Up e LevMinimum_Dn do bloco init() mudaram. O bloco star() do Expert Advisor apresenta novas variáveis declaradas como estática para armazenar valores entre os ticks do terminal. O código para o cálculo das ordens pendentes e níveis de Trailing Stop é organizado em pequenos módulos dentro dos blocos para obtenção dos sinais de negociação. Com o objetivo de executar um negócio, usamos diferentes funções cujo valor dos cinco é usado na inicialização da variável Margin_Mode, como um valor mais lógico nas condições flutuantes do Stop Loss.
Para demonstrar as oportunidades oferecidas pela utilização das funções IndicatorCounted_() e ReSetAsIndexBuffer(), neste Expert Advisor foi substituído o indicador personalizadoJFatl.mq4, sendo a função JFATL() inserida no código do Expert Advisor.
bool JFATL(int Number, string symbol, int timeframe, int Length, int Phase, int IPC, double& Buffer[])
A função recebe os parâmetros de entrada do indicador e o array buffer[]. Em caso de cálculo bem-sucedido, a função retornará verdadeiro, caso contrário será falso. O array é feito por referência, convertido ao analógico bufffer do indicador preenchido com os valores do indicador JFATL. Na função, a JJMASeries() é substituída pela JJMASeries1() que não executa cálculos na barra de zero. Temos também substituído a função PriceSeries pela iPriceSeries(). O bloco de inicialização do indicador foi transferido para o bloco de "Inicialização Zero". Por favor, observe que a função JJMASeries1() é usada somente dentro desta função no Expert Advisor, assim o valor da variável Number não é recalculada e será trasnmitida diretamente à JJMASeries1(). O mesmo se aplica à função IndicatorCounted_().
Eu já falei sobre essas substituições de indicadores com função em meus outros artigos dedicados a este assunto: 1, 2, 3. O Expert Advisor que apresenta esta substituição é representado pelo arquivo Exp_17_.mq4. Devemos observar o fato de que a suavização do algoritmo JMA empregado no indicador JFatl.mq4 consume muito recursos, essa substituição do indicador tem como resultado um ganho bastante significativo na velocidade de otimização neste Expert Advisor quando comparado com a versão anterior. Finalmente, para os mais preguiçosos de vocês, o mesmo Expert Advisor (Exp_17R.mq4) foi desenvolvido de tal forma que ele pode conter todas as funções necessárias no seu código, sem necessidade de qualquer adicional, incluir arquivos ou indicadores para a sua compilação e operação. A operação de todos os três análogos deste Expert Advisor é idêntica! Exceto talvez o fato de que os valores das variáveis IPC_Dn e IPC_Up no último Expert Advisor variam dentro de uma faixa um pouco menor (0-10), devido a falta da chamada do indicador Heiken Ashi#.mq4.
No fórum, você pode ocasionalmente ver alguns gurus de programação MQL4 desaprovarem a idéia de escrever tais funções de indicador, cuja opinião é como "colocar as calças pela cabeça". Pessoalmente eu somente gasto quinze minutos de meu tempo escrevendo essa função com base num código bastante fácil de entender. Então, se uma pessoa pode ser seis vezes mais rápida ao executar uma maratona de otimização com as "calças postas pela cabeça", eu ficarei com esta opção!
Sistema de Rompimento para Negociação de Notícias
Esta versão de sistema de negociação já foi apresentado para sua consideração no meu artigo, na forma do Expert Advisor Exp_10.mq4, onde com base nas funções Lite_EXPERT2.mqh é completamente análogo. É um pouco mais complicado do que a versão original, mas muito mais confiável, pois não é afetada por diferentes casos de Expert Advisor, Terminal ou reinicialização do Sistema Operacional. Para determinar o tempo após o qual uma posição aberta deve ser fechada, este Expert Advisor usa a função TradeTimeLevelCheck():
Esta função retorna "true" após o ponto de tempo do valor a qual foi transmitida, como um parâmetro de entrada à função de colocação das ordens pendentes ou posições de abertura. O valor tal como é obtido pela função da variável global.
Agora precisamos alterar o algoritmo de cálculo da ordem pendente, mas neste caso, ordens Stop também devem ser calculadas de forma dinâmica, além do Stop Loss e Take Profit. Essencialmente, isso não muda nada para nós e tudo é implementada da mesma forma. Além disso, Trailing Stop no Expert Advisor original trabalha em cada tick, precisando movê-lo a cada mudança de barra. O código final do Expert Advisor (Exp_18.mq4) certamente não é tão simples como o original, mas a lógica do programa é bastante concisa e direta. Exp_18R.mq4 é um análogo completo do último Expert Advisor implementado na forma de um produto acabado, arquivo auto-suficiente.
Conclusão
Eu acredito que as funções personalizadas do Lite_EXPERT2.mqh não são novidades, quando comparadas com as funções do Lite_EXPERT1.mqh em termos de abordagem de programação.
Simplesmente aumentam a funcionalidade da programação, mantendo-se essencialmente as mesmas em termos de aplicação. Então, depois de um cuidadoso estudo das funções do Lite_EXPERT1.mqh, você não terá qualquer dificuldade em aprender a funcionalidade do Lite_EXPERT2.mqh de forma rápida e fácil.
Traduzido do russo pela MetaQuotes Ltd.
Artigo original: https://www.mql5.com/ru/articles/1384
- 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