Negociando opções sem opções (Parte 3): Estratégias complexas com opções
Introdução
No artigo anterior desta série, analisamos as estratégias básicas com opções e testamos seu funcionamento no mercado real. Também criamos um EA que implementa uma estratégia com opções. Agora é hora de analisar o funcionamento e implementar as estratégias que os traders de opções utilizam na prática e explorar as novas possibilidades oferecidas pela negociação de opções.
Visualização dos níveis de opções
Antes de avançarmos, vamos adicionar ao EA a possibilidade de exibir os níveis de opções atuais. Para facilitar o acompanhamento visual da negociação, seria conveniente ver no terminal a posição do preço atual do ativo subjacente em relação aos níveis de opções utilizados na emulação. Vamos implementar esse recurso e testá-lo com as estratégias com opções analisadas na Parte 2.
Exibiremos os níveis de opções como linhas traçadas desde o início do dia até o momento atual. Também seria conveniente visualizar no terminal a posição do strike, ou dos strikes. Para isso, começaremos desenvolvendo o método CalculateLevelPrice. Na prática, esse método executa a operação inversa: a partir de um determinado valor da delta da opção, calcula o valor do preço relativo. A partir desse preço relativo, obteremos o preço absoluto correspondente a cada nível de opção.
Adicionaremos os métodos abstratos TOptionConstructionBase::CalculateUpLevelPrice e TOptionConstructionBase::CalculateDnLevelPrice. Depois, eles serão definidos nas classes derivadas. Vamos analisar em mais detalhes os métodos de cálculo.
Por que são necessários dois métodos? Porque o sinal da delta será diferente para preços do ativo subjacente acima e abaixo do preço de strike. Dessa forma, cobrimos todas as situações possíveis. Os argumentos dos métodos TOptionConstructionBase::CalculateUpLevelPrice e TOptionConstructionBase::CalculateDnLevelPrice são os seguintes:
- _strike_price - preço de strike;
- _norm_price - preço usado para normalização em relação ao intervalo de volatilidade;
- _limit_price - preço máximo/mínimo do intervalo usado na busca pelo método da bisseção (no caso geral, corresponde ao preço de normalização), acima ou abaixo do preço de strike, respectivamente, conforme se trate do limite máximo ou mínimo;
- _target_delta - valor-alvo da delta da estrutura de opções para o qual se busca o nível de preço;
OBSERVAÇÃO:
Como a sigmoide se aproxima exponencialmente de zero e de um (ou de menos um), mas nunca atinge esses valores, utilizamos valores próximos de zero e de um para definir explicitamente os níveis de opções correspondentes ao nível zero e ao nível máximo (por exemplo, o décimo).
Para o nível zero, usamos uma delta igual a _norm_zero_level com o sinal apropriado. Para o nível máximo, usamos uma delta igual a +-0.96 (valor escolhido empiricamente), também com o sinal apropriado. Além disso, limitamos o intervalo de valores de _norm_zero_level entre 0.01 e 0.05 (lembrando que o primeiro nível da emulação de opções corresponde a uma delta igual a +-0.1).
O código desses métodos é o seguinte:
// --------------------------------------------------------------------- // 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; }
O método TOptionConstructionBase::CalculateUpPriceLevels percorre em um laço todos os valores dos níveis de emulação de opções e chama o método TOptionConstructionBase::CalculateUpLevelPrice, que calcula o preço correspondente a uma determinada delta.
Para o cálculo, utilizaremos o método da bisseção, ou método da dicotomia, evitando assim a necessidade de resolver analiticamente a equação da sigmoide. Isso é possível porque a sigmoide é uma função contínua e monotônica em relação ao preço e, no trecho operacional da estrutura de opções, onde ocorre a maior parte do rebalanceamento, a soma das sigmoides também é monotônica.
A Fig. 1 mostra esquematicamente as iterações, com as três primeiras etapas Step1,...Step3, durante a busca por um ponto dentro do intervalo (o valor target na Fig. 1). O método consiste em determinar sucessivamente em qual metade do intervalo [up_limit;low_limit] se encontra o ponto target procurado. Depois disso, alteramos o limite do intervalo, neste caso, nas três primeiras etapas, o limite superior up_limit, atribuindo a ele o valor correspondente ao ponto médio do intervalo:
half_point = (up_limit + low_limit) / 2 ---> up_limit = half_point
Repetimos esse procedimento até que o comprimento do intervalo, igual a (up_limit - low_limit), se torne menor ou igual ao valor de precisão especificado em _tolerance.
Nesse momento, o valor procurado será igual ao último valor de half_point. A distância entre o valor encontrado e target não excederá a precisão especificada. Esse procedimento de cálculo dos níveis de opções será executado uma vez por dia, no início de um novo dia, ou quando o EA for iniciado.

