English Русский 中文 Español Deutsch 日本語
preview
Construindo um Modelo de Restrição de Tendência com Candlestick (Parte 9): Expert Advisor de Múltiplas Estratégias (I)

Construindo um Modelo de Restrição de Tendência com Candlestick (Parte 9): Expert Advisor de Múltiplas Estratégias (I)

MetaTrader 5Sistemas de negociação |
109 0
Clemence Benjamin
Clemence Benjamin

Conteúdo principal:



Introdução

Desde o início desta série de artigos, nosso foco tem sido alinhar nossos experts com o sentimento predominante das velas diárias (D1). A formação da vela diária serviu como principal elemento norteador. No entanto, precisávamos descer para timeframes menores para identificar níveis de entrada dentro do mercado D1. Por exemplo, no timeframe M1, queríamos que o mercado atingisse níveis extremos no Índice de Força Relativa (RSI) para sinalizar possíveis operações para o Expert Advisor. Neste estágio inicial, não introduzimos muitas estratégias para manter o conteúdo fácil de entender para iniciantes.

Porém, há uma vasta coleção de estratégias para estudar e integrar ao algoritmo do nosso Expert Advisor de Restrição de Tendência. Hoje, vamos analisar de perto algumas estratégias bem conhecidas desenvolvidas por figuras influentes no trading, a quem me refiro como os "Pais do Mercado". Esta fase da nossa discussão elevará nossa compreensão, mantendo ainda o tema original do nosso título. Também vamos abordar as limitações das estratégias discutidas em nosso desenvolvimento anterior, que focaram principalmente em RSI e lógica de restrição. Além disso, vamos explorar como incorporar novas estratégias no Expert Advisor.

Antes de mergulharmos nas sete principais estratégias, vamos recapitular a lógica de restrição no nosso código: 

 Uma condição de candlestick de alta em MQL5:

void OnTick()
{
    // Determine current daily trend (bullish )
    double daily_open = iOpen(_Symbol, PERIOD_D1, 0);
    double daily_close = iClose(_Symbol, PERIOD_D1, 0);

    bool is_bullish = daily_close > daily_open;
}

Uma condição de candlestick de baixar em MQL5:

void OnTick()
{
    // Determine current daily trend (bearish)
    double daily_open = iOpen(_Symbol, PERIOD_D1, 0);
    double daily_close = iClose(_Symbol, PERIOD_D1, 0);

    
    bool is_bearish = daily_close < daily_open;
}

No código acima, o sentimento do timeframe maior serve como nosso fator de restrição. Neste caso, optamos pelo timeframe D1.

Implementação da condição de restrição:

Agora que estabelecemos o sentimento de baixa e alta da nossa vela diária, podemos utilizar a função ''if()'' juntamente com a lógica da nossa condição de entrada. 

Para um Dia de Alta:

 if (is_bullish)
    {
        // Logic for bullish trend
        Print("The daily trend is bullish.");

   // You can add your trading logic here, for example:
        // if (OrderSelect(...)) { /* Place buy order */ }
    }

Para um Dia de Baixa:

 if (is_bearish)
    {
        // Logic for bearish trend
        Print("The daily trend is bearish.");
        // You can add your trading logic here, for example:
        // if (OrderSelect(...)) { /* Place sell order */ }
    }

Ao final desta discussão, você poderá observar:

1. Outras estratégias e o homem por trás delas.

2. Incorporação de uma nova estratégia nos módulos do Expert Advisor existente.

3. Implementação de um número mágico.

Em resumo, os três pontos-chave acima proporcionarão aos traders um melhor entendimento de várias estratégias e das motivações por trás delas, além de insights sobre como implementar MQL5 para integrar novas estratégias em códigos existentes.

Em resumo, os três pontos-chave acima proporcionarão aos traders um melhor entendimento de várias estratégias e das motivações por trás delas, além de insights sobre como implementar MQL5 para integrar novas estratégias em códigos existentes. Você verá a necessidade de expandir as estratégias do nosso Expert Advisor, especialmente porque o mercado está em constante evolução. Essas estratégias compostas são essenciais para se adaptar a qualquer cenário de mercado. Quando uma estratégia falha, sempre há outra que pode ser empregada. Eu me esforcei para descobrir os aspectos matemáticos que fundamentam cada estratégia, pois essas funções matemáticas servem como elemento base para o desenvolvimento eficiente de algoritmos.

