Indicadores: MACD Crossing the zero level (color candles) - página 3

 
Andrey F. Zelinsky:

publique o código com suas edições - explique quais edições você fez - vamos ver.

Se estiver interessado em fazer isso sozinho, há uma chance de descobrir.


#property copyright   "Copyright 2009-2013, MetaQuotes Software Corp."
#property link        "http://www.mql5.com"
#property version     "5.20"
#property description "It is important to make sure that the expert works with a normal"
#property description "chart and the user did not make any mistakes setting input"
#property description "variables (Lots, TakeProfit, TrailingStop) in our case,"
#property description "we check TakeProfit on a chart of more than 2*trend_period bars"
//---
#include <Trade\Trade.mqh>
#include <Trade\SymbolInfo.mqh>
#include <Trade\PositionInfo.mqh>
#include <Trade\AccountInfo.mqh>
//---
input double InpLots          =0.1; // Lotes.
input int    InpTakeProfit    =50;  // Take Profit (em pips)
input int    InpTrailingStop  =30;  // Nível de parada móvel (em pips)
input int    InpMACDOpenLevel =3;   // Nível de abertura MACD (em pips)
input int    InpMACDCloseLevel=2;   // Nível de fechamento do MACD (em pips)
input int    InpMATrendPeriod =26;  // Período de tendência MA
//---
int ExtTimeOut=10; // tempo limite em segundos entre as operações comerciais
//+------------------------------------------------------------------+
//| Exemplo de classe de especialista MACD|
//+------------------------------------------------------------------+
class CSampleExpert
  {
protected:
   double            m_adjusted_point;             // valor do ponto ajustado para 3 ou 5 pontos
   CTrade            m_trade;                      // objeto de negociação
   CSymbolInfo       m_symbol;                     // objeto de informação de símbolo
   CPositionInfo     m_position;                   // objeto de posição comercial
   CAccountInfo      m_account;                    // wrapper de informações da conta
   //--- indicadores
   int               m_handle_macd;                // Identificador do indicador MACD
   
   //--- buffers de indicadores
   double            m_buff_MACD_main[];           // Buffer principal do indicador MACD
   
  
   //--- dados do código para processamento
   double            m_macd_current;
   double            m_macd_previous;
   

   //---
   double            m_macd_open_level;
   double            m_macd_close_level;
   double            m_traling_stop;
   double            m_take_profit;

public:
                     CSampleExpert(void);
                    ~CSampleExpert(void);
   bool              Init(void);
   void              Deinit(void);
   bool              Processing(void);

protected:
   bool              InitCheckParameters(const int digits_adjust);
   bool              InitIndicators(void);
   bool              LongClosed(void);
   bool              ShortClosed(void);
   bool              LongModified(void);
   bool              ShortModified(void);
   bool              LongOpened(void);
   bool              ShortOpened(void);
  };
//--- especialista global
CSampleExpert ExtExpert;
//+------------------------------------------------------------------+
//| Construtor|
//+------------------------------------------------------------------+
CSampleExpert::CSampleExpert(void) : m_adjusted_point(0),
                                     m_handle_macd(INVALID_HANDLE),
                                     
                                     m_macd_current(0),
                                     m_macd_previous(0),                                                                   
                                     m_macd_open_level(0),
                                     m_macd_close_level(0),
                                     m_traling_stop(0),
                                     m_take_profit(0)
  {
   ArraySetAsSeries(m_buff_MACD_main,true);
   
  
  }
//+------------------------------------------------------------------+
//| Destruidor|
//+------------------------------------------------------------------+
CSampleExpert::~CSampleExpert(void)
  {
  }
