English Русский 中文 Español Deutsch 日本語
Expert Advisor Multiplataforma: Stops

Expert Advisor Multiplataforma: Stops

MetaTrader 5Exemplos | 13 novembro 2017, 09:20
1 698 0
Enrico Lambino
Enrico Lambino

Índice

  1. Introdução
  2. COrder
  3. CStop
  4. CStops
  5. COrderStop
  6. COrderStops
  7. Representação dos Stops no Gráfico
  8. Verificação da Ordem de Stop
  9. Exemplos
  10. Conclusão
  11. Programas Utilizados ​​no Artigo
  12. Arquivos das Classes Apresentados no Artigo


Introdução

Conforme discutido em um artigo anterior, para um expert advisor multiplataforma, nós criamos um gerenciador de ordens (COrderManager) que cuida da maioria das diferenças entre a MQL4 e MQL5 no que diz respeito à entrada e encerramento de posições. Em ambas as versões, o expert advisor salva as informações das negociações na memória criando instâncias da COrder. Os containers de ponteiros dinâmicos para as instâncias deste objeto de classe também estão disponíveis como membros da classe COrderManager (para o histórico de negociações e as negociações atuais).

É possível que o gerenciador de ordens gerencie diretamente os níveis de stop de cada operação. No entanto, fazer isso há certas limitações:

  • A COrderManager provavelmente teria que ser estendida para personalizar como ela lida com os níveis de stop para cada operação.
  • Os métodos existentes da COrderManager tratam apenas da entrada das posições principais.

É possível que a COrderManager seja estendida para que ela possa lidar com os níveis de stop para cada transação (ordem executada) por conta própria. No entanto, isso não se limita apenas à colocação dos níveis, mas também a outras tarefas relacionadas ao monitoramento desses stops, como modificação e verificação se o mercado já atingiu um determinado nível. Essas funções tornariam a COrderManager muito mais complexa que atualmente ela é, sem mencionar as implementações divididas.

O gerenciador de ordens só lida com a entrada das operações principais, enquanto que alguns níveis de stop exigem que o EA realize outras operações de negociação, como a colocação de ordens pendentes e o fechamento das posições atuais. Embora seja possível para o gerenciador de ordens lidar com isso por conta própria, seria melhor fazê-lo concentrar-se na entrada de posições principais e deixar outro objeto de classe lidar com os níveis de stop.

Neste artigo, nós discutiremos a implementação em que a COrderManager trataria exclusivamente a entrada e saída das operações principais (como atualmente é) e, em seguida, a implementação dos níveis de stop tratados separadamente por outro objeto da classe (CStop).

COrder

Como nós aprendemos do artigo anterior (veja Expert Advisor Multiplataforma: Ordens), uma instância da COrder é criada após uma operação de negociação bem-sucedida (entrada). Tanto para a MetaTrader 4 como para a MetaTrader 5, as informações relativas ao stoploss e takeprofit podem ser salvas na ponta da corretora. No entanto, no caso dos stops estarem ocultos da corretora ou envolvidos em vários níveis de stop, as informações sobre a maioria dessas paradas devem ser salvas localmente. Assim, no último caso, após uma entrada bem sucedida de uma posição, a instância da COrder deve ser criada primeiro, seguido das instâncias de objeto que representam seus níveis de stoploss e takeprofit. Em um artigo anterior, nós demonstramos como as instâncias COrder são adicionadas ao gerenciador de ordens após a criação, conforme mostrado na figura a seguir:


TradeOpen

Os níveis de stop são adicionados da mesma maneira. Para fazer isso, nós precisamos apenas inserir o método após a nova instância COrder ser criada e antes de ser adicionada à lista de negociações em andamento (COrders). Assim, nós precisamos apenas modificar a ilustração acima, conforme mostrado na ilustração a seguir:


TradeOpen - com ordens de stop

O funcionamento geral da criação dos níveis de stop é exibido na figura a seguir:

Operação geral de criação dos níveis de stop

Conforme exibido acima nos dois fluxogramas anteriores, assim que uma negociação for inserida com sucesso, uma nova instância da COrder será criada representando-a. Depois disso, as instâncias da COrderStop serão criadas para cada um dos níveis de stoploss e takeprofit definidos. Se não houvesse uma instância da CStop declarada na inicialização do EA, esse processo específico seria ignorado. Por outro lado, se as instâncias da COrderStop foram criadas, os ponteiros para essas instâncias serão armazenados sob a instância COrder criada anteriormente. Nós podemos encontrar esta operação dentro do método Init da COrder:

bool COrderBase::Init(COrders *orders,CStops *stops)
  {
   if(CheckPointer(orders))
      SetContainer(GetPointer(orders));
   if(CheckPointer(stops))
      CreateStops(GetPointer(stops));
   m_order_stops.SetContainer(GetPointer(this));
   return true;
  }

Para a criação dos níveis de stop para a instância da COrder, nós podemos ver que ele chama o método CreateStops, que é mostrado abaixo:

void COrderBase::CreateStops(CStops *stops)
  {
   if(!CheckPointer(stops))
      return;
   if(stops.Total()>0)
     {
      for(int i=0;i<stops.Total();i++)
        {
         CStop *stop=stops.At(i);
         if(CheckPointer(stop)==POINTER_INVALID)
            continue;
         m_order_stops.NewOrderStop(GetPointer(this),stop);
        }
     }
  }
O método itera sobre todas as instâncias disponíveis da CStop, que representa cada par dos níveis de stoploss e takeprofit. Cada uma dessas instâncias da CStop é passada para uma instância da COrderStops, que é simplesmente um container para todos os níveis de stop para uma determinada ordem. Nós podemos então construir a hierarquia dos objetos de classe da seguinte maneira:


Hierarquia dos níveis de stop

Para cada instância da COrder, existe um membro do tipo COrderStops. Esta instância COrderStops é um container (uma extensão da CArrayObj), que contém os ponteiros para instâncias da COrderStop. Cada instância da COrderStop representa um nível de stop (CStop) para apenas essa operação em específico (instância COrder).

CStop

Conforme discutido anteriormente, nós gostaríamos de ter um certo nível de liberdade de personalização de como os níveis de stop de cada negociação são tratados, sem ter que modificar o código fonte do gerenciador de ordens. Isso é amplamente realizado pela classe CStop. Entre as responsabilidades desta classe estão as seguintes:

  1. definir os níveis de stoploss e takeprofit
  2. realizar os cálculos necessários para calcular os níveis de stop
  3. implementar os níveis de stoploss e takeprofit para a operação principal
  4. verificar se o nível de stop foi disparado
  5. conciliar as diferenças entre a MQL4 e MQL5 na implementação dos níveis de stoploss e takeprofit
  6. definir como os stops devem ser tratados ao longo do tempo (por exemplo, breakeven, stop móvel, etc.)

Os pontos 1-5 serão discutidos neste artigo, enquanto que o 6 será discutido em um artigo separado.

Tipos

Três tipos de stop serão discutidos neste artigo:

  1. Stop na ponta da corretora - stops que são enviados à corretora juntamente com a solicitação de negociação
  2. Ordem Stop Pendente - stops que utilizam ordens pendentes que agem como hedge total ou parcial contra a posição principal (MetaTrader 4, MetaTrader 5 no modo hedge) ou como realização parcial ou total da posição principal (MetaTrader 5 no modo netting).
  3. Stop virtual (stop oculto) - stops que são ocultos da corretora e que são gerenciados localmente pelo EA.

Na MetaTrader 4, o stop na ponta da corretora são as ordens de stoploss e takeprofit e que os traders estão mais familiarizados. Estes são os preços ou os níveis de stop que são enviados à corretora junto com a operação principal. Na versão da MetaTrader 5, o modo hedge usa o mesmo mecanismo que a versão da MetaTrader 4. Por outro lado, para o modo netting, uma ordem de stop pendente será usada para este tipo da CStop, uma vez que o stoploss e o takeprofit são diferentes (aplicados em toda a posição do símbolo ou instrumento).

Uma ordem stop pendente usa ordens pendentes para imitar de alguma forma um stop na ponta da corretora. Assim que as ordens pendentes forem executadas, o EA executaria uma operação de negociação (OrderCloseBy) para fechar a posição principal usando o volume da ordem pendente que foi acionada. Isso é verdade para a versão da MetaTrader 4 e a MetaTrader 5 no modo de hedge. Para a MetaTrader 5 na versão modo netting, a realização parcial ou total da posição principal é feita automaticamente, uma vez que só pode haver uma posição mantida a qualquer momento por símbolo.

Stop principal

O stop principal é o nível de stop que desencadeia a saída de uma posição inteira. Normalmente, este é o stop na ponta da corretora. Quando o stoploss ou takeprofit na ponta da corretora é desencadeada, toda a posição é encerada a mercado, independente se o EA pretende continuar trabalhando nisso ou não. No entanto, se houver vários níveis de stop e não há stop na ponta da corretora, deixar o EA decidir qual é o stop principal provavelmente é uma má ideia. Nesse caso, o programador deve selecionar qual instância da CStop é o stop principal da posição. Isso é útil especialmente para algumas funções e recursos que dependem do stop principal da posição, como o gerenciamento de dinheiro. Uma vez que o stoploss do nível de stop principal leva à saída de toda a posição, ele representa o risco máximo ao abrir uma posição. E, sabendo da instância do stop principal, o EA poderá calcular os lotes em conformidade.

Vale ressaltar que quando um stop é atribuído como stop principal, seu volume sempre será igual ao volume inicial da operação principal. Isso funcionaria bem com stops virtuais e na ponta da corretora, mas não em stops que se baseiam em ordens pendentes. Existem dois problemas associados que levam a essa abordagem.

O primeiro motivo é que, na MetaTrader 4, o preço de entrada da ordem pendente pode ser modificada enquanto a ordem pendente ainda não for acionada. Na MetaTrader 5, isso não é possível, uma vez que uma registro claro das operações de negociação deve ser mantido. Uma nova ordem pendente deve ser emitida e, se bem-sucedida, a antiga deve ser excluída e, a partir daí, o EA deve usar a nova ordem pendente como um novo nível de stop.

O segundo problema é a possibilidade da antiga ordem pendente ser acionada enquanto a ordem pendente de substituição está sendo enviada à corretora. Uma vez que o EA não tem controle sobre o desencadeamento das ordens pendentes (a corretora possui), isso pode levar a problemas como posições remanescentes ou um nível de stop encerrar a posição principal com um volume maior que o devido.

Para evitar esses problemas, a abordagem mais simples seria alocar o volume das ordens pendentes na execução das mesmas, em vez de ajustar o volume das ordens pendentes dinamicamente ao longo da vida da posição principal. No entanto, isso requer que não haja outro ordem stop pendente se o stop principal for do tipo ordem stop pendente.

Volume