Após revisar o Expert Advisor recente, encontrei alguns erros de aviso (warnings), que você pode ter notado se acompanhou. Veja a imagem abaixo:

Erro de aviso

Um aviso de compilação

Esse erro estava na linha 78 e coluna 28, veja destacado abaixo:

aviso

Aviso na linha 78, coluna 28

Esse aviso é um dos mais simples de corrigir, pois é autoexplicativo. Aqui está um trecho de código com a correção:

long position_type = PositionGetInteger(POSITION_TYPE);

A correção acima envolveu substituir int por long.

O código-fonte mais recente do nosso Expert Advisor de Restrição de Tendência está disponível aqui, mas você também pode revisar o artigo anterior para obter o arquivo fonte. Não deixe de praticar a depuração do código como fizemos acima antes de implementar as novas funcionalidades.

//+------------------------------------------------------------------+
//|                                      Trend Constraint Expert.mq5 |
//|                                Copyright 2024, Clemence Benjamin |
//|             https://www.mql5.com/en/users/billionaire2024/seller |
//+------------------------------------------------------------------+
#property copyright "Copyright 2024, Clemence Benjamin"
#property link      "https://www.mql5.com/en/users/billionaire2024/seller"
#property version   "1.00"
#property strict

#include <Trade\Trade.mqh>  // Include the trade library

// Input parameters
input int    RSI_Period = 14;            // RSI period
input double RSI_Overbought = 70.0;      // RSI overbought level
input double RSI_Oversold = 30.0;        // RSI oversold level
input double Lots = 0.1;                 // Lot size
input double StopLoss = 100;             // Stop Loss in points
input double TakeProfit = 200;           // Take Profit in points
input double TrailingStop = 50;          // Trailing Stop in points

// Global variables
double rsi_value;
int rsi_handle;
CTrade trade;  // Declare an instance of the CTrade class

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   // Create an RSI indicator handle
   rsi_handle = iRSI(_Symbol, PERIOD_CURRENT, RSI_Period, PRICE_CLOSE);
   if (rsi_handle == INVALID_HANDLE)
     {
      Print("Failed to create RSI indicator handle");
      return(INIT_FAILED);
     }

   return(INIT_SUCCEEDED);
  }

//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   // Release the RSI indicator handle
   IndicatorRelease(rsi_handle);
  }

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   // Determine current daily trend (bullish or bearish)
   double daily_open = iOpen(_Symbol, PERIOD_D1, 0);
   double daily_close = iClose(_Symbol, PERIOD_D1, 0);

   bool is_bullish = daily_close > daily_open;
   bool is_bearish = daily_close < daily_open;

   // Get the RSI value for the current bar
   double rsi_values[];
   if (CopyBuffer(rsi_handle, 0, 0, 1, rsi_values) <= 0)
     {
      Print("Failed to get RSI value");
      return;
     }
   rsi_value = rsi_values[0];

   // Close open positions if the trend changes
   for (int i = PositionsTotal() - 1; i >= 0; i--)
     {
      if (PositionSelect(PositionGetSymbol(i)))  // Corrected usage
        {
         long position_type = PositionGetInteger(POSITION_TYPE);
         ulong ticket = PositionGetInteger(POSITION_TICKET);  // Get the position ticket

         if ((position_type == POSITION_TYPE_BUY && is_bearish) ||
             (position_type == POSITION_TYPE_SELL && is_bullish))
           {
            trade.PositionClose(ticket);  // Use the ulong variable directly
           }
        }
     }

   // Check for buy condition (bullish trend + RSI oversold)
   if (is_bullish && rsi_value < RSI_Oversold)
     {
      // No open positions? Place a buy order
      if (PositionsTotal() == 0)
        {
         double price = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
         double sl = price - StopLoss * _Point;
         double tp = price + TakeProfit * _Point;

         // Open a buy order
         trade.Buy(Lots, _Symbol, price, sl, tp, "TrendConstraintExpert Buy");
        }
     }

   // Check for sell condition (bearish trend + RSI overbought)
   if (is_bearish && rsi_value > RSI_Overbought)
     {
      // No open positions? Place a sell order
      if (PositionsTotal() == 0)
        {
         double price = SymbolInfoDouble(_Symbol, SYMBOL_BID);
         double sl = price + StopLoss * _Point;
         double tp = price - TakeProfit * _Point;

         // Open a sell order
         trade.Sell(Lots, _Symbol, price, sl, tp, "TrendConstraintExpert Sell");
        }
     }

   // Apply trailing stop
   for (int i = PositionsTotal() - 1; i >= 0; i--)
     {
      if (PositionSelect(PositionGetSymbol(i)))  // Corrected usage
        {
         double price = PositionGetDouble(POSITION_PRICE_OPEN);
         double stopLoss = PositionGetDouble(POSITION_SL);
         double current_price;

         if (PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY)
           {
            current_price = SymbolInfoDouble(_Symbol, SYMBOL_BID);
            if (current_price - price > TrailingStop * _Point)
              {
               if (stopLoss < current_price - TrailingStop * _Point)
                 {
                  trade.PositionModify(PositionGetInteger(POSITION_TICKET), current_price - TrailingStop * _Point, PositionGetDouble(POSITION_TP));
                 }
              }
           }
         else if (PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL)
           {
            current_price = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
            if (price - current_price > TrailingStop * _Point)
              {
               if (stopLoss > current_price + TrailingStop * _Point || stopLoss == 0)
                 {
                  trade.PositionModify(PositionGetInteger(POSITION_TICKET), current_price + TrailingStop * _Point, PositionGetDouble(POSITION_TP));
                 }
              }
           }
        }
     }
  }
