Negociamos con opciones sin opciones (Parte 3): Estrategias complejas con opciones
Introducción
En el artículo anterior de esta serie, analizamos las estrategias básicas con opciones y comprobamos su rendimiento en el mercado real. Creamos un asesor experto que implementa una estrategia de opciones. Ahora es el momento de analizar las estrategias que utilizan los operadores de opciones en la práctica y aplicarlas. Esto nos permitirá explorar las nuevas oportunidades que ofrece la negociación de opciones.
Visualización de los niveles de opción
Antes de continuar, vamos a añadir al asesor experto la función de mostrar los niveles de opción actuales. Para facilitar el seguimiento visual del proceso de negociación, sería útil ver en el terminal la posición del precio actual del activo subyacente con respecto a los niveles de opción utilizados en la simulación. Además, pondremos a prueba las estrategias con opciones que se han analizado en la parte 2.
Mostraremos los niveles de opción como líneas que se extienden desde el inicio de la jornada hasta el momento actual. También sería útil que los precios de ejercicio aparecieran en la pantalla del terminal. En primer lugar, definamos el método CalculateLevelPrice. De hecho, este método realiza la operación inversa: calcula el precio relativo a partir de un valor dado de la delta de la opción. A partir del precio relativo, obtendremos un valor de precio absoluto específico para cada nivel de opción.
Añadamos los métodos abstractos TOptionConstructionBase::CalculateUpLevelPrice y TOptionConstructionBase::CalculateDnLevelPrice y definámoslos en las clases derivadas. Examinemos con más detalle estos métodos de cálculo.
¿Por qué hay dos métodos? Esto se hace porque la delta variará en función de si el precio del activo subyacente está por encima o por debajo del precio de ejercicio. Por eso tenemos en cuenta todos los casos posibles. Los argumentos de los métodos TOptionConstructionBase::CalculateUpLevelPrice y TOptionConstructionBase::CalculateDnLevelPrice son los siguientes:
- _strike_price — precio de ejercicio;
- _norm_price: el precio normalizado en función de un rango de volatilidad;
- _limit_price: el precio máximo o mínimo para un intervalo al realizar una búsqueda mediante el método de bisección (que suele ser igual al precio de normalización), por encima o por debajo del precio de ejercicio, respectivamente;
- _target_delta — el valor objetivo de la delta de la estructura de opciones para la que se busca el nivel de precio.
NOTA:
Dado que la función sigmoide se aproxima a cero y a uno (o a menos uno) de forma exponencial, pero nunca llega a alcanzarlos, utilizamos valores cercanos a cero y a uno para definir explícitamente los niveles de opción correspondientes al nivel cero y al máximo (por ejemplo, el décimo).
Para el nivel cero, tomamos una delta igual a _norm_zero_level con el signo correspondiente. Para el nivel máximo, utilizamos un valor de delta de ±0,96 (determinado empíricamente) con el signo correspondiente. En este caso, limitaremos el rango del valor _norm_zero_level a un intervalo comprendido entre 0,01 y 0,05 (téngase en cuenta que el primer nivel de emulación de opciones corresponde a una delta de ±0,1).
El código de estos métodos es el siguiente:
// --------------------------------------------------------------------- // Calculate price levels corresponding to the upper option levels: // --------------------------------------------------------------------- void CalculateUpPriceLevels(const double _norm_zero_level, double& _strike_price[], double& _norm_price[], double& _limit_price[]) override { // If the array has zero size, there are no levels: if(ArraySize(this.up_level_values_Array) == 0) { ArrayResize(this.up_price_level_Array, 0); return; } // Zero and last levels are set separately: this.up_level_values_Array[0] = _norm_zero_level; this.up_level_values_Array[10] = 0.96; ArrayResize(this.up_price_level_Array, this.emulation_levels_number + 1); // Main levels: for (int i = 0; i <= this.emulation_levels_number; i++) { this.up_price_level_Array[i] = this.CalculateUpLevelPrice(_strike_price[1], _norm_price[1], _limit_price[1], this.up_level_values_Array[i]); } } // --------------------------------------------------------------------- // Calculate price level for the specified normalized delta: // --------------------------------------------------------------------- double CalculateUpLevelPrice(const double _strike_price, const double _norm_price, const double _limit_price, const double _target_delta) override { double low_limit = _strike_price; double up_limit = _limit_price; double half_point = (low_limit + up_limit) / 2.0; double curr_point = this.UpdateOptionConstructionDelta(half_point); // Till the error (segment length) exceeds the specified one, continue dividing the segment: while (MathAbs(search_point - _target_delta) > this.tolerance) { // Evaluate the position of the current (average) point relative to the target one: if(curr_point > _target_delta) { up_limit = half_point; } else if(fc < _target_delta) { low_limit = half_point; } else { return (half_point); } // Next middle point on the segment: half_point = (low_limit + up_limit) / 2.0; curr_point = this.UpdateOptionConstructionDelta(half_point); } return (low_limit + up_limit) / 2.0; }
El método TOptionConstructionBase::CalculateUpPriceLevels recorre todos los valores de los niveles de emulación de opciones y llama al método TOptionConstructionBase::CalculateUpLevelPrice, que calcula el precio correspondiente a la delta especificada.
Para este cálculo, utilizaremos el método de bisección (método de dicotomía) para evitar resolver la ecuación sigmoide de forma analítica. Esto es posible porque la sigmoide es una función continua y monótona del precio y, dentro del rango de funcionamiento de la estructura de opciones (donde se produce el rebalanceo principal), la suma de las sigmoides también es monótona.
La figura 1 ilustra esquemáticamente el proceso iterativo (los tres primeros pasos: paso 1, …, paso 3) para hallar un punto dentro de un segmento (el valor target en la fig. 1). El método consiste en determinar sucesivamente en qué mitad del intervalo [up_limit; low_limit] se encuentra el punto de interés target. Una vez determinado esto, desplazamos el límite del segmento (en este caso, el límite superior up_limit en los tres primeros pasos) hasta el punto medio del intervalo:
half_point = (up_limit + low_limit) / 2 ---> up_limit = half_point
Repita este procedimiento hasta que la longitud del segmento, igual a (up_limit - low_limit), sea menor o igual que la tolerancia especificada en _tolerance.
En este caso, el valor que buscamos será igual al último valor de half_point. La distancia entre el valor que buscamos y target no superará la precisión especificada. Este procedimiento para calcular los niveles de opción se ejecutará una vez al día, al comienzo de cada nueva jornada o cuando se inicie el asesor experto.