Para o nível de stop principal, não há necessidade de atribuir o tamanho do lote deduzido da posição principal, pois assim que ela for acionada, toda a posição deverá ser fechada. No entanto, para os outros tipos de níveis de stop, o volume deveria ser considerado, pois geralmente eles devem ser destinados apenas para o fechamento parcial da posição principal. A alocação é dividida em quatro tipos diferentes:

  1. Fixa - tamanho do lote fixo
  2. Porcentagem remanescente - percentual remanescente da posição principal
  3. Percentagem Total - percentual do lote total (volume inicial) da operação principal
  4. Restante - o volume remanescente da operação principal.

O lote fixo é a forma mais simples de alocação de volume. No entanto, isso não funcionaria de forma ótima se o EA estiver usando alguma forma de cálculo de lotes dinâmico para cada posição, ou seja, gerenciamento de dinheiro. Isso é ideal apenas para uso quando o lote é fixo durante a operação do EA.

A Percentagem remanescente e o restante são melhor utilizados quando o stop principal é virtual. O Restante impedirá o EA de criar posições remanescentes a partir de volumes que não foram encerrados ou da execução de uma operação de encerramento com um volume superior a transação principal. A Percentagem Remanescente, por outro lado, é usada quando o EA deve fechar a operação não com base no volume inicial da ordem, mas sim no volume atual da posição originada pela ordem.

O percentual total pode ser usado com os stops na ponta da corretora, virtual e pendentes. Os cálculos usando este método são baseados no volume inicial da transação principal.

Uma-Cancela-a-Outra (OCO)

A CStop é sempre representada por um par de valores, sendo cada valor representando o stoploss ou o takeprofit. No entanto, é possível haver um nível unilateral (possuindo o takeprofit e não o stoploss, ou vice-versa) atribuindo o valor zero para qualquer campo. Por padrão, quando um nível de stop é acionado, acontece o cancelamento do outro. A única exceção para isso é quando a instância CStop é um stop principal.

Classe base

A classe base para a CStop (CStopBase) é exibida no seguinte código:

class CStopBase : public CObject
  {
protected:
   //--- parâmetros da ordem stop   
   bool              m_active;
   bool              m_main;
   string            m_name;
   bool              m_oco;
   double            m_stoploss;
   string            m_stoploss_name;
   ENUM_STOP_TYPE    m_stop_type;
   double            m_takeprofit;
   string            m_takeprofit_name;
   int               m_delay;
   //--- parâmetros de negociação da ordem stop
   ENUM_VOLUME_TYPE  m_volume_type;
   double            m_volume;
   int               m_magic;
   int               m_deviation;
   string            m_comment;
   //--- parâmetros dos objetos da ordem stop
   bool              m_entry_visible;
   bool              m_stoploss_visible;
   bool              m_takeprofit_visible;
   color             m_entry_color;
   color             m_stoploss_color;
   color             m_takeprofit_color;
   ENUM_LINE_STYLE   m_entry_style;
   ENUM_LINE_STYLE   m_stoploss_style;
   ENUM_LINE_STYLE   m_takeprofit_style;
   //--- objetos
   CSymbolManager   *m_symbol_man;
   CSymbolInfo      *m_symbol;
   CAccountInfo     *m_account;
   CTradeManager     m_trade_man;
   CExpertTradeX    *m_trade;
   CTrails          *m_trails;
   CEventAggregator *m_event_man;
   CStops           *m_stops;
public:
                     CStopBase(void);
                    ~CStopBase(void);
   virtual int       Type(void) const {return CLASS_TYPE_STOP;}
   //--- Inicialização
   virtual bool      Init(CSymbolManager*,CAccountInfo*,CEventAggregator*);
   virtual bool      InitAccount(CAccountInfo*);
   virtual bool      InitEvent(CEventAggregator*);
   virtual bool      InitSymbol(CSymbolManager*);
   virtual bool      InitTrade(void);
   virtual CStops   *GetContainer(void);
   virtual void      SetContainer(CStops*);
   virtual bool      Validate(void) const;
   //--- getters e setters
   bool              Active(void);
   void              Active(const bool);
   bool              Broker(void) const;
   void              Comment(const string);
   string            Comment(void) const;
   void              Delay(int delay);
   int               Delay(void) const;
   void              SetDeviation(const int);
   int               SetDeviation(void) const;
   void              EntryColor(const color clr);
   void              EntryStyle(const ENUM_LINE_STYLE);
   void              EntryVisible(const bool);
   bool              EntryVisible(void) const;
   void              Magic(const int);
   int               Magic(void) const;
   void              Main(const bool);
   bool              Main(void) const;
   void              Name(const string);
   string            Name(void) const;
   void              OCO(const bool oco);
   bool              OCO(void) const;
   bool              Pending(void) const;
   void              StopLoss(const double);
   double            StopLoss(void) const;
   void              StopLossColor(const color);
   bool              StopLossCustom(void);
   void              StopLossName(const string);
   string            StopLossName(void) const;
   void              StopLossVisible(const bool);
   bool              StopLossVisible(void) const;
   void              StopLossStyle(const ENUM_LINE_STYLE);
   void              StopType(const ENUM_STOP_TYPE);
   ENUM_STOP_TYPE    StopType(void) const;
   string            SymbolName(void);
   void              TakeProfit(const double);
   double            TakeProfit(void) const;
   void              TakeProfitColor(const color);
   bool              TakeProfitCustom(void);
   void              TakeProfitName(const string);
   string            TakeProfitName(void) const;
   void              TakeProfitStyle(const ENUM_LINE_STYLE);
   void              TakeProfitVisible(const bool);
   bool              TakeProfitVisible(void) const;
   bool              Virtual(void) const;
   void              Volume(double);
   double            Volume(void) const;
   void              VolumeType(const ENUM_VOLUME_TYPE);
   ENUM_VOLUME_TYPE  VolumeType(void) const;
   //--- verificação da ordem stop
   virtual bool      CheckStopLoss(COrder*,COrderStop*);
   virtual bool      CheckTakeProfit(COrder*,COrderStop*);
   virtual bool      CheckStopOrder(ENUM_STOP_MODE,COrder*,COrderStop*)=0;
   virtual bool      DeleteStopOrder(const ulong)=0;
   virtual bool      DeleteMarketStop(const ulong)=0;
   virtual bool      OrderModify(const ulong,const double);
   //--- criação do objeto da ordem stop
   virtual CStopLine *CreateEntryObject(const long,const string,const int,const double);
   virtual CStopLine *CreateStopLossObject(const long,const string,const int,const double);
   virtual CStopLine *CreateTakeProfitObject(const long,const string,const int,const double);
   //--- cálculo do preço da ordem stop   
   virtual bool      Refresh(const string);
   virtual double    StopLossCalculate(const string,const ENUM_ORDER_TYPE,const double);
   virtual double    StopLossCustom(const string,const ENUM_ORDER_TYPE,const double);
   virtual double    StopLossPrice(COrder*,COrderStop*);
   virtual double    StopLossTicks(const ENUM_ORDER_TYPE,const double);
   virtual double    TakeProfitCalculate(const string,const ENUM_ORDER_TYPE,const double);
   virtual double    TakeProfitCustom(const string,const ENUM_ORDER_TYPE,const double);
   virtual double    TakeProfitPrice(COrder*,COrderStop*);
   virtual double    TakeProfitTicks(const ENUM_ORDER_TYPE,const double);
   //--- stop móvel   
   virtual bool      Add(CTrails*);
   virtual double    CheckTrailing(const string,const ENUM_ORDER_TYPE,const double,const double,const ENUM_TRAIL_TARGET);
protected:
   //--- criação de objetos
   virtual CStopLine *CreateObject(const long,const string,const int,const double);
   //--- cálculo do preço da ordem stop
   virtual double    LotSizeCalculate(COrder*,COrderStop*);
   //--- entrada da ordem stop   
   virtual bool      GetClosePrice(const string,const ENUM_ORDER_TYPE,double&);
   //--- saída da ordem stop
   virtual bool      CloseStop(COrder*,COrderStop*,const double)=0;
   //--- desinicialização
   virtual void      Deinit(void);
   virtual void      DeinitSymbol(void);
   virtual void      DeinitTrade(void);
   virtual void      DeinitTrails(void);
  };

Para os níveis de stoploss e takeprofit com base no número de pips ou pontos, há pelo menos quatro métodos de classe que precisam ser lembrados:

  1. O tipo do stop (na ponta da corretora, ordem pendente ou virtual), usando o método StopType
  2. O tipo do cálculo do volume utilizado, usando o método VolumeType
  3. O nível de stoploss em pontos (sempre que necessário), usando o método StopLoss
  4. O nível de takeprofit em pontos (sempre que necessário), usando o método TakeProfit

Todos esses são meros setters sobre os membros de classe, portanto, não há necessidade de detalhar mais esses métodos. Grande parte do restante dos métodos são necessários apenas pela classe em seus cálculos internos. Entre os mais importantes desses métodos protegidos estão os métodos StopLossCalculate e TakeProfitCalculate, cujo código é exibido abaixo:

double CStopBase::StopLossCalculate(const string symbol,const ENUM_ORDER_TYPE type,const double price)
  {   
   if(!Refresh(symbol))
      return 0;
   if(type==ORDER_TYPE_BUY || type==ORDER_TYPE_BUY_STOP || type==ORDER_TYPE_BUY_LIMIT)
      return price-m_stoploss*m_symbol.Point();
   else if(type==ORDER_TYPE_SELL || type==ORDER_TYPE_SELL_STOP || type==ORDER_TYPE_SELL_LIMIT)
      return price+m_stoploss*m_symbol.Point();
   return 0;
  }

double CStopBase::TakeProfitCalculate(const string symbol,const ENUM_ORDER_TYPE type,const double price)
  {
   if(!Refresh(symbol))
      return 0;
   if(type==ORDER_TYPE_BUY || type==ORDER_TYPE_BUY_STOP || type==ORDER_TYPE_BUY_LIMIT)
      return price+m_takeprofit*m_symbol.Point();
   else if(type==ORDER_TYPE_SELL || type==ORDER_TYPE_SELL_STOP || type==ORDER_TYPE_SELL_LIMIT)
      return price-m_takeprofit*m_symbol.Point();
   return 0;
  }

Ambos os métodos precisam de três argumentos, todos os quais estão relacionados a operação principal. Os métodos começam primeiro a atualizar o símbolo através do método Refresh, que simplesmente atualiza o gerenciador de símbolos com o símbolo correto a ser usado. Uma vez que o símbolo foi atualizado, ele retorna o valor do stoploss ou takeprofit com base no valor do ponto fornecido para a instância da classe durante a inicialização.

CStops

A classe CStops servirá como container para as instâncias da CStop. Uma instância desta classe terá que ser adicionada dinamicamente ao gerenciador de ordens como um de seus membros. O código a seguir mostra a CStopsBase, que é a classe base para a CStops:

class CStopsBase : public CArrayObj
  {
protected:
   bool              m_active;
   CEventAggregator *m_event_man;
   CObject          *m_container;
public:
                     CStopsBase(void);
                    ~CStopsBase(void);
   virtual int       Type(void) const {return CLASS_TYPE_STOPS;}
   //--- Inicialização
   virtual bool      Init(CSymbolManager*,CAccountInfo*,CEventAggregator*);
   virtual CObject  *GetContainer(void);
   virtual void      SetContainer(CObject*);
   virtual bool      Validate(void) const;
   //--- setters e getters
   virtual bool      Active(void) const;
   virtual void      Active(const bool);
   virtual CStop    *Main(void);
   //--- recuperação
   virtual bool      CreateElement(const int);
  };

Esta classe é muito semelhante aos outros containers descritos até agora nesta série de artigos.

COrderStop

A COrderStop representa a implementação da CStop para uma operação em específico. Para uma determinada posição, uma CStop pode criar no máximo uma COrderStop. No entanto, um número arbitrário de instâncias da COrderStop pode compartilhar a mesma instância da CStop. Assim, se um EA tiver 3 instâncias diferentes da CStop, normalmente esperamos que cada instância da COrder tenha o mesmo número de instâncias da COrderStop. Se o EA tiver realizado 1000 negociações, o número de instâncias da COrderStop criada será 1000 * 3 = 3000, enquanto o número de instâncias CStop criadas ainda seriam de 3.

A definição da COrderStopBase, a partir da qual a COrderStop se baseia, é exibida no código abaixo:

class COrderStopBase : public CObject
  {
protected:
   bool              m_active;
   //--- parâmetros do stop
   double            m_volume;
   CArrayDouble      m_stoploss;
   CArrayDouble      m_takeprofit;
   ulong             m_stoploss_ticket;
   ulong             m_takeprofit_ticket;
   bool              m_stoploss_closed;
   bool              m_takeprofit_closed;
   bool              m_closed;
   ENUM_STOP_TYPE    m_stop_type;
   string            m_stop_name;
   //--- objeto da ordem principal
   COrder           *m_order;
   //--- objetos do stop
   CStop            *m_stop;
   CStopLine        *m_objentry;
   CStopLine        *m_objsl;
   CStopLine        *m_objtp;
   COrderStops      *m_order_stops;
public:
                     COrderStopBase(void);
                    ~COrderStopBase(void);
   virtual int       Type(void) const {return CLASS_TYPE_ORDERSTOP;}
   //--- Inicialização
   virtual void      Init(COrder*,CStop*,COrderStops*);
   virtual COrderStops *GetContainer(void);
   virtual void      SetContainer(COrderStops*);
   virtual void      Show(bool);
   //--- getters e setters  
   bool              Active(void) const;
   void              Active(bool active);
   string            EntryName(void) const;
   ulong             MainMagic(void) const;
   ulong             MainTicket(void) const;
   double            MainTicketPrice(void) const;
   ENUM_ORDER_TYPE   MainTicketType(void) const;
   COrder           *Order(void);
   void              Order(COrder*);
   CStop            *Stop(void);
   void              Stop(CStop*);
   bool              StopLoss(const double);
   double            StopLoss(void) const;
   double            StopLoss(const int);
   void              StopLossClosed(const bool);
   bool              StopLossClosed(void);
   double            StopLossLast(void) const;
   string            StopLossName(void) const;
   void              StopLossTicket(const ulong);
   ulong             StopLossTicket(void) const;
   void              StopName(const string);
   string            StopName(void) const;
   bool              TakeProfit(const double);
   double            TakeProfit(void) const;
   double            TakeProfit(const int);
   void              TakeProfitClosed(const bool);
   bool              TakeProfitClosed(void);
   double            TakeProfitLast(void) const;
   string            TakeProfitName(void) const;
   void              TakeProfitTicket(const ulong);
   ulong             TakeProfitTicket(void) const;
   void              Volume(const double);
   double            Volume(void) const;
   //--- verificação   
   virtual void      Check(double&)=0;
   virtual bool      Close(void);
   virtual bool      CheckTrailing(void);
   virtual bool      DeleteChartObject(const string);
   virtual bool      DeleteEntry(void);
   virtual bool      DeleteStopLines(void);
   virtual bool      DeleteStopLoss(void);
   virtual bool      DeleteTakeProfit(void);
   virtual bool      IsClosed(void);
   virtual bool      Update(void) {return true;}
   virtual void      UpdateVolume(double) {}
   //--- desinicialização 
   virtual void      Deinit(void);
   //--- recuperação
   virtual bool      Save(const int);
   virtual bool      Load(const int);
   virtual void      Recreate(void);
protected:
   virtual bool      IsStopLossValid(const double) const;
   virtual bool      IsTakeProfitValid(const double) const;
   virtual bool      Modify(const double,const double);
   virtual bool      ModifyStops(const double,const double);
   virtual bool      ModifyStopLoss(const double) {return true;}
   virtual bool      ModifyTakeProfit(const double){return true;}
   virtual bool      UpdateOrderStop(const double,const double){return true;}
   virtual bool      MoveStopLoss(const double);
   virtual bool      MoveTakeProfit(const double);
  };

COrderStop está contida pela COrderStops (a ser discutida na próxima seção), que por sua vez é contida pela COrder. No desenvolvimento atual do EA, não há mais necessidade de declarar uma instância da COrderStop. Isso é criado automaticamente pela COrder com base em uma instância particular da CStop.

COrderStops

class COrderStopsBase : public CArrayObj
  {
protected:
   bool              m_active;
   CArrayInt         m_types;
   COrder           *m_order;
public:
                     COrderStopsBase(void);
                    ~COrderStopsBase(void);
   virtual int       Type(void) const {return CLASS_TYPE_ORDERSTOPS;}
   void              Active(bool);
   bool              Active(void) const;
   //--- Inicialização
   virtual CObject *GetContainer(void);
   virtual void      SetContainer(COrder*);
   virtual bool      NewOrderStop(COrder*,CStop*)=0;
   //--- verificação
   virtual void      Check(double &volume);
   virtual bool      CheckNewTicket(COrderStop*);
   virtual bool      Close(void);
   virtual void      UpdateVolume(const double) {}
   //--- ocultando e exibindo as linhas de stop
   virtual void      Show(const bool);
   //--- recuperação
   virtual bool      CreateElement(const int);
   virtual bool      Save(const int);
   virtual bool      Load(const int);
  };


Assim como a CStop, isso se parece apenas com um container típico. No entanto, ele contém alguns métodos que refletem os métodos dos objetos cujos ponteiros destinam-se ao armazenamento (COrderStop).

Representação dos Stops no Gráfico

CStopLine é um membro da classe da CStop, cuja principal responsabilidade é a representação gráfica dos níveis de stop no gráfico. Ele possui três funções principais em um EA:

  1. Mostra os níveis de stop na inicialização de uma instância da COrder
  2. Atualiza os níveis de stop no evento onde um ou ambos os níveis de stop foram alterados
  3. Remove as linhas de stop assim que a operação principal é encerrada

Todas essas funções são implementadas através da classe CStop.

A definição da CStopLineBase, a partir da qual a CStopLine é baseado, é exibida abaixo:

class CStopLineBase : public CChartObjectHLine
  {
protected:
   bool              m_active;
   CStop            *m_stop;
public:
                     CStopLineBase(void);
                    ~CStopLineBase(void);
   virtual int       Type(void) const {return CLASS_TYPE_STOPLINE;}
   virtual void      SetContainer(CStop*);
   virtual CStop    *GetContainer(void);
   bool              Active(void) const;
   void              Active(const bool);
   virtual bool      ChartObjectExists(void) const;
   virtual double    GetPrice(const int);
   virtual bool      Move(const double);
   virtual bool      SetStyle(const ENUM_LINE_STYLE);
   virtual bool      SetColor(const color);
  };

Nas versões mais antigas da MetaTrader 4, os níveis de stoploss e takeprofit não são modificáveis ​​pelo método de arraste. Esses níveis tiveram de ser modificados através da janela de ordens ou através do uso de EA's ou scripts. No entanto, a representação gráfica desses níveis ainda pode ser útil, especialmente quando se trata dos stops virtuais.

Verificação da Ordem de Stop

Depois que os níveis de stop foram criados com sucesso para uma determinada posição, o próximo passo seria verificar se o mercado atingiu um determinado nível de stop. Para os stops na ponta da corretora, o processo não é necessário, uma vez que a operação de fechamento é realizada pelo lado do servidor. No entanto, para os stops virtuais e pendentes, na maioria dos casos, cabe ao EA realizar a operação de encerramento.

Para os stops virtuais, o expert advisor é inteiramente responsável por monitorar o movimento do mercado e para verificar se o mercado atingiu ou não um determinado nível de parada. A figura a seguir mostra a operação geral. Assim que o mercado atingir um nível de stop, o expert advisor executa a operação de fechamento apropriada.

Verificação da OrderStop (virtual)

Para stops com base nas ordens pendentes, o processo é um pouco mais complexo. A ativação de um nível de stop leva ao acionamento de uma ordem pendente, ou seja, se tornando uma posição. Isso é feito automaticamente na ponta da corretora. Assim, seria da responsabilidade do EA detectar se a ordem pendente ainda está pendente ou se ela foi executada a mercado. Se a ordem pendente já tiver sido acionada, o expert advisor será responsável por fechar a posição principal com o volume da ordem pendente que acabou de ser acionada - uma operação de encerramento por uma ordem oposta.

Verificação da COrderStop (ordem stop pendente)

Em todos os casos, assim que um determinado nível de ordem stop é acionado, o nível de stop é marcado como fechado. Isso é para impedir que um determinado nível de stop seja executado mais de uma vez.

Exemplos

Exemplo 1: Um EA usando Heiken Ashi e Média Móvel, com um único nível de stop (stop principal)

Na maioria dos expert advisors, um stoploss e takeprofit são, muitas vezes suficientes. Nós vamos agora estender o exemplo no artigo anterior (veja Expert Advisor Multiplataforma: Filtros de Tempo) para a adição de stoploss e takeprofit no código fonte. Para fazer isso, primeiro, nós criamos uma nova instância do container (CStops). Em seguida, crie uma instância da CStop e, em seguida, adicione o ponteiro ao container. O ponteiro para o container será eventualmente adicionado ao gerenciador de ordens. O código é exibido abaixo:

int OnInit()
  {
//--- outro código

   CStops *stops=new CStops();

   CStop *main=new CStop("main");
   main.StopType(stop_type_main);
   main.VolumeType(VOLUME_TYPE_PERCENT_TOTAL);
   main.Main(true);
   main.StopLoss(stop_loss);
   main.TakeProfit(take_profit);
   stops.Add(GetPointer(main));
   
   order_manager.AddStops(GetPointer(stops));     
//--- outro código
  }