//+------------------------------------------------------------------+


Discussão sobre as 7 Estratégias Famosas Selecionadas

Operar no mercado Forex exige uma combinação de habilidade e estratégia. Ao longo dos anos, várias abordagens surgiram que podem ajudar os traders a maximizar suas chances de sucesso. Aqui, vou abordar brevemente sete estratégias eficazes de negociação Forex, cada uma fundamentada em princípios matemáticos essenciais e teorias desenvolvidas por economistas e traders influentes. Uma vez que a estratégia é absorvida, torna-se mais fácil aplicar as habilidades de programação e criar um Algoritmo para a estratégia.

(i) Estratégia de Seguimento de Tendência

A estratégia de seguimento de tendência é baseada nos princípios de Charles Dow, que formulou a Teoria de Dow no final do século XIX (1896). Dow acreditava que os mercados se movem em tendências, e identificar essas tendências pode proporcionar oportunidades substanciais de negociação. A matemática por trás do seguimento de tendência frequentemente emprega médias móveis, onde os traders usam a média móvel simples (SMA) para suavizar as flutuações de preço.

A fórmula real para a Média Móvel Simples (SMA) é:

SMA

Onde:

  • é o número de períodos (ou pontos de dados).
  • (P_i)  é o preço (ou valor) no (i-ésimo) período.

Esta fórmula calcula o preço médio ao longo de N períodos. Pesquisas de apoio, como os trabalhos de Richard Dennis e seu experimento "Turtles" na década de 1980, demonstram que o seguimento de tendência pode gerar lucros significativos, especialmente em mercados com forte tendência.

(ii) Operação em Faixa (Range Trading)

A operação em faixa é fundamentada nos conceitos de níveis de suporte e resistência, cruciais para a análise técnica. Esses conceitos foram bem documentados por J. Welles Wilder em seu livro "New Concepts in Technical Trading Systems" (1978). Os traders identificam o suporte como um nível de preço onde o interesse de compra impede quedas, enquanto a resistência dificulta aumentos de preço. A base matemática para calcular os pontos de pivô, um método comum para identificar esses níveis, é dada por:

A fórmula real para o Ponto de Pivô (PP) é:

pivot

Onde:

  • High é o preço mais alto do período de negociação anterior.
  • Low é o preço mais baixo do período de negociação anterior.
  • Close é o preço de fechamento do período de negociação anterior.

Esta fórmula calcula o ponto pivô central usado na análise técnica para determinar possíveis níveis de suporte e resistência para o próximo período de negociação. Pesquisas, como a de John Murphy em "Technical Analysis of the Financial Markets" (1986), enfatizam que os níveis de suporte e resistência frequentemente servem como indicadores psicológicos que podem ajudar os traders a tomar decisões informadas.

(iii) Breakout Trading (Negociação de Rompimento)

A negociação de rompimento baseia-se na crença de que movimentos substanciais de preço ocorrem quando os preços rompem níveis estabelecidos de suporte ou resistência. Richard Donchian introduziu essa estratégia na década de 1950, e seu trabalho com os Canais de Donchian enfatiza o uso da volatilidade para identificar pontos de rompimento. Os traders calculam os Canais de Donchian usando a máxima mais alta (HH) e a mínima mais baixa (LL) em um período especificado:

(Faixa Superior = HH)

(Faixa Inferior = LL)

Canais de Donchian

Canais de Donchian

Pesquisas em finanças comportamentais apoiam a ideia de que traders frequentemente seguem rompimentos devido ao comportamento de manada, o que reforça o momentum na direção do rompimento. O trabalho publicado por pesquisadores como Daniel Kahneman e Amos Tversky em seu artigo de 1979, "Prospect Theory: An Analysis of Decision under Risk", destaca como fatores psicológicos influenciam o comportamento de negociação durante rompimentos.

(iv) Carry Trade

O carry trade aproveita os diferenciais de taxa de juros entre duas moedas, com base nas teorias de Paridade de Taxa de Juros (IRP). Esse princípio tem raízes nas teorias econômicas formuladas no início do século XX, notavelmente por economistas como Paul Samuelson em obras como "Foundations of Economic Analysis" (1947).

A fórmula básica para calcular o retorno esperado em um carry trade é dada por:

ER

Onde:

  • (i_high) e (i_low) são as taxas de juros das moedas de alto rendimento e de baixo rendimento, respectivamente.
  • (Delta S) representa a variação esperada na taxa de câmbio. 
 Kenneth Rogoff, em seu artigo de 1998, destaca como desvios da paridade de taxa de juros podem criar oportunidades de negociação lucrativas.

(v) Scalping

O scalping é uma estratégia de negociação de alta frequência que explora pequenos movimentos de preço, fundamentada na Teoria da Microestrutura de Mercado (MMT). Essa teoria evoluiu através do trabalho de diversos pesquisadores, incluindo Lawrence Harris em "Market Making and the Financial Performance of Nasdaq Firms" (1998). Scalpers executam múltiplas negociações em curtos intervalos de tempo, buscando lucrar com variações mínimas de preço.

Métricas importantes para scalpers incluem spreads bid-ask e análise de fluxo de ordens, frequentemente calculados através de métricas como:

profit

Onde:

  • (Selling Price) é o preço pelo qual o ativo é vendido.

  • (Buying Price) é o preço pelo qual o ativo foi originalmente comprado.

  • (Transaction Costs) são quaisquer taxas ou custos associados ao processo de compra e venda (por exemplo, taxas de corretagem, impostos).

O gerenciamento de risco torna-se crítico, pois algumas negociações desfavoráveis podem levar a perdas significativas.

(vi) Análise Fundamentalista

A análise fundamentalista envolve o exame de indicadores econômicos e fatores geopolíticos que impactam a valorização das moedas. Pioneirada por Benjamin Graham e David Dodd em "Security Analysis" (1934), essa abordagem enfatiza a importância de avaliar o valor intrínseco das moedas. Traders utilizam diversos indicadores, como crescimento do Produto Interno Bruto (PIB) e taxas de desemprego, para tomar decisões informadas. Técnicas matemáticas, como o índice Preço/Lucro (P/L) para ações, também podem ser adaptadas;

P^E

Onde:

  • (Market Price per share) é o preço atual de uma ação da empresa.

  • Earnings per Share (EPS) é o lucro da empresa atribuído a cada ação ordinária em circulação.

Pesquisas extensas apoiam a eficácia da análise fundamentalista, especialmente durante relatórios econômicos relevantes ou anúncios de bancos centrais, que frequentemente levam a movimentos substanciais no mercado.


(vii) Utilizando Indicadores Técnicos

A análise técnica, baseada nas ideias de Charles Dow e outros, parte do pressuposto de que movimentos passados de preços podem fornecer insights sobre o comportamento futuro. Vários indicadores técnicos, como o Índice de Força Relativa (RSI), são utilizados para medir o momentum do mercado. O RSI é calculado usando a fórmula: 

RSI

Onde:

  • (RS) representa os ganhos e perdas médios durante um período especificado.

RS

Pesquisas de apoio, como as de Thomas Bulkowski em "Encyclopedia of Candlestick Charts" (2008), mostram que certos padrões e indicadores podem aprimorar a precisão das negociações, permitindo que os traders antecipem movimentos de mercado com base na ação de preço histórica. Cada uma dessas estratégias é fundamentada em teorias de base, princípios matemáticos e pesquisas extensas que orientam as decisões dos traders no mercado Forex. Compreender as complexidades dessas estratégias pode aumentar significativamente a capacidade de um trader de navegar pelas complexidades da negociação Forex, levando, em última análise, a resultados mais informados e lucrativos. Ao empregar essas estratégias de forma criteriosa, os traders podem desenvolver uma abordagem de negociação robusta, adaptada às suas preferências individuais e tolerâncias ao risco.


