Торгуем опционы без опционов (Часть 3): Сложные опционные стратегии
Введение
В предыдущей статье данного цикла мы разобрали базовые опционные стратегии и протестировали их работу на реальном рынке. Создали эксперт, реализующий опционную стратегию. Теперь пора рассмотреть работу и реализовать те стратегии, которые используются на практике опционными трейдерами. Почувствовать новые возможности, появившиеся при торговле опционами.
Визуализация опционных уровней
Прежде чем двигаться дальше, добавим в эксперт возможность отображения текущих опционных уровней. Было бы удобно для визуального контроля процесса торговли видеть в терминале положение текущей цены базового актива относительно используемых при эмуляции опционных уровней. Сделаем это и протестируем на примере рассмотренных в части 2 опционных стратегий.
Будем отображать опционные уровни в виде линий от начала дня и до текущего времени. Также, было бы удобно видеть положение страйка (страйков) на экране терминала. Для начала разработаем метод CalculateLevelPrice. Фактически, данный метод выполняет обратную операцию — по заданному значению дельты опциона вычисляет значение относительной цены. Из относительной цены мы получим конкретное значение абсолютной цены для каждого опционного уровня.
Добавим абстрактные методы TOptionConstructionBase::CalculateUpLevelPrice и TOptionConstructionBase::CalculateDnLevelPrice. Определим их в классах потомках. Рассмотрим методы вычисления подробней.
Почему методов два? Это сделано, поскольку знак дельты будет различен для цен базового актива выше/ниже цены страйка. Поэтому предусматриваем все возможные варианты. Аргументы методов TOptionConstructionBase::CalculateUpLevelPrice и TOptionConstructionBase::CalculateDnLevelPrice следующие:
- _strike_price — цена страйка;
- _norm_price — цена, нормирующая на диапазон волатильности;
- _limit_price — максимальная/минимальная цена для отрезка при поиске методом деления отрезка пополам (в общем случае равна цене нормировки) — вверх/вниз от цены страйка, соответственно;
- _target_delta — целевое значение дельты опционной конструкции, для которого идет поиск ценового уровня;
ЗАМЕЧАНИЕ:
Поскольку сигмоид экспоненциально приближается к нулю и к единице (или минус единице) и никогда не достигает их, то используем значения, близкие к нулю и к единице, для принудительной установки опционных уровней, соответствующих нулевому уровню и максимальному (например десятому).
Для нулевого уровня берем дельту, равную _norm_zero_level с нужным знаком. Для максимального уровня берем значение дельты, равное +-0.96 (значение выбрано опытным путем) — также с нужным знаком. При этом, ограничим диапазон изменения значения _norm_zero_level от 0.01 до 0.05 (напомним, что первому уровню эмуляции опционов соответствует дельта, равная +-0.1).
Код данных методов имеет следующий вид:
// --------------------------------------------------------------------- // Рассчитать ценовые уровни, соотвествующие верхним опционным уровням: // --------------------------------------------------------------------- void CalculateUpPriceLevels(const double _norm_zero_level, double& _strike_price[], double& _norm_price[], double& _limit_price[]) override { // Если массив нулевого размера, то значит уровни отсутствуют: if(ArraySize(this.up_level_values_Array) == 0) { ArrayResize(this.up_price_level_Array, 0); return; } // Нулевой и последний уровень задаем отдельно: 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); // Основные уровни: 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]); } } // --------------------------------------------------------------------- // Рассчитать значение цены для заданной нормированной дельты: // --------------------------------------------------------------------- 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); // Пока ошибка (длина отрезка) больше заданной, продолжаем деление отрезка: while (MathAbs(search_point - _target_delta) > this.tolerance) { // Оценим положение текущей (средней) точки относительно целевой точки: if(curr_point > _target_delta) { up_limit = half_point; } else if(fc < _target_delta) { low_limit = half_point; } else { return (half_point); } // Очередная средняя точка на отрезке: half_point = (low_limit + up_limit) / 2.0; curr_point = this.UpdateOptionConstructionDelta(half_point); } return (low_limit + up_limit) / 2.0; }
Метод TOptionConstructionBase::CalculateUpPriceLevels перебирает в цикле все значения уровней эмуляции опционов и вызывает метод TOptionConstructionBase::CalculateUpLevelPrice, который рассчитывает цену, соответствующую заданной дельте.
Для вычисления будем использовать метод деления отрезка пополам (метод дихотомии), чтобы не решать уравнение сигмоида в аналитическом виде. Это можно сделать, поскольку сигмоид является непрерывной монотонной функцией от цены и на рабочем участке опционной конструкции (там, где происходит основная ребалансировка) сумма сигмоидов также монотонна.
На рис.1 схематично изображен процесс итераций (первые три шага - Step1,..Step3) при поиске точки внутри отрезка (значение target на рис.1). Метод заключается в последовательном определении в какой половине отрезка [up_limit;low_limit] находится искомая точка target. После определения, изменяем границу отрезка (в данном случае, на первых трех шагах верхнюю границу up_limit) на значение середины отрезка:
half_point = (up_limit + low_limit) / 2 ---> up_limit = half_point
Повторяем данную процедуру до тех пор, пока длина отрезка, равная (up_limit - low_limit) станет меньше или равной значению заданной точности _tolerance.
При этом искомое значение будет равно последнему значению half_point. Искомое значение будет не дальше от target, чем заданная точность. Такая процедура вычисления опционных уровней будет вызываться раз в сутки с наступлением нового дня или при старте эксперта.

