English Русский 中文 Deutsch 日本語 Português
Asesor Experto multiplataforma: Niveles stop

Asesor Experto multiplataforma: Niveles stop

MetaTrader 5Ejemplos | 18 octubre 2017, 10:28
2 387 0
Enrico Lambino
Enrico Lambino

Índice

  1. Introducción
  2. COrder
  3. CStop
  4. CStops
  5. COrderStop
  6. COrderStops
  7. Representación de los niveles stop en el gráfico
  8. Comprobación de las órdenes en el nivel stop
  9. Ejemplos
  10. Conclusión
  11. Programas utilizados en el artículo
  12. Archivos de las clases creadas en el artículo


Introducción

En el artículo anterior creamos para el experto comercial multiplataforma un gestor de órdenes (COrderManager), que suaviza la mayoría de las diferencias entre MQL4 y MQL5 en cuanto a la apertura y al cierre de las operaciones. En ambas versiones el asesor guarda en la memoria la información sobre las transacciones mediante la creación de ejemplares COrder. Los contenedores con punteros dinámicos a los ejemplares de este objeto de clase también están disponibles como miembros de la clase COrderManager (tanto para las transacciones actuales, como para las que ya se encuentran en la historia).

Podemos hacerlo de tal forma que el gestor de órdenes procese directamente los niveles stop para cada transacción. Sin embargo, para ello existen determinadas limitaciones:

  • COrderManager debe ser ampliado para procesar los niveles stop para cada transacción.
  • Los métodos existentes de COrderManager solo procesan la entrada de las operaciones principales.

Podemos ampliar COrderManager de tal forma que procese los niveles stop para cada transacción de forma por sí mismo. Sin embargo, esto no solo se limita a la colocación de los niveles actuales. También debe ejecutar otras tareas relacionadas con la vigilancia y el cambio de los stops, y también comprobar si el mercado ya ha alcanzado un cierto nivel. Estas funciones hacen COrderManager mucho más complejo de lo que actualmente es, sin mencionar su implementación aparte.

El gestor de órdenes solo se ocupa de la entrada de las operaciones principales, mientras que algunos niveles stop necesitarán que el asesor realice otras operaciones comerciales, tales como la colocación de órdenes pendientes y el cierre de las posiciones actuales. Si bien es posible que el gestor sea capaz de procesar todo ello por sí mismo, sería mejor poder dedicarlo a la entrada de las operaciones principales, y dejar que otro objeto de la clase manejara los niveles stop.

En este artículo, vamos a analizar una implementación en la que COrderManager manejará exclusivamente las entradas y salidas de las operaciones principales (como hace actualmente), y luego implementaremos separadamente el procesamiento de los niveles stop por parte de otro objeto de la clase (cstop).

COrder

Como hemos visto en uno de los artículos anteriores, el ejemplar de COrders se crea después de una operación comercial exitosa (apertura de una transacción). Por ello, tanto para MetaTrader 4 como para MetaTrader 5, la información relativa a los stop-loss y take-profit puede estar guardada en el extremo del bróker. Sin embargo, en el caso de que los stops estén ocultos del bróker o solo estén involucrados varios niveles stop, la información con respecto a la mayoría de estos se guardará localmente. Así, en el último caso, después de una entrada exitosa de una posición, el ejemplar COrders debe crearse primero, seguido de los ejemplares de los objetos que representan sus niveles stop-loss y Take-Profit. En uno de los artículos anteriores, mostramos cómo se añaden los ejemplares Corder al gestor de órdenes durante la creación. Esto se muestra también en la figura siguiente:


TradeOpen

Los niveles stop se añaden de la misma manera. Para ello, solo hay que insertar el método después de crear el nuevo ejemplar COrders, y antes de añadirlo a la lista de las transacciones actuales (COrders). Por lo tanto, la ilustración anterior cambia ligeramente:


TradeOpen con órdenes stop

El proceso general de creación de los niveles stop se muestra en la siguiente figura:

Aspecto general de la creación de niveles stop

Como se muestra en los dos diagramas de flujo anteriores, tan pronto como la transacción se ha abierto con éxito, se crea un nuevo ejemplar de COrders. Después de ello, se crearán ejemplares de COrderStop para cada uno de los niveles de stop-loss y Take-Profit definidos. Si no hubiera ningún ejemplar declarado de cstop en la inicialización del asesor experto, este proceso en particular puede ser omitido. Por otro lado, si los ejemplares de COrderStop han sido creados, los punteros a estos ejemplares se almacenarán el ejemplar COrders anteriormente creado. Estas operaciones se encuentran en el método Init de la clase 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 crear los niveles stop para el ejemplar COrder, podemos ver cómo se llama el método de esta clase CreateStops:

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);
        }
     }
  }

El método itera sobre todos los ejemplares disponibles de cstop que representan cada par de niveles stop-loss y take-Profit. Cada uno de estos ejemplares de CStop es transmitido a un ejemplar de COrderStops, que es simplemente un contenedor para todos los niveles stop de una orden dada. De esta forma, podemos construir la jerarquía de los objetos de la clase de la siguiente manera:


Jerarquía de los objetos stop

Para cada ejemplar de COrder se dispone de un miembro del tipo COrderStops. Este ejemplar de COrderStops es un contenedor (extensión CArrayObj), que contiene los punteros a los ejemplares de COrderStop. Cada ejemplar de COrderStop representa un nivel stop (cstop) solo para esta transacción en particular (ejemplar COrders).

CStop

Como se señaló anteriormente, nos gustaría tener la posibilidad de personalizar la forma en que se gestiona el nivel stop de cada transacción, sin tener que modificar el código fuente del gestor de órdenes. Esto se logra en gran medida con la ayuda de la clase cstop. Entre las posibilidades de esta clase figuran las siguientes:

  1. definir los niveles de stop-loss y take-profit;
  2. calcular los niveles stop;
  3. implementar los niveles de stop-loss y take-profit para la transacción principal;
  4. comprobar si se ha alcanzado el nivel stop;
  5. suavizar las diferencias entre la implementación del stop-loss y el take-profit en los lenguajes MQL4 y MQL5;
  6. definir las acciones al alcanzar los stops (por ejemplo, ausencia de pérdidas, trailing-stop, etc.)

Discutiremos los puntos 1-5 más abajo, el punto 6 tendrá su propio artículo.

Tipos

Vamos a hablar de +çtres tipos de paradas:

  1. El stop que se activa en el lado del bróker será el nivel stop que se manda al bróker junto con la orden comercial.
  2. Stop colocado según una orden pendiente. Se activa o bien como cobertura total/parcial en la dirección opuesta a la dirección principal (MetaTrader 4 o modo cobertura en MetaTrader 5), o bien como la resta de la posición principal (modo compensación MetaTrader 5).
  3. El stop virtual permanece oculto para el bróker y se procesa de forma local, dentro del asesor.

En MetaTrader 4, al primer grupo de stops pertenecen los stop-loss y take-profit más extendidos. Los precios con los que deberán activarse se envían al bróker junto con la orden comercial sobre la transacción principal. La versión de MetaTrader 5 para el modo de cobertura utiliza el mismo mecanismo que la versión de MetaTrader 4. En el modo de compensación, para este tipo de CStop se usarán stops según las órdenes pendientes, puesto que los stop-loss y take-profit aquí se distinguen (se aplican a la posición completa de un símbolo).