Incorporação de um número mágico

Números mágicos no MQL5 servem como uma ferramenta organizacional fundamental, semelhante a uma assinatura única que um Expert Advisor (EA) usa para marcar suas negociações. Pense nisso como se cada EA tivesse seu próprio identificador pessoal que carimba em cada negociação que abre. Isso é particularmente útil em contas que executam várias estratégias simultaneamente, pois ajuda o EA a manter suas operações claramente separadas das demais.

Ao definir o número mágico como um parâmetro de entrada, você oferece flexibilidade, permitindo ajustes nas configurações do EA sem precisar voltar ao código-fonte. Quando o EA analisa as posições abertas, ele usa esse número para identificar rapidamente quais negociações são suas.

A função PositionGetInteger(POSITION_MAGIC) recupera o número mágico anexado a cada negociação, permitindo que o EA decida seu próximo passo: modificar, monitorar ou fechar uma posição. Para um trader ou desenvolvedor, isso significa menos preocupação com interferências acidentais entre diferentes estratégias e uma depuração mais fácil, já que cada negociação pode ser rastreada até a estratégia de origem. Assim, incorporar e gerenciar números mágicos de forma eficaz garante que suas estratégias de negociação permaneçam precisas e bem organizadas nos mercados financeiros.

Aqui está um trecho de código mostrando a incorporação:

input int MagicNumber = 12345678; // Define a unique magic number for the EA

// Within the OnTick() or relevant function
for (int i = 0; i < PositionsTotal(); i++) {
    if (PositionGetSymbol(i) == _Symbol && PositionSelect(PositionGetSymbol(i))) {
        long currentMagicNumber = PositionGetInteger(POSITION_MAGIC);

        if (currentMagicNumber == MagicNumber) { // Check if the position belongs to this EA
            // Perform actions on this position, like closing or modifying
        }
    }
}

// When opening a new trade
double price = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
double sl = price - StopLoss * _Point;
double tp = price + TakeProfit * _Point;