//+------------------------------------------------------------------+
//| Inicialização e verificação dos parâmetros de entrada
//+------------------------------------------------------------------+
bool CSampleExpert::Init(void)
  {
//--- inicializar informações comuns
   m_symbol.Name(Symbol());              // símbolo
   m_trade.SetExpertMagicNumber(12345);  // magia
//--- sintonia para 3 ou 5 dígitos
   int digits_adjust=1;
   if(m_symbol.Digits()==3 || m_symbol.Digits()==5)
      digits_adjust=10;
   m_adjusted_point=m_symbol.Point()*digits_adjust;
//--- definir o desvio padrão para negociação em pontos ajustados
   m_macd_open_level =InpMACDOpenLevel*m_adjusted_point;
   m_macd_close_level=InpMACDCloseLevel*m_adjusted_point;
   m_traling_stop    =InpTrailingStop*m_adjusted_point;
   m_take_profit     =InpTakeProfit*m_adjusted_point;
//--- definir o desvio padrão para negociação em pontos ajustados
   m_trade.SetDeviationInPoints(3*digits_adjust);
//---
   if(!InitCheckParameters(digits_adjust))
      return(false);
   if(!InitIndicators())
      return(false);
//--- bem-sucedido
   return(true);
  }
//+------------------------------------------------------------------+
//| Verificação de parâmetros de entrada|
//+------------------------------------------------------------------+
bool CSampleExpert::InitCheckParameters(const int digits_adjust)
  {
//--- verificações de dados iniciais
   if(InpTakeProfit*digits_adjust<m_symbol.StopsLevel())
     {
      printf("Take Profit must be greater than %d",m_symbol.StopsLevel());
      return(false);
     }
   if(InpTrailingStop*digits_adjust<m_symbol.StopsLevel())
     {
      printf("Trailing Stop must be greater than %d",m_symbol.StopsLevel());
      return(false);
     }
//--- verificar a quantidade correta de lotes
   if(InpLots<m_symbol.LotsMin() || InpLots>m_symbol.LotsMax())
     {
      printf("Lots amount must be in the range from %f to %f",m_symbol.LotsMin(),m_symbol.LotsMax());
      return(false);
     }
   if(MathAbs(InpLots/m_symbol.LotsStep()-MathRound(InpLots/m_symbol.LotsStep()))>1.0 E-10)
     {
      printf("Lots amount is not corresponding with lot step %f",m_symbol.LotsStep());
      return(false);
     }
//--- aviso
   if(InpTakeProfit<=InpTrailingStop)
      printf("Warning: Trailing Stop must be less than Take Profit");
//--- bem-sucedido
   return(true);
  }
//+------------------------------------------------------------------+
//| Inicialização dos indicadores|
//+------------------------------------------------------------------+
bool CSampleExpert::InitIndicators(void)
  {
//--- criar o indicador MACD
   if(m_handle_macd==INVALID_HANDLE)
      if((m_handle_macd=iMACD(NULL,0,12,26,9,PRICE_CLOSE))==INVALID_HANDLE)
        {
         printf("Error creating MACD indicator");
         return(false);
        }
//--- crie o indicador EMA e adicione-o à coleção
  
      
//--- bem-sucedido
   return(true);
  }
//+------------------------------------------------------------------+
//| Verificação de fechamento de posição longa|
//+------------------------------------------------------------------+
bool CSampleExpert::LongClosed(void)
  {
   bool res=false;
//--- ela deve ser fechada?
   
      if(m_macd_current<0 && m_macd_previous>0)
         if(m_macd_current<m_macd_close_level)
           {
            //--- posição de fechamento
            if(m_trade.PositionClose(Symbol()))
               printf("Long position by %s to be closed",Symbol());
            else
               printf("Error closing position by %s : '%s'",Symbol(),m_trade.ResultComment());
            //--- processado e não pode ser modificado
            res=true;
           }
//--- resultado
   return(res);
  }
//+------------------------------------------------------------------+
//| Verificação de fechamento de posição vendida|
//+------------------------------------------------------------------+
bool CSampleExpert::ShortClosed(void)
  {
   bool res=false;
//--- ela deve ser fechada?
   
      if(m_macd_current>0 && m_macd_previous<0)
         if(MathAbs(m_macd_current)>m_macd_close_level)
           {
            //--- posição de fechamento
            if(m_trade.PositionClose(Symbol()))
               printf("Short position by %s to be closed",Symbol());
            else
               printf("Error closing position by %s : '%s'",Symbol(),m_trade.ResultComment());
            //--- processado e não pode ser modificado
            res=true;
           }
//--- resultado
   return(res);
  }