Рис.1 Последовательность поиска точки внутри отрезка
После применения метода CalculateUpLevelPrice ко всем значениям опционных уровней (0,1,..10) мы получаем массив значений цен, соответствующих этим уровням — опционным уровням выше цены страйка. Для получения значений опционных уровней ниже цены страйка, используется метод CalculateDnLevelPrice (см. файл "OptionEmulatorA3.mqh"). Поиск делается аналогично — различие состоит в том, что опционные уровни откладываются вниз по ценовой шкале от цены страйка. В общем случае, уровни вниз и вверх не обязательно симметричны.
Теперь выполним задачу визуализации опционных уровней на графике терминала МetaТrader 5. Для этого разработаем два класса: класс, инкапсулирующий сам уровень, и класс для манипуляции списком уровней. Класс визуализации уровня представлен ниже:
// ===================================================================== // Базовый класс опционного уровня - порожден от '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: // --------------------------------------------------------------------- // Конструктор: // --------------------------------------------------------------------- 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(); } // --------------------------------------------------------------------- // Деструктор: // --------------------------------------------------------------------- ~TPriceLevelBase() { DESTROY_OBJECT(this.trend); DESTROY_OBJECT(this.text); } // --------------------------------------------------------------------- // Создание объекта: // --------------------------------------------------------------------- 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); } // --------------------------------------------------------------------- // Обновление объекта: // --------------------------------------------------------------------- void Update(const datetime _time) { this.text.SetPoint(0, _time + 15 * 60, this.price); this.trend.SetPoint(1, _time, this.price); } }; // ---------------------------------------------------------------------
Как видим, класс TPriceLevelBase порожден от стандартного класса CObject. Это сделано для того, чтобы можно было использовать стандартный класс для манипуляции списком. Об этом ниже. Объект "уровень" представляет собой горизонтальный отрезок (линию), исходящий от времени открытия текущего дня и до текущего времени внутри дня. Справа от линии будем отображать текстовую метку —номер уровня.
Члены-данные, которые инкапсулируют свойства объекта "уровень" — это стандартные свойства графического объекта "линия" и графического объекта "текстовая метка" на графике терминала МetaТrader 5. Назначение их следующее:
- long chart_id — идентификатор графика, на котором находится данный графический объект;
- int window — идентификатор подокна на графике с графическим объектом, в данном случае ноль для основного окна графика;
- string trend_name — название объекта "линия" для его идентификации среди других подобных объектов на данном графике;
- string text_name — название объекта "текст" для его идентификации среди других подобных объектов на данном графике;
- double price — значение ценового уровня, на котором находятся объекты - горизонтальный отрезок и текстовая метка;
- CChartObjectTrend* trend — указатель на графический объект "линия" из стандартной библиотеки МetaТrader 5;
- CChartObjectText* text — указатель на графический объект "текстовая метка" из стандартной библиотеки МetaТrader 5.
Уровни обновляются с появлением нового бара на графике МetaТrader 5. С открытием нового дня, старые уровни удаляются и начинают отрисовываться новые для текущего дня. Перед этим производится перерасчет исторической волатильности HV для нового дня.
Обновление уровней внутри дня происходит при вызове метода TPriceLevelBase::Update(const datetime _time), аргументом которого является время открытия текущего бара. Временная координата текстовой метки смещается дополнительно вправо, чтобы не накладываться на линию уровня.
Класс для манипуляции списком уровней TVisualPriceLevels представлен ниже:
// ===================================================================== // Визуализация уровней ребалансировки опционной конструкции: // ===================================================================== class TVisualPriceLevels : public CList { private: long chart_id; int window; public: // --------------------------------------------------------------------- // Деструктор: // --------------------------------------------------------------------- ~TVisualPriceLevels() { this.Clear(); } // --------------------------------------------------------------------- // Конструктор: // --------------------------------------------------------------------- TVisualPriceLevels(const long _chart_id, const int _window) : chart_id(_chart_id), window(_window), CList() { this.FreeMode(true); } // --------------------------------------------------------------------- // Добавление уровня: // --------------------------------------------------------------------- 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); } // --------------------------------------------------------------------- // Обновление уровней: // --------------------------------------------------------------------- void Update(const datetime _time) { if(this.Total() > 0) { TPriceLevelBase* trend = this.GetFirstNode(); while(trend != NULL) { trend.Update(_time); trend = this.GetNextNode(); } } } }; // ---------------------------------------------------------------------
Как и в классе TPriceLevelBase здесь также есть метод TVisualPriceLevels::Update(const datetime _time), который обновляет все добавленные в список уровни путем перебора объектов и вызова в каждом объекте метода TPriceLevelBase::Update(const datetime _time).
Добавился метод TPriceLevelBase::AddLevel с параметрами, задающими расположение и стиль линии (опционного уровня)/текстовой метки. Данный метод создает объект типа TPriceLevelBase и добавляет его в список, вызывая метод CList::Add стандартного класса CList.
Кроме того, добавим в основной файл эксперта ("Article3-OptionTrader.mq5") новые входные параметры для задания свойств отображаемых на экране уровней — цвет текстовой метки, цвет линии, стиль линии. Можно раздельно задать параметры линий/текстовых меток для страйка и уровней ребалансировки вверх/вниз.
// --------------------------------------------------------------------- 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 // --------------------------------------------------------------------
Результат работы части эксперта, отвечающей за визуализацию уровней, представлен на рис.2. Хорошо заметно не линейное распределение опционных уровней по ценовой шкале — результат работы формулы Блэка-Шоулза. В данном случае цена страйка — это цена открытия дня. Для более сложных опционных конструкций цен страйков может быть несколько и их значения отличаться от цены открытия.