Los stops según las órdenes pendientes en cierta medida imitan los stops en el lado del bróker. Tan pronto como una orden pendiente es ejecutada, el asesor realizará una operación comercial (OrderCloseBy), para cerrar la posición principal con el volumen de la orden pendiente que se acaba de activar. Esto es cierto tanto para MetaTrader 4, como para el modo de cobertura de MetaTrader 5. Para MetaTrader 5 en su modo de compensación, la salida de una parte o de todo el volumen de la posición principal se realiza automáticamente, ya que en este modo, para un símbolo, solo puede haber abierta al mismo tiempo una posición.

Stop principal

El stop principal es el nivel de parada que da lugar al cierre completo de una posición. Normalmente, se trata del stop en el lado del bróker. Cuando se activa un stop-loss o un take-profit enviado al bróker, toda la posición se cierra en el mercado, independientemente de si el asesor tiene la intención de continuar trabajando o no. Sin embargo, si hay varios niveles stop y estos no han sido enviados al bróker, no será buena idea dejar al propio asesor decidir cuál de ellos es el principal. En este caso, el programador deberá designar por sí mismo el ejemplar de CStop para esta transacción. Esto puede ser útil especialmente para algunas funciones y características que dependen del stop principal de la posición, tales como la gestión de dinero. Puesto que el stop-loss en el nivel stop principal conlleva el cierre total de la posición, este supondrá precisamente el riesgo máximo para la entrada en esta transacción. Y, disponiendo ya del ejemplar del nivel stop principal, el asesor es capaz de calcular de acuerdo con este el tamaño del lote.

Vale la pena señalar que cuando un stop se designa como principal, su volumen será siempre análogo al volumen inicial de la transacción principal. Esto funciona bien con los stops del brokér y los virtuales, pero no con los stops basados en las órdenes pendientes. Hay dos problemas relacionados con ello.

La primera razón es que en MetaTrader 4, el precio de entrada de una orden pendiente puede ser modificado mientras la orden pendiente aún no se haya activado. En MetaTrader 5 esto no es posible, puesto que aquí debe guardarse una historia de las operaciones comerciales completa e inalterada. Por eso hay que colocar una nueva orden pendiente. La antigua se elimina, y a partir de entonces, el asesor deberá utilizar como nuevo nivel stop la orden pendiente recién colocada.

El segundo problema deriva de la posible activación de antiguas órdenes pendientes mientras la nueva se envía al bróker. Dado que el asesor no tiene control sobre la activación de las órdenes pendientes que han sido enviadas al bróker junto con la orden comercial, esto puede causar problemas tales como: transacciones huérfanas o el cierre de la transacción principal con un volumen mayor del que se suponía.

Con el fin de evitar estos problemas, el enfoque más sencillo sería asignar el volumen de las órdenes pendientes directamente al abrir la posición, en lugar de ajustarlo de forma dinámica a lo largo de la vida de la transacción. Sin embargo, para ello será necesario que, aparte de la orden pendiente designada con el stop principal, no existan otras órdenes pendientes.

Volumen

Para el nivel stop principal no hay necesidad de designar el tamaño del lote a restar de la posición principal, porque al activarse se cierra toda la posición. Sin embargo, para los otros tipos de niveles stop hay que tener en cuenta el volumen, ya que es por lo general designado para el cierre parcial de la posición principal. La distribución en este caso se divide en cuatro tipos diferentes:

  1. Fijo — designa un volumen fijo del lote
  2. Tanto por ciento del resto - porcentaje del volumen de lote restante de la posición principal
  3. Porcentaje Total - porcentaje del lote inicial total de la transacción principal
  4. Restante - el volumen restante de la operación principal.

Designar un volumen fijo de lote es la forma más sencilla de distribuir el volumen. Sin embargo, esto no funcionaría de forma óptima si el asesor está utilizando algún tipo de cálculo dinámico del tamaño del lote para cada posición (por ejemplo, la gestión de dinero). Este método solo es ideal cuando el tamaño del lote no se modifica durante todo el funcionamiento del asesor experto.

Será mejor no usar el tanto por ciento restante y el resto, si el stop principal es virtual (oculto). El resto prevendrá al asesor contra las transacciones "huérfanas" a partir del volumen no cerrado o contra el cierre con un volumen que supere el resto según la transacción principal. El tanto por ciento del resto se utiliza cuando el asesor debe cerrar una operación basada no en el volumen inicial, sino en el que queda actualmente en la transacción principal.

El porcentaje total puede ser utilizado con los stops del bróker, con los virtuales y con los stops según órdenes pendientes. Los cálculos que utilizan este método se basan en el volumen inicial de la transacción principal.

Una-Cancela-la-Otra (OCO)

CStop siempre está representado por un par de valores, que representan los stop-loss o los take-profit. Sin embargo, es posible establecer solo un stop (take-profit sin stop-loss, o viceversa) asignando un cero al nivel ausente. Por defecto, al activarse un nivel stop, se cierran los demás. Solo hay una excepción a esta norma: cuando el ejemplar de CStop es el nivel stop principal.

Clase básica

La clase básica para CStop (CStopBase) se muestra en el siguiente fragmento de código:

class CStopBase : public CObject
  {
protected:
   //--- parámetros de la orden 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 comerciales de la orden stop
   ENUM_VOLUME_TYPE  m_volume_type;
   double            m_volume;
   int               m_magic;
   int               m_deviation;
   string            m_comment;
   //--- parámetros del objeto de la orden 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;}
   //--- inicialización
   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;
   //--- métodos de obtención y colocación
   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;
   //--- comprobación
   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);
   //--- создание объекта стоп-ордера
   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 del precio de la orden 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);
   //--- trailing
   virtual bool      Add(CTrails*);
   virtual double    CheckTrailing(const string,const ENUM_ORDER_TYPE,const double,const double,const ENUM_TRAIL_TARGET);
protected:
   //--- creación del objeto
   virtual CStopLine *CreateObject(const long,const string,const int,const double);
   //--- cálculo del precio de la orden stop
   virtual double    LotSizeCalculate(COrder*,COrderStop*);
   //--- entrada en la orden stop   
   virtual bool      GetClosePrice(const string,const ENUM_ORDER_TYPE,double&);
   //--- salida de la orden stop
   virtual bool      CloseStop(COrder*,COrderStop*,const double)=0;
   //--- deinitialization
   virtual void      Deinit(void);
   virtual void      DeinitSymbol(void);
   virtual void      DeinitTrade(void);
   virtual void      DeinitTrails(void);
  };

Para los niveles de stop-loss y take-profit basados ​​en el número de pips o puntos, se deberán guardar por lo menos cuatro métodos de clase:

  1. El tipo de nivel stop (de bróker, basado en una orden pendiente, o virtual), método StopType
  2. El tipo utilizado para el cálculo del volumen, método VolumeType
  3. El nivel stop-loss en puntos (siempre que sea necesario), método StopLoss
  4. El nivel takeprofit en puntos (siempre que sea necesario), método TakeProfit