Fig. 1: Algoritmo para localizar un punto dentro de un segmento de recta
Tras aplicar el método CalculateUpLevelPrice a todos los valores de los niveles de opción (0, 1, ..., 10), obtenemos una matriz de valores de precio correspondientes a estos niveles: los niveles de opción por encima del precio de ejercicio. Para calcular los niveles de opción por debajo del precio de ejercicio, se utiliza el método CalculateDnLevelPrice (véase el archivo OptionEmulatorA3.mqh). La búsqueda se realiza de la misma manera; la diferencia radica en que los niveles de opción se representan gráficamente hacia abajo a lo largo de la escala de precios, partiendo del precio de ejercicio. En general, los niveles inferior y superior no son necesariamente simétricos.
Ahora vamos a representar los niveles de opción en el gráfico del terminal MetaTrader 5. Para ello, crearemos dos clases: una que encapsule el nivel en sí y otra para manipular la lista de niveles. A continuación se muestra la clase de visualización de niveles:
// ===================================================================== // Base class of the option level - derived from CObject: // ===================================================================== #define DESTROY_OBJECT(object) { if(CheckPointer(object) == POINTER_DYNAMIC) delete(object); } // --------------------------------------------------------------------- class TPriceLevelBase : public CObject { private: long chart_id; int window; string trend_name; string text_name; double price; protected: CChartObjectTrend* trend; CChartObjectText* text; public: // --------------------------------------------------------------------- // Constructor: // --------------------------------------------------------------------- TPriceLevelBase(long _chart_id, const int _window) : chart_id(_chart_id), window(_window), trend_name(GetUniqIdentString()), text_name(GetUniqIdentString()), CObject() { this.trend = new CChartObjectTrend(); this.text = new CChartObjectText(); } // --------------------------------------------------------------------- // Destructor: // --------------------------------------------------------------------- ~TPriceLevelBase() { DESTROY_OBJECT(this.trend); DESTROY_OBJECT(this.text); } // --------------------------------------------------------------------- // Create object: // --------------------------------------------------------------------- void Create(const datetime _time1, const datetime _time2, const double _price, const string _text, const int _font_size, const color _color1, const color _color2, const int _width, const ENUM_LINE_STYLE _style) { this.price = _price; this.trend.Background(false); this.trend.Create(this.chart_id, this.trend_name, this.window, _time1, _price, _time2, _price); this.trend.Width(_width); this.trend.Style(_style); this.trend.RayRight(false); this.trend.Color(_color1); this.text.Create(this.chart_id, this.text_name, this.window, _time2 + 15 * 60, _price); this.text.Description(_text); this.text.FontSize(_font_size); this.text.Anchor(ANCHOR_LEFT); this.text.Background(false); this.text.Color(_color2); } // --------------------------------------------------------------------- // Update the object: // --------------------------------------------------------------------- void Update(const datetime _time) { this.text.SetPoint(0, _time + 15 * 60, this.price); this.trend.SetPoint(1, _time, this.price); } }; // ---------------------------------------------------------------------
Como podemos ver, la clase TPriceLevelBase deriva de la clase estándar CObject. Esto se hace para que se pueda utilizar una clase estándar para manipular la lista. Más información al respecto a continuación. Un objeto «nivel» representa un segmento horizontal que se extiende desde la apertura de la jornada hasta el momento actual. A la derecha de la línea, mostraremos una etiqueta de texto: el número de nivel.
Los miembros de datos que encapsulan las propiedades del objeto «nivel» son las propiedades estándar de los objetos gráficos «línea» y «etiqueta de texto» del gráfico del terminal MetaTrader 5. Su finalidad es la siguiente:
- long chart_id — el ID del gráfico en el que se encuentra el objeto gráfico;
- int window — el ID de la subventana del gráfico que contiene el objeto gráfico; en este caso, cero para la ventana principal del gráfico;
- string trend_name — el nombre del objeto «línea» para identificarlo entre otros objetos similares del gráfico;
- string text_name — el nombre del objeto «texto» para identificarlo entre otros objetos similares del gráfico;
- double price — el valor del nivel de precio en el que se encuentran los objetos: un segmento horizontal y una etiqueta de texto;
- CChartObjectTrend* trend — el puntero al objeto gráfico «línea» de la biblioteca estándar de MetaTrader 5;
- CChartObjectText* text — el puntero al objeto gráfico «etiqueta de texto» de la biblioteca estándar de MetaTrader 5.
Los niveles se actualizan cuando aparece una nueva barra en el gráfico de MetaTrader 5. Al comienzo de un nuevo día, se eliminan los niveles anteriores y se empiezan a trazar los nuevos para el día en curso. Antes de eso, se vuelve a calcular la volatilidad histórica (HV) para el nuevo día.
Los niveles intradía se actualizan cuando se invoca el método TPriceLevelBase::Update(const datetime _time); su argumento es la hora de apertura de la barra actual. La coordenada temporal de la etiqueta de texto se desplaza más hacia la derecha para que no se superponga con la línea de nivel.
A continuación se muestra la clase para manipular la lista TVisualPriceLevels:
// ===================================================================== // Visualize rebalancing levels for an option structure: // ===================================================================== class TVisualPriceLevels : public CList { private: long chart_id; int window; public: // --------------------------------------------------------------------- // Destructor: // --------------------------------------------------------------------- ~TVisualPriceLevels() { this.Clear(); } // --------------------------------------------------------------------- // Constructor: // --------------------------------------------------------------------- TVisualPriceLevels(const long _chart_id, const int _window) : chart_id(_chart_id), window(_window), CList() { this.FreeMode(true); } // --------------------------------------------------------------------- // Add a level: // --------------------------------------------------------------------- void AddLevel(const datetime _time1, const datetime _time2, const double _price, const string _text, const int _font_size, const color _color1, const color _color2, const int _width, const ENUM_LINE_STYLE _style) { TPriceLevelBase* new_level = new TPriceLevelBase(this.chart_id, this.window); new_level.Create(_time1, _time2, _price, _text, _font_size, _color1, _color2, _width, _style); this.Add(new_level); } // --------------------------------------------------------------------- // Update levels: // --------------------------------------------------------------------- void Update(const datetime _time) { if(this.Total() > 0) { TPriceLevelBase* trend = this.GetFirstNode(); while(trend != NULL) { trend.Update(_time); trend = this.GetNextNode(); } } } }; // ---------------------------------------------------------------------
Al igual que en la clase TPriceLevelBase, aquí también hay un método llamado TVisualPriceLevels::Update(const datetime _time), que actualiza todos los niveles añadidos a la lista iterando por los objetos y llamando al método TPriceLevelBase::Update(const datetime _time) en cada uno de ellos.
Se ha añadido el método TVisualPriceLevels::AddLevel, con parámetros que especifican la posición y el estilo de la línea (para un nivel de opción) o de la etiqueta de texto. Este método crea un objeto de tipo TPriceLevelBase y lo añade a la lista llamando al método CList::Add de la clase estándar CList.
Además, añadiremos nuevos parámetros de entrada al archivo principal del asesor experto («Article3-OptionTrader.mq5») para configurar las propiedades de los niveles que se muestran en pantalla: el color de la etiqueta de texto, el color de la línea y el estilo de la línea. Podemos configurar los parámetros de las líneas y las etiquetas de texto por separado para el precio de ejercicio y los niveles de rebalanceo al alza y a la baja.
// --------------------------------------------------------------------- input color StrikeLevelTextColor = clrYellow; // Strike Level Text Color input color StrikeLevelColor = clrYellow; // Strike Level Color input ENUM_LINE_STYLE StrikeLevelStyle = STYLE_SOLID; // Strike Level Line Style input color OptionUpLevelsTextColor = clrYellow; // Option Up Levels Text Color input color OptionUpLevelsColor = clrLightGreen; // Option Up Levels Color input ENUM_LINE_STYLE OptionUpLevelsStyle = STYLE_DOT; // Option Up Levels Line Style input color OptionDnLevelsTextColor = clrYellow; // Option Dn Levels Text Color input color OptionDnLevelsColor = clrLightPink; // Option Dn Levels Color input ENUM_LINE_STYLE OptionDnLevelsStyle = STYLE_DOT; // Option Dn Levels Line Style // --------------------------------------------------------------------
Los resultados del trabajo realizado por la parte del asesor experto encargada de la visualización de niveles se muestran en la fig. 2. La distribución no lineal de los niveles de opción a lo largo de la escala de precios es claramente visible, como consecuencia de la fórmula de Black-Scholes. En este caso, el precio de ejercicio es el precio de apertura de la jornada. En el caso de estructuras de opciones más complejas, puede haber varios precios de ejercicio, y sus valores pueden diferir del precio de apertura.