Рис.2 Визуализация опционных уровней
Сложные опционные стратегии
Теперь дополним наш список опционных конструкций новыми стратегиями:
// --------------------------------------------------------------------- // Опционная конструкция: // --------------------------------------------------------------------- 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 }; // --------------------------------------------------------------------
Рассмотрим смысл и условия использования новых стратегий, перечисленных выше.
Покупка стрэдла — Long STRADDLE
- Смысл: одновременная покупка опционов колл и пут с одинаковыми страйками;
- Условие использования: если есть уверенность в росте или падении цены базового актива выше диапазона исторической волатильности HV, но нет предположений о направлении;
- Прибыль: не ограничена;
- Риск: премия, уплаченная за два опциона (при эмуляции отсутствует) + убыток при ребалансировке опционной конструкции.
Зависимость значения дельты опционной конструкции "Delta" от относительного изменения цены "DPrice" приведена на рис.3. Такая зависимость получается при покупке двух опционов с одинаковыми страйками — покупка опциона Long Put и покупка опциона Long Call. В таблице слева от графика приведены значения DPrice (x в таблице), при которых происходит ребалансировка опционной конструкции.

Рис.3 Зависимость значения дельты "Delta" от относительного изменения цены "DPrice" (x - в таблице) для эмулируемой опционной конструкции Long STRADDLE. S = 0.5, K = 10. Диапазон по дельте разбит на десять равных частей
Примерный график зависимости PnL (Прибыль/Убыток - Profit/Loss) от относительного изменения цены приведен на рис.4. Нужно понимать, что график этот теоретический для среднего значения исторической волатильности HV цены базового актива. Риск в большой степени зависит от количества ребалансировок опционной конструкции — каждая ребалансировка добавляет убыток к общему PnL. В этом и заключается главное отличие эмулированного опциона от реального.
Из графика видно, что максимальный профит получается, если цена базового актива выходит за пределы диапазона волатильности HV (как минимум, не совершает большого числа колебаний между опционными уровнями) — на рисунке закрашено зеленым цветом.
Левая часть оси DPrice (DPrice < 0) соответствует падению цены базового актива относительно цены страйка — обозначена стрелкой, направленной влево с надписью "Long Put working area, Long Call = 0" (рабочая область опциона Long Put). В этой области значение дельты опциона Long Call равно нулю, то есть на эмуляцию совокупной опционной позиции он не влияет.
Правая часть оси DPrice (DPrice > 0) соответствует росту цены базового актива относительно цены страйка — обозначена стрелкой, направленной вправо с надписью "Long Call working area, Long Put = 0" (рабочая область опциона Long Call). В этой области значение дельты опциона Long Put равно нулю, то есть на эмуляцию совокупной опционной позиции он не влияет.
На графике также обозначены: области прибыли (Profit), убытка (Loss) и положение цены страйк (Strike).