if (trade.Buy(Lots, _Symbol, price, sl, tp, "TrendFollowing Buy")) {
    Print("Buy order placed with Magic Number: ", MagicNumber);
} else {
    Print("Error placing buy order: ", GetLastError());


Implementação da Estratégia de Seguimento de Tendência

Das estratégias selecionadas acima, a maioria não pode ser implementada em nosso programa, pois carece de alguns dados necessários para seu uso no momento. Por exemplo, o Carry Trade não é viável apenas com este código, pois envolve diferenciais de taxa de juros, e a análise fundamentalista requer feeds externos de dados econômicos detalhando PIB, taxas de emprego, etc. Para guardar para exploração futura, focaremos na estratégia mais viável.

O acompanhamento de tendência é uma abordagem que identifica e negocia na direção de uma tendência de mercado sustentada, usando técnicas como médias móveis para confirmar a direção da tendência. Nosso código de especialista já usa o RSI para avaliar condições de sobrecompra ou sobrevenda, mas integrar médias móveis pode refinar ainda mais o processo de tomada de decisão. Aqui, usamos uma média móvel de curto prazo (50 períodos) e uma média móvel de longo prazo (200 períodos) para determinar a direção da tendência. Se a média de curto prazo cruzar acima da média de longo prazo, é um sinal de tendência de alta; inversamente, se cruzar abaixo, indica uma tendência de baixa. A integração desse método ajuda a confirmar tendências de alta ou baixa, aumentando a precisão das entradas de negociação junto com as condições do RSI.

 Aqui está nosso trecho de código para calcular médias móveis antes da integração no programa principal.

//Calculate moving averages
double ma_short = iMA(_Symbol, PERIOD_CURRENT, 50, 0, MODE_EMA, PRICE_CLOSE, 0);
double ma_long = iMA(_Symbol, PERIOD_CURRENT, 200, 0, MODE_EMA, PRICE_CLOSE, 0);

//Determine the trend  direction
bool is_uptrend = ma_short > ma_long;
bool is_downtrend = ma_short < ma_long;

if (is_bullish && is_uptrend && rsi_value < RSI_Oversold)
{
   // Implement buy order logic here
}

if (is_bearish && is_downtrend && rsi_value > RSI_Overbought)
{
   // Implement sell order logic here
}

Para incorporar efetivamente uma estratégia seguidora de tendência em um Expert Advisor (EA) existente, começamos aprimorando a lógica de inicialização e processamento dentro de seus módulos. Começando com a função OnInit(), introduzimos o cálculo de duas Médias Móveis Exponenciais (EMAs) críticas, tipicamente uma de 50 períodos para tendências de curto prazo e uma de 200 períodos para tendências de longo prazo, usando a função iMA.

À medida que avançamos para o método OnTick(), essas EMAs são recalculadas a cada novo tick de mercado, permitindo que o EA determine a direção atual da tendência; um cruzamento onde a EMA de curto prazo sobe acima da de longo prazo sinaliza uma tendência de alta, enquanto um cruzamento onde cai abaixo indica uma tendência de baixa.

Integrando esses sinais de tendência à análise existente de RSI, criamos condições nas quais o algoritmo abre ordens de compra durante tendências de alta confirmadas quando o RSI está sobrevendido, e ordens de venda durante tendências de baixa quando o RSI está sobrecomprado.

Usando a classe CTrade para execução, definimos meticulosamente parâmetros para stop loss, take profit e trailing stop, garantindo um gerenciamento de risco robusto. Além disso, dentro do mesmo loop OnTick(), um sistema é incorporado para fechar com segurança quaisquer posições existentes caso a tendência identificada se reverta, alinhando assim cada negociação à direção de mercado verificada. Por meio dessas atualizações estratégicas, o EA é adaptado de forma eficiente para empregar uma estratégia seguidora de tendência, integrando-a perfeitamente às suas funcionalidades atuais e aprimorando a eficácia geral da negociação.

Aqui está um programa totalmente integrado:

//+------------------------------------------------------------------+
//|                                      Trend Constraint Expert.mq5 |
//|                                Copyright 2024, Clemence Benjamin |
//|             https://www.mql5.com/en/users/billionaire2024/seller |
//+------------------------------------------------------------------+
#property copyright "Copyright 2024, Clemence Benjamin"
#property link      "https://www.mql5.com/en/users/billionaire2024/seller"
#property version   "1.00"
#property strict

#include <Trade\Trade.mqh>  // Include the trade library

// Input parameters
input int    RSI_Period = 14;            // RSI period
input double RSI_Overbought = 70.0;      // RSI overbought level
input double RSI_Oversold = 30.0;        // RSI oversold level
input double Lots = 0.1;                 // Lot size
input double StopLoss = 100;             // Stop Loss in points
input double TakeProfit = 200;           // Take Profit in points
input double TrailingStop = 50;          // Trailing Stop in points
input int    MagicNumber = 12345678;     // Magic number for this EA

// Global variables
double rsi_value;
int rsi_handle;
CTrade trade;  // Declare an instance of the CTrade class

// Variables for moving averages
double ma_short;
double ma_long;

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   // Create an RSI indicator handle
   rsi_handle = iRSI(_Symbol, PERIOD_CURRENT, RSI_Period, PRICE_CLOSE);
   if (rsi_handle == INVALID_HANDLE)
     {
      Print("Failed to create RSI indicator handle");
      return(INIT_FAILED);
     }

   return(INIT_SUCCEEDED);
  }