A seguir, é exibido os resultados do teste do stop na ponta da corretora na MetaTrader 4. Isso é o que os traders normalmente esperam das operações executadas por um expert advisor na plataforma.

# Hora Tipo Ordem Tamanho Preço S / L T / P Lucro Saldo
1 2017.01.03 10:00 sell 1 0.30 1.04597 1.05097 1.04097
2 2017.01.03 11:34 t/p 1 0.30 1.04097 1.05097 1.04097 150.00 3150.00
3 2017.01.05 11:00 sell 2 0.30 1.05149 1.05649 1.04649
4 2017.01.05 17:28 s/l 2 0.30 1.05649 1.05649 1.04649 -150.00 3000.00

Para as ordens stop pendentes, os stops são colocados antecipadamente, como no sl/tp padrão, mas na forma de ordens pendentes. Assim que a ordem pendente for acionada, o expert advisor irá então executar uma operação de encerramento, encerrando a posição principal pelo volume da ordem pendente acionada. No entanto, ao contrário do sl/tp padrão, o EA executa isso no lado do cliente. Isso não será executado a menos que a plataforma de negociação esteja em execução e o EA esteja sendo executado em um gráfico.

# Hora Tipo Ordem Tamanho Preço S / L T / P Lucro Saldo
1 2017.01.03 10:00 sell 1 0.30 1.04597 0.00000 0.00000
2 2017.01.03 10:00 buy stop 2 0.30 1.05097 0.00000 0.00000
3 2017.01.03 10:00 buy limit 3 0.30 1.04097 0.00000 0.00000
4 2017.01.03 11:34 buy 3 0.30 1.04097 0.00000 0.00000
5 2017.01.03 11:34 close by 1 0.30 1.04097 0.00000 0.00000 150.00 3150.00
6 2017.01.03 11:34 close by 3 0.00 1.04097 0.00000 0.00000 0.00 3150.00
7 2017.01.03 11:34 delete 2 0.30 1.05097 0.00000 0.00000
8 2017.01.05 11:00 sell 4 0.30 1.05149 0.00000 0.00000
9 2017.01.05 11:00 buy stop 5 0.30 1.05649 0.00000 0.00000
10 2017.01.05 11:00 buy limit 6 0.30 1.04649 0.00000 0.00000
11 2017.01.05 17:28 buy 5 0.30 1.05649 0.00000 0.00000
12 2017.01.05 17:28 close by 4 0.30 1.05649 0.00000 0.00000 -150.00 3000.00
13 2017.01.05 17:28 close by 5 0.00 1.05649 0.00000 0.00000 0.00 3000.00
14 2017.01.05 17:28 delete 6 0.30 1.04649 0.00000 0.00000


Os stops virtuais não enviam nada sobre os stops na operação principal. A corretora só é informada assim que o EA executa uma ordem de encerramento. A tabela a seguir mostra o comportamento do EA usando os stops virtuais. Aqui, assim que o preço-alvo para um nível de stop é acionado, o EA envia uma solicitação de negociação ao servidor para encerrar a operação principal.

# Hora Tipo Ordem Tamanho Preço S / L T / P Lucro Saldo
1 2017.01.03 10:00 sell 1 0.30 1.04597 0.00000 0.00000
2 2017.01.03 11:34 close 1 0.30 1.04097 0.00000 0.00000 150.00 3150.00
3 2017.01.05 11:00 sell 2 0.30 1.05149 0.00000 0.00000
4 2017.01.05 17:28 close 2 0.30 1.05649 0.00000 0.00000 -150.00 3000.00


Agora, vamos para a MetaTrader 5. O modo hedge na MetaTrader 5 está muito mais próximo da MetaTrader 4 em termos de resultados finais. A tabela a seguir mostra os resultados do teste com os stops na ponta da corretora. Aqui, nós podemos ver claramente os níveis de stoploss e takeprofit das operações principais em suas respectivas colunas.













Ordens
Horário de abertura Ordem Símbolo Tipo Volume Preço S / L T / P Hora Estado Comentário
2017.01.03 10:00:00 2 EURUSD sell 0.30 / 0.30 1.04597 1.05097 1.04097 2017.01.03 10:00:00 filled
2017.01.03 11:34:38 3 EURUSD buy 0.30 / 0.30 1.04097

2017.01.03 11:34:38 filled tp 1.04097
2017.01.05 11:00:00 4 EURUSD sell 0.30 / 0.30 1.05149 1.05649 1.04649 2017.01.05 11:00:00 filled
2017.01.05 17:28:37 5 EURUSD buy 0.30 / 0.30 1.05649

2017.01.05 17:28:37 filled sl 1.05649

Ofertas
Hora Oferta Símbolo Tipo Direção Volume Preço Ordem Comissão Swap Lucro Saldo Comentário
2017.01.01 00:00:00 1
Saldo



0.00 0.00 3 000.00 3 000.00
2017.01.03 10:00:00 2 EURUSD sell in 0.30 1.04597 2 0.00 0.00 0.00 3 000.00
2017.01.03 11:34:38 3 EURUSD buy out 0.30 1.04097 3 0.00 0.00 150.00 3 150.00 tp 1.04097
2017.01.05 11:00:00 4 EURUSD sell in 0.30 1.05149 4 0.00 0.00 0.00 3 150.00
2017.01.05 17:28:37 5 EURUSD buy out 0.30 1.05649 5 0.00 0.00 -150.00 3 000.00 sl 1.05649

0.00 0.00 0.00 3 000.00

No modo hedge, as ordens pendentes funcionam basicamente da mesma maneira que a MetaTrader 4, então o EA também executará uma operação de encerramento quando uma ordem pendente tiver sido acionada.














Ordens
Horário de abertura Ordem Símbolo Tipo Volume Preço S / L T / P Hora Estado Comentário
2017.01.03 10:00:00 2 EURUSD sell 0.30 / 0.30 1.04597

2017.01.03 10:00:00 filled
2017.01.03 10:00:00 3 EURUSD buy stop 0.30 / 0.00 1.05097

2017.01.03 11:34:38 canceled
2017.01.03 10:00:00 4 EURUSD buy limit 0.30 / 0.30 1.04097

2017.01.03 11:34:38 filled
2017.01.03 11:34:38 5 EURUSD close by 0.30 / 0.30 1.04097

2017.01.03 11:34:38 filled close #2 by #4
2017.01.05 11:00:00 6 EURUSD sell 0.30 / 0.30 1.05149

2017.01.05 11:00:00 filled
2017.01.05 11:00:00 7 EURUSD buy stop 0.30 / 0.30 1.05649

2017.01.05 17:28:37 filled
2017.01.05 11:00:00 8 EURUSD buy limit 0.30 / 0.00 1.04649

2017.01.05 17:28:37 canceled
2017.01.05 17:28:37 9 EURUSD close by 0.30 / 0.30 1.05649

2017.01.05 17:28:37 filled close #6 by #7

Ofertas
Hora Oferta Símbolo Tipo Direção Volume Preço Ordem Comissão Swap Lucro Saldo Comentário
2017.01.01 00:00:00 1
Saldo



0.00 0.00 3 000.00 3 000.00
2017.01.03 10:00:00 2 EURUSD sell in 0.30 1.04597 2 0.00 0.00 0.00 3 000.00
2017.01.03 11:34:38 3 EURUSD buy in 0.30 1.04097 4 0.00 0.00 0.00 3 000.00
2017.01.03 11:34:38 4 EURUSD buy out by 0.30 1.04097 5 0.00 0.00 150.00 3 150.00 close #2 by #4
2017.01.03 11:34:38 5 EURUSD sell out by 0.30 1.04597 5 0.00 0.00 0.00 3 150.00 close #2 by #4
2017.01.05 11:00:00 6 EURUSD sell in 0.30 1.05149 6 0.00 0.00 0.00 3 150.00
2017.01.05 17:28:37 7 EURUSD buy in 0.30 1.05649 7 0.00 0.00 0.00 3 150.00
2017.01.05 17:28:37 9 EURUSD sell out by 0.30 1.05149 9 0.00 0.00 0.00 3 150.00 close #6 by #7
2017.01.05 17:28:37 8 EURUSD buy out by 0.30 1.05649 9 0.00 0.00 -150.00 3 000.00 close #6 by #7

0.00 0.00 0.00 3 000.00

Usando os stops virtuais, normalmente não vemos a marca "close" da maneira que vemos na MetaTrader 4. Em vez disso, a operação de fechamento usa o tipo oposto da operação principal, mas podemos ver no histórico de transações, seja ela comprada/vendida e de entrada ou saída (in/out).














Ordens
Horário de abertura Ordem Símbolo Tipo Volume Preço S / L T / P Hora Estado Comentário
2017.01.03 10:00:00 2 EURUSD sell 0.30 / 0.30 1.04597

2017.01.03 10:00:00 filled
2017.01.03 11:34:38 3 EURUSD buy 0.30 / 0.30 1.04097

2017.01.03 11:34:38 filled
2017.01.05 11:00:00 4 EURUSD sell 0.30 / 0.30 1.05149

2017.01.05 11:00:00 filled
2017.01.05 17:28:37 5 EURUSD buy 0.30 / 0.30 1.05649

2017.01.05 17:28:37 filled

Ofertas
Hora Oferta Símbolo Tipo Direção Volume Preço Ordem Comissão Swap Lucro Saldo Comentário
2017.01.01 00:00:00 1
Saldo



0.00 0.00 3 000.00 3 000.00
2017.01.03 10:00:00 2 EURUSD sell in 0.30 1.04597 2 0.00 0.00 0.00 3 000.00
2017.01.03 11:34:38 3 EURUSD buy out 0.30 1.04097 3 0.00 0.00 150.00 3 150.00
2017.01.05 11:00:00 4 EURUSD sell in 0.30 1.05149 4 0.00 0.00 0.00 3 150.00
2017.01.05 17:28:37 5 EURUSD buy out 0.30 1.05649 5 0.00 0.00 -150.00 3 000.00

0.00 0.00 0.00 3 000.00

Para o modo de compensação, uma vez que a MetaTrader 5 neste modo usa o stoploss e o takeprofit global (aplica-se a toda a posição), o EA tem que usar ordens pendentes para que as negociações tenham níveis de stoploss e de takeprofit. Conforme discutido anteriormente, quando no modo hedge, os stops na ponta da corretora irá operar com stops com base nas ordens pendentes, conforme é exibido na tabela a seguir:













Ordens
Horário de abertura Ordem Símbolo Tipo Volume Preço S / L T / P Hora Estado Comentário
2017.01.03 10:00:00 2 EURUSD sell 0.30 / 0.30 1.04597

2017.01.03 10:00:00 filled
2017.01.03 10:00:00 3 EURUSD buy stop 0.30 / 0.00 1.05097