Fig. 2. Visualización de los niveles de opción
Estrategias complejas con opciones
Ahora vamos a añadir algunas estrategias nuevas a nuestra lista de estructuras de opciones:
// --------------------------------------------------------------------- // Option construction: // --------------------------------------------------------------------- enum ENUM_OPTION_CONSTRUCTION { ENUM_OPTION_CONSTRUCTION_STRADDLE_LONG = 5, // Long STRADDLE ENUM_OPTION_CONSTRUCTION_STRADDLE_SHORT = 6, // Short STRADDLE ENUM_OPTION_CONSTRUCTION_STRANGLE_LONG = 7, // Long STRANGLE ENUM_OPTION_CONSTRUCTION_STRANGLE_SHORT = 8, // Short STRANGLE }; // --------------------------------------------------------------------
Analicemos el objetivo y las condiciones de uso de las nuevas estrategias mencionadas anteriormente.
Compra de un straddle — straddle comprado
- Significado: la compra simultánea de una opción de compra (call) y una opción de venta (put) con el mismo precio de ejercicio;
- Condición de uso: si se confía en que el precio del activo subyacente subirá o bajará más allá del rango de volatilidad histórica (HV), pero no se hacen suposiciones sobre la dirección;
- Beneficios: ilimitados;
- Riesgo: la prima pagada por dos opciones (no se paga prima en la emulación) + la pérdida sufrida durante el rebalanceo de la estrategia de opciones.
En la figura 3 se muestra la relación entre la delta de la estructura de opciones (Delta) y la variación relativa del precio (DPrice). Esta relación se produce cuando compramos dos opciones con el mismo precio de ejercicio: la compra de una opción de venta y la compra de una opción de compra. La tabla situada a la izquierda del gráfico recoge los valores de DPrice (x en la tabla) a los que se realiza el rebalanceo de la estructura de opciones.