Fig.1 Sequência de busca de um ponto dentro do intervalo
Depois de aplicar o método CalculateUpLevelPrice a todos os valores dos níveis de opções (0,1,...10), obtemos um array de preços correspondentes a esses níveis, ou seja, aos níveis de opções acima do preço de strike. Para obter os níveis de opções abaixo do preço de strike, utiliza-se o método CalculateDnLevelPrice (consulte o arquivo "OptionEmulatorA3.mqh"). A busca é realizada de forma análoga; a diferença é que os níveis de opções são posicionados para baixo na escala de preços a partir do preço de strike. De modo geral, os níveis inferiores e superiores não precisam ser simétricos.
Agora vamos implementar a visualização dos níveis de opções no gráfico do terminal MetaTrader 5. Para isso, desenvolveremos duas classes: uma classe que encapsula o próprio nível e outra destinada a manipular a lista de níveis. A classe de visualização do nível é apresentada abaixo:
// ===================================================================== // 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, a classe TPriceLevelBase é derivada da classe padrão CObject. Isso foi feito para permitir o uso da classe padrão de manipulação de listas, que veremos mais adiante. O objeto "nível" é um segmento horizontal, ou linha, que se estende desde o horário de abertura do dia atual até o horário atual dentro desse mesmo dia. À direita da linha, exibiremos um rótulo de texto com o número do nível.
Os membros de dados que encapsulam as propriedades do objeto "nível" correspondem às propriedades padrão do objeto gráfico "linha" e do objeto gráfico "rótulo de texto" no gráfico do terminal MetaTrader 5. Sua finalidade é a seguinte:
- long chart_id - identificador do gráfico no qual se encontra esse objeto gráfico;
- int window - identificador da subjanela do gráfico que contém o objeto gráfico; neste caso, zero para a janela principal do gráfico;
- string trend_name - nome do objeto "linha", usado para identificá-lo entre outros objetos semelhantes no mesmo gráfico;
- string text_name - nome do objeto "texto", usado para identificá-lo entre outros objetos semelhantes no mesmo gráfico;
- double price - valor do nível de preço no qual se encontram os objetos: o segmento horizontal e o rótulo de texto;
- CChartObjectTrend* trend - ponteiro para o objeto gráfico "linha" da biblioteca padrão do MetaTrader 5;
- CChartObjectText* text - ponteiro para o objeto gráfico "etiqueta de texto" da biblioteca padrão do MetaTrader 5.
Os níveis são atualizados sempre que surge uma nova barra no gráfico do MetaTrader 5. Com o início de um novo dia, os níveis anteriores são removidos e os novos níveis são desenhados para o dia atual. Antes disso, a volatilidade histórica HV é recalculada para o novo dia.
Durante o dia, os níveis são atualizados quando o método TPriceLevelBase::Update(const datetime _time) é chamado, recebendo como argumento o horário de abertura da barra atual. A coordenada temporal da etiqueta de texto é deslocada um pouco mais para a direita, para evitar que ela se sobreponha à linha do nível.
A classe TVisualPriceLevels, destinada à manipulação da lista de níveis, é apresentada abaixo:
// ===================================================================== // 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(); } } } }; // ---------------------------------------------------------------------
Assim como na classe TPriceLevelBase, aqui também existe o método TVisualPriceLevels::Update(const datetime _time), que atualiza todos os níveis adicionados à lista. Para isso, ele percorre os objetos e chama, em cada um deles, o método TPriceLevelBase::Update(const datetime _time).
Também foi adicionado o método TPriceLevelBase::AddLevel, cujos parâmetros definem a posição e o estilo da linha do nível de opção e da etiqueta de texto. Esse método cria um objeto do tipo TPriceLevelBase e o adiciona à lista por meio do método CList::Add da classe padrão CList.
Além disso, adicionaremos ao arquivo principal do EA ("Article3-OptionTrader.mq5") novos parâmetros de entrada para definir as propriedades dos níveis exibidos na tela: cor da etiqueta de texto, cor da linha e estilo da linha. É possível configurar separadamente os parâmetros das linhas e etiquetas de texto para o strike e para os níveis de rebalanceamento acima e abaixo dele.
// --------------------------------------------------------------------- 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 // --------------------------------------------------------------------
O resultado da parte do EA responsável pela visualização dos níveis é apresentado na Fig. 2. É fácil perceber que a distribuição dos níveis de opções ao longo da escala de preços não é linear, como consequência da fórmula de Black-Scholes. Neste caso, o preço de strike corresponde ao preço de abertura do dia. Em estruturas de opções mais complexas, pode haver vários preços de strike, e seus valores podem ser diferentes do preço de abertura.