Рис.4 Зависимость значения "PnL" (прибыль/убыток) от относительного изменения цены "DPrice" для эмулируемой опционной конструкции Long STRADDLE.
Пример работы опционной конструкции Long Straddle показан на рис.5. В данном случае опционная конструкция была доведена до экспирации. Поскольку цена совершала колебания внутри диапазона волатильности и к концу дня почти вернулась к цене открытия, получен некоторый убыток.
Также из графика видно, что около 15 часов цена базового актива достигала седьмого уровня эмуляции и можно было досрочно экспирировать опционы с получением прибыли. Проблем с ликвидностью, в отличие от реальных опционов, не было бы.

Рис.5 Работа опционной стратегии Long Straddle
Продажа стрэдла — Short STRADDLE
- Смысл: одновременная продажа опционов колл и пут с одинаковыми страйками;
- Условие использования: если есть уверенность в том, что цена базового актива останется в среднем диапазоне исторической волатильности HV, а направление ее не имеет значения;
- Прибыль: премия, которую платит покупатель за два опциона (при эмуляции отсутствует) + прибыль, накапливающаяся при колебаниях цены внутри диапазона (есть только при эмуляции);
- Риск: не ограничен.
Зависимость значения дельты опционной конструкции "Delta" от относительного изменения цены "DPrice" приведена на рис.6. Такая зависимость получается при продаже двух опционов с одинаковыми страйками — продажа опциона Long Put и продажа опциона Long Call. В таблице слева от графика приведены значения DPrice (x в таблице), при которых происходит ребалансировка опционной конструкции.

Рис.6 Зависимость значения дельты "Delta" от относительного изменения цены "DPrice" (x - в таблице) для эмулируемой опционной конструкции Short STRADDLE. S = 0.5, K = 10. Диапазон по дельте разбит на десять равных частей
Примерный график зависимости значения PnL (профит/убыток) от относительного изменения цены приведен на рис.7. Нужно понимать, что график этот теоретический для среднего значения исторической волатильности HV цены базового актива. В этом — главное отличие эмулированного опциона от реального.
Из графика видно, что профит получается, если цена базового актива остается в пределах диапазона исторической волатильности HV — на рисунке закрашено зеленым цветом. Чем больше колебаний цены между опционными уровнями, тем выше прибыль при экспирации (при этом, для максимизации прибыли цена должна возвратиться как можно ближе к цене страйка). Направление колебаний относительно цены страйка значения не имеет, — мы получаем почти идеальную конструкцию для торговли в диапазоне.
Если цена базового актива выйдет за пределы диапазона исторической волатильности HV и останется там до экспирации, то мы получим убыток. Тем больший, чем сильней будет выход. Теоретически, риск не ограничен. В реальности мы всегда можем закрыть позиции и остановить работу советника. Существуют более сложные опционные конструкции, автоматически снижающие риск до приемлемой величины и почти не влияющие на прибыль. Об этом — в следующей статье.
Левая часть оси DPrice (DPrice < 0) соответствует падению цены базового актива относительно цены страйка — обозначена стрелкой, направленной влево с надписью "Short Put working area, Short Call = 0" (рабочая область опциона Short Put). В этой области значение дельты опциона Short Call равно нулю, то есть на эмуляцию совокупной опционной позиции он не влияет.
Правая часть оси DPrice (DPrice > 0) соответствует росту цены базового актива относительно цены страйка — обозначена стрелкой, направленной вправо с надписью "Short Call working area, Short Put = 0" (рабочая область опциона Short Call). В этой области значение дельты опциона Short Put равно нулю, то есть на эмуляцию совокупной опционной позиции он не влияет.
На графике также обозначены: области прибыли (Profit), убытка (Loss) и положение цены страйк (Strike).

Рис.7 Зависимость значения PnL (профит/убыток) от относительного изменения цены "DPrice" для эмулируемой опционной конструкции Short STRADDLE
Пример работы опционной конструкции Short Straddle показан на рис.8. Максимальный достигнутый уровень для ребалансировки опционной позиции внутри дня был равен девяти. Хорошо видно как на каждом колебании цены базового актива между опционными уровнями, мы добавляем прибыль. К концу дня, до наступления экспирации, все позиции были закрыты — цена вернулась к нулевому уровню. В данном случае наш прогноз нахождения цены в диапазоне полностью оправдался. Понятно, что такое происходит не всегда.