2017.01.03 11:34:38 canceled
2017.01.03 10:00:00 4 EURUSD buy limit 0.30 / 0.30 1.04097

2017.01.03 11:34:38 filled
2017.01.05 11:00:00 5 EURUSD sell 0.30 / 0.30 1.05149

2017.01.05 11:00:00 filled
2017.01.05 11:00:00 6 EURUSD buy stop 0.30 / 0.30 1.05649

2017.01.05 17:28:37 filled
2017.01.05 11:00:00 7 EURUSD buy limit 0.30 / 0.00 1.04649

2017.01.05 17:28:37 canceled

Ofertas
Hora Oferta Símbolo Tipo Direção Volume Preço Ordem Comissão Swap Lucro Saldo Comentário
2017.01.01 00:00:00 1
Saldo



0.00 0.00 3 000.00 3 000.00
2017.01.03 10:00:00 2 EURUSD sell in 0.30 1.04597 2 0.00 0.00 0.00 3 000.00
2017.01.03 11:34:38 3 EURUSD buy out 0.30 1.04097 4 0.00 0.00 150.00 3 150.00
2017.01.05 11:00:00 4 EURUSD sell in 0.30 1.05149 5 0.00 0.00 0.00 3 150.00
2017.01.05 17:28:37 5 EURUSD buy out 0.30 1.05649 6 0.00 0.00 -150.00 3 000.00

0.00 0.00 0.00 3 000.00

A tabela a seguir mostra o resultado quando os stops são baseadas em ordens pendentes. Isso seria o mesmo que a tabela anterior, pelo motivo mencionado anteriormente.













Ordens
Horário de abertura Ordem Símbolo Tipo Volume Preço S / L T / P Hora Estado Comentário
2017.01.03 10:00:00 2 EURUSD sell 0.30 / 0.30 1.04597

2017.01.03 10:00:00 filled
2017.01.03 10:00:00 3 EURUSD buy stop 0.30 / 0.00 1.05097

2017.01.03 11:34:38 canceled
2017.01.03 10:00:00 4 EURUSD buy limit 0.30 / 0.30 1.04097

2017.01.03 11:34:38 filled
2017.01.05 11:00:00 5 EURUSD sell 0.30 / 0.30 1.05149

2017.01.05 11:00:00 filled
2017.01.05 11:00:00 6 EURUSD buy stop 0.30 / 0.30 1.05649

2017.01.05 17:28:37 filled
2017.01.05 11:00:00 7 EURUSD buy limit 0.30 / 0.00 1.04649

2017.01.05 17:28:37 canceled

Ofertas
Hora Oferta Símbolo Tipo Direção Volume Preço Ordem Comissão Swap Lucro Saldo Comentário
2017.01.01 00:00:00 1
Saldo



0.00 0.00 3 000.00 3 000.00
2017.01.03 10:00:00 2 EURUSD sell in 0.30 1.04597 2 0.00 0.00 0.00 3 000.00
2017.01.03 11:34:38 3 EURUSD buy out 0.30 1.04097 4 0.00 0.00 150.00 3 150.00
2017.01.05 11:00:00 4 EURUSD sell in 0.30 1.05149 5 0.00 0.00 0.00 3 150.00
2017.01.05 17:28:37 5 EURUSD buy out 0.30 1.05649 6 0.00 0.00 -150.00 3 000.00

0.00 0.00 0.00 3 000.00

A tabela a seguir mostra o uso de stops virtuais na MetaTrader 5 no modo netting. Os níveis de stop virtual no modo netting podem parecer os mesmos em modo de hedge, mas o funcionamento interno é diferente.














Ordens
Horário de abertura Ordem Símbolo Tipo Volume Preço S / L T / P Hora Estado Comentário
2017.01.03 10:00:00 2 EURUSD sell 0.30 / 0.30 1.04597

2017.01.03 10:00:00 filled
2017.01.03 11:34:38 3 EURUSD buy 0.30 / 0.30 1.04097

2017.01.03 11:34:38 filled
2017.01.05 11:00:00 4 EURUSD sell 0.30 / 0.30 1.05149

2017.01.05 11:00:00 filled
2017.01.05 17:28:37 5 EURUSD buy 0.30 / 0.30 1.05649

2017.01.05 17:28:37 filled

Ofertas
Hora Oferta Símbolo Tipo Direção Volume Preço Ordem Comissão Swap Lucro Saldo Comentário
2017.01.01 00:00:00 1
Saldo



0.00 0.00 3 000.00 3 000.00
2017.01.03 10:00:00 2 EURUSD sell in 0.30 1.04597 2 0.00 0.00 0.00 3 000.00
2017.01.03 11:34:38 3 EURUSD buy out 0.30 1.04097 3 0.00 0.00 150.00 3 150.00
2017.01.05 11:00:00 4 EURUSD sell in 0.30 1.05149 4 0.00 0.00 0.00 3 150.00
2017.01.05 17:28:37 5 EURUSD buy out 0.30 1.05649 5 0.00 0.00 -150.00 3 000.00

0.00 0.00 0.00 3 000.00

Exemplo 2: Um EA usando Heiken Ashi e média móvel, com três níveis de stop

Os expert advisors mais complexos muitas vezes exigem mais de um mercado de stoploss e takeprofit. Nós usamos o mesmo método que o exemplo anterior na adição de níveis de stop adicionais, ou seja, os níveis de stop chamados de "stop1" e "stop2":

int OnInit()
  {
//--- outro código
  
   CStops *stops=new CStops();

   CStop *main=new CStop("main");
   main.StopType(stop_type_main);
   main.VolumeType(VOLUME_TYPE_PERCENT_TOTAL);
   main.Main(true);
   main.StopLoss(stop_loss);
   main.TakeProfit(take_profit);
   stops.Add(GetPointer(main));
   
   CStop *stop1=new CStop("stop1");
   stop1.StopType(stop_type1);
   stop1.VolumeType(VOLUME_TYPE_PERCENT_TOTAL);
   stop1.Volume(0.35);
   stop1.StopLoss(stop_loss1);
   stop1.TakeProfit(take_profit1);
   stops.Add(GetPointer(stop1));
   
   CStop *stop2=new CStop("stop2");
   stop2.StopType(stop_type2);
   stop2.VolumeType(VOLUME_TYPE_PERCENT_TOTAL);
   stop2.Volume(0.35);
   stop2.StopLoss(stop_loss2);
   stop2.TakeProfit(take_profit2);
   stops.Add(GetPointer(stop2));
   
   order_manager.AddStops(GetPointer(stops));

//--- outro código
  }

A tabela a seguir mostra os resultados de um teste na MetaTrader 4:

# Hora Tipo Ordem Tamanho Preço S / L T / P Lucro Saldo
1 2017.01.03 10:00 sell 1 0.30 1.04597 1.05097 1.04097
2 2017.01.03 10:00 buy stop 2 0.11 1.04847 0.00000 0.00000
3 2017.01.03 10:00 buy limit 3 0.11 1.04347 0.00000 0.00000
4 2017.01.03 10:21 buy 3 0.11 1.04347 0.00000 0.00000
5 2017.01.03 10:21 close by 1 0.11 1.04347 1.05097 1.04097 27.50 3027.50
6 2017.01.03 10:21 sell 4 0.19 1.04597 1.05097 1.04097
7 2017.01.03 10:21 close by 3 0.00 1.04347 0.00000 0.00000 0.00 3027.50
8 2017.01.03 10:21 delete 2 0.11 1.04847 0.00000 0.00000
9 2017.01.03 10:34 close 4 0.11 1.04247 1.05097 1.04097 38.50 3066.00
10 2017.01.03 10:34 sell 5 0.08 1.04597 1.05097 1.04097
11 2017.01.03 11:34 t/p 5 0.08 1.04097 1.05097 1.04097 40.00 3106.00
12 2017.01.05 11:00 sell 6 0.30 1.05149 1.05649 1.04649
13 2017.01.05 11:00 buy stop 7 0.11 1.05399 0.00000 0.00000
14 2017.01.05 11:00 buy limit 8 0.11 1.04899 0.00000 0.00000
15 2017.01.05 12:58 buy 8 0.11 1.04899 0.00000 0.00000
16 2017.01.05 12:58 close by 6 0.11 1.04899 1.05649 1.04649 27.50 3133.50
17 2017.01.05 12:58 sell 9 0.19 1.05149 1.05649 1.04649
18 2017.01.05 12:58 close by 8 0.00 1.04899 0.00000 0.00000 0.00 3133.50
19 2017.01.05 12:58 delete 7 0.11 1.05399 0.00000 0.00000
20 2017.01.05 16:00 close 9 0.19 1.05314 1.05649 1.04649 -31.35 3102.15
21 2017.01.05 16:00 buy 10 0.30 1.05314 1.04814 1.05814
22 2017.01.05 16:00 sell stop 11 0.11 1.05064 0.00000 0.00000
23 2017.01.05 16:00 sell limit 12 0.11 1.05564 0.00000 0.00000
24 2017.01.05 17:09 sell 12 0.11 1.05564 0.00000 0.00000
25 2017.01.05 17:09 close by 10 0.11 1.05564 1.04814 1.05814 27.50 3129.65
26 2017.01.05 17:09 buy 13 0.19 1.05314 1.04814 1.05814
27 2017.01.05 17:09 close by 12 0.00 1.05564 0.00000 0.00000 0.00 3129.65
28 2017.01.05 17:09 delete 11 0.11 1.05064 0.00000 0.00000
29 2017.01.05 17:28 close 13 0.11 1.05664 1.04814 1.05814 38.50 3168.15
30 2017.01.05 17:28 buy 14 0.08 1.05314 1.04814 1.05814
31 2017.01.05 17:40 t/p 14 0.08 1.05814 1.04814 1.05814 40.00 3208.15


Conforme mostrado na tabela acima, todos os três níveis de stop foram ativados para o primeiro comércio. Para o nível de stop virtual, o EA realizou um fechamento parcial na operação principal como esperado. Para o nível de stop usando ordens pendentes, assim que a ordem pendente foi executada, o EA realizou um fechamento por operação e deduziu seu volume opreação principal. Finalmente, para o nível de stop principal, que é um stop na ponta da corretora, A principal operação deixou o mercado com o volume restante de 0.08 lotes.

A tabela a seguir mostra os resultados de um teste na MetaTrader 5 no modo hedge:














Ordens
Horário de abertura Ordem Símbolo Tipo Volume Preço S / L T / P Hora Estado Comentário
2017.01.03 10:00:00 2 EURUSD sell 0.30 / 0.30 1.04597 1.05097 1.04097 2017.01.03 10:00:00 filled
2017.01.03 10:00:00 3 EURUSD buy stop 0.11 / 0.00 1.04847

2017.01.03 10:21:32 canceled
2017.01.03 10:00:00 4 EURUSD buy limit 0.11 / 0.11 1.04347