Fig.2 Visualização dos níveis de opções
Estratégias complexas com opções
Agora vamos ampliar nossa lista de estruturas de opções com novas estratégias:
// --------------------------------------------------------------------- // 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 }; // --------------------------------------------------------------------
Vamos analisar o objetivo e as condições de uso das novas estratégias mencionadas acima.
Compra de straddle - Long STRADDLE
- Estrutura: compra simultânea de opções call e put com o mesmo preço de strike;
- Condição de uso: quando há expectativa de que o preço do ativo subjacente suba ou caia além do intervalo definido pela volatilidade histórica HV, mas sem uma previsão sobre a direção do movimento;
- Lucro: ilimitado;
- Risco: prêmio pago pelas duas opções (ausente na emulação) + prejuízo decorrente do rebalanceamento da estrutura de opções.
A dependência entre o valor da delta da estrutura de opções "Delta" e a variação relativa do preço "DPrice" é apresentada na Fig. 3. Essa relação é obtida pela compra de duas opções com o mesmo preço de strike: uma opção Long Put e uma opção Long Call. A tabela à esquerda do gráfico mostra os valores de DPrice (x na tabela) nos quais ocorre o rebalanceamento da estrutura de opções.

Fig.3 Dependência do valor da delta "Delta" em relação à variação relativa do preço "DPrice" (x - na tabela) para a estrutura de opções emulada Long STRADDLE. S = 0.5, K = 10. O intervalo da delta é dividido em dez partes iguais
Um gráfico aproximado da relação entre o PnL (Lucro/Prejuízo - Profit/Loss) e a variação relativa do preço é apresentado na Fig. 4. É importante observar que esse gráfico é teórico e corresponde a um valor médio da volatilidade histórica HV do preço do ativo subjacente. O risco depende, em grande medida, do número de rebalanceamentos da estrutura de opções: cada rebalanceamento acrescenta um prejuízo ao PnL total. Essa é justamente a principal diferença entre uma opção emulada e uma opção real.
O gráfico mostra que o lucro máximo é obtido quando o preço do ativo subjacente sai dos limites do intervalo de volatilidade HV ou, no mínimo, não oscila repetidamente entre os níveis de opções. Essa região está destacada em verde na figura.
A parte esquerda do eixo DPrice (DPrice < 0) corresponde à queda do preço do ativo subjacente em relação ao preço de strike. Ela é indicada por uma seta apontando para a esquerda com a inscrição "Long Put working area, Long Call = 0" (região operacional da opção Long Put). Nessa região, a delta da opção Long Call é igual a zero e, portanto, ela não afeta a emulação da posição agregada em opções.
A parte direita do eixo DPrice (DPrice > 0) corresponde à alta do preço do ativo subjacente em relação ao preço de strike. Ela é indicada por uma seta apontando para a direita com a inscrição "Long Call working area, Long Put = 0" (região operacional da opção Long Call). Nessa região, a delta da opção Long Put é igual a zero e, portanto, ela não afeta a emulação da posição agregada em opções.
O gráfico também indica as regiões de lucro (Profit) e prejuízo (Loss), além da posição do preço de strike (Strike).