Рис.8 Работа опционной стратегии Short Straddle
Покупка стрэнгла — Long STRANGLE
- Смысл: одновременная покупка опционов колл и пут с разными страйками, лежащими внутри диапазона исторической волатильности HV;
- Условие использования: если есть уверенность в сильном изменении цены базового актива, но нет предположений о направлении;
- Прибыль: не ограничена;
- Риск: премия, уплаченная за два опциона (при эмуляции отсутствует) + убыток при ребалансировке опционной конструкции.
Отличие от Long Straddle состоит в том, что здесь используются два страйка — для отрицательной и для положительной области DPrice. В промежутке между страйками позиция равна нулю, следовательно, размер текущего PnL в этой области не меняется.
Примерный график зависимости PnL (Прибыль/Убыток - Profit/Loss) от относительного изменения цены приведен на рис.9. Нужно понимать, что график этот теоретический для среднего значения исторической волатильности HV цены базового актива. Риск в большой степени зависит от количества ребалансировок опционной конструкции - каждая ребалансировка добавляет убыток к общему PnL. В этом — главное отличие эмулированного опциона от реального.
Левая часть оси DPrice (DPrice < 0) соответствует падению цены базового актива относительно цены страйка Strike1 — обозначена стрелкой, направленной влево с надписью "Long Put working area, Long Call = 0" (рабочая область опциона Long Put). В этой области значение дельты опциона Long Call равно нулю, то есть на эмуляцию совокупной опционной позиции он не влияет.
Правая часть оси DPrice (DPrice > 0) соответствует росту цены базового актива относительно цены страйка Strike2 — обозначена стрелкой, направленной вправо с надписью "Long Call working area, Long Put = 0" (рабочая область опциона Long Call). В этой области значение дельты опциона Long Put равно нулю, то есть на эмуляцию совокупной опционной позиции он не влияет.
Из графика видно, что максимальный профит получается, если цена базового актива выходит за пределы диапазона волатильности HV (как минимум, не совершает большого числа колебаний между опционными уровнями) — на рисунке закрашено зеленым цветом. Колебания цены между страйками не оказывает влияния на Прибыль/Убыток, так как в этой области дельта обоих обпционов равна нулю.
На графике также обозначены: области прибыли (Profit), убытка (Loss) и положение цен страйков (Strike1 и Strike2).

Рис.9 Зависимость значения PnL (профит/убыток) от относительного изменения цены "DPrice" для эмулируемой опционной конструкции Long STRANGLE
Пример работы опционной конструкции Long Strangle показан на рис.10. Видно не линейное распределение уровней эмуляции и сделки ребалансировки опционной позиции. Положение уровней Strike1 и Strike2 соответствует значению относительного изменения цены (DPrice) равному 0.1 от значения исторической волатильности HV для текущего дня.
Это значение задается во внешних параметрах эксперта с помощью показанной ниже переменной (может меняться от 0.01 до 0.10):
В данном случае, цена базового актива в первой половине дня увеличивалась и достигала восьмого уровня эмуляции. На откатах вниз накапливался убыток, но на момент создания картинки позиция находится в неплохой прибыли (даже с учетом закрытых отрицательных сделок). Здесь возникает желание досрочной экспирации опционной конструкции — данную возможность мы добавим в эксперт в дальнейшем. Также автоматизируем досрочную экспирацию с заданием уровня экспирации.