2017.01.03 10:21:32 filled
2017.01.03 10:21:32 5 EURUSD close by 0.11 / 0.11 1.04347

2017.01.03 10:21:32 filled close #2 by #4
2017.01.03 10:33:40 6 EURUSD buy 0.11 / 0.11 1.04247

2017.01.03 10:33:40 filled
2017.01.03 11:34:38 7 EURUSD buy 0.08 / 0.08 1.04097

2017.01.03 11:34:38 filled tp 1.04097
2017.01.05 11:00:00 8 EURUSD sell 0.30 / 0.30 1.05149 1.05649 1.04649 2017.01.05 11:00:00 filled
2017.01.05 11:00:00 9 EURUSD buy stop 0.11 / 0.00 1.05399

2017.01.05 12:58:27 canceled
2017.01.05 11:00:00 10 EURUSD buy limit 0.11 / 0.11 1.04899

2017.01.05 12:58:27 filled
2017.01.05 12:58:27 11 EURUSD close by 0.11 / 0.11 1.04896

2017.01.05 12:58:27 filled close #8 by #10
2017.01.05 16:00:00 12 EURUSD buy 0.19 / 0.19 1.05307

2017.01.05 16:00:00 filled
2017.01.05 16:00:00 13 EURUSD buy 0.30 / 0.30 1.05307 1.04807 1.05807 2017.01.05 16:00:00 filled
2017.01.05 16:00:00 14 EURUSD sell stop 0.11 / 0.00 1.05057

2017.01.05 17:09:40 canceled
2017.01.05 16:00:00 15 EURUSD sell limit 0.11 / 0.11 1.05557

2017.01.05 17:09:40 filled
2017.01.05 17:09:40 16 EURUSD close by 0.11 / 0.11 1.05557

2017.01.05 17:09:40 filled close #13 by #15
2017.01.05 17:28:47 17 EURUSD sell 0.11 / 0.11 1.05660

2017.01.05 17:28:47 filled
2017.01.05 17:29:15 18 EURUSD sell 0.08 / 0.08 1.05807

2017.01.05 17:29:15 filled tp 1.05807

Ofertas
Hora Oferta Símbolo Tipo Direção Volume Preço Ordem Comissão Swap Lucro Saldo Comentário
2017.01.01 00:00:00 1
Saldo



0.00 0.00 3 000.00 3 000.00
2017.01.03 10:00:00 2 EURUSD sell in 0.30 1.04597 2 0.00 0.00 0.00 3 000.00
2017.01.03 10:21:32 3 EURUSD buy in 0.11 1.04347 4 0.00 0.00 0.00 3 000.00
2017.01.03 10:21:32 4 EURUSD buy out by 0.11 1.04347 5 0.00 0.00 27.50 3 027.50 close #2 by #4
2017.01.03 10:21:32 5 EURUSD sell out by 0.11 1.04597 5 0.00 0.00 0.00 3 027.50 close #2 by #4
2017.01.03 10:33:40 6 EURUSD buy out 0.11 1.04247 6 0.00 0.00 38.50 3 066.00
2017.01.03 11:34:38 7 EURUSD buy out 0.08 1.04097 7 0.00 0.00 40.00 3 106.00 tp 1.04097
2017.01.05 11:00:00 8 EURUSD sell in 0.30 1.05149 8 0.00 0.00 0.00 3 106.00
2017.01.05 12:58:27 9 EURUSD buy in 0.11 1.04896 10 0.00 0.00 0.00 3 106.00
2017.01.05 12:58:27 10 EURUSD buy out by 0.11 1.04896 11 0.00 0.00 27.83 3 133.83 close #8 by #10
2017.01.05 12:58:27 11 EURUSD sell out by 0.11 1.05149 11 0.00 0.00 0.00 3 133.83 close #8 by #10
2017.01.05 16:00:00 12 EURUSD buy out 0.19 1.05307 12 0.00 0.00 -30.02 3 103.81
2017.01.05 16:00:00 13 EURUSD buy in 0.30 1.05307 13 0.00 0.00 0.00 3 103.81
2017.01.05 17:09:40 14 EURUSD sell in 0.11 1.05557 15 0.00 0.00 0.00 3 103.81
2017.01.05 17:09:40 16 EURUSD buy out by 0.11 1.05307 16 0.00 0.00 0.00 3 103.81 close #13 by #15
2017.01.05 17:09:40 15 EURUSD sell out by 0.11 1.05557 16 0.00 0.00 27.50 3 131.31 close #13 by #15
2017.01.05 17:28:47 17 EURUSD sell out 0.11 1.05660 17 0.00 0.00 38.83 3 170.14
2017.01.05 17:29:15 18 EURUSD sell out 0.08 1.05807 18 0.00 0.00 40.00 3 210.14 tp 1.05807

0.00 0.00 210.14 3 210.14

Conforme mostrado na tabela acima, o EA funciona de forma um tanto similar na MetaTrader 5 no modo hedge. A mecânica foi a mesma que na MetaTrader 4 para os três tipos de níveis de stop.

A tabela a seguir mostra os resultados de um teste na MetaTrader 5, modo netting:














Ordens
Horário de abertura Ordem Símbolo Tipo Volume Preço S / L T / P Hora Estado Comentário
2017.01.03 10:00:00 2 EURUSD sell 0.30 / 0.30 1.04597

2017.01.03 10:00:00 filled
2017.01.03 10:00:00 3 EURUSD buy stop 0.30 / 0.00 1.05097

2017.01.03 11:34:38 canceled
2017.01.03 10:00:00 4 EURUSD buy limit 0.30 / 0.30 1.04097

2017.01.03 11:34:38 filled
2017.01.03 10:00:00 5 EURUSD buy stop 0.11 / 0.00 1.04847

2017.01.03 10:21:32 canceled
2017.01.03 10:00:00 6 EURUSD buy limit 0.11 / 0.11 1.04347

2017.01.03 10:21:32 filled
2017.01.03 10:33:40 7 EURUSD buy 0.11 / 0.11 1.04247

2017.01.03 10:33:40 filled
2017.01.05 11:00:00 8 EURUSD sell 0.30 / 0.30 1.05149

2017.01.05 11:00:00 filled
2017.01.05 11:00:00 9 EURUSD buy stop 0.30 / 0.00 1.05649

2017.01.05 16:00:00 canceled
2017.01.05 11:00:00 10 EURUSD buy limit 0.30 / 0.00 1.04649

2017.01.05 16:00:00 canceled
2017.01.05 11:00:00 11 EURUSD buy stop 0.11 / 0.00 1.05399

2017.01.05 12:58:27 canceled
2017.01.05 11:00:00 12 EURUSD buy limit 0.11 / 0.11 1.04899

2017.01.05 12:58:27 filled
2017.01.05 16:00:00 13 EURUSD buy 0.19 / 0.19 1.05307

2017.01.05 16:00:00 filled
2017.01.05 16:00:00 14 EURUSD buy 0.30 / 0.30 1.05307

2017.01.05 16:00:00 filled
2017.01.05 16:00:00 15 EURUSD sell stop 0.30 / 0.00 1.04807

2017.01.05 17:29:15 canceled
2017.01.05 16:00:00 16 EURUSD sell limit 0.30 / 0.30 1.05807

2017.01.05 17:29:15 filled
2017.01.05 16:00:00 17 EURUSD sell stop 0.11 / 0.00 1.05057

2017.01.05 17:09:40 canceled
2017.01.05 16:00:00 18 EURUSD sell limit 0.11 / 0.11 1.05557

2017.01.05 17:09:40 filled
2017.01.05 17:28:47 19 EURUSD sell 0.11 / 0.11 1.05660

2017.01.05 17:28:47 filled

Ofertas
Hora Oferta Símbolo Tipo Direção Volume Preço Ordem Comissão Swap Lucro Saldo Comentário
2017.01.01 00:00:00 1
Saldo



0.00 0.00 3 000.00 3 000.00
2017.01.03 10:00:00 2 EURUSD sell in 0.30 1.04597 2 0.00 0.00 0.00 3 000.00
2017.01.03 11:34:38 5 EURUSD buy in/out 0.30 1.04097 4 0.00 0.00 40.00 3 040.00
2017.01.03 10:21:32 3 EURUSD buy out 0.11 1.04347 6 0.00 0.00 27.50 3 067.50
2017.01.03 10:33:40 4 EURUSD buy out 0.11 1.04247 7 0.00 0.00 38.50 3 106.00
2017.01.05 11:00:00 6 EURUSD sell in/out 0.30 1.05149 8 0.00 -0.61 231.44 3 336.83
2017.01.05 12:58:27 7 EURUSD buy in/out 0.11 1.04896 12 0.00 0.00 20.24 3 357.07
2017.01.05 16:00:00 8 EURUSD buy in 0.19 1.05307 13 0.00 0.00 0.00 3 357.07
2017.01.05 16:00:00 9 EURUSD buy in 0.30 1.05307 14 0.00 0.00 0.00 3 357.07
2017.01.05 17:29:15 12 EURUSD sell out 0.30 1.05807 16 0.00 0.00 157.11 3 514.18
2017.01.05 17:09:40 10 EURUSD sell out 0.11 1.05557 18 0.00 0.00 30.11 3 544.29
2017.01.05 17:28:47 11 EURUSD sell out 0.11 1.05660 19 0.00 0.00 41.44 3 585.73

0.00 -0.61 586.34 3 585.73

Aqui, nós encontramos um problema. O nível de stop final fechou em 0.30 lotes em vez de 0.08 lotes como observado nos dois testes anteriores.

Conforme discutido anteriormente, o stoploss e takeprofit padrão na MetaTrader 5 no modo hedge, é diferente dos dos dois anteriores. Assim, o EA converteria a o stop na ponta da corretora em um stop baseado em ordem pendente. No entanto, com esta configuração, o EA já possui dois níveis de stop baseados em ordens pendentes, e um deles é um stop principal. Como também discutido anteriormente, isso levaria a posições remanescentes. O nível de stop loss final ou principal sempre terá um volume igual ao volume inicial da operação principal. E uma vez que houve outros níveis de stop envolvidos, ele pode levar ao nível de stop principal para encerrar a operação principal por um volume maior que a posição remanescente.

Para corrigir isso, uma maneira é configurar o stop principal para ser virtual, ao invés de ser baseado na ponta da corretar ou em ordem pendente. Com esta nova configuração, o EA agora tem 2 stops que são virtuais e um stop que é baseado em ordens pendentes. O resultado de um teste usando esta nova configuração é exibido abaixo.














Ordens
Horário de abertura Ordem Símbolo Tipo Volume Preço S / L T / P Hora Estado Comentário
2017.01.03 10:00:00 2 EURUSD sell 0.30 / 0.30 1.04597

2017.01.03 10:00:00 filled
2017.01.03 10:00:00 3 EURUSD buy stop 0.11 / 0.00 1.04847