Fig.4 Dependência do valor de "PnL" (lucro/prejuízo) em relação à variação relativa do preço "DPrice" para a estrutura de opções emulada Long STRADDLE.
Um exemplo do funcionamento da estrutura de opções Long Straddle é apresentado na Fig. 5. Neste caso, a estrutura de opções foi mantida até a expiração. Como o preço oscilou dentro do intervalo de volatilidade e, no final do dia, quase retornou ao preço de abertura, houve um pequeno prejuízo.
O gráfico também mostra que, por volta das 15 horas, o preço do ativo subjacente atingiu o sétimo nível de emulação, momento em que seria possível encerrar antecipadamente as opções com lucro. Ao contrário do que ocorre com opções reais, não haveria problemas de liquidez.

Fig.5 Funcionamento da estratégia com opções Long Straddle
Venda de straddle - Short STRADDLE
- Estrutura: venda simultânea de opções call e put com o mesmo preço de strike;
- Condição de uso: quando há expectativa de que o preço do ativo subjacente permaneça dentro da faixa de preços correspondente à volatilidade histórica média HV, independentemente da direção do movimento;
- Lucro: prêmio pago pelo comprador pelas duas opções (ausente na emulação) + lucro acumulado com as oscilações do preço dentro do intervalo (presente apenas na emulação);
- Risco: ilimitado.
A dependência entre o valor da delta da estrutura de opções "Delta" e a variação relativa do preço "DPrice" é apresentada na Fig. 6. Essa relação é obtida pela venda de duas opções com o mesmo preço de strike: venda de uma opção Long Put e venda de uma opção Long Call. A tabela à esquerda do gráfico mostra os valores de DPrice (x na tabela) nos quais ocorre o rebalanceamento da estrutura de opções.

Fig.6 Dependência do valor da delta "Delta" em relação à variação relativa do preço "DPrice" (x - na tabela) para a estrutura de opções emulada Short STRADDLE. S = 0.5, K = 10. O intervalo da delta é dividido em dez partes iguais
Um gráfico aproximado da relação entre o PnL (lucro/prejuízo) e a variação relativa do preço é apresentado na Fig. 7. É importante observar que esse gráfico é teórico e corresponde a um valor médio da volatilidade histórica HV do preço do ativo subjacente. Essa é a principal diferença entre uma opção emulada e uma opção real.
O gráfico mostra que há lucro quando o preço do ativo subjacente permanece dentro da faixa de preços definida pela volatilidade histórica HV, região destacada em verde na figura. Quanto maior o número de oscilações do preço entre os níveis de opções, maior será o lucro na expiração. Para maximizar esse lucro, o preço deve retornar o mais próximo possível do preço de strike. A direção das oscilações em relação ao preço de strike não faz diferença, o que nos proporciona uma estrutura praticamente ideal para operar em mercado lateral.
Se o preço do ativo subjacente ultrapassar os limites da faixa de preços definida pela volatilidade histórica HV e permanecer fora dele até a expiração, teremos prejuízo. Quanto mais o preço se afastar para além dessa faixa, maior será a perda. Teoricamente, o risco é ilimitado. Na prática, porém, sempre podemos fechar as posições e interromper a operação do EA. Existem estruturas de opções mais complexas que reduzem automaticamente o risco a um nível aceitável, praticamente sem afetar o lucro. Esse será o tema do próximo artigo.
A parte esquerda do eixo DPrice (DPrice < 0) corresponde à queda do preço do ativo subjacente em relação ao preço de strike. Ela é indicada por uma seta apontando para a esquerda com a inscrição "Short Put working area, Short Call = 0" (região operacional da opção Short Put). Nessa região, a delta da opção Short Call é igual a zero e, portanto, ela não afeta a emulação da posição agregada em opções.
A parte direita do eixo DPrice (DPrice > 0) corresponde à alta do preço do ativo subjacente em relação ao preço de strike. Ela é indicada por uma seta apontando para a direita com a inscrição "Short Call working area, Short Put = 0" (região operacional da opção Short Call). Nessa região, a delta da opção Short Put é igual a zero e, portanto, ela não afeta a emulação da posição agregada em opções.
O gráfico também indica as regiões de lucro (Profit) e prejuízo (Loss), além da posição do preço de strike (Strike).

