
Construindo um Modelo de Restrição de Tendência com Candlestick (Parte 9): Expert Advisor de Múltiplas Estratégias (I)
Conteúdo principal:
- Introdução
- Discussão sobre as 7 Estratégias Famosas Selecionadas
- Incorporação de um número mágico.
- Implementação da Estratégia de Seguimento de Tendência
- Resultados dos Testes
- Conclusão
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:
Um aviso de compilação
Esse erro estava na linha 78 e coluna 28, veja destacado abaixo:
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) é:
Onde:
- N é 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) é:
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
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:
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.
(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:
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;
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:
Onde:
- (RS) representa os ganhos e perdas médios durante um período especificado.
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 Advisor no índice Boom 500
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
Aviso: Todos os direitos sobre esses materiais pertencem à MetaQuotes Ltd. É proibida a reimpressão total ou parcial.
Esse artigo foi escrito por um usuário do site e reflete seu ponto de vista pessoal. A MetaQuotes Ltd. não se responsabiliza pela precisão das informações apresentadas nem pelas possíveis consequências decorrentes do uso das soluções, estratégias ou recomendações descritas.





- 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