Fig. 3. Relación entre el valor de Delta y la variación relativa de DPrice (x, tal como se muestra en la tabla) para la estrategia de opciones straddle comprado emulada. S = 0,5, K = 10. El rango de delta se divide en diez partes iguales
En la figura 4 se muestra un gráfico ilustrativo que refleja la relación entre el beneficio/pérdida (PnL) y la variación relativa del precio. Es importante tener en cuenta que este gráfico es una representación teórica basada en la volatilidad histórica media (HV) del precio del activo subyacente. El riesgo depende en gran medida del número de rebalanceos de la estrategia de opciones, ya que cada rebalanceo contribuye al PnL total, pudiendo generar tanto beneficios como pérdidas. Esta es la principal diferencia entre una opción emulada y una real.
El gráfico muestra que pueden obtenerse mayores beneficios cuando el precio del activo subyacente se desplaza considerablemente fuera del rango de volatilidad histórica (HV), especialmente si no se producen fluctuaciones frecuentes entre los niveles de opción. Las zonas resaltadas en verde ilustran este comportamiento.
El lado izquierdo del eje DPrice (DPrice < 0) corresponde a una caída del precio del activo subyacente con respecto al precio de ejercicio; está marcado por una flecha que apunta hacia la izquierda con la indicación «Área de actuación de la compra de una opción de venta, compra de una opción de compra = 0» (el área de actuación de la compra de una opción de venta). En esta región, el modelo de emulación considera nula la contribución de la opción de compra (call) a la delta de la posición conjunta.
El lado derecho del eje DPrice (DPrice > 0) corresponde a un aumento del precio del activo subyacente con respecto al precio de ejercicio; está marcado por una flecha que apunta hacia la derecha con la indicación «Área de actuación de la compra de una opción de compra, compra de una opción de venta = 0» (el área de actuación de la compra de una opción de compra). En esta región, la delta de la compra de una opción de venta es cero; es decir, no tiene ningún efecto en la simulación de la posición conjunta en opciones.
El gráfico también muestra el beneficio (Profit), la pérdida (Loss) y el precio de ejercicio (Strike).

Fig. 4: Relación entre el valor «PnL» (beneficio/pérdida) y la variación relativa del precio (DPrice) para una estrategia de opciones straddle comprado simulada.
En la figura 5 se muestra un ejemplo de cómo funciona la estrategia de opciones straddle comprado. En este caso, la estructura de opciones se mantuvo hasta su vencimiento. Dado que el precio fluctuó dentro del rango de volatilidad y, al cierre de la jornada, casi había vuelto al precio de apertura, se registró una pequeña pérdida.
El gráfico también muestra que, alrededor de las 15:00 h, el precio del activo subyacente alcanzó el séptimo nivel de emulación, lo que habría permitido cerrar anticipadamente las posiciones de la estrategia emulada y asegurar un beneficio. A diferencia de lo que ocurre con las opciones reales, no habría problemas de liquidez.

Fig. 5. Estrategia de opciones straddle comprado
Venta de un straddle — straddle vendido
- Significado: La venta simultánea de opciones de compra y de venta con los mismos precios de ejercicio;
- Condición de uso: Si se tiene la certeza de que el precio del activo subyacente se mantiene dentro del rango medio de su volatilidad histórica (HV), siendo irrelevante la dirección del movimiento del precio;
- Beneficio: La prima pagada por el comprador por las dos opciones (no aplicable en la emulación) + el beneficio acumulado cuando el precio fluctúa dentro del rango (aplicable únicamente en la emulación);
- Riesgo: ilimitado.
En la figura 6 se muestra la relación entre la delta de la estructura de opciones y la variación relativa de DPrice. Esta relación se produce al vender dos opciones con el mismo precio de ejercicio: una opción de venta y una opción de compra. La tabla situada a la izquierda del gráfico recoge los valores de DPrice (x en la tabla) en los que se realiza el rebalanceo de la estructura de opciones.