//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   // Release the RSI indicator handle
   IndicatorRelease(rsi_handle);
  }

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   // Calculate moving averages
   ma_short = iMA(_Symbol, PERIOD_CURRENT, 50, 0, MODE_EMA, PRICE_CLOSE);
   ma_long  = iMA(_Symbol, PERIOD_CURRENT, 200, 0, MODE_EMA, PRICE_CLOSE);

   // Determine trend direction
   bool is_uptrend = ma_short > ma_long;
   bool is_downtrend = ma_short < ma_long;

   // Get the RSI value for the current bar
   double rsi_values[];
   if (CopyBuffer(rsi_handle, 0, 0, 1, rsi_values) <= 0)
     {
      Print("Failed to get RSI value");
      return;
     }
   rsi_value = rsi_values[0];

   // Close open positions if the trend changes
   for (int i = 0; i < PositionsTotal(); i++) // Correct loop initialization
     {
      if (PositionGetSymbol(i) == _Symbol && PositionSelect(PositionGetSymbol(i)))  // Select position by symbol
        {
         long position_type = PositionGetInteger(POSITION_TYPE);
         long currentMagicNumber = PositionGetInteger(POSITION_MAGIC);
         ulong ticket = PositionGetInteger(POSITION_TICKET);

         if (currentMagicNumber == MagicNumber) // Ensure only this EA's orders are checked
           {
            if ((position_type == POSITION_TYPE_BUY && is_downtrend) ||
                (position_type == POSITION_TYPE_SELL && is_uptrend))
              {
               trade.PositionClose(ticket);
              }
           }
        }
     }

   // Check for buy condition (uptrend + RSI oversold)
   if (is_uptrend && rsi_value < RSI_Oversold)
     {
      // No open positions? Place a buy order
      bool open_position = false;

      for (int i = 0; i < PositionsTotal(); i++) // Correct loop initialization
        {
         if (PositionGetSymbol(i) == _Symbol && PositionSelect(PositionGetSymbol(i)))
           {
            long currentMagicNumber = PositionGetInteger(POSITION_MAGIC);

            if (currentMagicNumber == MagicNumber)
              {
               open_position = true;
               break;
              }
           }
        }

      if (!open_position)
        {
         double price = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
         double sl = price - StopLoss * _Point;
         double tp = price + TakeProfit * _Point;

         // Open a buy order
         if (trade.Buy(Lots, _Symbol, price, sl, tp, "TrendFollowing Buy"))
            Print("Buy order placed with Magic Number: ", MagicNumber);
         else
            Print("Error placing buy order: ", GetLastError());
        }
     }

   // Check for sell condition (downtrend + RSI overbought)
   if (is_downtrend && rsi_value > RSI_Overbought)
     {
      // No open positions? Place a sell order
      bool open_position = false;

      for (int i = 0; i < PositionsTotal(); i++) // Correct loop initialization
        {
         if (PositionGetSymbol(i) == _Symbol && PositionSelect(PositionGetSymbol(i)))
           {
            long currentMagicNumber = PositionGetInteger(POSITION_MAGIC);

            if (currentMagicNumber == MagicNumber)
              {
               open_position = true;
               break;
              }
           }
        }

      if (!open_position)
        {
         double price = SymbolInfoDouble(_Symbol, SYMBOL_BID);
         double sl = price + StopLoss * _Point;
         double tp = price - TakeProfit * _Point;

         // Open a sell order
         if (trade.Sell(Lots, _Symbol, price, sl, tp, "TrendFollowing Sell"))
            Print("Sell order placed with Magic Number: ", MagicNumber);
         else
            Print("Error placing sell order: ", GetLastError());
        }
     }

   // Apply trailing stop
   for (int i = 0; i < PositionsTotal(); i++) // Correct loop initialization
     {
      if (PositionGetSymbol(i) == _Symbol && PositionSelect(PositionGetSymbol(i))) // Select position by symbol
        {
         long currentMagicNumber = PositionGetInteger(POSITION_MAGIC);

         if (currentMagicNumber == MagicNumber) // Apply trailing stop only to this EA's positions
           {
            double price = PositionGetDouble(POSITION_PRICE_OPEN);
            double stopLoss = PositionGetDouble(POSITION_SL);
            double current_price;

            if (PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY)
              {
               current_price = SymbolInfoDouble(_Symbol, SYMBOL_BID);
               if (current_price - price > TrailingStop * _Point)
                 {
                  if (stopLoss < current_price - TrailingStop * _Point)
                    {
                     trade.PositionModify(PositionGetInteger(POSITION_TICKET), current_price - TrailingStop * _Point, PositionGetDouble(POSITION_TP));
                    }
                 }
              }
            else if (PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL)
              {
               current_price = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
               if (price - current_price > TrailingStop * _Point)
                 {
                  if (stopLoss > current_price + TrailingStop * _Point || stopLoss == 0)
                    {
                     trade.PositionModify(PositionGetInteger(POSITION_TICKET), current_price + TrailingStop * _Point, PositionGetDouble(POSITION_TP));
                    }
                 }
              }
           }
        }
     }
  }
//+------------------------------------------------------------------+


Resultados dos Testes

Testei o Expert Advisor no índice B00M 500 e observei as ordens. No entanto, ainda há muito a ser feito para evitar que múltiplas ordens sejam abertas simultaneamente. O desempenho em uma conta demo de US$ 10.000 apresentou resultados positivos, mas os resultados podem não ser os mesmos em contas reais e com menor capital. É importante observar que este sistema não garante lucros; ele é destinado a fins educacionais, experimentos e pesquisas.

Lançamento do Expert

Lançamento do Expert Advisor no índice Boom 500