//+------------------------------------------------------------------+
//| Verificação de modificação de posição longa|
//+------------------------------------------------------------------+
bool CSampleExpert::LongModified(void)
  {
   bool res=false;
//--- verificar o trailing stop
   if(InpTrailingStop>0)
     {
      if(m_symbol.Bid()-m_position.PriceOpen()>m_adjusted_point*InpTrailingStop)
        {
         double sl=NormalizeDouble(m_symbol.Bid()-m_traling_stop,m_symbol.Digits());
         double tp=m_position.TakeProfit();
         if(m_position.StopLoss()<sl || m_position.StopLoss()==0.0)
           {
            //--- modificar posição
            if(m_trade.PositionModify(Symbol(),sl,tp))
               printf("Long position by %s to be modified",Symbol());
            else
              {
               printf("Error modifying position by %s : '%s'",Symbol(),m_trade.ResultComment());
               printf("Modify parameters : SL=%f,TP=%f",sl,tp);
              }
            //--- modificado e deve sair do expert
            res=true;
           }
        }
     }
//--- resultado
   return(res);
  }
//+------------------------------------------------------------------+
//| Verificação da modificação da posição vendida
//+------------------------------------------------------------------+
bool CSampleExpert::ShortModified(void)
  {
   bool   res=false;
//--- verificar o trailing stop
   if(InpTrailingStop>0)
     {
      if((m_position.PriceOpen()-m_symbol.Ask())>(m_adjusted_point*InpTrailingStop))
        {
         double sl=NormalizeDouble(m_symbol.Ask()+m_traling_stop,m_symbol.Digits());
         double tp=m_position.TakeProfit();
         if(m_position.StopLoss()>sl || m_position.StopLoss()==0.0)
           {
            //--- modificar posição
            if(m_trade.PositionModify(Symbol(),sl,tp))
               printf("Short position by %s to be modified",Symbol());
            else
              {
               printf("Error modifying position by %s : '%s'",Symbol(),m_trade.ResultComment());
               printf("Modify parameters : SL=%f,TP=%f",sl,tp);
              }
            //--- modificado e deve sair do expert
            res=true;
           }
        }
     }
//--- resultado
   return(res);
  }
//+------------------------------------------------------------------+
//| Verificar a abertura de posição longa|
//+------------------------------------------------------------------+
bool CSampleExpert::LongOpened(void)
  {
   bool res=false;
//--- verificar a possibilidade de posição longa (BUY)
   
      if(m_macd_current>0 && m_macd_previous<0)
         if(MathAbs(m_macd_current)>(m_macd_open_level))
           {
            double price=m_symbol.Ask();
            double tp   =m_symbol.Bid()+m_take_profit;
            //--- verifique se há dinheiro grátis
            if(m_account.FreeMarginCheck(Symbol(),ORDER_TYPE_BUY,InpLots,price)<0.0)
               printf("We have no money. Free Margin = %f",m_account.FreeMargin());
            else
              {
               //--- posição aberta
               if(m_trade.PositionOpen(Symbol(),ORDER_TYPE_BUY,InpLots,price,0.0,tp))
                  printf("Position by %s to be opened",Symbol());
               else
                 {
                  printf("Error opening BUY position by %s : '%s'",Symbol(),m_trade.ResultComment());
                  printf("Open parameters : price=%f,TP=%f",price,tp);
                 }
              }
            //--- em qualquer caso, devemos sair do expert
            res=true;
           }
//--- resultado
   return(res);
  }