Fig. 6. Relación entre el valor de delta y la variación relativa del precio DPrice (x en la tabla) para la estructura de opciones de straddle vendido emulada. S = 0,5, K = 10. El rango de delta se divide en diez partes iguales
La fig. 7 muestra un gráfico aproximado que ilustra la relación entre el beneficio/pérdida (PnL) y la variación relativa del precio. Es importante tener en cuenta que este gráfico es una representación teórica basada en la volatilidad histórica media (HV) del precio del activo subyacente. Esta es la principal diferencia entre una opción simulada y una real.
El gráfico muestra que se obtiene un beneficio si el precio del activo subyacente se mantiene dentro del rango de volatilidad histórica (HV), que aparece sombreado en verde en la figura. Cuanto mayores sean las fluctuaciones del precio entre los niveles de opción, mayor será el beneficio al vencimiento (sin embargo, para maximizar el beneficio, el precio debería volver a situarse lo más cerca posible del precio de ejercicio). La dirección de las fluctuaciones con respecto al precio de ejercicio es irrelevante: obtenemos una configuración casi ideal para la operativa en rango.
Si el precio del activo subyacente se sitúa fuera del rango de volatilidad histórica (HV) y se mantiene ahí hasta el vencimiento, incurriremos en una pérdida. Cuanto más se aleje el precio de ese rango, mayor será la pérdida. En teoría, el riesgo es ilimitado. En realidad, siempre podemos cerrar nuestras posiciones y detener el funcionamiento del asesor experto. Existen estructuras de opciones más complejas que reducen automáticamente el riesgo a un nivel aceptable y que prácticamente no afectan a los beneficios. Más información al respecto en el próximo artículo.
El lado izquierdo del eje DPrice (DPrice < 0) corresponde a una caída del precio del activo subyacente con respecto al precio de ejercicio; está marcado por una flecha que apunta hacia la izquierda con la etiqueta «Área de trabajo de la venta de una opción de venta, venta de una opción de compra = 0» (área de trabajo de la venta de una opción de venta). En esta región, la delta de la venta de una opción de compra es cero, lo que significa que no tiene ningún efecto en la simulación de la posición conjunta en opciones.
El lado derecho del eje DPrice (DPrice > 0) corresponde a un aumento del precio del activo subyacente con respecto al precio de ejercicio; se indica mediante una flecha que apunta hacia la derecha con la etiqueta «Área de trabajo de la venta de una opción de compra, venta de una opción de venta = 0» (área de trabajo de la venta de una opción de compra). En esta región, la delta de la venta de una opción de venta es cero; es decir, no tiene ningún efecto en la simulación de la posición conjunta en opciones.
El gráfico también muestra el beneficio (Profit), la pérdida (Loss) y el precio de ejercicio (Strike).

Fig. 7. Relación entre el valor de PnL (beneficio/pérdida) y la variación relativa del precio (DPrice) para la estrategia simulada de opciones strangle vendido
En la figura 8 se muestra un ejemplo de cómo funciona la estrategia de opciones straddle vendido. El nivel más alto alcanzado durante el rebalanceo intradía de la posición en opciones fue el noveno. El gráfico muestra cómo los rebalanceos realizados durante las fluctuaciones del precio del activo subyacente entre los niveles de opción pueden contribuir a la obtención de beneficios. Al final del día, antes del vencimiento, todas las posiciones se habían cerrado, ya que la variación relativa del precio (DPrice) había vuelto prácticamente a cero. En este caso, nuestra previsión de que el precio se mantendría dentro de un determinado rango resultó ser totalmente acertada. Evidentemente, no siempre es así.

Fig. 8. Estrategia de opciones straddle vendido
Compra de un strangle — strangle comprado
- Significado: La compra simultánea de opciones de compra y de venta con diferentes precios de ejercicio que se encuentran dentro del rango de la volatilidad histórica (HV);
- Condición de uso: Si se tiene la certeza de que el precio del activo subyacente variará de forma significativa, pero se desconoce en qué dirección lo hará;
- Beneficios: ilimitados;
- Riesgo: la prima pagada por dos opciones (no se paga prima en la emulación) + la pérdida sufrida durante el rebalanceo de la estrategia de opciones.
La diferencia con respecto a un straddle comprado es que esta estrategia utiliza dos precios de ejercicio: uno para la región negativa de DPrice y otro para la región positiva. Entre ambos precios de ejercicio, la exposición simulada al activo subyacente es nula; por lo tanto, mientras no se realicen nuevas operaciones, el PnL de la estrategia emulada permanece sin cambios.
En la figura 9 se muestra un gráfico aproximado que ilustra la relación entre el PnL (beneficio/pérdida) y la variación relativa del precio. Es importante tener en cuenta que este gráfico es una representación teórica basada en la volatilidad histórica media (HV) del precio del activo subyacente. El riesgo depende en gran medida del número de rebalanceos de la estrategia de opciones, ya que cada rebalanceo contribuye al PnL total, pudiendo generar tanto beneficios como pérdidas. Esta es la principal diferencia entre una opción simulada y una real.
El lado izquierdo del eje DPrice (DPrice < 0) corresponde a una caída del precio del activo subyacente con respecto al precio de ejercicio Strike1; está marcado con una flecha que apunta hacia la izquierda y lleva la etiqueta «Área de actuación de la compra de una opción de venta, compra de una opción de compra = 0» (el área de actuación de la compra de una opción de venta). En esta región, el modelo de emulación considera nula la contribución de la opción de compra (call) a la delta de la posición conjunta.
El lado derecho del eje DPrice (DPrice > 0) corresponde a un aumento del precio del activo subyacente con respecto al precio de ejercicio Strike2; está marcado con una flecha que apunta hacia la derecha y lleva la etiqueta «Área de actuación de la compra de una opción de compra, compra de una opción de venta = 0» (el área de actuación de la compra de una opción de compra). En esta región, la delta de la compra de una opción de venta es cero; es decir, no tiene ningún efecto en la simulación de la posición conjunta en opciones.
El gráfico muestra que el beneficio máximo se alcanza cuando el precio del activo subyacente se sitúa fuera del rango de volatilidad histórica (HV) (o, como mínimo, no fluctúa con frecuencia entre los precios de ejercicio de las opciones); las zonas resaltadas en verde en la figura ilustran este fenómeno. Las fluctuaciones del precio entre los precios de ejercicio no afectan al beneficio ni a la pérdida, ya que la delta de ambas opciones es cero en este rango.
El gráfico también muestra las zonas de beneficio (Profit) y pérdida (Loss), así como los precios de ejercicio (Strike1 y Strike2).