2017.01.03 10:21:32 canceled
2017.01.03 10:00:00 4 EURUSD buy limit 0.11 / 0.11 1.04347

2017.01.03 10:21:32 filled
2017.01.03 10:33:40 5 EURUSD buy 0.11 / 0.11 1.04247

2017.01.03 10:33:40 filled
2017.01.03 11:34:38 6 EURUSD buy 0.08 / 0.08 1.04097

2017.01.03 11:34:38 filled
2017.01.05 11:00:00 7 EURUSD sell 0.30 / 0.30 1.05149

2017.01.05 11:00:00 filled
2017.01.05 11:00:00 8 EURUSD buy stop 0.11 / 0.00 1.05399

2017.01.05 12:58:27 canceled
2017.01.05 11:00:00 9 EURUSD buy limit 0.11 / 0.11 1.04899

2017.01.05 12:58:27 filled
2017.01.05 16:00:00 10 EURUSD buy 0.19 / 0.19 1.05307

2017.01.05 16:00:00 filled
2017.01.05 16:00:00 11 EURUSD buy 0.30 / 0.30 1.05307

2017.01.05 16:00:00 filled
2017.01.05 16:00:00 12 EURUSD sell stop 0.11 / 0.00 1.05057

2017.01.05 17:09:40 canceled
2017.01.05 16:00:00 13 EURUSD sell limit 0.11 / 0.11 1.05557

2017.01.05 17:09:40 filled
2017.01.05 17:28:47 14 EURUSD sell 0.11 / 0.11 1.05660

2017.01.05 17:28:47 filled
2017.01.05 17:29:15 15 EURUSD sell 0.08 / 0.08 1.05807

2017.01.05 17:29:15 filled

Ofertas
Hora Oferta Símbolo Tipo Direção Volume Preço Ordem Comissão Swap Lucro Saldo Comentário
2017.01.01 00:00:00 1
Saldo



0.00 0.00 3 000.00 3 000.00
2017.01.03 10:00:00 2 EURUSD sell in 0.30 1.04597 2 0.00 0.00 0.00 3 000.00
2017.01.03 10:21:32 3 EURUSD buy out 0.11 1.04347 4 0.00 0.00 27.50 3 027.50
2017.01.03 10:33:40 4 EURUSD buy out 0.11 1.04247 5 0.00 0.00 38.50 3 066.00
2017.01.03 11:34:38 5 EURUSD buy out 0.08 1.04097 6 0.00 0.00 40.00 3 106.00
2017.01.05 11:00:00 6 EURUSD sell in 0.30 1.05149 7 0.00 0.00 0.00 3 106.00
2017.01.05 12:58:27 7 EURUSD buy out 0.11 1.04896 9 0.00 0.00 27.83 3 133.83
2017.01.05 16:00:00 8 EURUSD buy out 0.19 1.05307 10 0.00 0.00 -30.02 3 103.81
2017.01.05 16:00:00 9 EURUSD buy in 0.30 1.05307 11 0.00 0.00 0.00 3 103.81
2017.01.05 17:09:40 10 EURUSD sell out 0.11 1.05557 13 0.00 0.00 27.50 3 131.31
2017.01.05 17:28:47 11 EURUSD sell out 0.11 1.05660 14 0.00 0.00 38.83 3 170.14
2017.01.05 17:29:15 12 EURUSD sell out 0.08 1.05807 15 0.00 0.00 40.00 3 210.14

0.00 0.00 210.14 3 210.14

O volume total obtido pelos níveis de stop é agora igual ao volume inicial da operação principal.

Exemplo 3: Stops com Gerenciamento de Dinheiro

Em um artigo anterior (veja Expert Advisor Multiplataforma: Controle de Capital), discutiu-se que alguns métodos de controle de capital dependem de um determinado nível de stop (é possível utilizar o takeprofit, mas normalmente se usa o stoploss). Métodos de controle de capital, como o risco fixo fracionado, risco fixo e risco fixo por ponto/pip, muitas vezes exigem um nível de stoploss finito. Não definir esse nível sugere um risco muito grande ou mesmo infinito e, portanto, o volume calculado também seria grande. Para mostrar um expert advisor capaz de usar os objetos de classe mencionados neste artigo com controle de capital, nós modificaremos o primeiro exemplo para que as linhas de código comentadas anteriormente sejam incluídas na compilação.

Primeiro, nós removemos as tags do comentário nas linhas de código para os métodos de controle de capital, conforme mostrado no código abaixo, dentro da função OnInit:

int OnInit()
  {
//--- outro código
   order_manager=new COrderManager();
   money_manager= new CMoneys();
   CMoney *money_fixed=new CMoneyFixedLot(0.05);
   CMoney *money_ff=new CMoneyFixedFractional(5);
   CMoney *money_ratio=new CMoneyFixedRatio(0,0.1,1000);
   CMoney *money_riskperpoint=new CMoneyFixedRiskPerPoint(0.1);
   CMoney *money_risk=new CMoneyFixedRisk(100);

   money_manager.Add(money_fixed);
   money_manager.Add(money_ff);
   money_manager.Add(money_ratio);
   money_manager.Add(money_riskperpoint);
   money_manager.Add(money_risk);
   order_manager.AddMoneys(money_manager);
//--- outro código
  }

Então, no topo do código fonte, nós declaramos uma enumeração personalizada para que possamos criar um parâmetro externo que nos permita selecionar o método de controle de capital a ser usado, na ordem em que foram apresentados no código fonte:

enum ENUM_MM_TYPE
  {
   MM_FIXED=0,
   MM_FIXED_FRACTIONAL,
   MM_FIXED_RATIO,
   MM_FIXED_RISK_PER_POINT,
   MM_FIXED_RISK
  };

Em seguida, nós declaramos um novo parâmetro de entrada para esta enumeração:

input ENUM_MM_TYPE mm_type=MM_FIXED_FRACTIONAL;

Finalmente, nós devemos vincular esse parâmetro à seleção atual do método de controle de capital dentro da função OnTick:

void OnTick()
  {
//---   
   manage_trades();
   if(symbol_info.RefreshRates())
     {
      signals.Check();
      if(signals.CheckOpenLong())
        {
         close_last();
         if(time_filters.Evaluate(TimeCurrent()))
           {
            Print("Entering buy trade..");
            money_manager.Selected((int)mm_type); //use mm_type, cast to 'int' type
            order_manager.TradeOpen(Symbol(),ORDER_TYPE_BUY,symbol_info.Ask());
           }
        }
      else if(signals.CheckOpenShort())
        {
         close_last();
         if(time_filters.Evaluate(TimeCurrent()))
           {
            Print("Entering sell trade..");
            money_manager.Selected((int)mm_type); //use mm_type, cast to 'int' type
            order_manager.TradeOpen(Symbol(),ORDER_TYPE_SELL,symbol_info.Bid());
           }
        }
     }
  }

Uma vez que os métodos de controle de capital lidam apenas com o cálculo puro, não há nenhum problema em relação à compatibilidade entre a MQL4 e a MQL5. Os dois exemplos anteriores já mostraram como os níveis de stop funcionam nas duas plataformas. As tabelas a seguir mostram os resultados dos testes na MetaTrader 5 no modo hedge.

A tabela a seguir mostra o resultado do teste usando o controle de capital fracionado fixo. O programado é arriscar 5% da conta. Com um saldo inicial de $3000, nós esperamos que o valor seja de cerca de $150 se ele atingir o stoploss para a primeiro operação. Uma vez que o stoploss e o takeprofit têm o mesmo valor (500 pontos), nós esperamos que a operação seja lucrativa em $150 se atingir o takeprofit.














Ordens
Horário de abertura Ordem Símbolo Tipo Volume Preço S / L T / P Hora Estado Comentário
2017.01.03 10:00:00 2 EURUSD sell 0.30 / 0.30 1.04597 1.05097 1.04097 2017.01.03 10:00:00 filled
2017.01.03 11:34:38 3 EURUSD buy 0.30 / 0.30 1.04097

2017.01.03 11:34:38 filled tp 1.04097
2017.01.05 11:00:00 4 EURUSD sell 0.32 / 0.32 1.05149 1.05649 1.04649 2017.01.05 11:00:00 filled
2017.01.05 16:00:00 5 EURUSD buy 0.32 / 0.32 1.05307

2017.01.05 16:00:00 filled
2017.01.05 16:00:00 6 EURUSD buy 0.31 / 0.31 1.05307 1.04807 1.05807 2017.01.05 16:00:00 filled
2017.01.05 17:29:15 7 EURUSD sell 0.31 / 0.31 1.05807

2017.01.05 17:29:15 filled tp 1.05807

Ofertas
Hora Oferta Símbolo Tipo Direção Volume Preço Ordem Comissão Swap Lucro Saldo Comentário
2017.01.01 00:00:00 1
Saldo



0.00 0.00 3 000.00 3 000.00
2017.01.03 10:00:00 2 EURUSD sell in 0.30 1.04597 2 0.00 0.00 0.00 3 000.00
2017.01.03 11:34:38 3 EURUSD buy out 0.30 1.04097 3 0.00 0.00 150.00 3 150.00 tp 1.04097
2017.01.05 11:00:00 4 EURUSD sell in 0.32 1.05149 4 0.00 0.00 0.00 3 150.00
2017.01.05 16:00:00 5 EURUSD buy out 0.32 1.05307 5 0.00 0.00 -50.56 3 099.44
2017.01.05 16:00:00 6 EURUSD buy in 0.31 1.05307 6 0.00 0.00 0.00 3 099.44
2017.01.05 17:29:15 7 EURUSD sell out 0.31 1.05807 7 0.00 0.00 155.00 3 254.44 tp 1.05807

0.00 0.00 254.44 3 254.44

Note que o valor calculado do volume também dependeria da precisão do lote da corretora, determinado pelos parâmetros de lote mínimo e o passo mínimo do lote. Não podemos esperar que o expert advisor sempre faça os cálculos precisos. Com essas restrições, o expert advisor pode achar necessário arredondar o valor em algum momento. O mesmo é verdade para os outros métodos de controle de capital.

Para o controle de capital por risco fixo por ponto, a configuração programada é arriscar $0.1 por ponto de stoploss. Com a configuração de 500 pontos tanto para o stoploss quanto para o takeprofit, nós esperamos que o lucro/perda seja de $50 de qualquer forma.














Ordens
Horário de abertura Ordem Símbolo Tipo Volume Preço S / L T / P Hora Estado Comentário
2017.01.03 10:00:00 2 EURUSD sell 0.10 / 0.10 1.04597 1.05097 1.04097 2017.01.03 10:00:00 filled
2017.01.03 11:34:38 3 EURUSD buy 0.10 / 0.10 1.04097