//+------------------------------------------------------------------+
//| Verificação de abertura de posição vendida|
//+------------------------------------------------------------------+
bool CSampleExpert::ShortOpened(void)
  {
   bool res=false;
//--- verificar a possibilidade de posição vendida (SELL)
  
      if(m_macd_current<0 && m_macd_previous>0)
         if(m_macd_current<(m_macd_open_level) )
           {
            double price=m_symbol.Bid();
            double tp   =m_symbol.Ask()-m_take_profit;
            //--- verifique se há dinheiro grátis
            if(m_account.FreeMarginCheck(Symbol(),ORDER_TYPE_SELL,InpLots,price)<0.0)
               printf("We have no money. Free Margin = %f",m_account.FreeMargin());
            else
              {
               //--- posição aberta
               if(m_trade.PositionOpen(Symbol(),ORDER_TYPE_SELL,InpLots,price,0.0,tp))
                  printf("Position by %s to be opened",Symbol());
               else
                 {
                  printf("Error opening SELL position by %s : '%s'",Symbol(),m_trade.ResultComment());
                  printf("Open parameters : price=%f,TP=%f",price,tp);
                 }
              }
            //--- em qualquer caso, devemos sair do expert
            res=true;
           }
//--- resultado
   return(res);
  }
//+------------------------------------------------------------------+
//| a função principal retorna true se alguma posição for processada
//+------------------------------------------------------------------+
bool CSampleExpert::Processing(void)
  {
//--- taxas de atualização
   if(!m_symbol.RefreshRates())
      return(false);
//--- indicadores de atualização
   if(BarsCalculated(m_handle_macd)<2 )
      return(false);
   if(CopyBuffer(m_handle_macd,0,0,2,m_buff_MACD_main)  !=2 )
      
      
      return(false);
// m_indicators.Refresh();
//--- para simplificar a codificação e acelerar o acesso
//--- os dados são colocados em variáveis internas
   m_macd_current   =m_buff_MACD_main[0];
   m_macd_previous  =m_buff_MACD_main[1];
   
  
//--- é importante entrar no mercado corretamente, 
//--- mas é mais importante sair dele corretamente.... 
//--- primeiro verifique se a posição existe - tente selecioná-la
   if(m_position.Select(Symbol()))
     {
      if(m_position.PositionType()==POSITION_TYPE_BUY)
        {
         //--- tente fechar ou modificar a posição longa
         if(LongClosed())
            return(true);
         if(LongModified())
            return(true);
        }
      else
        {
         //--- tente fechar ou modificar a posição vendida
         if(ShortClosed())
            return(true);
         if(ShortModified())
            return(true);
        }
     }
//--- nenhuma posição aberta identificada
   else
     {
      //--- verificar a possibilidade de posição longa (BUY)
      if(LongOpened())
         return(true);
      //--- verificar a possibilidade de posição vendida (SELL)
      if(ShortOpened())
         return(true);
     }
//--- sair sem processamento de posição
   return(false);
  }