Fig. 9. Relación entre el valor de PnL (beneficio/pérdida) y la variación relativa del precio (DPrice) para la estrategia simulada de opciones strangle comprado
En la figura 10 se muestra un ejemplo de cómo funciona la estrategia de opciones strangle comprado. Se pueden observar la distribución no lineal de los niveles de emulación y las operaciones de rebalanceo de la posición en opciones. Los niveles de Strike1 y Strike2 se corresponden con una variación relativa del precio (DPrice) igual a 0,1 veces la volatilidad histórica (HV) del día en cuestión.
Este valor se configura en los parámetros externos del asesor experto mediante la variable que se muestra a continuación (puede oscilar entre 0,01 y 0,10):
En este caso, el precio del activo subyacente subió durante la primera mitad de la jornada y alcanzó el octavo nivel de emulación. Las pérdidas se acumularon durante los retrocesos, pero en el momento en que se tomó esta captura de pantalla, la posición registraba un buen beneficio (incluso tras tener en cuenta las operaciones con pérdidas ya cerradas). Esto apunta a la posibilidad de un vencimiento anticipado; añadiremos esta función al asesor experto en el futuro. Además, automatizaremos el vencimiento anticipado estableciendo un nivel de vencimiento.

Fig. 10: Estrategia de opciones strangle comprado
Venta de un strangle — strangle vendido
- Significado: La venta simultánea de opciones de compra y de venta con diferentes precios de ejercicio que se encuentran dentro del rango de la volatilidad histórica (HV).
- Condición de uso: Si se tiene la certeza de que el precio del activo subyacente se mantendrá dentro de un amplio rango, independientemente de su dirección
- Beneficio: la prima pagada por el comprador por las dos opciones (que no se abona en un escenario simulado) + el beneficio acumulado a medida que el precio fluctúa dentro de un amplio rango
- Riesgo: ilimitado
La diferencia con respecto al straddle vendido es que esta estrategia utiliza dos precios de ejercicio: uno para la región negativa de DPrice y otro para la región positiva. Entre ambos precios de ejercicio, la exposición simulada al activo subyacente es nula; por lo tanto, mientras no se realicen nuevas operaciones, el PnL de la estrategia emulada permanece sin cambios.
En la figura 11 se muestra un gráfico de ejemplo que ilustra la relación entre el beneficio/pérdida (PnL) y la variación relativa del precio. Es importante tener en cuenta que este gráfico es una representación teórica basada en la volatilidad histórica media (HV) del precio del activo subyacente. Esta es la principal diferencia entre una opción simulada y una real.
El gráfico muestra que se genera un beneficio si el precio del activo subyacente se mantiene dentro del rango de volatilidad histórica (HV), que aparece sombreado en verde en la figura. Cuanto mayores sean las fluctuaciones del precio entre los niveles de opción, mayor será el beneficio al vencimiento (sin embargo, para maximizar el beneficio, el precio debería volver a situarse lo más cerca posible del precio de ejercicio). La dirección de las fluctuaciones con respecto al precio de ejercicio es irrelevante: obtenemos una configuración casi ideal para la operativa en rango.
Si el precio del activo subyacente se sitúa fuera del rango de volatilidad histórica (HV) y se mantiene ahí hasta el vencimiento, incurriremos en una pérdida. Cuanto más se aleje el precio de ese rango, mayor será la pérdida. En teoría, el riesgo es ilimitado. En realidad, siempre podemos cerrar nuestras posiciones y detener el funcionamiento del asesor experto. Existen estructuras de opciones más complejas que reducen automáticamente el riesgo a un nivel aceptable y que prácticamente no afectan a los beneficios. Más información al respecto en el próximo artículo.
El lado izquierdo del eje DPrice (DPrice < 0) corresponde a una caída del precio del activo subyacente con respecto al precio de ejercicio; está marcado por una flecha que apunta hacia la izquierda con la etiqueta «Área de trabajo de la venta de una opción de venta, venta de una opción de compra = 0» (área de trabajo de la venta de una opción de venta). En esta región, la delta de la venta de una opción de compra es cero, lo que significa que no tiene ningún efecto en la simulación de la posición conjunta en opciones.
El lado derecho del eje DPrice (DPrice > 0) corresponde a un aumento del precio del activo subyacente con respecto al precio de ejercicio; se indica mediante una flecha que apunta hacia la derecha con la etiqueta «Área de trabajo de la venta de una opción de compra, venta de una opción de venta = 0» (área de trabajo de la venta de una opción de compra). En esta región, la delta de la venta de una opción de venta es cero; es decir, no tiene ningún efecto en la simulación de la posición conjunta en opciones.
El gráfico también muestra las zonas de beneficio (Profit) y pérdida (Loss), así como los precios de ejercicio (Strike1 y Strike2).

Fig. 11. Relación entre el valor de PnL (beneficio/pérdida) y la variación relativa del precio (DPrice) para la estrategia simulada de opciones strangle vendido
En la figura 12 se muestra un ejemplo de la estrategia de opciones strangle vendido. Los niveles de Strike1 y Strike2 se corresponden con una variación relativa del precio (DPrice) igual a 0,08 de la volatilidad histórica (HV) del día actual. El gráfico muestra que, durante la primera mitad del día, el precio del activo subyacente osciló por encima del precio de apertura, entre el precio de ejercicio y el cuarto nivel de rebalanceo. Como resultado, se obtuvieron algunos beneficios.
Alrededor de las 15:30 h, hora de Moscú, el precio del activo subyacente cambió de dirección a la baja y fluctuó varias veces entre el primer y el quinto nivel de rebalanceo, lo que generó beneficios adicionales. Llegados a este punto, ya podemos ejercer las opciones de forma anticipada para asegurar los beneficios. Por lo general, la decisión final siempre recae en el operador.
Como podemos ver, en esta estrategia de opciones, la dirección del movimiento del precio del activo subyacente es irrelevante: lo importante es que su precio se mantenga dentro del rango de la volatilidad histórica (HV). Esto es cierto en el caso de una distribución normal de los incrementos de precios, pero, en realidad, es posible que se produzcan picos de precios en una sola dirección. En esta situación, pueden resultar útiles tanto las estrategias con opciones más complejas como el cierre anticipado de la posición.