Todos ellos son simplemente métodos de instalación de los miembros de la clase, por lo que no hay necesidad de dar más detalles sobre estos métodos. La mayor parte del resto de los métodos son necesarios para la clase solamente en sus cálculos internos. Entre los más importantes de estos métodos protegidos se encuentran los métodos StopLossCalculate y TakeProfitCalculate. Su código se muestra a continuación:

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 métodos tienen tres argumentos, todos los cuales están relacionados con el comercio principal. Los métodos empiezan por la actualización del símbolo a través del método Refresh, que sencillamente actualiza el gestor de símbolos y no el símbolo que queremos utilizar. Una vez que el símbolo se ha actualizado, retorna el valor de stop-loss o take-profit basado en el valor suministrado por el ejemplar de clase durante la inicialización.

CStops

La clase CStops es un contenedor para los ejemplares CStop. El ejemplar de esta clase deberá añadirse de forma dinámica al gestor de órdenes como uno de sus miembros. El siguiente código muestra CStopsBase, que es la clase básica para 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;}
   //--- inicialización
   virtual bool      Init(CSymbolManager*,CAccountInfo*,CEventAggregator*);
   virtual CObject  *GetContainer(void);
   virtual void      SetContainer(CObject*);
   virtual bool      Validate(void) const;
   //--- métodos de colocación y obtención
   virtual bool      Active(void) const;
   virtual void      Active(const bool);
   virtual CStop    *Main(void);
   //--- recovery
   virtual bool      CreateElement(const int);
  };

Esta clase es muy similar a los otros recipientes descritos hasta ahora en esta serie.

COrderStop

COrderStop representa la implementación de CStop para una operación en particular. Para una posición dada, CStop puede crear un máximo de un ejemplar de COrderStop. Sin embargo, un número arbitrario de ejemplares de COrderStop puede compartir un mismo ejemplar de CStop. Por lo tanto, si un asesor experto tiene 3 ejemplares diferentes de CStop, normalmente esperamos que cada ejemplar de COrders tenga el mismo número de ejemplares de COrderStop. Si el asesor de expertos ha realizado 1.000 transacciones, el número de ejemplares de COrderStop creados será 1000 * 3 = 3000, mientras que el número de ejemplares de CStop creados todavía sería 3.

La definición de COrderStopBase, que constituye la base de COrderStop, se muestra en el siguiente código:

class COrderStopBase : public CObject
  {
protected:
   bool              m_active;
   //--- parámetros del 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 de la orden principal
   COrder           *m_order;
   //--- objetos 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;}
   //--- inicialización
   virtual void      Init(COrder*,CStop*,COrderStops*);
   virtual COrderStops *GetContainer(void);
   virtual void      SetContainer(COrderStops*);
   virtual void      Show(bool);
   //--- métodos de obtención y colocación  
   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;
   //--- comprobación   
   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) {}
   //--- deinitialization 
   virtual void      Deinit(void);
   //--- recovery
   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 se guarda en COrderStops (lo veremos más abajo), que, a su vez, se contiene en COrder. En la implementación actual del asesor ya no hay necesidad de declarar un ejemplar de COrderStop. Este es creado automáticamente por COrders, usando como base un ejemplar aparte de 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;
   //--- inicialización
   virtual CObject *GetContainer(void);
   virtual void      SetContainer(COrder*);
   virtual bool      NewOrderStop(COrder*,CStop*)=0;
   //--- comprobación
   virtual void      Check(double &volume);
   virtual bool      CheckNewTicket(COrderStop*);
   virtual bool      Close(void);
   virtual void      UpdateVolume(const double) {}
   //--- ocultar y mostrar las líneas de los niveles
   virtual void      Show(const bool);
   //--- recovery
   virtual bool      CreateElement(const int);
   virtual bool      Save(const int);
   virtual bool      Load(const int);
  };


Al igual que CStop, tiene la apariencia de un simple contenedor de clase típico. Sin embargo, dentro contiene algunos métodos que reflejan los métodos de los objetos cuyos punteros están designados para el guardado (COrderStop).

Representación de los niveles stop en el gráfico

CStopLine es un miembro de la clase de CStop, designado para la representación gráfica de los niveles stop. Ejecuta en el asesor tres funciones básicas:

  1. Muestra los niveles stop al inicializar el ejemplar de COrders
  2. Actualiza los niveles stop, si uno de ellos o ambos han sido modificados
  3. Elimina las líneas de los niveles stop en cuanto la transacción principal se cierra

Todas estas funciones se implementan a través de la clase CStop.

La definición de CStopLineBase en la que se basa CStopLine, se muestra a continuación:

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);
  };

En las versiones anteriores de MetaTrader 4, los niveles stop-loss y take-profit no se pueden desplazar mediante el arrastre. Solo se los puede modificar en la ventana de la orden comercial o usando scripts o expertos especiales. Sin embargo, la representación gráfica de estos niveles todavía puede ser útil, especialmente en el caso de los stops ocultos (virtuales).

Comprobación de las órdenes en el nivel stop

Después de que los niveles stop se hayan creado con éxito para una posición dada, el siguiente paso será comprobar si el mercado ha llegado a un nivel stop determinado. Para los stops del bróker el proceso no es obligatorio, ya que la operación de cierre se realiza en el lado del servidor. Sin embargo, en el caso de los stops virtuales y los stops basados en las órdenes pendientes, el propio asesor llevará a cabo la operación de cierre.

Para los stops ocultos (virtuales), el asesor es el único responsable de vigilar el movimiento del mercado y comprobar si se ha atravesado un nivel stop determinado. La siguiente figura muestra el esquema general de la operación. Tan pronto como el mercado alcanza un nivel stop, el asesor lleva a cabo la operación de cierre correspondiente.

OrderStop Checking (virtual)

Para los stops basados en órdenes pendientes, el proceso es ligeramente más complejo. La activación de un nivel stop provocará la activación de una orden pendiente, es decir, la aparición de la posición correspondiente. Esto se realiza de forma automática en el lado del bróker. Por lo tanto, el asesor asume la responsabilidad de detectar si una orden pendiente dada aún está pendiente o ya ha entrado en el mercado. Si la orden pendiente ya ha sido activada, el asesor será el encargado de cerrar la posición principal con el volumen correspondiente a esta orden: en esto consistirá la operación de cierre de la transacción con una opuesta.

COrderStop checking (pending order stop)

En todos los casos, el nivel stop se marcará como cerrado en cuanto se active la orden sobre él. Esto se ha hecho así para proteger el nivel stop contra la activación múltiple.

Ejemplos

Ejemplo №1: asesor que usa Heiken Ashi y Moving Average, con un nivel stop (stop principal)

Para la mayoría de asesores, basta con un stop-loss y un take-profit. Ahora vamos a completar el ejemplo del artíclo anterior, añadiendo al código fuente original un stop-loss y un take-profit. Para ello, en primer lugar, crearemos un nuevo ejemplar del contenedor (CStops). A continuación, crearemos un ejemplar de CStop, y luego añadiremos el puntero a su contenedor. El puntero al contenedor será añadido luego al gestor de órdenes. El código se muestra a continuación:

int OnInit()
  {
//--- other code

   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));     
//--- other code
  }

La simulación del stop del bróker en MetaTrader 4 muestra los resultados mostrados más abajo.

# Hora Tipo Orden Volumen Precio S / L T / P Beneficio Balance
1 2017.01.03 10:00 venta 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 venta 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 los stops pendientes, los niveles se colocan como los stop-loss/take-profit estándares, pero en forma de órdenes pendientes. El asesor ejecuta la operación de cierre con una transacción opuesta partiendo de la transacción principal con el volumen indicado en la orden activada. Sin embargo, a diferencia del stop-loss/take-profit estándar, el asesor realiza esto en el lado del cliente. Es decir, la operación no se podrá ejecutar si la plataforma de comercial está cerrada: el asesor debe estar iniciado en el gráfico de trabajo.

# Hora Tipo Orden Volumen Precio S / L T / P Beneficio Balance
1 2017.01.03 10:00 venta 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 Compra 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 venta 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 Compra 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


Los stops virtuales (ocultos) no envían ninguna información a la transacción principal. El bróker solamente es informado cuando el asesor ejecuta la orden de cierre. El siguiente recuadro muestra el comportamiento del asesor al usar stops virtuales. En este caso, tan pronto como se alcanza el nivel objetivo del precio para el nivel stop, el asesor envía una solicitud comercial al servidor para cerrar la transacción principal.

# Hora Tipo Orden Volumen Precio S / L T / P Beneficio Balance
1 2017.01.03 10:00 venta 1 0.30 1.04597 0.00000 0.00000
2 2017.01.03 11:34 Cierre 1 0.30 1.04097 0.00000 0.00000 150.00 3150.00
3 2017.01.05 11:00 venta 2 0.30 1.05149 0.00000 0.00000
4 2017.01.05 17:28 Cierre 2 0.30 1.05649 0.00000 0.00000 -150.00 3000.00


Ahora, vamos a analizar MetaTrader 5. El modo de cobertura en MetaTrader 5 se encuentra mucho más cerca de MetaTrader 4 en términos de resultados finales. El recuadro siguiente muestra los resultados de la simulación para los stops de los brókeres. Aquí, podemos ver detalladamente los niveles de stop-loss y take-profit de la operación principal en sus correspondientes columnas.













Órdenes
Hora de apertura Orden Símbolo Tipo Volumen Precio S / L T / P Hora Estado Comentarios
2017.01.03 10:00:00 2 EURUSD venta 0.30 / 0.30 1.04597 1.05097 1.04097 2017.01.03 10:00:00 ejecutada
2017.01.03 11:34:38 3 EURUSD Compra 0.30 / 0.30 1.04097

2017.01.03 11:34:38 ejecutada tp 1.04097
2017.01.05 11:00:00 4 EURUSD venta 0.30 / 0.30 1.05149 1.05649 1.04649 2017.01.05 11:00:00 ejecutada
2017.01.05 17:28:37 5 EURUSD Compra 0.30 / 0.30 1.05649

2017.01.05 17:28:37 ejecutada sl 1.05649

Transacciones
Hora Transacción Símbolo Tipo Dirección Volumen Precio Orden Comisión Swap Beneficio Balance Comentarios
2017.01.01 00:00:00 1
balance



0.00 0.00 3 000.00 3 000.00
2017.01.03 10:00:00 2 EURUSD venta in 0.30 1.04597 2 0.00 0.00 0.00 3 000.00
2017.01.03 11:34:38 3 EURUSD Compra 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 venta in 0.30 1.05149 4 0.00 0.00 0.00 3 150.00
2017.01.05 17:28:37 5 EURUSD Compra 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

En el modo de cobertura, las órdenes pendientes funcionan básicamente de la misma manera que en MetaTrader 4: el asesor también ejecuta la operación de cierre con la opuesta cuando se activa una orden pendiente.














Órdenes
Hora de apertura Orden Símbolo Tipo Volumen Precio S / L T / P Hora Estado Comentarios
2017.01.03 10:00:00 2 EURUSD venta 0.30 / 0.30 1.04597

2017.01.03 10:00:00 ejecutada
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 ejecutada
2017.01.03 11:34:38 5 EURUSD close by 0.30 / 0.30 1.04097

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

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

2017.01.05 17:28:37 ejecutada
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 ejecutada close #6 by #7

Transacciones
Hora Transacción Símbolo Tipo Dirección Volumen Precio Orden Comisión Swap Beneficio Balance Comentarios
2017.01.01 00:00:00 1
balance



0.00 0.00 3 000.00 3 000.00
2017.01.03 10:00:00 2 EURUSD venta in 0.30 1.04597 2 0.00 0.00 0.00 3 000.00
2017.01.03 11:34:38 3 EURUSD Compra in 0.30 1.04097 4 0.00 0.00 0.00 3 000.00
2017.01.03 11:34:38 4 EURUSD Compra 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 venta 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 venta in 0.30 1.05149 6 0.00 0.00 0.00 3 150.00
2017.01.05 17:28:37 7 EURUSD Compra in 0.30 1.05649 7 0.00 0.00 0.00 3 150.00
2017.01.05 17:28:37 9 EURUSD venta 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 Compra 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

Al usar stops virtuales (ocultos), no vemos las típicas marcas "close", como en MetaTrader 4. En lugar de ello, la operación de cierre usa otro método: la apertura de posición en dirección opuesta; pero nosotros no podemos ver esto en la historia de transacciones, independientemente de si se trata de una transacción de compra o de venta.














Órdenes
Hora de apertura Orden Símbolo Tipo Volumen Precio S / L T / P Hora Estado Comentarios
2017.01.03 10:00:00 2 EURUSD venta 0.30 / 0.30 1.04597

2017.01.03 10:00:00 ejecutada
2017.01.03 11:34:38 3 EURUSD Compra 0.30 / 0.30 1.04097

2017.01.03 11:34:38 ejecutada
2017.01.05 11:00:00 4 EURUSD venta 0.30 / 0.30 1.05149

2017.01.05 11:00:00 ejecutada
2017.01.05 17:28:37 5 EURUSD Compra 0.30 / 0.30 1.05649

2017.01.05 17:28:37 ejecutada

Transacciones
Hora Transacción Símbolo Tipo Dirección Volumen Precio Orden Comisión Swap Beneficio Balance Comentarios
2017.01.01 00:00:00 1
balance



0.00 0.00 3 000.00 3 000.00
2017.01.03 10:00:00 2 EURUSD venta in 0.30 1.04597 2 0.00 0.00 0.00 3 000.00
2017.01.03 11:34:38 3 EURUSD Compra out 0.30 1.04097 3 0.00 0.00 150.00 3 150.00
2017.01.05 11:00:00 4 EURUSD venta in 0.30 1.05149 4 0.00 0.00 0.00 3 150.00
2017.01.05 17:28:37 5 EURUSD Compra 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 el modo de compensación, puesto que MetaTrader 5 utiliza para ello stop-loss y take-profit globales (se aplican a toda la posición), el asesor tiene que utilizar órdenes pendientes para crear niveles stop aparte. Como se discutió anteriormente, en el modo de cobertura, los stops del bróker serán procesados como stops basados en órdenes pendientes, como se muestra en el recuadro:













Órdenes
Hora de apertura Orden Símbolo Tipo Volumen Precio S / L T / P Hora Estado Comentarios
2017.01.03 10:00:00 2 EURUSD venta 0.30 / 0.30 1.04597

2017.01.03 10:00:00 ejecutada
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 ejecutada
2017.01.05 11:00:00 5 EURUSD venta 0.30 / 0.30 1.05149

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

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

2017.01.05 17:28:37 canceled

Transacciones
Hora Transacción Símbolo Tipo Dirección Volumen Precio Orden Comisión Swap Beneficio Balance Comentarios
2017.01.01 00:00:00 1
balance



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

0.00 0.00 0.00 3 000.00

El siguiente recuadro muestra los resultados cuando los stops se basan en órdenes pendientes. Esto será semejante al recuadro anterior por la razón mencionada anteriormente.













Órdenes
Hora de apertura Orden Símbolo Tipo Volumen Precio S / L T / P Hora Estado Comentarios
2017.01.03 10:00:00 2 EURUSD venta 0.30 / 0.30 1.04597

2017.01.03 10:00:00 ejecutada
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 ejecutada
2017.01.05 11:00:00 5 EURUSD venta 0.30 / 0.30 1.05149

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

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

2017.01.05 17:28:37 canceled

Transacciones
Hora Transacción Símbolo Tipo Dirección Volumen Precio Orden Comisión Swap Beneficio Balance Comentarios
2017.01.01 00:00:00 1
balance



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

0.00 0.00 0.00 3 000.00

El siguiente recuadro muestra el uso de stops virtuales (ocultos) en MetaTrader 5, (modo de compensación). Los niveles stop virtuales en el modo de compensación pueden parecer iguales a los del modo de cobertura, pero son diferentes en cuanto a su funcionamiento interno.














Órdenes
Hora de apertura Orden Símbolo Tipo Volumen Precio S / L T / P Hora Estado Comentarios
2017.01.03 10:00:00 2 EURUSD venta 0.30 / 0.30 1.04597

2017.01.03 10:00:00 ejecutada
2017.01.03 11:34:38 3 EURUSD Compra 0.30 / 0.30 1.04097

2017.01.03 11:34:38 ejecutada
2017.01.05 11:00:00 4 EURUSD venta 0.30 / 0.30 1.05149

2017.01.05 11:00:00 ejecutada
2017.01.05 17:28:37 5 EURUSD Compra 0.30 / 0.30 1.05649

2017.01.05 17:28:37 ejecutada

Transacciones
Hora Transacción Símbolo Tipo Dirección Volumen Precio Orden Comisión Swap Beneficio Balance Comentarios
2017.01.01 00:00:00 1
balance



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

0.00 0.00 0.00 3 000.00

Ejemplo №2: asesor que usa Heiken Ashi y una media móvil, con tres niveles stop

Los asesores complejos necesitan con frecuencia más de un stop-loss y take-profit. Vamos a utilizar el mismo método que se describe en el ejemplo anterior para añadir niveles stop adicionales, que denominaremos "stop1" y "stop2":

int OnInit()
  {
//--- other code
  
   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));

//--- other code
  }

El siguiente recuadro muestra los resultados de la simulación en MetaTrader 4:

# Hora Tipo Orden Volumen Precio S / L T / P Beneficio Balance
1 2017.01.03 10:00 venta 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 Compra 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 venta 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 Cierre 4 0.11 1.04247 1.05097 1.04097 38.50 3066.00
10 2017.01.03 10:34 venta 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 venta 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 Compra 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 venta 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 Cierre 9 0.19 1.05314 1.05649 1.04649 -31.35 3102.15
21 2017.01.05 16:00 Compra 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
Comercio 2017.01.05 17:09 venta 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 Compra 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 Cierre 13 0.11 1.05664 1.04814 1.05814 38.50 3168.15
30- 2017.01.05 17:28 Compra 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


Como se muestra en el recuadro anterior, los tres niveles stop se han activado para la primera transacción. Para el nivel stop virtual, el asesor ejecuta el cierre parcial de la transacción principal, como se esperaba. Para el nivel stop con uso de órdenes pendientes, tan pronto como la orden se ha activado, el asesor ha ejecutado la operación de cierre con la opuesta y ha restado su volumen de la transacción principal. Por último, para el nivel de stop principal, que era el del bróker, la transacción principal ha sido cerrada con un volumen completo de 0,08 lotes.

El recuadro de más abajo muestra los resultados de la simulación en el modo de cobertura en MetaTrader 5:














Órdenes
Hora de apertura Orden Símbolo Tipo Volumen Precio S / L T / P Hora Estado Comentarios
2017.01.03 10:00:00 2 EURUSD venta 0.30 / 0.30 1.04597 1.05097 1.04097 2017.01.03 10:00:00 ejecutada
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 ejecutada
2017.01.03 10:21:32 5 EURUSD close by 0.11 / 0.11 1.04347

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

2017.01.03 10:33:40 ejecutada
2017.01.03 11:34:38 7 EURUSD Compra 0.08 / 0.08 1.04097

2017.01.03 11:34:38 ejecutada tp 1.04097
2017.01.05 11:00:00 8 EURUSD venta 0.30 / 0.30 1.05149 1.05649 1.04649 2017.01.05 11:00:00 ejecutada
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 ejecutada
2017.01.05 12:58:27 11 EURUSD close by 0.11 / 0.11 1.04896

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

2017.01.05 16:00:00 ejecutada
2017.01.05 16:00:00 13 EURUSD Compra 0.30 / 0.30 1.05307 1.04807 1.05807 2017.01.05 16:00:00 ejecutada
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 ejecutada
2017.01.05 17:09:40 16 EURUSD close by 0.11 / 0.11 1.05557

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

2017.01.05 17:28:47 ejecutada
2017.01.05 17:29:15 18 EURUSD venta 0.08 / 0.08 1.05807

2017.01.05 17:29:15 ejecutada tp 1.05807

Transacciones
Hora Transacción Símbolo Tipo Dirección Volumen Precio Orden Comisión Swap Beneficio Balance Comentarios
2017.01.01 00:00:00 1
balance



0.00 0.00 3 000.00 3 000.00
2017.01.03 10:00:00 2 EURUSD venta in 0.30 1.04597 2 0.00 0.00 0.00 3 000.00
2017.01.03 10:21:32 3 EURUSD Compra in 0.11 1.04347 4 0.00 0.00 0.00 3 000.00
2017.01.03 10:21:32 4 EURUSD Compra 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 venta 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 Compra out 0.11 1.04247 6 0.00 0.00 38.50 3 066.00
2017.01.03 11:34:38 7 EURUSD Compra 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 venta in 0.30 1.05149 8 0.00 0.00 0.00 3 106.00
2017.01.05 12:58:27 9 EURUSD Compra in 0.11 1.04896 10 0.00 0.00 0.00 3 106.00
2017.01.05 12:58:27 10 EURUSD Compra 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 venta 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 Compra out 0.19 1.05307 12 0.00 0.00 -30.02 3 103.81
2017.01.05 16:00:00 13 EURUSD Compra in 0.30 1.05307 13 0.00 0.00 0.00 3 103.81
2017.01.05 17:09:40 14 EURUSD venta in 0.11 1.05557 15 0.00 0.00 0.00 3 103.81
2017.01.05 17:09:40 16 EURUSD Compra 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 venta 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 venta out 0.11 1.05660 17 0.00 0.00 38.83 3 170.14
2017.01.05 17:29:15 18 EURUSD venta 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