Fig.7 Dependência do valor de PnL (lucro/prejuízo) em relação à variação relativa do preço "DPrice" para a estrutura de opções emulada Short STRADDLE
Um exemplo do funcionamento da estrutura de opções Short Straddle é apresentado na Fig. 8. O nível máximo atingido para o rebalanceamento da posição em opções durante o dia foi o nível nove. É fácil observar como cada oscilação do preço do ativo subjacente entre os níveis de opções aumenta o lucro acumulado. No final do dia, antes da expiração, todas as posições foram fechadas, pois o preço retornou ao nível zero. Neste caso, nossa expectativa de que o preço permanecesse dentro do intervalo se confirmou plenamente. Naturalmente, isso nem sempre acontece.

Fig.8 Funcionamento da estratégia com opções Short Straddle
Compra de strangle - Long STRANGLE
- Estrutura: compra simultânea de opções call e put com preços de strike diferentes, ambos localizados dentro da faixa de preços definida pela volatilidade histórica HV;
- Condição de uso: quando há expectativa de uma forte variação do preço do ativo subjacente, mas sem uma previsão quanto à direção do movimento;
- Lucro: ilimitado;
- Risco: prêmio pago pelas duas opções (ausente na emulação) + prejuízo decorrente do rebalanceamento da estrutura de opções.
A diferença em relação ao Long Straddle é que, neste caso, são utilizados dois preços de strike: um para a região negativa de DPrice e outro para a região positiva. No intervalo entre os strikes, a posição é igual a zero e, portanto, o PnL atual não se altera nessa região.
Um gráfico aproximado da relação entre o PnL (Lucro/Prejuízo - Profit/Loss) e a variação relativa do preço é apresentado na Fig. 9. É importante observar que esse gráfico é teórico e corresponde a um valor médio da volatilidade histórica HV do preço do ativo subjacente. O risco depende, em grande medida, do número de rebalanceamentos da estrutura de opções: cada rebalanceamento acrescenta um prejuízo ao PnL total. Essa é a principal diferença entre uma opção emulada e uma opção real.
A parte esquerda do eixo DPrice (DPrice < 0) corresponde à queda do preço do ativo subjacente em relação ao preço de strike Strike1. Ela é indicada por uma seta apontando para a esquerda com a inscrição "Long Put working area, Long Call = 0" (região operacional da opção Long Put). Nessa região, a delta da opção Long Call é igual a zero e, portanto, ela não afeta a emulação da posição agregada em opções.
A parte direita do eixo DPrice (DPrice > 0) corresponde à alta do preço do ativo subjacente em relação ao preço de strike Strike2. Ela é indicada por uma seta apontando para a direita com a inscrição "Long Call working area, Long Put = 0" (região operacional da opção Long Call). Nessa região, a delta da opção Long Put é igual a zero e, portanto, ela não afeta a emulação da posição agregada em opções.
O gráfico mostra que o lucro máximo é obtido quando o preço do ativo subjacente sai dos limites do intervalo de volatilidade HV ou, no mínimo, não oscila repetidamente entre os níveis de opções. Essa região está destacada em verde na figura. As oscilações do preço entre os strikes não afetam o Lucro/Prejuízo, pois, nessa região, a delta das duas opções é igual a zero.
O gráfico também indica as regiões de lucro (Profit) e prejuízo (Loss), além das posições dos preços de strike (Strike1 e Strike2).

Fig.9 Dependência do valor de PnL (lucro/prejuízo) em relação à variação relativa do preço "DPrice" para a estrutura de opções emulada Long STRANGLE
Um exemplo do funcionamento da estrutura de opções Long Strangle é apresentado na Fig. 10. É possível observar a distribuição não linear dos níveis de emulação e as operações de rebalanceamento da posição em opções. As posições dos níveis Strike1 e Strike2 correspondem a um valor de DPrice igual a 0.1 vezes a volatilidade histórica HV do dia atual.
Esse valor é definido nos parâmetros de entrada do EA por meio da variável apresentada abaixo e pode variar de 0.01 a 0.10:
Neste caso, o preço do ativo subjacente subiu durante a primeira metade do dia e chegou ao oitavo nível de emulação. Nos recuos, houve acúmulo de prejuízo, mas, no momento em que a imagem foi capturada, a posição ainda apresentava um bom lucro, mesmo considerando as operações com prejuízo já encerradas. Nesse ponto, surge a ideia de antecipar a expiração da estrutura de opções. Essa possibilidade será adicionada ao EA posteriormente. Também automatizaremos a expiração antecipada, permitindo definir o nível em que ela deverá ocorrer.