//+------------------------------------------------------------------+
//| Função de inicialização de especialista|
//+------------------------------------------------------------------+
int OnInit(void)
  {
//--- criar todos os objetos necessários
   if(!ExtExpert.Init())
      return(INIT_FAILED);
//--- secceed
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Função de manipulação de ticks do especialista|
//+------------------------------------------------------------------+
void OnTick(void)
  {
   static datetime limit_time=0; // tempo de processamento da última negociação + tempo limite
//--- não processar se houver tempo limite
   if(TimeCurrent()>=limit_time)
     {
      //--- verificar se há dados
      
        {
         //--- alterar o tempo limite pelo tempo limite em segundos se processado
         if(ExtExpert.Processing())
            limit_time=TimeCurrent()+ExtTimeOut;
        }
     }
  }

Removi todos os dados sobre"média móvel" e "linha de sinal MACD", tudo o que consegui encontrar.

bool CSampleExpert::LongOpened(void)
  {
   bool res=false;
//--- verificar a possibilidade de posição longa (BUY)
   
      if(m_macd_current>0 && m_macd_previous<0)
         if(MathAbs(m_macd_current)>(m_macd_open_level))

Nesse local, em vez de um valor de "0", foi fornecida a linha média. Eu a substituí por "0" em todos os lugares, ao vender e ao fechar os traços.

Автоматический трейдинг и тестирование торговых стратегий
Автоматический трейдинг и тестирование торговых стратегий
  • www.mql5.com
Выберите подходящую торговую стратегию и оформите подписку на нее в пару кликов. Все Сигналы сопровождаются подробной статистикой и графиками. Станьте Поставщиком торговых сигналов и продавайте подписку тысячам трейдеров по всему миру. Наш сервис позволит вам хорошо зарабатывать на прибыльной стратегии даже при небольшом стартовом капитале...
 
Krivets:


Removi todos os dados sobre"média móvel" e "linha de sinal MACD", tudo o que pude encontrar.

Nesse local, em vez do valor "0", a linha média foi especificada. Substituí-o por um valor "0" em todos os lugares, ao vender e ao fechar os rastros.


No exemplo longo:

bool CSampleExpert::LongOpened(void)
  {
   bool res=false;
//--- verificar a possibilidade de posição longa (BUY)
   
      if(m_macd_current>0 && m_macd_previous<0)
         if(MathAbs(m_macd_current)>(m_macd_open_level))
           {

-- Qual é a função da condição destacada?

 

Aqui está o que eu tenho depois de corrigir o que foi destacado acima (pequenos comentários sobre as especificidades das aberturas):


 
Andrey F. Zelinsky:

usando o long como exemplo:

-- qual é o papel da condição destacada?


MathAbs(m_macd_current)>m_macd_open_level - valor atual da linha principal do indicador MACD, módulo

 
Krivets:

MathAbs(m_macd_current)>m_macd_open_level - valor atual da linha principal do indicador MACD modulo


sim, somente essa condição deve ser removida ou definida corretamente - acima está uma imagem do desempenho do EA com essa condição removida

 
Andrey F. Zelinsky:

Sim, mas essa condição deve ser removida ou definida corretamente - acima está uma imagem do desempenho do EA com essa condição removida.


Não alterei a condição, mas alterei outros valores.

input double InpLots          =0.1; // Lotes.
input int    InpTakeProfit    =0;  // Take Profit (em pips)
input int    InpTrailingStop  =0;  // Nível de parada móvel (em pips)
input int    InpMACDOpenLevel =0;   // Nível de abertura MACD (em pips)
input int    InpMACDCloseLevel=0;   // Nível de fechamento do MACD (em pips)
input int    InpMATrendPeriod =26;  // Período de tendência MA

Alterei OpenLevel e Closelevel para 0. Se entendi corretamente, essa é uma das condições para abrir uma posição.

E desabilitei o Takeprofit e o Stoploss.

 

A abertura da posição ocorre por meio do cruzamento do "0", mas, por algum motivo, a operação é fechada após 10 pips. E é desejável que a operação tenha sido aberta após a segunda barra, porque a primeira barra não está formada e há entradas falsas.

Também defini que a operação não fosse feita antes de 60 segundos, ou seja, 10, e a cada 10 segundos, durante o minuto, ele faz uma compra ou venda, ou seja, em um minuto, 6 operações. Se você definir 1 lote, em um minuto haverá uma compra de 6 lotes ou uma venda, dependendo de onde a linha "0" for cruzada.

int ExtTimeOut=60; // tempo limite em segundos entre as operações comerciais
 

Descobri parcialmente o problema, configurei o TakeProfit para 10000 e ele começou a rolar normalmente, mas perdeu algumas negociações. É necessário adicionar uma função para que o rollover ocorra na segunda barra, obtendo-se negociações falsas e, mais provavelmente, por causa dessas negociações perdidas.

Se o TakeProfit for definido para o valor necessário, por exemplo, em "RTS" 100 pontos, ele fecha uma operação no TP e abre uma nova quando o indicador cruza "0". Testei-o em minutos, pois há muitos sinais.