Como se ve en el recuadro anterior, el asesor funciona de una forma similar a como lo hace en MetaTrader 5 en el modo de cobertura. El macanismo ha sido el mismo que en MetaTrader 4 para los tres tipos de niveles stop.

El recuadro de más abajo muestra los resultados de la simulación en el modo de compensación en MetaTrader 5:














Órdenes
Hora de apertura Orden Símbolo Tipo Volumen Precio S / L T / P Hora Estado Comentarios
2017.01.03 10:00:00 2 EURUSD venta 0.30 / 0.30 1.04597

2017.01.03 10:00:00 ejecutada
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 ejecutada
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 ejecutada
2017.01.03 10:33:40 7 EURUSD Compra 0.11 / 0.11 1.04247

2017.01.03 10:33:40 ejecutada
2017.01.05 11:00:00 8 EURUSD venta 0.30 / 0.30 1.05149

2017.01.05 11:00:00 ejecutada
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 ejecutada
2017.01.05 16:00:00 13 EURUSD Compra 0.19 / 0.19 1.05307

2017.01.05 16:00:00 ejecutada
2017.01.05 16:00:00 14 EURUSD Compra 0.30 / 0.30 1.05307

2017.01.05 16:00:00 ejecutada
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 ejecutada
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 ejecutada
2017.01.05 17:28:47 19 EURUSD venta 0.11 / 0.11 1.05660

2017.01.05 17:28:47 ejecutada

Transacciones
Hora Transacción Símbolo Tipo Dirección Volumen Precio Orden Comisión Swap Beneficio Balance Comentarios
2017.01.01 00:00:00 1
balance



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

0.00 -0.61 586.34 3 585.73

Aquí, nos encontramos con un problema. El nivel stop final ha cerrado a 0,30 lotes, en lugar de a 0,08, como se observa en las dos pruebas anteriores.

Como se discutió anteriormente, los stoploss y takeprofit estándares en MetaTrader 5 (modo de compensación), son diferentes a los de los dos otros modos. Por lo tanto, el asesor convierte el stop del bróker en un stop basado en una orden pendiente. Sin embargo, con esta configuración, el asesor ya tiene dos niveles stop basados en órdenes pendientes, y uno de ellos es el básico. Como también se señaló anteriormente, esto provocar transacciones huérfanas. El nivel stop final o principal siempre tendrá un volumen equivalente al volumen inicial de la operación principal. Y puesto que se introducen otros niveles stop, esto puede conllevar el cierre de la posición con el stop principal, además, con un volumen mayor al inicial.

Vamos a corregir este error: vamos a designar como stop principal, no el del bróker o el pendiente, sino el virtual. Con esta nueva configuración, el asesor tiene ahora dos stops virtuales y otro stop basado en una orden pendiente. El resultado de la simulación con esta nueva configuración se muestra a continuación.














Órdenes
Hora de apertura Orden Símbolo Tipo Volumen Precio S / L T / P Hora Estado Comentarios
2017.01.03 10:00:00 2 EURUSD venta 0.30 / 0.30 1.04597

2017.01.03 10:00:00 ejecutada
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 ejecutada
2017.01.03 10:33:40 5 EURUSD Compra 0.11 / 0.11 1.04247

2017.01.03 10:33:40 ejecutada
2017.01.03 11:34:38 6 EURUSD Compra 0.08 / 0.08 1.04097

2017.01.03 11:34:38 ejecutada
2017.01.05 11:00:00 7 EURUSD venta 0.30 / 0.30 1.05149

2017.01.05 11:00:00 ejecutada
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 ejecutada
2017.01.05 16:00:00 10 EURUSD Compra 0.19 / 0.19 1.05307

2017.01.05 16:00:00 ejecutada
2017.01.05 16:00:00 11 EURUSD Compra 0.30 / 0.30 1.05307

2017.01.05 16:00:00 ejecutada
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 ejecutada
2017.01.05 17:28:47 14 EURUSD venta 0.11 / 0.11 1.05660

2017.01.05 17:28:47 ejecutada
2017.01.05 17:29:15 15 EURUSD venta 0.08 / 0.08 1.05807

2017.01.05 17:29:15 ejecutada

Transacciones
Hora Transacción Símbolo Tipo Dirección Volumen Precio Orden Comisión Swap Beneficio Balance Comentarios
2017.01.01 00:00:00 1
balance



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

0.00 0.00 210.14 3 210.14

El volumen total tomado por los niveles stop es ahora igual al volumen inicial de la operación principal.

Ejmplo #3: Stops con gestión de dinero

En uno de los artículos anteriores se discutió que algunos métodos de gestión de dinero dependen de un cierto nivel stop (normalmente se trata de un take-profit, pero a veces se usa un stop-loss). Los métodos de gestión de dinero tales como el riesgo fijo fraccional, el método de riesgo fijo y el método de riesgo fijo por puntos/pips a menudo requieren un nivel final de stop-loss. Si no se establece este nivel, se presupone que existe un riesgo muy elevado (e incluso infinito), y por consiguiente, también el volumen calculado será muy alto. Con el fin de mostrar un asesor experto capaz de utilizar los objetos de clase mencionados en este artículo con la gestión de dinero, modificaremos el primer ejemplo de manera que las líneas de código previamente comentadas sean incluidas en la compilación.

En primer lugar, eliminaremos las etiquetas de comentario en las líneas de código para los métodos de gestión de dinero, como se muestra en el código siguiente, dentro de la función OnInit:

int OnInit()
  {
//--- other code
   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);
//--- other code
  }

Al inicio del código declaramos una enumeración personalizada para crear un parámetro externo que nos permita elegir el método de gestión de dinero, en el mismo orden que se muestra en el código fuente.

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

A continuación, declaramos el nuevo parámetro de entrada para esta enumeración:

input ENUM_MM_TYPE mm_type=MM_FIXED_FRACTIONAL;

Por último, tenemos que vincular este parámetro a la elección actual del método de gestión de dinero dentro de la función 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());
           }
        }
     }
  }

Puesto que los métodos de gestión de dinero se ocupan solo de los cálculos puros, no surgirá ningún problema con respecto a la compatibilidad entre MQL4 y MQL5. Los dos ejemplos anteriores ya han demostrado que los niveles stop funcionan en ambas plataformas. Los siguientes recuadros muestran los resultados de la simulación en MetaTrader 5, en el modo de cobertura.

