Negociamos con opciones sin opciones (Parte 2): Aplicación en el trading real
Introducción
En la primera parte de esta serie, describimos brevemente el instrumento de trading opción, así como sus posibilidades, ventajas e inconvenientes. Asimismo, desarrollamos la teoría y la implementación práctica en MQL5 de un método para emular una opción mediante el uso del activo subyacente. Ahora ha llegado el momento de probar las opciones en la práctica, para operar en el mercado.
Para ello, debemos crear un asesor experto que se encargue de traducir los niveles de emulación de la opción en órdenes y posiciones reales sobre el activo subyacente, así como de reequilibrar continuamente la posición total resultante.
Uso en el trading real
En primer lugar, analizaremos qué estrategias se pueden utilizar en el trading. Aquí solo analizaremos estrategias especulativas. Empezaremos por lo más sencillo: la compra y venta de opciones individuales. Para ello, elaboraremos una tabla con todas las variantes posibles.
Estrategias de trading sencillas y condiciones de uso
Compra de una opción Call — Long Call
- Idea: compra de una opción call
- Condición: si se tiene confianza en la subida del precio del activo subyacente
- Beneficio: ilimitado
- Riesgo: la prima pagada por la opción (no existe en la emulación)
Compra de una opción Put — Long Put
- Idea: compra de una opción put a la espera de que baje el precio del activo subyacente
- Condición: si se tiene confianza en el descenso del precio del activo subyacente
- Beneficio: ilimitado
- Riesgo: la prima pagada por la opción (no existe en la emulación)
Venta de opción Call — Short Call
- Idea: venta de una opción call con la expectativa de que el precio del activo subyacente no suba, aunque tampoco tenga necesariamente que bajar
- Condición: si se tiene confianza en la ausencia de subida del precio del activo subyacente
- Beneficio: la prima que paga el comprador de la opción (no existe en la emulación)
- Riesgo: ilimitado
Venta de opción Put — Short Put
- Idea: venta de una opción put con la expectativa de que el precio del activo subyacente no baje, aunque tampoco tenga necesariamente que subir
- Condición: si se tiene confianza en que el precio del activo subyacente no bajará
- Beneficio: la prima que paga el comprador de la opción (no existe en la emulación)
- Riesgo: ilimitado
Notas:
- La venta de opciones individuales emuladas no tiene especial sentido, ya que no se obtiene ninguna prima por ella. Sin embargo, para la posterior creación de estructuras de opciones (en términos del mercado bursátil, carteras de opciones), es necesario implementar todas las variantes.
- Al comprar opciones individuales emuladas, como es lógico, no se paga prima alguna. Sin embargo, al reequilibrar la cartera puede «acumularse» cierta pérdida (que puede considerarse equivalente al pago de una prima). Su cuantía depende de la variación concreta del precio del activo subyacente y del tiempo que se mantengan las posiciones. En general, esta pérdida es comparable a la prima.
Desarrollamos un asesor experto para implementar una estrategia de trading
La clase base TOptionBase y las clases de opciones OptionLongCall, OptionLongPut, OptionShortCall y OptionShortPut no sufren modificaciones (véase el artículo anterior de esta serie). Ahora añadiremos la clase básica de la estructura de opciones, que más adelante nos permitirá crear estructuras de opciones de cualquier complejidad.
A continuación se muestra la clase TOptionConstructionBase. La hemos derivado de la clase estándar CList, que forma parte de las bibliotecas de MQL5. Para acceder a CList, hay que añadir la siguiente línea al principio:
#include <Arrays\List.mqh> Esto nos permitirá manipular listas de opciones para obtener las características agregadas de la cartera que necesitamos. Así pues, presentamos la clase de la estructura de opciones:
// ===================================================================== // La clase base de la estructura de opciones se deriva de «CList»: // ===================================================================== class TOptionConstructionBase : public CList { protected: ENUM_OPTION_CONSTRUCTION type_enum; double total_delta; bool is_option_construction_inited_Flag; public: // --------------------------------------------------------------------- // Destructor: // --------------------------------------------------------------------- ~TOptionConstructionBase() { this.Clear(); } // --------------------------------------------------------------------- // Constructor: // --------------------------------------------------------------------- TOptionConstructionBase(ENUM_OPTION_CONSTRUCTION _type_enum) : type_enum(_type_enum), total_delta(0.0), is_option_construction_inited_Flag(false), CList() { this.FreeMode(true); } // --------------------------------------------------------------------- // Obtener el valor de la delta normalizada calculada anteriormente: // --------------------------------------------------------------------- double GetOptionConstructionDelta() { return(this.total_delta); } // --------------------------------------------------------------------- // Obtener el valor de bandera de inicialización general de la estructura de opciones: // --------------------------------------------------------------------- bool IsOptionConstructionInited() { return(this.is_option_construction_inited_Flag); } // --------------------------------------------------------------------- // Establecer el rango de normalización de la delta para el precio de ejercicio central: // --------------------------------------------------------------------- void SetOptionConstructionRange(const double& _strike[], const double& _norm_price[]) { this.is_option_construction_inited_Flag = true; if(this.Total() > 0) { int i = 0; TOptionBase* curr_option = this.GetFirstNode(); while(curr_option != NULL) { curr_option.SetRange(_strike[i], _norm_price[i]); if(curr_option.IsRangeInited() == true) { this.is_option_construction_inited_Flag = this.is_option_construction_inited_Flag && true; } else { this.is_option_construction_inited_Flag = false; } curr_option = this.GetNextNode(); i++; } } } // --------------------------------------------------------------------- // Iterador de actualización de la delta: // --------------------------------------------------------------------- double UpdateOptionConstructionDelta(const double _price) { this.total_delta = 0.0; if(this.Total() > 0) { TOptionBase* curr_option = this.GetFirstNode(); while(curr_option != NULL) { this.total_delta += curr_option.UpdateDelta(_price); curr_option = this.GetNextNode(); } } return(this.total_delta); } // --------------------------------------------------------------------- // Creación de una estructura de opciones: // --------------------------------------------------------------------- virtual void CreateOptionConstruction(const double _k, const double _s, const int _digits) = 0; }; // ---------------------------------------------------------------------
Analicemos esta clase con más detalle. Como podemos ver, al final del código presentado aparece la declaración del método abstracto CreateOptionConstruction, por lo que la propia clase base es abstracta. Este método crea directamente una estructura de opciones y se definirá en las clases derivadas. El método recibe los parámetros _k, _s y _digits. Los dos primeros son los valores de K y S en la sigmoide que emula una opción. El último es el número de decimales del activo subyacente.
Además, se ha añadido una enumeración para el tipo de estructura de opciones ENUM_OPTION_CONSTRUCTION. En este momento, tiene el siguiente aspecto:
// --------------------------------------------------------------------- // Estructura de opciones: // --------------------------------------------------------------------- enum ENUM_OPTION_CONSTRUCTION { ENUM_OPTION_CONSTRUCTION_RISING = 0, // Base Active Rising - posición larga en opción CALL ENUM_OPTION_CONSTRUCTION_FALLING = 1, // Activo subyacente a la baja - posición larga en opción put ENUM_OPTION_CONSTRUCTION_NOT_RISING = 2, // Activo subyacente que no sube - posición corta en opción call ENUM_OPTION_CONSTRUCTION_NOT_FALLING = 3, // Activo subyacente que no cae - posición corta en opción put }; // ---------------------------------------------------------------------
Más adelante añadiremos estructuras más complejas y nuevos tipos a la enumeración. Este tipo se pasa como parámetro al constructor de la clase al crear un objeto.
El método SetOptionConstructionRange(const double& _strike[], const double& _norm_price[]) permite establecer el rango de normalización de la delta para el precio de ejercicio (strike) central de cada una de las opciones que forman parte de la estructura de opciones. Los parámetros con los valores de los precios de ejercicio (strikes) y de los rangos de normalización se pasan como referencias a arrays que deben contener los valores correspondientes. El tamaño de los arrays debe ser igual al número de opciones de la estructura de opciones.
En las estructuras mencionadas anteriormente, el tamaño siempre es igual a uno. En esta versión de prueba no se comprueba si el tamaño es correcto, pero es fácil añadir esta comprobación en la versión operativa para trading real. Dado que la estructura de opciones viene definida desde el principio, el tamaño de los arrays (es decir, el número de opciones) se conoce de antemano.
Además, en la clase básica se define un método para actualizar la delta total de la estructura de opciones UpdateOptionConstructionDelta(const double _price), que devuelve la delta total calculada. El parámetro de entrada del método es el precio del activo subyacente. Este método utiliza los métodos de la clase CList para recorrer todos los elementos de la lista.
A continuación, derivamos de la clase básica las estructuras de opciones reales. Dado que toda la funcionalidad se encuentra en la clase básica, las clases derivadas tienen una estructura bastante sencilla:
// ===================================================================== // Clase de la estructura de opciones de tipo «Base Active Rising»: // ===================================================================== class BaseActiveRisingOptionConstruction : public TOptionConstructionBase { public: // --------------------------------------------------------------------- // Constructor: // --------------------------------------------------------------------- BaseActiveRisingOptionConstruction() : TOptionConstructionBase(ENUM_OPTION_CONSTRUCTION_RISING) { } // --------------------------------------------------------------------- // Creación de una estructura de opciones: // --------------------------------------------------------------------- virtual void CreateOptionConstruction(const double _k, const double _s, const int _digits) override { this.Add(new OptionLongCall(_k, _s, _digits)); } }; // ===================================================================== // Clase de la estructura de opciones de tipo «Base Active Falling»: // ===================================================================== class BaseActiveFallingOptionConstruction : public TOptionConstructionBase { public: // --------------------------------------------------------------------- // Constructor: // --------------------------------------------------------------------- BaseActiveFallingOptionConstruction() : TOptionConstructionBase(ENUM_OPTION_CONSTRUCTION_FALLING) { } // --------------------------------------------------------------------- // Creación de una estructura de opciones: // --------------------------------------------------------------------- virtual void CreateOptionConstruction(const double _k, const double _s, const int _digits) override { this.Add(new OptionLongPut(_k, _s, _digits)); } }; // ===================================================================== // Clase de la estructura de opciones de tipo «Base Active NOT Rising»: // ===================================================================== class BaseActiveNotRisingOptionConstruction : public TOptionConstructionBase { public: // --------------------------------------------------------------------- // Constructor: // --------------------------------------------------------------------- BaseActiveNotRisingOptionConstruction() : TOptionConstructionBase(ENUM_OPTION_CONSTRUCTION_NOT_RISING) { } // --------------------------------------------------------------------- // Creación de una estructura de opciones: // --------------------------------------------------------------------- virtual void CreateOptionConstruction(const double _k, const double _s, const int _digits) override { this.Add(new OptionShortCall(_k, _s, _digits)); } }; // ===================================================================== // Clase de la estructura de opciones de tipo «Base Active NOT Falling»: // ===================================================================== class BaseActiveNotFallingOptionConstruction : public TOptionConstructionBase { public: // --------------------------------------------------------------------- // Constructor: // --------------------------------------------------------------------- BaseActiveNotFallingOptionConstruction() : TOptionConstructionBase(ENUM_OPTION_CONSTRUCTION_NOT_FALLING) { } // --------------------------------------------------------------------- // Creación de una estructura de opciones: // --------------------------------------------------------------------- virtual void CreateOptionConstruction(const double _k, const double _s, const int _digits) override { this.Add(new OptionShortPut(_k, _s, _digits)); } }; // ---------------------------------------------------------------------
Lo único que hay que hacer en la clase derivada es definir el método de creación de la estructura de opciones CreateOptionConstruction. En este método, creamos el objeto de la opción necesaria (o de un grupo de opciones) y añadimos el objeto creado a la lista llamando al método CList::Add.
Estas clases se encuentran en el archivo «OptionEmulatorA2.mqh», que se adjunta a este artículo.
Parámetros de entrada
Ahora pasaremos a la implementación del asesor experto propiamente dicho para la emulación mediante la gestión de posiciones reales. En primer lugar, añadiremos una enumeración que definirá el estado global (general) del asesor experto o el estado del trading:
// --------------------------------------------------------------------- // Estado actual del trading: // --------------------------------------------------------------------- enum ENUM_TRADE_MODE_STATE { ENUM_TRADE_MODE_STARTED, // El trading ESTÁ EN MARCHA, las posiciones SE GESTIONAN ENUM_TRADE_MODE_STOPPED, // El trading ESTÁ DETENIDO, todas las posiciones están CERRADAS ENUM_TRADE_MODE_PAUSED, // El trading está PAUSADO por el operador, las posiciones existentes NO SE GESTIONAN ENUM_TRADE_MODE_WAITING, // El trading QUEDA A LA ESPERA de una reanudación automática, las posiciones existentes SE GESTIONAN, SI ES POSIBLE }; // ---------------------------------------------------------------------
En la versión inicial del asesor experto solo se utilizarán dos estados: «trading detenido» y «trading en marcha». El trading se inicia al arrancar el asesor experto, una vez finalizada su inicialización, y se detiene al alcanzarse el momento de vencimiento. Utilizaremos opciones diarias con vencimiento obligatorio antes del inicio de un nuevo día.
Añadiremos al asesor experto los parámetros externos configurables necesarios:
// ===================================================================== // Parámetros externos configurables: // ===================================================================== input ENUM_OPTION_CONSTRUCTION OptionConstruction = ENUM_OPTION_CONSTRUCTION_RISING; // Estructura de opciones input ulong BaseMagic = 10000UL; // Número mágico básico input int MinLotsMultiplier = 1; // Multiplicador del lote mínimo // --------------------------------------------------------------------- input int AddNewFromHours = 0; // Añadir nuevas horas desde (0...23) input int AddNewToHours = 24; // Añadir nuevas horas hasta (1...24) input int ExpirationTimeHours = 24; // Hora de vencimiento, horas (1...24) input int ExpirationTimeMinutes = 0; // Hora de vencimiento, minutos (0...59) // --------------------------------------------------------------------- input double ZeroDelta = 0.01; // Delta cero (0,01...0,1) input string ForceAutoExpirationTime = "23:50"; // Forzar hora de vencimiento automática (servidor MT5) input int ADRDaysNumber = 20; // Número de días para calcular la volatilidad histórica // ---------------------------------------------------------------------
Parámetros externos que pueden suscitar dudas:
- BaseMagic — valor básico del número mágico (al abrir una posición, se le suma el número del nivel de emulación de la opción multiplicado por 100);
- MinLotsMultiplier — multiplicador del lote mínimo al determinar el volumen de la posición en cada uno de los niveles;
- AddNewFromHours — inicio del funcionamiento intradía del asesor experto, en horas (de 0 a 23 horas);
- AddNewToHours — finalización del funcionamiento intradía del asesor experto, en horas (de 1 a 24 horas);
- ExpirationTimeHours — hora de vencimiento intradía de la estructura de opciones, en horas de 1 a 24 horas;
- ExpirationTimeMinutes — hora de vencimiento intradía de la estructura de opciones, en minutos de 0 a 59 minutos;
- ForceAutoExpirationTime — hora de vencimiento forzado y detención del asesor experto, en formato «hh:mm»;
- ADRDaysNumber — número de días para calcular la volatilidad histórica (HV).
Asesor experto de trading
Son de interés las siguientes funciones del asesor experto de trading:
//--------------------------------------------------------------------- // Obtener el volumen de trading normalizado: //--------------------------------------------------------------------- // • entrada: lote requerido; // • salida: lote normalizado; //--------------------------------------------------------------------- double NormalizeLots(const double _requied_lots) { double lots, koeff; int nmbr; if(min_trade_volume_step > 0.0) { koeff = 1.0 / min_trade_volume_step; nmbr = (int)MathLog10(koeff); } else { koeff = 1.0 / min_trade_volume; nmbr = 2; } lots = MathFloor(_requied_lots * koeff) / koeff; // Límite inferior del lote: if(lots < min_trade_volume) { lots = min_trade_volume; } // Límite superior del lote: if(lots > max_trade_volume) { lots = max_trade_volume; } lots = NormalizeDouble(lots, nmbr); return(lots); }
La normalización del lote es necesaria porque, en el trading real, los instrumentos tienen incrementos discretos del volumen negociable. Además, se limitan el número de decimales en la representación del volumen y los valores mínimo y máximo del volumen. Todos estos requisitos se tienen en cuenta en la función presentada anteriormente NormalizeLots.
// --------------------------------------------------------------------- // Normalización del precio teniendo en cuenta el paso de variación de las cotizaciones: // --------------------------------------------------------------------- double NormalizePrice(const double _price) { // Tamaño mínimo del paso de variación de las cotizaciones, en puntos: double min_price_step = NormalizeDouble(symbol_tick_size / Point(), 0 ); double norm_price = NormalizeDouble(NormalizeDouble((NormalizeDouble(_price / Point(), 0 )) / min_price_step, 0 ) * min_price_step * Point(), Digits()); return(norm_price); } // ---------------------------------------------------------------------
Aquí se utilizan los valores de las variables globales obtenidos durante la inicialización:
double min_trade_volume = SymbolInfoDouble(Symbol(), SYMBOL_VOLUME_MIN); double max_trade_volume = SymbolInfoDouble(Symbol(), SYMBOL_VOLUME_MAX); double min_trade_volume_step = SymbolInfoDouble(Symbol(), SYMBOL_VOLUME_STEP); double symbol_tick_size = SymbolInfoDouble(Symbol(), SYMBOL_TRADE_TICK_SIZE);
El algoritmo de funcionamiento del asesor experto se basa en el controlador del evento de llegada de un nuevo tick OnTick. A continuación se muestra un esquema simplificado del controlador:
// Procesamiento de un nuevo tick (si se cumplen todas las condiciones necesarias): if(is_bars_loaded_Flag == true && is_adr_levels_calculated_Flag == true && option_construstion_Ptr.IsOptionConstructionInited() == true) { if(SymbolInfoTick(Symbol(), tick) == true) { ask_option_construction_delta = option_construstion_Ptr.UpdateOptionConstructionDelta(tick.ask); bid_option_construction_delta = option_construstion_Ptr.UpdateOptionConstructionDelta(tick.bid); curr_option_construction_delta = option_construstion_Ptr.UpdateOptionConstructionDelta((tick.ask + tick.bid) / 2.0); if(is_first_ea_starting == true) { is_first_ea_starting = false; Print("CurrDelta : ", DoubleToString(curr_option_construction_delta, 3), " BidDelta : ", DoubleToString(bid_option_construction_delta, 3), " AskDelta : ", DoubleToString(ask_option_construction_delta, 3)); } // Calculamos el VOLUMEN DE POSICIÓN REQUERIDO actual, comprobando si ha cambiado el nivel de emulación de opciones: if(option_contruction_volume_Ptr.UpdateOptionLevel(curr_option_construction_delta, prev_option_level_value) == true) { // Signo actual del nivel de emulación de opciones (+1/0/-1): live_option_level_sign = option_contruction_volume_Ptr.GetOptionLevelSign(); // Valor actual (en valor absoluto) del nivel de emulación de opciones (0/1/2/3/4/5/6/7/8/9/10): live_option_level_value = option_contruction_volume_Ptr.GetOptionLevel(); // Es necesario modificar el volumen de la posición, es decir, reequilibrar la estructura de opciones: if(live_option_level_value > 0) { live_position_lots_abs = NormalizeLots(live_option_level_value * min_trade_volume_step * MinLotsMultiplier); } else { live_position_lots_abs = 0.0; } Print("#NEW LEVEL Position Volume : ", DoubleToString(live_option_level_value * live_option_level_sign * MinLotsMultiplier, 1), " CurrDelta : ", DoubleToString(curr_option_construction_delta, 3), " Levels Prev/Live: ", prev_option_level_value, "/", live_option_level_value); // Si estamos en el modo «STARTED», ajustaremos el volumen total de la posición virtual y de la real: if(current_trade_mode_state == ENUM_TRADE_MODE_STARTED) { // Si el valor del NIVEL de emulación de opciones HA AUMENTADO, significa que hay que añadir posiciones en los nuevos niveles: if(live_option_level_value > prev_option_level_value) { // Posiciones BUY: if(live_option_level_sign == 1) { // Si aún no ha transcurrido el intervalo para colocar nuevas órdenes: if(CheckAddingNew(tick.time) == true) { // Colocaremos órdenes reales en los nuevos niveles: OpenBuyLevels(live_option_level_value, live_option_level_value - prev_option_level_value); } } // Posiciones SELL: else if(live_option_level_sign == -1) { // Si está permitido el trading: if(is_trade_allowed_Flag == true) { // Si aún no ha transcurrido el intervalo para colocar nuevas órdenes: if(CheckAddingNew(tick.time) == true) { // Colocaremos órdenes reales en los nuevos niveles: OpenSellLevels(live_option_level_value, live_option_level_value - prev_option_level_value); } } } prev_option_level_value = live_option_level_value; prev_option_level_sign = live_option_level_sign; } // Si el valor del NIVEL de emulación de opciones HA DISMINUIDO, significa que hay que cerrar parte o la totalidad de las posiciones en los niveles anteriores: else if(live_option_level_value < prev_option_level_value) { // Posiciones BUY: if(live_option_level_sign == 1) { // Si está permitido el trading: if(is_trade_allowed_Flag == true) { for(int curr_level = prev_option_level_value; curr_level > live_option_level_value; curr_level--) { CloseLevelPositions(Symbol(), POSITION_TYPE_BUY, curr_level); } } } // Posiciones SELL: else if(live_option_level_sign == -1) { // Si está permitido el trading: if(is_trade_allowed_Flag == true) { for(int curr_level = prev_option_level_value; curr_level > live_option_level_value; curr_level--) { CloseLevelPositions(Symbol(), POSITION_TYPE_SELL, curr_level); } } } // El valor actual (en valor absoluto) del nivel de delta en la emulación de opciones ha pasado a ser CERO (hay que cerrar todas las posiciones): else if(live_option_level_sign == 0) { // Si está permitido el trading: if(is_trade_allowed_Flag == true) { if(prev_option_level_sign == 1) { for(int curr_level = prev_option_level_value; curr_level > live_option_level_value; curr_level--) { CloseLevelPositions(Symbol(), POSITION_TYPE_BUY, curr_level); } } else if(prev_option_level_sign == -1) { for(int curr_level = prev_option_level_value; curr_level > live_option_level_value; curr_level--) { CloseLevelPositions(Symbol(), POSITION_TYPE_SELL, curr_level); } } } live_position_lots_abs = 0.0; live_option_level_sign = 0; } } } prev_option_level_value = live_option_level_value; prev_option_level_sign = live_option_level_sign; } } } }
Realizamos el seguimiento del cambio del nivel de emulación de opciones llamando al método UpdateOptionLevel: si el nivel ha cambiado, este método devuelve «verdadero». Aquí comparamos el valor actual y el anterior (en el tick anterior) de los niveles de emulación de opciones.
Si es necesario reequilibrar las posiciones, comprobamos si el nivel de emulación de opciones ha aumentado o disminuido. Si ha aumentado, se requiere añadir posiciones. Si ha disminuido, es necesario cerrar parte de las posiciones. Si el nivel de emulación pasa a ser cero, cerramos todas las posiciones abiertas. De este modo se reequilibra la posición global.
Cabe señalar que, para calcular el delta actual de la estructura de opciones, tomamos la media entre Bid y Ask. Esto permite reducir la dependencia de las variaciones del delta respecto a las variaciones del spread. El código completo del asesor experto puede consultarse en los archivos adjuntos a este artículo.
Para abrir y cerrar posiciones se utilizan órdenes de mercado. Esto se ha hecho para facilitar la comprobación del funcionamiento del asesor experto (se asegura la ejecución de las órdenes). En el futuro, se recomienda (y así se hará) pasar a utilizar órdenes límite para abrir posiciones. Esto permitirá reducir los costes por comisiones y mejorará los resultados del trading al eliminar el spread al entrar en posiciones.
Comprobamos en tiempo real la emulación y el trading
Supongamos que hemos decidido que, durante el día, el precio de EURUSD se moverá principalmente al alza. Establezcamos el tipo de estructura de opciones OptionConstruction = ENUM_OPTION_CONSTRUCTION_RISING. En las siguientes figuras se muestra un ejemplo del funcionamiento de un asesor experto que emula la estructura de opciones Base Active Rising - Long CALL: fig. 1 — desde la apertura del día; fig. 2 — detalle del tramo de trading. Se abrieron los niveles de emulación del 1 al 9. Al inicio del funcionamiento del asesor experto, se llevó a cabo un reequilibrio de los niveles:

Fig. 1. Funcionamiento de la estructura de opciones Base Active Rising - Long CALL — vista general.

Fig. 2. Funcionamiento de la estructura de opciones Base Active Rising - Long CALL — vista ampliada.

Fig. 3. Estado actual de las posiciones en la emulación de la estructura de opciones Base Active Rising - Long CALL

Fig. 4. Resultado del reequilibrio en la emulación de la estructura de opciones Base Active Rising - Long CALL en forma de operaciones de la historia de trading
Ahora supongamos que al día siguiente decidimos que el precio cambiará de tendencia y bajará. Establezcamos el tipo de estructura de opciones OptionConstruction = ENUM_OPTION_CONSTRUCTION_FALLING. Esta vez la suerte nos dio la espalda: hacia el final del día, el precio se giró en nuestra contra y sufrimos cierta pérdida. En la fig. 5 vemos la ejecución de la estructura de opciones especificada. Se abrieron los niveles de emulación del 1 al 5. En este caso, el importe de la pérdida realizada debido al reequilibrio ha sido de -5,77 USD; véase la fig. 6.

Fig. 5. Funcionamiento de la estructura de opciones Base Active Rising - Long Put — vista general

Fig. 6. Resultado del reequilibrio en la emulación de la estructura de opciones Base Active Rising - Long Put en forma de operaciones de la historia de trading
El volumen total máximo de las posiciones puede alcanzar el valor 0,1 = 10 niveles * 0,01; este es el volumen objetivo de la estructura de opciones cuando el multiplicador del lote mínimo es igual a uno. Como se puede ver en la fig. 4, tras el reequilibrio de la estructura de opciones hemos obtenido una pérdida fijada de -2,39 USD en el primer caso y de -5,77 USD en el segundo (véase la fig. 6). Es el equivalente a la prima pagada por la compra de una opción. Tal y como se ha establecido en el parámetro de entrada del asesor experto ForceAutoExpirationTime = «23:50», a las 23:50 se produjo el vencimiento de la estructura de opciones, con lo que se registró un resultado positivo en el primer caso. Está claro que el resultado del trading depende de la situación concreta del mercado y de nuestras acciones.
Conclusión
Hoy hemos analizado la implementación práctica de un asesor experto que emula una estructura de opciones determinada. Asimismo, hemos comprobado que la práctica se ajusta a los principios teóricos expuestos en el primer artículo de esta serie. En el próximo artículo analizaremos la implementación de estrategias de opciones que tienen un valor práctico real, y que son utilizadas por tráders profesionales de opciones.
Traducción del ruso hecha por MetaQuotes Ltd.
Artículo original: https://www.mql5.com/ru/articles/18363
Advertencia: todos los derechos de estos materiales pertenecen a MetaQuotes Ltd. Queda totalmente prohibido el copiado total o parcial.
Este artículo ha sido escrito por un usuario del sitio web y refleja su punto de vista personal. MetaQuotes Ltd. no se responsabiliza de la exactitud de la información ofrecida, ni de las posibles consecuencias del uso de las soluciones, estrategias o recomendaciones descritas.
Utilizando redes neuronales en MetaTrader
Cómo creamos la plataforma de trading más potente con aprendizaje automático: crónica del desarrollo de MQL y MetaTrader según los archivos, foros y lanzamientos
Particularidades del trabajo con números del tipo double en MQL4
Desarrollo de un kit de herramientas para el análisis de la acción del precio (Parte 30): Commodity Channel Index (CCI), Zero Line EA
- 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
¡Buenos días!
Por supuesto que es interesante.
¡PERO!
Tú:
--> Supongamos que hemos decidido que, a lo largo del día, el precio del EUR/USD se moverá principalmente al alza...
---> Ahora supongamos que al día siguiente decidimos que el precio dará un giro y bajará...
De nuevo, un «lanzamiento de moneda» que, en última instancia, acabará inevitablemente con la pérdida del depósito.
Tú, Dmitri, has hecho un gran trabajo, pero eso no te llevará a obtener ingresos estables.
Añadido
Hace tiempo realicé un experimento.
Tomé un periodo anual de velas M1 y, al principio, compraba al abrirse la vela y vendía al cerrarse, y así durante todo el año.
El resultado fue una gran pérdida.
Después cambié la compra por la venta, y la venta por la compra, y volví a hacerlo durante todo el año. Y...
¡obtuve una gran pérdida! :)
Añadido
Operaciones con una cartera de cobertura compuesta por futuros sobre todas las acciones del MOEX.
Riesgos +85/-15 %
Un -15 % porque podrían anunciar dividendos de forma inesperada
Hace 9 días
Hoy
Estoy trabajando a fondo para reducir el -15 %
Bueno, no hay estrategias de mercado que garanticen unos ingresos estables. Ni siquiera la tuya, y menos aún en las circunstancias actuales, en las que no se sabe qué nos deparará el mañana. Por eso, solo se puede sacar algo de beneficio intradía, sin posiciones abiertas de un día para otro; todo esto es mi humilde opinión.
En tu caso, con el HFT, los principales beneficios provienen del par «acción — futuros sobre esa acción», ¿lo he entendido bien?
Bueno, no hay estrategias de mercado que garanticen unos ingresos estables. Ni siquiera la tuya, y menos aún en las circunstancias actuales, en las que no se sabe qué nos deparará el mañana. Por eso, solo se puede sacar algo de beneficio en operaciones intradía, sin posiciones abiertas de un día para otro; todo esto es mi humilde opinión.
En su caso, con el HFT, los principales beneficios provienen del par «acción — futuros sobre dicha acción», ¿lo he entendido bien?
No, debido a que Finam no ofrece descuento por las acciones compradas, ahora mismo no utilizo esa estrategia «de oro» con un 100 % de rentabilidad.
Ahora solo opero con una cartera de futuros de cobertura para absolutamente todas las acciones de MOEH.
---> Así que no hay estrategias de mercado que garanticen unos ingresos estables.
Simplemente aún no las conoces...
Nadie, ni siquiera yo, te las va a contar.
Añadido
Cualquier estrategia de cobertura debe generar beneficios constantes.
Hay cinco factores importantes
1. Riesgos
2. Una correcta implementación
3. Rapidez en la ejecución de las órdenes de negociación
4. La codicia del operador (a algunos les basta con un 50 % anual, mientras que a otros ni siquiera un 500 % les parece suficiente; por eso, el 99 % de los operadores pierden dinero...)
5. Operar ÚNICAMENTE mediante robots (el factor humano debe excluirse por completo)¿Qué hay que saber al respecto?
Esperas a que se produzca la máxima divergencia (en sentido estadístico) entre la acción y el futuro, compras la acción en ese momento y vendes el futuro. Esperas a que venza el contrato. Con un capital elevado, es una estrategia que funciona bastante bien. Pero también tiene sus riesgos.
Antes, dentro de un mismo día (o días), comprabas o vendías aprovechando la divergencia o la convergencia, y quizá solo cerrabas una de las posiciones.
¿Por qué no lo haces ahora? Al parecer, falta liquidez.
Por sí mismas, las opciones y las estrategias con opciones no generan ningún beneficio. Es igual que en el mercado de divisas: 50/50. La matemática es la misma: una distribución normal de probabilidades.
Las opciones solo pueden generar beneficios (sin riesgo) si se utilizan conjuntamente con futuros o acciones.