tester

Resultado do teste no índice Boom 500 em 2019


Conclusão

Em conclusão, nossa discussão sobre a construção de um Expert Advisor de Estratégias Múltiplas usando MQL5 concentrou-se em entender as origens das principais estratégias existentes e integrar uma estratégia seguidora de tendência junto com elementos-chave como o Índice de Força Relativa (RSI). O componente seguidor de tendência utiliza médias móveis para determinar a direção da tendência de mercado, permitindo que os traders alinhem suas posições com movimentos de longo prazo, que frequentemente são mais estáveis e potencialmente mais lucrativos. Ao empregar essas médias móveis, nosso sistema pode identificar tendências de alta e de baixa, facilitando decisões de negociação informadas com base em direções de mercado bem definidas.

A incorporação estratégica de uma metodologia seguidora de tendência complementa o uso do RSI, que é essencial para identificar condições de sobrecompra e sobrevenda. Juntos, esses componentes criam uma abordagem equilibrada que captura tanto o momentum da tendência quanto se alinha ao conceito fundamental da série, Trend Constraint. Outra melhoria crítica feita durante nosso desenvolvimento foi a integração de números mágicos — um recurso inicialmente ausente, mas crucial para o gerenciamento preciso de negociações em ambientes com múltiplas estratégias. Os números mágicos servem como identificadores únicos, ajudando a manter as estratégias separadas e permitindo que os traders rastreiem e gerenciem cada uma de forma independente.

Das sete estratégias que consideramos, implementamos apenas uma até agora, deixando muitos desenvolvimentos potenciais para exploração futura. Compile e teste o arquivo-fonte anexado para avaliar seu desempenho e obter ideias para implementação em seus próprios projetos. Bons trades!

Traduzido do Inglês pela MetaQuotes Ltd.
Artigo original: https://www.mql5.com/en/articles/15509

Arquivos anexados |
Criando um Expert Advisor Integrado MQL5-Telegram (Parte 7): Análise de Comandos para Automação de Indicadores em Gráficos Criando um Expert Advisor Integrado MQL5-Telegram (Parte 7): Análise de Comandos para Automação de Indicadores em Gráficos
Neste artigo, exploramos como integrar comandos do Telegram com MQL5 para automatizar a adição de indicadores em gráficos de negociação. Cobrimos o processo de análise (parsing) dos comandos dos usuários, sua execução no MQL5 e o teste do sistema para garantir uma negociação baseada em indicadores de forma fluida.
Repensando estratégias clássicas (Parte X): A IA pode operar o MACD? Repensando estratégias clássicas (Parte X): A IA pode operar o MACD?
Junte-se a nós em uma análise empírica do indicador MACD para verificar se a aplicação da inteligência artificial à estratégia que inclui esse indicador pode aumentar a precisão da previsão do par EURUSD. Avaliamos simultaneamente se é mais fácil prever o próprio indicador do que o preço, bem como se o valor do indicador permite prever os níveis futuros de preço. Forneceremos as informações necessárias para que você decida se vale a pena investir seu tempo integrando o MACD às suas estratégias de trading com o uso de inteligência artificial.
Data Science e ML (Parte 30): O Casal Poderoso para Prever o Mercado de Ações, Redes Neurais Convolucionais (CNNs) e Redes Neurais Recorrentes (RNNs) Data Science e ML (Parte 30): O Casal Poderoso para Prever o Mercado de Ações, Redes Neurais Convolucionais (CNNs) e Redes Neurais Recorrentes (RNNs)
Neste artigo, exploramos a integração dinâmica das Redes Neurais Convolucionais (CNNs) e das Redes Neurais Recorrentes (RNNs) na previsão do mercado de ações. Aproveitando a capacidade das CNNs de extrair padrões e a proficiência das RNNs em lidar com dados sequenciais. Vamos ver como essa combinação poderosa pode aumentar a precisão e eficiência dos algoritmos de negociação.
Criando um painel MQL5 interativo usando a classe Controls (Parte 1): Configurando o painel Criando um painel MQL5 interativo usando a classe Controls (Parte 1): Configurando o painel
Neste artigo, vamos criar um painel de negociação interativo utilizando a classe Controls no MQL5, voltado para otimizar as operações de trading. O painel conterá um cabeçalho, botões de navegação para trading, fechamento e informações, além de botões especializados para envio de ordens e gerenciamento de posições. Ao final do artigo, teremos um painel básico pronto para futuras melhorias.