Fig.10 Funcionamento da estratégia com opções Long Strangle
Venda de strangle - Short STRANGLE
- Estrutura: venda simultânea de opções call e put com preços de strike diferentes, ambos localizados dentro da faixa de preços definida pela volatilidade histórica HV;
- Condição de uso: quando há expectativa de que o preço do ativo subjacente permaneça dentro de um intervalo amplo, independentemente da direção do movimento;
- Lucro: prêmio pago pelo comprador pelas duas opções (ausente na emulação) + lucro acumulado com as oscilações do preço dentro desse intervalo amplo;
- Risco: ilimitado.
A diferença em relação ao Short Straddle é que, neste caso, são utilizados dois preços de strike: um para a região negativa de DPrice e outro para a região positiva. No intervalo entre os strikes, a posição é igual a zero e, portanto, o PnL atual não se altera nessa região.
Um gráfico aproximado da relação entre o PnL (lucro/prejuízo) e a variação relativa do preço é apresentado na Fig. 11. É importante observar que esse gráfico é teórico e corresponde a um valor médio da volatilidade histórica HV do preço do ativo subjacente. Essa é a principal diferença entre uma opção emulada e uma opção real.
O gráfico mostra que há lucro quando o preço do ativo subjacente permanece dentro da faixa de preços definida pela volatilidade histórica HV, região destacada em verde na figura. Quanto maior o número de oscilações do preço entre os níveis de opções, maior será o lucro na expiração. Para maximizar esse lucro, o preço deve retornar o mais próximo possível do preço de strike. A direção das oscilações em relação ao preço de strike não faz diferença, o que nos proporciona uma estrutura praticamente ideal para operar em mercado lateral.
Se o preço do ativo subjacente ultrapassar os limites da faixa de preços definida pela volatilidade histórica HV e permanecer fora dele até a expiração, teremos prejuízo. Quanto mais o preço se afastar para além dessa faixa, maior será a perda. Teoricamente, o risco é ilimitado. Na prática, porém, sempre podemos fechar as posições e interromper a operação do EA. Existem estruturas de opções mais complexas que reduzem automaticamente o risco a um nível aceitável, praticamente sem afetar o lucro. Esse será o tema do próximo artigo.
A parte esquerda do eixo DPrice (DPrice < 0) corresponde à queda do preço do ativo subjacente em relação ao preço de strike. Ela é indicada por uma seta apontando para a esquerda com a inscrição "Short Put working area, Short Call = 0" (região operacional da opção Short Put). Nessa região, a delta da opção Short Call é igual a zero e, portanto, ela não afeta a emulação da posição agregada em opções.
A parte direita do eixo DPrice (DPrice > 0) corresponde à alta do preço do ativo subjacente em relação ao preço de strike. Ela é indicada por uma seta apontando para a direita com a inscrição "Short Call working area, Short Put = 0" (região operacional da opção Short Call). Nessa região, a delta da opção Short Put é igual a zero e, portanto, ela não afeta a emulação da posição agregada em opções.
O gráfico também indica as regiões de lucro (Profit) e prejuízo (Loss), além das posições dos preços de strike (Strike1 e Strike2).

Fig.11 Dependência do valor de PnL (lucro/prejuízo) em relação à variação relativa do preço "DPrice" para a estrutura de opções emulada Long STRADDLE
Um exemplo do funcionamento da estrutura de opções Long Strangle é apresentado na Fig. 12. As posições dos níveis Strike1 e Strike2 correspondem a um valor de DPrice igual a 0.08 vezes a volatilidade histórica HV do dia atual. O gráfico mostra que, durante a primeira metade do dia, o preço do ativo subjacente oscilou acima do preço de abertura, entre o strike e o quarto nível de rebalanceamento. Como resultado, foi acumulado algum lucro.
Por volta das 15:30, horário de Moscou, o preço do ativo subjacente inverteu a direção e passou a cair e oscilou várias vezes entre o primeiro e o quinto níveis de rebalanceamento, gerando mais algum lucro. Nesse ponto, já seria possível exercer as opções antecipadamente e realizar o lucro. De modo geral, a decisão final sempre cabe ao trader.
Como podemos ver, nessa estratégia com opções, a direção do movimento do ativo subjacente não é relevante. O importante é que seu preço permaneça dentro da faixa de preços definida pela volatilidade histórica HV. Isso se aplica quando os incrementos de preço seguem uma distribuição normal, mas, na prática, podem ocorrer valores atípicos do preço em uma única direção. Nesses casos, podem ser úteis estratégias com opções mais complexas ou a expiração antecipada da posição.