Рис.10 Работа опционной стратегии Long Strangle
Продажа стрэнгла — Short STRANGLE
- Смысл: одновременная продажа опционов колл и пут с разными страйками, лежащими внутри диапазона исторической волатильности HV
- Условие использования: если есть уверенность в том, что цена базового актива останется в широком диапазоне, а направление ее не имеет значения
- Прибыль: премия, которую платит покупатель за два опциона (при эмуляции отсутствует) + прибыль, накапливающаяся при колебаниях цены внутри широкого диапазона
- Риск: не ограничен
Отличие от Short Straddle в том, что здесь используются два страйка — для отрицательной и для положительной области DPrice. В промежутке между страйками позиция равна нулю, следовательно, размер текущего PnL в этой области не меняется.
Примерный график зависимости значения PnL (профит/убыток) от относительного изменения цены приведен на рис.11. Нужно понимать, что график этот теоретический для среднего значения исторической волатильности HV цены базового актива. В этом — главное отличие эмулированного опциона от реального.
Из графика видно, что профит получается, если цена базового актива остается в пределах диапазона исторической волатильности HV — на рисунке закрашено зеленым цветом. Чем больше колебаний цены между опционными уровнями, тем выше прибыль при экспирации (при этом, для максимизации прибыли цена должна возвратиться как можно ближе к цене страйка). Направление колебаний относительно цены страйка значения не имеет - мы получаем почти идеальную конструкцию для торговли в диапазоне.
Если цена базового актива выйдет за пределы диапазона исторической волатильности HV и останется там до экспирации, то мы получим убыток. Тем больший, чем сильней будет выход. Теоретически, риск не ограничен. В реальности мы всегда можем закрыть позиции и остановить работу советника. Существуют более сложные опционные конструкции, автоматически снижающие риск до приемлемой величины и почти не влияющие на прибыль. Об этом — в следующей статье.
Левая часть оси DPrice (DPrice < 0) соответствует падению цены базового актива относительно цены страйка — обозначена стрелкой, направленной влево с надписью "Short Put working area, Short Call = 0" (рабочая область опциона Short Put). В этой области значение дельты опциона Short Call равно нулю, то есть на эмуляцию совокупной опционной позиции он не влияет.
Правая часть оси DPrice (DPrice > 0) соответствует росту цены базового актива относительно цены страйка — обозначена стрелкой, направленной вправо с надписью "Short Call working area, Short Put = 0" (рабочая область опциона Short Call). В этой области значение дельты опциона Short Put равно нулю, то есть на эмуляцию совокупной опционной позиции он не влияет.
На графике также обозначены: области прибыли (Profit), убытка (Loss) и положение цен страйков (Strike1 и Strike2).

Рис.11 Зависимость значения PnL (профит/убыток) от относительного изменения цены "DPrice" для эмулируемой опционной конструкции Long STRADDLE
Пример работы опционной конструкции Long Strangle показан на рис.12. Положение уровней Strike1 и Strike2 соответствует значению относительного изменения цены (DPrice) равному 0.08 от значения исторической волатильности HV для текущего дня. Из графика видно, что в первой половине дня цена базового актива совершала колебания выше цены открытия — между страйком и четвертым уровне ребалансировки. В результате этого была накоплена некоторая прибыль.
Примерно в 15:30 МСК цена базового актива развернулась вниз и сделала несколько колебаний между первым и пятым уровнями ребалансировки — это принесло еще некоторую прибыль. Здесь уже можно исполнить опционы досрочно, зафиксировав прибыль. В общем случае, окончательное решение всегда остается за трейдером.
Как видим, для данной опционной стратегии направление движения базового актива не имеет значения — главное, чтобы цена его оставалась внутри диапазона исторической волатильности HV. Для нормального распределения приращений цены это так, но в реальности возможны однонаправленные выбросы цены. Здесь могут помочь либо более сложные опционные стратегии, либо досрочная экспирация позиции.

