
Asesor Experto multiplataforma: Niveles stop
Índice
- Introducción
- COrder
- CStop
- CStops
- COrderStop
- COrderStops
- Representación de los niveles stop en el gráfico
- Comprobación de las órdenes en el nivel stop
- Ejemplos
- Conclusión
- Programas utilizados en el artículo
- 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:
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:
El proceso general de creación de los niveles stop se muestra en la siguiente figura:
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:
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:
- definir los niveles de stop-loss y take-profit;
- calcular los niveles stop;
- implementar los niveles de stop-loss y take-profit para la transacción principal;
- comprobar si se ha alcanzado el nivel stop;
- suavizar las diferencias entre la implementación del stop-loss y el take-profit en los lenguajes MQL4 y MQL5;
- 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:
- 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.
- 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).
- 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:
- Fijo — designa un volumen fijo del lote
- Tanto por ciento del resto - porcentaje del volumen de lote restante de la posición principal
- Porcentaje Total - porcentaje del lote inicial total de la transacción principal
- 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:
- El tipo de nivel stop (de bróker, basado en una orden pendiente, o virtual), método StopType
- El tipo utilizado para el cálculo del volumen, método VolumeType
- El nivel stop-loss en puntos (siempre que sea necesario), método StopLoss
- 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:
- Muestra los niveles stop al inicializar el ejemplar de COrders
- Actualiza los niveles stop, si uno de ellos o ambos han sido modificados
- 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.
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.
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 |
Ó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 | |||||||||
Ó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 | |||||||||
Ó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 | |||||||||
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





- Aplicaciones de trading gratuitas
- 8 000+ señales para copiar
- Noticias económicas para analizar los mercados financieros
Usted acepta la política del sitio web y las condiciones de uso