Fig. 12. Estrategia de opciones strangle vendido
Implementación de un straddle comprado en MQL5
La clase StraddleLongOptionConstruction, que crea una estructura de opciones, deriva de la clase base TOptionConstructionBase (véase la descripción en el artículo anterior, «Negociamos con opciones sin opciones (Parte 2): uso en operaciones reales»). Los parámetros del constructor son el número de niveles de opción (int _levels_number) durante la emulación y el error máximo (double _tolerance) al calcular los precios correspondientes a los valores de delta para visualizar los niveles.
El método StraddleLongOptionConstruction::CreateOptionConstruction(...) crea dos objetos —uno de tipo OptionLongPut y otro de tipo OptionLongCall— y los añade a la lista CList, de la que deriva la clase base de la estructura de opciones, TOptionConstructionBase.
// ===================================================================== // 'Straddle Long' type option construction class: // ===================================================================== class StraddleLongOptionConstruction : public TOptionConstructionBase { public: // --------------------------------------------------------------------- // Constructor: // --------------------------------------------------------------------- StraddleLongOptionConstruction(const int _levels_number = 10, const double _tolerance = 0.00001) : TOptionConstructionBase(ENUM_OPTION_CONSTRUCTION_STRADDLE_LONG, _levels_number, _tolerance) { } // --------------------------------------------------------------------- // Create option construction: // --------------------------------------------------------------------- void CreateOptionConstruction(const double _k, const double _s, const int _digits) override { this.Add(new OptionLongPut(_k, _s, _digits)); this.Add(new OptionLongCall(_k, _s, _digits)); } ... the remaining part of the code is in the file "OptionEmulatorA3.mqh" ... }; // ---------------------------------------------------------------------
El resto de los métodos de la clase se describen en el artículo anterior y más arriba en este mismo artículo.
Implementación de un straddle vendido en MQL5
La clase StraddleShortOptionConstruction, que crea una estructura de opciones, deriva de la clase base TOptionConstructionBase (véase la descripción en el artículo anterior). Los parámetros del constructor son el número de niveles de opción (int _levels_number) durante la emulación y el error máximo (double _tolerance) al calcular los precios correspondientes a los valores de delta para visualizar los niveles.
El método StraddleShortOptionConstruction::CreateOptionConstruction(...) crea dos objetos —uno de tipo OptionShortPut y otro de tipo OptionShortCall— y los añade a CList, de la que deriva la clase base de la estructura de opciones, TOptionConstructionBase.
// ===================================================================== // Straddle Short type option construction class: // ===================================================================== class StraddleShortOptionConstruction : public TOptionConstructionBase { public: // --------------------------------------------------------------------- // Constructor: // --------------------------------------------------------------------- StraddleShortOptionConstruction(const int _levels_number = 10, const double _tolerance = 0.00001) : TOptionConstructionBase(ENUM_OPTION_CONSTRUCTION_STRADDLE_SHORT, _levels_number, _tolerance) { } // --------------------------------------------------------------------- // Create option construction: // --------------------------------------------------------------------- void CreateOptionConstruction(const double _k, const double _s, const int _digits) override { this.Add(new OptionShortPut(_k, _s, _digits)); this.Add(new OptionShortCall(_k, _s, _digits)); } ... the remaining part of the code is in the file "OptionEmulatorA3.mqh" ... }; // ---------------------------------------------------------------------
El resto de los métodos de la clase se describen en el artículo anterior y más arriba en este mismo artículo.
Implementación de un strangle comprado en MQL5
La clase StrangleLongOptionConstruction, que crea una estructura de opciones, deriva de la clase base TOptionConstructionBase (véase la descripción en el artículo anterior). Los parámetros del constructor son el número de niveles de opción (int _levels_number) durante la emulación y el error máximo (double _tolerance) al calcular los precios correspondientes a los valores de delta para visualizar los niveles.
El método StrangleLongOptionConstruction::CreateOptionConstruction(...) crea dos objetos —uno de tipo OptionLongPut y otro de tipo OptionLongCall— y los añade a la lista CList, de la que deriva la clase base de la estructura de opciones, TOptionConstructionBase.
// ===================================================================== // Strangle Long type option construction class: // ===================================================================== class StrangleLongOptionConstruction : public TOptionConstructionBase { public: // --------------------------------------------------------------------- // Constructor: // --------------------------------------------------------------------- StrangleLongOptionConstruction(const int _levels_number = 10, const double _tolerance = 0.00001) : TOptionConstructionBase(ENUM_OPTION_CONSTRUCTION_STRANGLE_LONG, _levels_number, _tolerance) { } // --------------------------------------------------------------------- // Create option construction: // --------------------------------------------------------------------- void CreateOptionConstruction(const double _k, const double _s, const int _digits) override { this.Add(new OptionLongPut(_k, _s, _digits)); this.Add(new OptionLongCall(_k, _s, _digits)); } ... the remaining part of the code is in the file "OptionEmulatorA3.mqh" ... }; // ---------------------------------------------------------------------
Esta estrategia de opciones se diferencia del straddle comprado en que se establecen precios de ejercicio distintos —Strike1 y Strike2— para la compra de una opción de venta y la compra de una opción de compra. El resto de los métodos de la clase se describen en el artículo anterior y más arriba en este mismo artículo.
Implementación de un strangle vendido en MQL5
La clase StrangleShortOptionConstruction, que crea una estructura de opciones, deriva de la clase base TOptionConstructionBase (véase la descripción en el artículo anterior). Los parámetros del constructor son el número de niveles de opción (int _levels_number) durante la emulación y el error máximo (double _tolerance) al calcular los precios correspondientes a los valores de delta para visualizar los niveles.
El método StrangleShortOptionConstruction::CreateOptionConstruction(...) crea dos objetos —uno de tipo OptionShortPut y otro de tipo OptionShortCall— y los añade a la lista CList, de la que deriva la clase base de la estructura de opciones, TOptionConstructionBase.
// ===================================================================== // Strangle Short type option construction class: // ===================================================================== class StrangleShortOptionConstruction : public TOptionConstructionBase { public: // --------------------------------------------------------------------- // Constructor: // --------------------------------------------------------------------- StrangleShortOptionConstruction(const int _levels_number = 10, const double _tolerance = 0.00001) : TOptionConstructionBase(ENUM_OPTION_CONSTRUCTION_STRANGLE_SHORT, _levels_number, _tolerance) { } // --------------------------------------------------------------------- // Create option construction: // --------------------------------------------------------------------- void CreateOptionConstruction(const double _k, const double _s, const int _digits) override { this.Add(new OptionShortPut(_k, _s, _digits)); this.Add(new OptionShortCall(_k, _s, _digits)); } ... the remaining part of the code is in the file "OptionEmulatorA3.mqh" ... }; // --------------------------------------------------------------------
La diferencia entre esta estrategia de opciones y el straddle vendido radica en que se establecen precios de ejercicio distintos —Strike1 y Strike2— para la venta de una opción de venta y la venta de una opción de compra. El resto de los métodos de la clase se describen en el artículo anterior de esta serie y más arriba en este mismo artículo.
Conclusión
Como podemos ver, implementar estructuras de opciones mediante un enfoque orientado a objetos es bastante sencillo y fácil de entender. Todos los detalles de implementación están encapsulados en las clases base. Dicho esto, la complejidad de la estructura de opciones (es decir, el número de elementos de la lista CList) solo está limitada por la imaginación del usuario y los recursos del ordenador.
Las estructuras de dos opciones descritas en el artículo se utilizan con bastante frecuencia en la operativa bursátil, en particular en la bolsa MOEX. Sin embargo, también existen estrategias más complejas con cuatro opciones que permiten reducir los riesgos asociados a las opciones compradas y asegurar los beneficios de las opciones vendidas; estas se tratarán en el cuarto artículo de esta serie.
Además, estamos mejorando nuestro asesor experto añadiendo un vencimiento activado por niveles, lo que nos permitirá asegurar automáticamente los beneficios en las estrategias que impliquen la compra de opciones.
En la siguiente tabla se enumeran todos los archivos adjuntos al artículo:
| Nombre del archivo | Descripción |
|---|---|
| Article3-OptionTrader.mq5 | El código del asesor experto que ejecuta las estrategias de opciones descritas en el artículo mediante la emulación de opciones |
| CheckNewBar.mqh | El código de la clase que comprueba si aparece una nueva barra en el gráfico del terminal MetaTrader 5 |
| OptionEmulatorA3.mqh | El código de las clases para emular las opciones y las estructuras de opciones descritas en el artículo |
| PriceLevelsA3.mqh | El código de la clase que muestra los niveles de opción en el gráfico del terminal MetaTrader 5 |
Traducción del ruso hecha por MetaQuotes Ltd.
Artículo original: https://www.mql5.com/ru/articles/18951
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.
En realidad, no he probado el robot en cuentas de netting.
¡Ah, ya veo!
Y yo que me preguntaba por qué no coincidía con mi ejecución de las operaciones,
Me había olvidado por completo de las cuentas de cobertura)
¡Ah, eso es!
Y yo me preguntaba por qué no coincidía con mi implementación del sistema de subastas,
Se me había olvidado por completo lo de las cuentas de cobertura)
En uno de los próximos artículos tengo pensado incluir el tema del netting. Pronto saldrá el cuarto artículo, bastante interesante, en mi opinión.
En general, aún hay mucho que compartir en este ámbito y en general.
¿Y vosotros simuláis operaciones en la Bolsa de Moscú?
En uno de los próximos artículos tengo pensado incluir información sobre el netting. Pronto publicaré el cuarto artículo, que, en mi opinión, es bastante interesante.
En general, aún hay mucho que compartir en este ámbito y en general.
¿Y vosotros simuláis operaciones en la Bolsa de Moscú?
No he llegado a la aplicación práctica, me he quedado en la fase de investigación.
De momento he dejado este tema en suspenso, pero leo con interés vuestros artículos. ¡Gracias por los artículos!
Quizá con los próximos artículos me animéis a retomar el tema)
Puedo enviaros el código de mi implementación; incluso tengo por ahí una calculadora de opciones.
Si te interesa, escríbeme por mensaje privado.
No llegó a la aplicación práctica, se quedó en la fase de investigación.
De momento he dejado este tema en suspenso, pero leo con interés vuestros artículos. ¡Gracias por los artículos!
Quizá con los próximos artículos me animéis a retomarlo de nuevo)
Puedo compartir el código de mi implementación; incluso tengo por ahí una calculadora de opciones.
Si te interesa, envíame un mensaje privado.