El siguiente recuadro muestra los resultados de la simulación con el uso de una gestión de dinero fija fraccional. Se ha programado un ajuste de riesgo de un 5% del balance de la cuenta. Con un balance inicial de $ 3000, esperamos que este valor constituya cerca de 150 $, si para la primera transacción se alcanza el stop-loss. Puesto que el stop-loss y el take-profit tienen el mismo valor (500 puntos), esperamos que el beneficio sea también de 150 dólares al alcanzar el take-profit.














Órdenes
Hora de apertura Orden Símbolo Tipo Volumen Precio S / L T / P Hora Estado Comentarios
2017.01.03 10:00:00 2 EURUSD venta 0.30 / 0.30 1.04597 1.05097 1.04097 2017.01.03 10:00:00 ejecutada
2017.01.03 11:34:38 3 EURUSD Compra 0.30 / 0.30 1.04097

2017.01.03 11:34:38 ejecutada tp 1.04097
2017.01.05 11:00:00 4 EURUSD venta 0.32 / 0.32 1.05149 1.05649 1.04649 2017.01.05 11:00:00 ejecutada
2017.01.05 16:00:00 5 EURUSD Compra 0.32 / 0.32 1.05307

2017.01.05 16:00:00 ejecutada
2017.01.05 16:00:00 6 EURUSD Compra 0.31 / 0.31 1.05307 1.04807 1.05807 2017.01.05 16:00:00 ejecutada
2017.01.05 17:29:15 7 EURUSD venta 0.31 / 0.31 1.05807

2017.01.05 17:29:15 ejecutada tp 1.05807

Transacciones
Hora Transacción Símbolo Tipo Dirección Volumen Precio Orden Comisión Swap Beneficio Balance Comentarios
2017.01.01 00:00:00 1
balance



0.00 0.00 3 000.00 3 000.00
2017.01.03 10:00:00 2 EURUSD venta in 0.30 1.04597 2 0.00 0.00 0.00 3 000.00
2017.01.03 11:34:38 3 EURUSD Compra 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 venta in 0.32 1.05149 4 0.00 0.00 0.00 3 150.00
2017.01.05 16:00:00 5 EURUSD Compra out 0.32 1.05307 5 0.00 0.00 -50.56 3 099.44
2017.01.05 16:00:00 6 EURUSD Compra in 0.31 1.05307 6 0.00 0.00 0.00 3 099.44
2017.01.05 17:29:15 7 EURUSD venta 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

Preste atención: el valor del volumen calculado también depende de la precisión del bróker, que define los parámetros del lote mínimo y el salto mínimo del lote. No podemos esperar que el asesor realice siempre cálculos precisos. Con estas limitaciones, nuestro asesor experto puede considerar necesario redondear el valor en algún momento. Lo mismo sucede con los otros métodos de gestión de dinero.

Para la gestión de dinero con riesgo fijo por puntos, se ha programado el ajuste: riesgo de $ 0,1 de dólar por punto de stoploss. Con un ajuste de 500 puntos de stop-loss y take-profit, esperamos que estos niveles stop cuesten $ 50 cada uno.














Órdenes
Hora de apertura Orden Símbolo Tipo Volumen Precio S / L T / P Hora Estado Comentarios
2017.01.03 10:00:00 2 EURUSD venta 0.10 / 0.10 1.04597 1.05097 1.04097 2017.01.03 10:00:00 ejecutada
2017.01.03 11:34:38 3 EURUSD Compra 0.10 / 0.10 1.04097

2017.01.03 11:34:38 ejecutada tp 1.04097
2017.01.05 11:00:00 4 EURUSD venta 0.10 / 0.10 1.05149 1.05649 1.04649 2017.01.05 11:00:00 ejecutada
2017.01.05 16:00:00 5 EURUSD Compra 0.10 / 0.10 1.05307

2017.01.05 16:00:00 ejecutada
2017.01.05 16:00:00 6 EURUSD Compra 0.10 / 0.10 1.05307 1.04807 1.05807 2017.01.05 16:00:00 ejecutada
2017.01.05 17:29:15 7 EURUSD venta 0.10 / 0.10 1.05807

2017.01.05 17:29:15 ejecutada tp 1.05807

Transacciones
Hora Transacción Símbolo Tipo Dirección Volumen Precio Orden Comisión Swap Beneficio Balance Comentarios
2017.01.01 00:00:00 1
balance



0.00 0.00 3 000.00 3 000.00
2017.01.03 10:00:00 2 EURUSD venta in 0.10 1.04597 2 0.00 0.00 0.00 3 000.00
2017.01.03 11:34:38 3 EURUSD Compra 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 venta in 0.10 1.05149 4 0.00 0.00 0.00 3 050.00
2017.01.05 16:00:00 5 EURUSD Compra out 0.10 1.05307 5 0.00 0.00 -15.80 3 034.20
2017.01.05 16:00:00 6 EURUSD Compra in 0.10 1.05307 6 0.00 0.00 0.00 3 034.20
2017.01.05 17:29:15 7 EURUSD venta 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 la gestión de dinero con riesgo fijo, se ha programado un ajuste de riesgo de $ 100. El asesor, a su vez, debe calcular el volumen que corresponde a este riesgo. El resultado se muestra a continuación.














Órdenes
Hora de apertura Orden Símbolo Tipo Volumen Precio S / L T / P Hora Estado Comentarios
2017.01.03 10:00:00 2 EURUSD venta 0.20 / 0.20 1.04597 1.05097 1.04097 2017.01.03 10:00:00 ejecutada
2017.01.03 11:34:38 3 EURUSD Compra 0.20 / 0.20 1.04097

2017.01.03 11:34:38 ejecutada tp 1.04097
2017.01.05 11:00:00 4 EURUSD venta 0.20 / 0.20 1.05149 1.05649 1.04649 2017.01.05 11:00:00 ejecutada
2017.01.05 16:00:00 5 EURUSD Compra 0.20 / 0.20 1.05307

2017.01.05 16:00:00 ejecutada
2017.01.05 16:00:00 6 EURUSD Compra 0.20 / 0.20 1.05307 1.04807 1.05807 2017.01.05 16:00:00 ejecutada
2017.01.05 17:29:15 7 EURUSD venta 0.20 / 0.20 1.05807

2017.01.05 17:29:15 ejecutada tp 1.05807

Transacciones
Hora Transacción Símbolo Tipo Dirección Volumen Precio Orden Comisión Swap Beneficio Balance Comentarios
2017.01.01 00:00:00 1
balance



0.00 0.00 3 000.00 3 000.00
2017.01.03 10:00:00 2 EURUSD venta in 0.20 1.04597 2 0.00 0.00 0.00 3 000.00
2017.01.03 11:34:38 3 EURUSD Compra 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 venta in 0.20 1.05149 4 0.00 0.00 0.00 3 100.00
2017.01.05 16:00:00 5 EURUSD Compra out 0.20 1.05307 5 0.00 0.00 -31.60 3 068.40
2017.01.05 16:00:00 6 EURUSD Compra in 0.20 1.05307 6 0.00 0.00 0.00 3 068.40
2017.01.05 17:29:15 7 EURUSD venta 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