Fig.12 Funcionamento da estratégia com opções Short Strangle
Implementação do Long Straddle em MQL5
A classe StraddleLongOptionConstruction, responsável por criar a estrutura de opções, é derivada da classe base TOptionConstructionBase (consulte a descrição no artigo anterior "Negociando opções sem opções (Parte 2): Uso na negociação real"). Os parâmetros do construtor são o número de níveis de opções (int _levels_number) utilizados na emulação e o erro máximo (double _tolerance) permitido no cálculo dos preços correspondentes aos valores da delta para a visualização dos níveis.
O método StraddleLongOptionConstruction::CreateOptionConstruction(...) cria dois objetos, um do tipo OptionLongPut e outro do tipo OptionLongCall, e os adiciona à lista CList; a classe base da estrutura de opções TOptionConstructionBase é derivada de CList.
// ===================================================================== // '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" ... }; // ---------------------------------------------------------------------
Os demais métodos da classe foram descritos no artigo anterior e nas seções anteriores deste artigo.
Implementação do Short Straddle em MQL5
A classe StraddleShortOptionConstruction, responsável por criar a estrutura de opções, é derivada da classe base TOptionConstructionBase (consulte a descrição no artigo anterior). Os parâmetros do construtor são o número de níveis de opções (int _levels_number) utilizados na emulação e o erro máximo (double _tolerance) permitido no cálculo dos preços correspondentes aos valores da delta para a visualização dos níveis.
O método StraddleShortOptionConstruction::CreateOptionConstruction(...) cria dois objetos, um do tipo OptionShortPut e outro do tipo OptionShortCall, e os adiciona à lista CList; a classe base da estrutura de opções TOptionConstructionBase é derivada de CList.
// ===================================================================== // 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" ... }; // ---------------------------------------------------------------------
Os demais métodos da classe foram descritos no artigo anterior e nas seções anteriores deste artigo.
Implementação do Long Strangle em MQL5
A classe StrangleLongOptionConstruction, responsável por criar a estrutura de opções, é derivada da classe base TOptionConstructionBase (consulte a descrição no artigo anterior). Os parâmetros do construtor são o número de níveis de opções (int _levels_number) utilizados na emulação e o erro máximo (double _tolerance) permitido no cálculo dos preços correspondentes aos valores da delta para a visualização dos níveis.
O método StrangleLongOptionConstruction::CreateOptionConstruction(...) cria dois objetos, um do tipo OptionLongPut e outro do tipo OptionLongCall, e os adiciona à lista CList, da qual é derivada a classe base da estrutura de opções 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" ... }; // ---------------------------------------------------------------------
A diferença entre essa estrutura de opções e o Long Straddle é que são definidos preços de strike diferentes, Strike1 e Strike2, para as opções Long Put e Long Call. Os demais métodos da classe foram descritos no artigo anterior e nas seções anteriores deste artigo.
Implementação do Short Strangle em MQL5
A classe StrangleShortOptionConstruction, responsável por criar a estrutura de opções, é derivada da classe base TOptionConstructionBase (consulte a descrição no artigo anterior). Os parâmetros do construtor são o número de níveis de opções (int _levels_number) utilizados na emulação e o erro máximo (double _tolerance) permitido no cálculo dos preços correspondentes aos valores da delta para a visualização dos níveis.
O método StrangleShortOptionConstruction::CreateOptionConstruction(...) cria dois objetos, um do tipo OptionShortPut e outro do tipo OptionShortCall, e os adiciona à lista CList, da qual é derivada a classe base da estrutura de opções 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" ... }; // --------------------------------------------------------------------
A diferença entre essa estrutura de opções e o Short Straddle é que são definidos preços de strike diferentes, Strike1 e Strike2, para as opções Short Put e Short Call. Os demais métodos da classe foram descritos no artigo anterior da série e nas seções anteriores deste artigo.
Conclusão
Como podemos ver, a implementação de estruturas de opções com uma abordagem orientada a objetos é bastante simples e fácil de compreender. Todos os detalhes da implementação ficam encapsulados nas classes base. Além disso, a complexidade da estrutura de opções, ou seja, na prática, o número de objetos na lista CList, é limitada apenas pela imaginação do usuário e pelos recursos computacionais disponíveis.
As estruturas com duas opções descritas neste artigo são amplamente utilizadas na negociação, inclusive na Bolsa de Moscou, MOEX. No entanto, também existem estratégias mais complexas, compostas por quatro opções, que permitem reduzir o risco das opções compradas e fixar o lucro das opções vendidas. Elas serão abordadas no quarto artigo desta série.
Também aprimoraremos nosso EA adicionando a expiração ao atingir um nível definido, o que permitirá realizar automaticamente o lucro nas estratégias com opções compradas.
A tabela a seguir apresenta todos os arquivos anexados ao artigo:
| Nome do arquivo | Descrição |
|---|---|
| Article3-OpionTrader.mq5 | Arquivo que contém o código do EA que negocia as estruturas de opções descritas no artigo utilizando a emulação de opções |
| CheckNewBar.mq5 | Arquivo que contém o código da classe responsável por detectar o surgimento de uma nova barra no gráfico do terminal MetaTrader 5 |
| OptionEmulatorA3.mq5 | Arquivo que contém o código das classes utilizadas para emular as opções e as estruturas de opções descritas no artigo |
| PriceLevelsA3.mq5 | Arquivo que contém o código das classes utilizadas para visualizar os níveis de opções no gráfico do terminal MetaTrader 5 |
Traduzido do russo pela MetaQuotes Ltd.
Artigo original: https://www.mql5.com/ru/articles/18951
Aviso: Todos os direitos sobre esses materiais pertencem à MetaQuotes Ltd. É proibida a reimpressão total ou parcial.
Esse artigo foi escrito por um usuário do site e reflete seu ponto de vista pessoal. A MetaQuotes Ltd. não se responsabiliza pela precisão das informações apresentadas nem pelas possíveis consequências decorrentes do uso das soluções, estratégias ou recomendações descritas.
Caminhe em novos trilhos: Personalize indicadores no MQL5
Redes neurais em trading: Dos transformers aos neurônios spiking (Componentes principais)
Está chegando o novo MetaTrader 5 e MQL5
Desenvolvendo um EA multimoeda (Parte 29): Aprimoramento do pipeline
- Aplicativos de negociação gratuitos
- 8 000+ sinais para cópia
- Notícias econômicas para análise dos mercados financeiros
Você concorda com a política do site e com os termos de uso
Na verdade, não testei o robô em contas de netting.
É isso mesmo!
E eu ainda estava pensando por que não batia com a minha execução das negociações,
Tinha esquecido completamente das contas de hedge)
É isso aí!
E eu fico pensando por que não bate com a minha implementação de negociação,
Já tinha esquecido completamente das contas de hedge)
Em um dos próximos artigos, pretendo abordar o tema do netting. Em breve sairá o quarto artigo — bastante interessante, na minha opinião.
De modo geral, ainda há muito o que compartilhar nessa área e no geral.
E vocês, fazem simulação na Bolsa de Moscou?
Em um dos próximos artigos, pretendo abordar o tema do netting. Em breve será publicado o quarto artigo — bastante interessante, na minha opinião.
De modo geral, ainda há muito o que compartilhar nessa área e no geral.
E vocês, fazem simulação na Bolsa de Moscou?
Ainda não cheguei à aplicação prática, fiquei na fase de pesquisa.
Por enquanto, deixei esse assunto de lado, mas leio seus artigos com interesse. Obrigado pelos artigos!
Talvez os próximos artigos me motivem a retomar o assunto)
Posso enviar o código da minha implementação; até tenho uma calculadora de opções guardada por aí.
Se tiver interesse, me mande uma mensagem privada.
Não chegou à aplicação prática, ficou na fase de pesquisa.
Por enquanto, deixei esse assunto de lado, mas leio seus artigos com interesse. Obrigado pelos artigos!
Talvez os próximos artigos me motivem a retomar o assunto)
Posso compartilhar o código da minha implementação; até mesmo a calculadora de opções está guardada em algum lugar.
Se tiver interesse, me mande uma mensagem privada.