2017.01.03 11:34:38 filled tp 1.04097
2017.01.05 11:00:00 4 EURUSD sell 0.10 / 0.10 1.05149 1.05649 1.04649 2017.01.05 11:00:00 filled
2017.01.05 16:00:00 5 EURUSD buy 0.10 / 0.10 1.05307

2017.01.05 16:00:00 filled
2017.01.05 16:00:00 6 EURUSD buy 0.10 / 0.10 1.05307 1.04807 1.05807 2017.01.05 16:00:00 filled
2017.01.05 17:29:15 7 EURUSD sell 0.10 / 0.10 1.05807

2017.01.05 17:29:15 filled tp 1.05807

Ofertas
Hora Oferta Símbolo Tipo Direção Volume Preço Ordem Comissão Swap Lucro Saldo Comentário
2017.01.01 00:00:00 1
Saldo



0.00 0.00 3 000.00 3 000.00
2017.01.03 10:00:00 2 EURUSD sell in 0.10 1.04597 2 0.00 0.00 0.00 3 000.00
2017.01.03 11:34:38 3 EURUSD buy out 0.10 1.04097 3 0.00 0.00 50.00 3 050.00 tp 1.04097
2017.01.05 11:00:00 4 EURUSD sell in 0.10 1.05149 4 0.00 0.00 0.00 3 050.00
2017.01.05 16:00:00 5 EURUSD buy out 0.10 1.05307 5 0.00 0.00 -15.80 3 034.20
2017.01.05 16:00:00 6 EURUSD buy in 0.10 1.05307 6 0.00 0.00 0.00 3 034.20
2017.01.05 17:29:15 7 EURUSD sell out 0.10 1.05807 7 0.00 0.00 50.00 3 084.20 tp 1.05807

0.00 0.00 84.20 3 084.20

Para o controle de capital de risco fixo, a configuração programada é arriscar $100. O EA, por sua vez, teria que calcular um volume que corresponderia a esse risco estabelecido. O resultado é exibido abaixo.














Ordens
Horário de abertura Ordem Símbolo Tipo Volume Preço S / L T / P Hora Estado Comentário
2017.01.03 10:00:00 2 EURUSD sell 0.20 / 0.20 1.04597 1.05097 1.04097 2017.01.03 10:00:00 filled
2017.01.03 11:34:38 3 EURUSD buy 0.20 / 0.20 1.04097

2017.01.03 11:34:38 filled tp 1.04097
2017.01.05 11:00:00 4 EURUSD sell 0.20 / 0.20 1.05149 1.05649 1.04649 2017.01.05 11:00:00 filled
2017.01.05 16:00:00 5 EURUSD buy 0.20 / 0.20 1.05307

2017.01.05 16:00:00 filled
2017.01.05 16:00:00 6 EURUSD buy 0.20 / 0.20 1.05307 1.04807 1.05807 2017.01.05 16:00:00 filled
2017.01.05 17:29:15 7 EURUSD sell 0.20 / 0.20 1.05807

2017.01.05 17:29:15 filled tp 1.05807

Ofertas
Hora Oferta Símbolo Tipo Direção Volume Preço Ordem Comissão Swap Lucro Saldo Comentário
2017.01.01 00:00:00 1
Saldo



0.00 0.00 3 000.00 3 000.00
2017.01.03 10:00:00 2 EURUSD sell in 0.20 1.04597 2 0.00 0.00 0.00 3 000.00
2017.01.03 11:34:38 3 EURUSD buy out 0.20 1.04097 3 0.00 0.00 100.00 3 100.00 tp 1.04097
2017.01.05 11:00:00 4 EURUSD sell in 0.20 1.05149 4 0.00 0.00 0.00 3 100.00
2017.01.05 16:00:00 5 EURUSD buy out 0.20 1.05307 5 0.00 0.00 -31.60 3 068.40
2017.01.05 16:00:00 6 EURUSD buy in 0.20 1.05307 6 0.00 0.00 0.00 3 068.40
2017.01.05 17:29:15 7 EURUSD sell out 0.20 1.05807 7 0.00 0.00 100.00 3 168.40 tp 1.05807

0.00 0.00 168.40 3 168.40

Lembre-se sempre que o gerenciamento de ordens sempre considerará o stop principal para ser usado para controle de capital. Se nenhum stop principal foi declarado, os métodos de controle de capital baseados no stoploss não podem ser usados, mesmo que haja outros stops presentes.

Conclusão

Neste artigo, nós discutimos a adição dos níveis de stop em um expert advisor em multiplataforma. As duas plataformas de negociação, apesar de ter muitos recursos paralelos, variam significativamente na forma como os níveis de stop são implementados. Este artigo forneceu um método onde essas diferenças podem ser reconciliadas para que um expert advisor seja compatível com ambas as plataformas.

Programas Usados ​​no Artigo

#
Nome
Tipo
Descrição
1.
stops_ha_ma1.mqh
Arquivo de Cabeçalho
Arquivo de cabeçalho principal usado para o expert advisor no primeiro exemplo
2.
stops_ha_ma1.mq4 Expert Advisor
Arquivo fonte principal usado para o expert advisor em MQL4 no primeiro exemplo
3.
stops_ha_ma1.mq5 Expert Advisor Arquivo fonte principal usado para o expert advisor em MQL5 no primeiro exemplo
4.  stops_ha_ma2.mqh Arquivo de Cabeçalho Arquivo de cabeçalho principal usado para o expert advisor no segundo exemplo
5.  stops_ha_ma2.mq4 Expert Advisor
Arquivo fonte principal usado para o expert advisor em MQL4 no segundo exemplo
6.  stops_ha_ma2.mq5 Expert Advisor
Arquivo fonte principal usado para o expert advisor em MQL5 no segundo exemplo
7.  stops_ha_ma3.mqh Arquivo de Cabeçalho Arquivo de cabeçalho principal usado para o expert advisor no terceiro exemplo
8.  stops_ha_ma3.mq4 Expert Advisor
Arquivo fonte principal usado para o expert advisor em MQL4 no terceiro exemplo
9.  stops_ha_ma3.mq5 Expert Advisor
Arquivo fonte principal usado para o expert advisor em MQL5 no terceiro exemplo

Arquivos de Classe Apresentados no Artigo

#
Nome
Tipo
Descrição
1.
MQLx\Base\Stop\StopBase.mqh
Arquivo de Cabeçalho
CStop (classe base)
2.
MQLx\MQL4\Stop\Stop.mqh Arquivo de Cabeçalho CStop (versão MQL4)
3.
MQLx\MQL5\Stop\Stop.mqh Arquivo de Cabeçalho CStop (versão MQL5)
4. MQLx\Base\Stop\StopsBase.mqh Arquivo de Cabeçalho CStops (container CStop, classe base)
5. MQLx\MQL4\Stop\Stops.mqh Arquivo de Cabeçalho CStops (versão MQL4)
6. MQLx\MQL5\Stop\Stops.mqh Arquivo de Cabeçalho CStops (versão MQL5)
7. MQLx\Base\Stop\StopLineBase.mqh Arquivo de Cabeçalho CStopLine (representação gráfica, classe base)
8. MQLx\MQL4\Stop\StopLine.mqh Arquivo de Cabeçalho CStopLine (versão MQL4)
9. MQLx\MQL5\Stop\StopLine.mqh Arquivo de Cabeçalho CStopLine (versão MQL5)
10.  MQLx\Base\Order\OrderStopBase.mqh Arquivo de Cabeçalho COrderStop (classe base)
11.  MQLx\MQL4\Order\OrderStop.mqh Arquivo de Cabeçalho COrderStop (versão MQL4)
12.  MQLx\MQL5\Order\OrderStop.mqh Arquivo de Cabeçalho COrderStop (versão MQL5)
13.
 MQLx\Base\Order\OrderStopVirtualBase.mqh Arquivo de Cabeçalho
COrderStopVirtual (nível de stop virtual, classe base)
14.  MQLx\Base\Order\OrderStopVirtual.mqh Arquivo de Cabeçalho
COrderStopVirtual (versão MQL4)
15.
 MQLx\Base\Order\OrderStopVirtual.mqh Arquivo de Cabeçalho
COrderStopVirtual (versão MQL5)
16.  MQLx\Base\Order\OrderStopPendingBase.mqh Arquivo de Cabeçalho
COrderStopPending (nível da ordem stop pendente, classe base)
17.  MQLx\Base\Order\OrderStopPending.mqh Arquivo de Cabeçalho
COrderStopPending (versão MQL4)
18.
 MQLx\Base\Order\OrderStopPending.mqh Arquivo de Cabeçalho
COrderStopPending (versão MQL5)
19.
 MQLx\Base\Order\OrderStopBroker.mqh Arquivo de Cabeçalho
COrderStopBroker (nível da ordem stop na ponta da corretora, classe base)
20.  MQLx\Base\Order\OrderStopBroker.mqh Arquivo de Cabeçalho
COrderStopBroker (versão MQL4)
21.  MQLx\Base\Order\OrderStopBroker.mqh Arquivo de Cabeçalho
COrderStopBroker (versão MQL5)
22.  MQLx\Base\Order\OrderStopsBase.mqh Arquivo de Cabeçalho
COrderStops (container COrderStop, classe base)
23.  MQLx\Base\Order\OrderStops.mqh Arquivo de Cabeçalho
COrderStops (versão MQL4)
24.  MQLx\Base\Order\OrderStops.mqh Arquivo de Cabeçalho
COrderStops (versão MQL5)

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

Arquivos anexados |
tester.zip (1445.59 KB)
MQL5.zip (708.29 KB)
Expert Advisor Multiplataforma: Stops personalizados, Breakeven e Stop Móveis Expert Advisor Multiplataforma: Stops personalizados, Breakeven e Stop Móveis
Este artigo discute como os níveis de stop personalizados podem ser configurados em um expert advisor multiplataforma. Ele também discute um método fortemente relacionado ao assunto na qual envolve a possibilidade de definir a evolução do nível de stop ao longo do tempo.
Busca automática de divergências e convergência Busca automática de divergências e convergência
O artigo examina todos os tipos de divergência: oculta, estendida, tripla, convergência, de classes A, B e C, etc. É criado um indicador universal para elas serem buscadas e exibidas num gráfico.
Otimizando uma estratégia usando o gráfico do saldo e comparando os resultados com o critério "Balance + max Sharpe Ratio" Otimizando uma estratégia usando o gráfico do saldo e comparando os resultados com o critério "Balance + max Sharpe Ratio"
Neste artigo, nós ainda consideramos um outro critério personalizado de otimização de uma estratégia de negociação com base na análise do gráfico de saldo. A regressão linear é calculada usando a função da biblioteca ALGLIB.
Avaliação de risco numa sequência de operações com um ativo Avaliação de risco numa sequência de operações com um ativo
Este artigo descreve como usar os métodos da teoria da probabilidade e estatística matemática na análise de sistemas de negociação.