Recuerde, el gestor de órdenes siempre considerará que para la gestión del dinero se usa solo el nivel stop principal. Si no se ha declarado un stop principal, los métodos de gestión de dinero basados en stop-loss no se pueden utilizar, incluso si hay otros stops presentes.

Conclusión

En este artículo hemos discutido la adición de niveles stop a un asesor experto multiplataforma. Las dos plataformas comerciales, a pesar de tener muchas características paralelas, se diferencian significativamente en la forma en que se implementan los niveles de parada. Este artículo proporciona un método con el que estas diferencias pueden ser suavizadas, haciendo así que el asesor sea compatible con ambas plataformas.

Programas utilizados en el artículo

#
Nombre
Tipo
Descripción de los parámetros
1
stops_ha_ma1.mqh
Archivo de encabezamiento
Archivo de encabezamiento principal utilizado para el asesor en el primer ejemplo
2.
stops_ha_ma1.mq4 Asesor Experto
Archivo fuente principal utilizado para el asesor en MQL4 en el primer ejemplo
3.
stops_ha_ma1.mq5 Asesor Experto Archivo fuente principal utilizado para el asesor en MQL5 en el primer ejemplo
4.  stops_ha_ma2.mqh Archivo de encabezamiento Archivo de encabezamiento principal utilizado para el asesor en el segundo ejemplo
5.  stops_ha_ma2.mq4 Asesor Experto
Archivo fuente principal utilizado para el asesor en MQL4 en el segundo ejemplo
6.  stops_ha_ma2.mq5 Asesor Experto
Archivo fuente principal utilizado para el asesor en MQL5 en el segundo ejemplo
7.  stops_ha_ma3.mqh Archivo de encabezamiento Archivo de encabezamiento principal utilizado para el asesor en el tercer ejemplo
8.  stops_ha_ma3.mq4 Asesor Experto
Archivo fuente principal utilizado para el asesor en MQL4 en el tercer ejemplo
9.  stops_ha_ma3.mq5 Asesor Experto
Archivo fuente principal utilizado para el asesor en MQL5 en el tercer ejemplo

Archivos de las clases creadas en el artículo

#
Nombre
Tipo
Descripción de los parámetros
1
MQLx\Base\Stop\StopBase.mqh
Archivo de encabezamiento
CStop (clase básica)
2.
MQLx\MQL4\Stop\Stop.mqh Archivo de encabezamiento CStop (versión MQL4)
3.
MQLx\MQL5\Stop\Stop.mqh Archivo de encabezamiento CStop (versión MQL5)
4. MQLx\Base\Stop\StopsBase.mqh Archivo de encabezamiento CStops (contenedor CStop, clase básica)
5. MQLx\MQL4\Stop\Stops.mqh Archivo de encabezamiento CStops (versión MQL4)
6. MQLx\MQL5\Stop\Stops.mqh Archivo de encabezamiento CStops (versión MQL5)
7. MQLx\Base\Stop\StopLineBase.mqh Archivo de encabezamiento CStopLine (presentación gráfica, clase básica)
8. MQLx\MQL4\Stop\StopLine.mqh Archivo de encabezamiento CStopLine (versión MQL4)
9. MQLx\MQL5\Stop\StopLine.mqh Archivo de encabezamiento CStopLine (versión MQL5)
10.  MQLx\Base\Order\OrderStopBase.mqh Archivo de encabezamiento COrderStop (clase básica)
11.  MQLx\MQL4\Order\OrderStop.mqh Archivo de encabezamiento COrderStop (versión MQL4)
12.  MQLx\MQL5\Order\OrderStop.mqh Archivo de encabezamiento COrderStop (versión MQL5)
13.
 MQLx\Base\Order\OrderStopVirtualBase.mqh Archivo de encabezamiento
COrderStopVirtual (nivel stop oculto o virtual, clase básica)
13.  MQLx\Base\Order\OrderStopVirtual.mqh Archivo de encabezamiento
COrderStopVirtual (versión MQL4)
15.
 MQLx\Base\Order\OrderStopVirtual.mqh Archivo de encabezamiento
COrderStopVirtual (versión MQL5)
16.  MQLx\Base\Order\OrderStopPendingBase.mqh Archivo de encabezamiento
COrderStopPending (nivel stop según orden pendiente, clase básica)
17.  MQLx\Base\Order\OrderStopPending.mqh Archivo de encabezamiento
COrderStopPending (versión MQL4)
18.
 MQLx\Base\Order\OrderStopPending.mqh Archivo de encabezamiento
COrderStopPending (versión MQL5)
19.
 MQLx\Base\Order\OrderStopBroker.mqh Archivo de encabezamiento
COrderStopBroker (nivel stop del bróker, clase básica)
20.  MQLx\Base\Order\OrderStopBroker.mqh Archivo de encabezamiento
COrderStopBroker (versión MQL4)
21.  MQLx\Base\Order\OrderStopBroker.mqh Archivo de encabezamiento
COrderStopBroker (versión MQL5)
22.  MQLx\Base\Order\OrderStopsBase.mqh Archivo de encabezamiento
COrderStops (contenedor COrderStop, clase básica)
23.  MQLx\Base\Order\OrderStops.mqh Archivo de encabezamiento
COrderStops (versión MQL4)
24.  MQLx\Base\Order\OrderStops.mqh Archivo de encabezamiento
COrderStops (versión MQL5)

Traducción del inglés realizada por MetaQuotes Ltd.
Artículo original: https://www.mql5.com/en/articles/3620

Archivos adjuntos |
tester.zip (1445.59 KB)
MQL5.zip (708.29 KB)
Evaluación del riesgo en la secuencia de transacciones con un activo Evaluación del riesgo en la secuencia de transacciones con un activo
En este artículo se describe el uso de los métodos del cálculo de probabilidades y la estadística matemática en el análisis de los sistemas comerciales.
Experto comercial universal: Indicador CUnIndicator y trabajo con órdenes pendientes (parte 9) Experto comercial universal: Indicador CUnIndicator y trabajo con órdenes pendientes (parte 9)
En este artículo se describe el trabajo con indicadores usando la clase universal CUnIndicator. Además de eso, han sido examinados nuevos métodos de trabajo con las órdenes pendientes. Obsérvese, a partir de este momento, la la estructura del proyecto CStrategy ha sufrido cambios considerables. Ahora, todos sus archivos se ubican en el mismo directorio para la comodidad de los usuarios.
Búsqueda automática de divergencia y convergencia Búsqueda automática de divergencia y convergencia
En este artículo, se analizan diferentes tipos de divergencia: regular, oculta, ampliada, triple, cuádruple, convergencia, divergencia de las clases A, B y C. Se crea un indicador universal para buscar y visualizarlas en el gráfico.
Examinamos en la práctica el método adaptativo del seguimiento del mercado Examinamos en la práctica el método adaptativo del seguimiento del mercado
La principal diferencia del sistema de trading que se propone en el artículo consiste en el uso de las herramientas matemáticas para analizar las cotizaciones bursátiles. En este sistema, se aplica la filtración digital y la estimación espectral de las series temporales discretas. Han sido descritos los aspectos teóricos de la estrategia y ha sido construido el Asesor Experto (EA) para testearla.