Рис.12 Работа опционной стратегии Short Strangle
Реализуем Long Straddle на MQL5
Класс StraddleLongOptionConstruction, создающий опционную конструкцию, порожден от базового класса TOptionConstructionBase (см. описание в предыдущей статье "Торгуем опционы без опционов (Часть 2): Использование в реальной торговле"). Параметры конструктора —это число опционных уровней (int _levels_number) при эмуляции и максимальная ошибка (double _tolerance) при вычислении цен, соотвествущих значениям дельты для визуализации уровней.
Метод StraddleLongOptionConstruction::CreateOptionConstruction(...) создает два объекта: типа OptionLongPut и типа OptionLongCall и добавляет их в список CList, от которого порожден базовый класс опционной конструкции TOptionConstructionBase.
// ===================================================================== // Класс опционной конструкции типа 'Straddle Long': // ===================================================================== class StraddleLongOptionConstruction : public TOptionConstructionBase { public: // --------------------------------------------------------------------- // Конструктор: // --------------------------------------------------------------------- StraddleLongOptionConstruction(const int _levels_number = 10, const double _tolerance = 0.00001) : TOptionConstructionBase(ENUM_OPTION_CONSTRUCTION_STRADDLE_LONG, _levels_number, _tolerance) { } // --------------------------------------------------------------------- // Создание опционной конструкции: // --------------------------------------------------------------------- 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)); } ... остальная часть кода находится в файле "OptionEmulatorA3.mqh" ... }; // ---------------------------------------------------------------------
Остальные методы класса описаны в предыдущей статье и ранее в данной статье.
Реализуем Short Straddle на MQL5
Класс StraddleShortOptionConstruction, создающий опционную конструкцию, порожден от базового класса TOptionConstructionBase (см. описание в предыдущей статье). Параметры конструктора — это число опционных уровней (int _levels_number) при эмуляции и максимальная ошибка (double _tolerance) при вычислении цен, соотвествущих значениям дельты для визуализации уровней.
Метод StraddleShortOptionConstruction::CreateOptionConstruction(...) — создает два объекта: типа OptionShortPut и типа OptionShortCall и добавляет их в список CList, от которого порожден базовый класс опционной конструкции TOptionConstructionBase.
// ===================================================================== // Класс опционной конструкции типа 'Straddle Short': // ===================================================================== class StraddleShortOptionConstruction : public TOptionConstructionBase { public: // --------------------------------------------------------------------- // Конструктор: // --------------------------------------------------------------------- StraddleShortOptionConstruction(const int _levels_number = 10, const double _tolerance = 0.00001) : TOptionConstructionBase(ENUM_OPTION_CONSTRUCTION_STRADDLE_SHORT, _levels_number, _tolerance) { } // --------------------------------------------------------------------- // Создание опционной конструкции: // --------------------------------------------------------------------- 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)); } ... остальная часть кода находится в файле "OptionEmulatorA3.mqh" ... }; // ---------------------------------------------------------------------
Остальные методы класса описаны в предыдущей статье и ранее в данной статье.
Реализуем Long Strangle на MQL5
Класс StrangleLongOptionConstruction, создающий опционную конструкцию, порожден от базового класса TOptionConstructionBase (см. описание в предыдущей статье). Параметры конструктора — это число опционных уровней (int _levels_number) при эмуляции и максимальная ошибка (double _tolerance) при вычислении цен, соотвествущих значениям дельты для визуализации уровней.
Метод StrangleLongOptionConstruction::CreateOptionConstruction(...) — создает два объекта: типа OptionLongPut и типа OptionLongCall и добавляет их в список CList, от которого порожден базовый класс опционной конструкции TOptionConstructionBase.
// ===================================================================== // Класс опционной конструкции типа 'Strangle Long': // ===================================================================== class StrangleLongOptionConstruction : public TOptionConstructionBase { public: // --------------------------------------------------------------------- // Конструктор: // --------------------------------------------------------------------- StrangleLongOptionConstruction(const int _levels_number = 10, const double _tolerance = 0.00001) : TOptionConstructionBase(ENUM_OPTION_CONSTRUCTION_STRANGLE_LONG, _levels_number, _tolerance) { } // --------------------------------------------------------------------- // Создание опционной конструкции: // --------------------------------------------------------------------- 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)); } ... остальная часть кода находится в файле "OptionEmulatorA3.mqh" ... }; // ---------------------------------------------------------------------
Отличие данной опционной конструкции от Long Straddle в том, что задаются разные цены страйков Strike1 и Strike2 для опционов Long Put и Long Call. Остальные методы класса описаны в предыдущей статье и ранее в данной статье.
Реализуем Short Strangle на MQL5
Класс StrangleShortOptionConstruction, создающий опционную конструкцию, порожден от базового класса TOptionConstructionBase (см. описание в предыдущей статье). Параметры конструктора — это число опционных уровней (int _levels_number) при эмуляции и максимальная ошибка (double _tolerance) при вычислении цен, соотвествущих значениям дельты для визуализации уровней.
Метод StrangleShortOptionConstruction::CreateOptionConstruction(...) — создает два объекта: типа OptionShortPut и типа OptionShortCall и добавляет их в список CList, от которого порожден базовый класс опционной конструкции TOptionConstructionBase.
// ===================================================================== // Класс опционной конструкции типа 'Strangle Short': // ===================================================================== class StrangleShortOptionConstruction : public TOptionConstructionBase { public: // --------------------------------------------------------------------- // Конструктор: // --------------------------------------------------------------------- StrangleShortOptionConstruction(const int _levels_number = 10, const double _tolerance = 0.00001) : TOptionConstructionBase(ENUM_OPTION_CONSTRUCTION_STRANGLE_SHORT, _levels_number, _tolerance) { } // --------------------------------------------------------------------- // Создание опционной конструкции: // --------------------------------------------------------------------- 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)); } ... остальная часть кода находится в файле "OptionEmulatorA3.mqh" ... }; // --------------------------------------------------------------------
Отличие данной опционной конструкции от Short Straddle в том, что задаются разные цены страйков Strike1 и Strike2 для опционов Short Put и Short Call. Остальные методы класса описаны в предыдущей статье серии и ранее в данной статье.
Заключение
Как видим, реализация опционных конструкций при объектно-ориентированном подходе весьма проста и прозрачна для понимания. Все особенности реализации скрыты в базовых классах. При этом, сложность опционной конструкции (фактически, число объектов в списке CList) ограничена только фантазией пользователя и ресурсами компьютера.
Описанные в статье двухопционные конструкции находят достаточно широкое применение в торговле — в частности, на московской бирже MOEX. Но есть и более сложные, четырехопционные стратегии, которые позволяют снизить риски для купленных опционов и зафиксировать прибыль для проданных опционов — о них пойдет речь в четвертой статье данного цикла.
Также, модернизируем наш эксперт, добавив в него экспирацию по уровню — это позволит автоматически фиксировать прибыль для стратегий с купленными опционами.
В следующей таблице представлены все файлы, приложенные к статье:
| Название файла | Описание |
|---|---|
| Article3-OpionTrader.mq5 | Файл, содержащий код эксперта, торгующего опционными конструкциями, описанными в статье, используя эмуляцию опционов |
| CheckNewBar.mq5 | Файл, содержащий код класса для проверки появления нового бара на графике терминала Meta Trader 5 |
| OptionEmulatorA3.mq5 | Файл, содержащий код классов для эмуляции опционов и опционных конструкций, описанных в статье |
| PriceLevelsA3.mq5 | Файл, содержащий код классов для визуализации опционных уровней на графике терминала Meta Trader 5 |
Предупреждение: все права на данные материалы принадлежат MetaQuotes Ltd. Полная или частичная перепечатка запрещена.
Данная статья написана пользователем сайта и отражает его личную точку зрения. Компания MetaQuotes Ltd не несет ответственности за достоверность представленной информации, а также за возможные последствия использования описанных решений, стратегий или рекомендаций.
Алгоритм Поиска Ворона — Crow Search Algorithm (CSA)
Нейросети в трейдинге: От трансформеров к спайковым нейронам (Основные компоненты)
Переходим на MQL5 Algo Forge (Часть 4): Работа с версиями и выпуск релизов
Разработка продвинутых торговых систем ICT: Реализация сигналов в индикаторе Order Blocks
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
Идея отличная!
Скажите, плз, имеет ли значение какого типа счет - с хеджированием или без?
Еще, какой бы час открытия рынка не ставить, базовый уровень всегда с начала суток. Это так должно быть? Как-то не логично...
Заранее спасибо!
Пропустил Ваше сообщение. Вообще, на неттинговых счетах робота не проверял. Там будет всегда одна позиция и надо делать сокращение/добавление объема при ребалансировке. Открываться, думаю, позиции будут, насчет правильного закрытия не уверен. Надо подкорректировать эксперт.
Если речь про
input int AddNewFromHours = 1; // Add New Hours (0...23) From
то это не час открытия рынка - это час внутри суток, с которого начинает торговать эксперт.
Положение опционных уровней определяется исходя из исторической волатильности HV. От этого параметра она не зависит.
Как-то так. Если что не понятно, спрашивайте.
Вообще, на неттинговых счетах робота не проверял.
Вон оно что!
А я думаю, почему не сходится с моей реализации торговли,
Забыл ужк про хеджевые счета)
Вон оно что!
А я думаю, почему не сходится с моей реализации торговли,
Забыл ужк про хеджевые счета)
В одной из следующих статей планирую добавить работу с неттингом. Скоро будет четвертая статья - довольно интересная, на мой взгляд.
Вообще, еше много есть чем поделиться в этой области и в целом.
А вы на мосбирже эмулируете?
В одной из следующих статей планирую добавить работу с неттингом. Скоро будет четвертая статья - довольно интересная, на мой взгляд.
Вообще, еше много есть чем поделиться в этой области и в целом.
А вы на мосбирже эмулируете?
До практического применения не дошел, остановился на уровне исследований.
Пока отложил эту тему, но с интересом читаю ваши статьи. Спасибо за статьи!
Возможно следуущими статьями сподвигните меня снова продолжить)
Могу скинуть код своей реализации, даже опционный калькулятор гдето валяется.
Если интересно напишите в личку.
До практического применения не дошел, остановился на уровне исследований.
Пока отложил эту тему, но с интересом читаю ваши статьи. Спасибо за статьи!
Возможно следуущими статьями сподвигните меня снова продолжить)
Могу скинуть код своей реализации, даже опционный калькулятор гдето валяется.
Если интересно напишите в личку.