preview
Торгуем опционы без опционов (Часть 2): Использование в реальной торговле

Торгуем опционы без опционов (Часть 2): Использование в реальной торговле

MetaTrader 5Примеры |
90 1
Dmitriy Skub
Dmitriy Skub

Введение

В первой части цикла мы кратко описали торговый инструмент опцион, его возможности, достоинства и недостатки. Разработали теорию и практическую реализацию на MQL5 способа эмуляции опциона через использование базового актива. Пора пробовать опционы в деле — для торговли на рынке. 

С этой целью нам нужно создать эксперт, который будет заниматься отображением уровней эмуляции опциона в реальные ордера и позиции на базовом активе и заниматься непрерывной ребалансировкой полученной суммарной позиции.


Использование в реальной торговле

Сначала разберем какие же стратегии можно использовать в торговле. Здесь мы рассматриваем только спекулятивные стратегии. Начнем с самых простых — покупка/продажа одиночных опционов. Для этого составим таблицу со всеми возможными вариантами.

Простые торговые стратегии и условия их использования

Покупка колл — Long Call

  • Смысл: покупка опциона колл 
  • Условие: если есть уверенность в росте цены базового актива
  • Прибыль: не ограничена
  • Риск: премия, уплаченная за опцион (при эмуляции отсутствует)

Покупка пут — Long Put

  • Смысл: покупка опциона пут в ожидании снижения цены базового актива
  • Условие: если есть уверенность в снижении цены базового актива
  • Прибыль: не ограничена
  • Риск: премия, уплаченная за опцион (при эмуляции отсутствует)

Продажа колл — Short Call

  • Смысл: продажа опциона колл в ожидании, что цена базового актива не пойдет в рост, но и не обязательно должна снизится
  • Условие: если есть уверенность в отсутствии роста цены базового актива
  • Прибыль: премия, которую платит покупатель опциона (при эмуляции отсутствует)
  • Риск: Не ограничен

Продажа пут — Short Put

  • Смысл: продажа опциона пут в ожидании, что цена базового актива не будет снижаться, но и не обязательно должна вырасти
  • Условие: если есть уверенность в отсутствии снижения цены базового актива
  • Прибыль: премия, которую платит покупатель опциона (при эмуляции отсутствует)
  • Риск: не ограничен

Примечания:

  • Продажа эмулируемых одиночных опционов особого смысла не имеет, так как премия за нее отсутствует. Но для дальнейшего создания опционных конструкций (в терминах фондового рынка — портфелей опционов) нужно реализовать все варианты.
  • При покупке эмулируемых одиночных опционов премия, естественно, не платится. Но при ребалансировке портфеля может "набежать" некоторый убыток (можно считать его эквивалентом уплаты премии). Размер его зависит от конкретного изменения цены базового актива и времени удержания позиций. В общем случае, этот убыток сравним с премией.


Пишем эксперт для реализации торговой стратегии

Базовый класс TOptionBase и классы опционов OptionLongCall, OptionLongPut, OptionShortCall, OptionShortPut остаются без изменений (см. предыдущую статью цикла). Теперь добавим базовый класс опционной конструкции, который, в дальнейшем, позволит создавать опционные конструкции любой сложности.

Этот класс TOptionConstructionBase показан ниже. Мы наследовали его от стандартного класса CList, входящего в состав библиотек MQL5. Для доступа к CList нужно добавить строку в начало:

#include    <Arrays\List.mqh>

Это позволит манипулировать списками опционов для получения нужной нам суммарной характеристики портфеля. Итак, встречаем класс опционной конструкции:

// =====================================================================
//  Базовый класс опционной конструкции - порожден от 'CList':
// =====================================================================
class TOptionConstructionBase : public CList
{
protected:
  ENUM_OPTION_CONSTRUCTION    type_enum;
  double    total_delta;
  bool      is_option_construction_inited_Flag;

public:
  // ---------------------------------------------------------------------
  //  Деструктор:
  // ---------------------------------------------------------------------
  ~TOptionConstructionBase()
  {
    this.Clear();
  }
  // ---------------------------------------------------------------------
  //  Конструктор:
  // ---------------------------------------------------------------------
  TOptionConstructionBase(ENUM_OPTION_CONSTRUCTION _type_enum)
  :
  type_enum(_type_enum),
  total_delta(0.0),
  is_option_construction_inited_Flag(false),
  CList()
  {
    this.FreeMode(true);
  }
  // ---------------------------------------------------------------------
  //  Получить значение вычисленной ранее нормированной дельты:
  // ---------------------------------------------------------------------
  double GetOptionConstructionDelta()
  {
    return(this.total_delta);
  }
  // ---------------------------------------------------------------------
  //  Получить значение флага общей инициализации опционной конструкции:
  // ---------------------------------------------------------------------
  bool IsOptionConstructionInited()
  {
    return(this.is_option_construction_inited_Flag);
  }
  // ---------------------------------------------------------------------
  //  Установить диапазон нормировки дельты для центрального страйка:
  // ---------------------------------------------------------------------
  void SetOptionConstructionRange(const double& _strike[], const double& _norm_price[])
  {
    this.is_option_construction_inited_Flag = true;
    if(this.Total() > 0)
    {
      int    i = 0;
      TOptionBase* curr_option = this.GetFirstNode();
      while(curr_option != NULL)
      {
        curr_option.SetRange(_strike[i], _norm_price[i]);
        if(curr_option.IsRangeInited() == true)
        {
          this.is_option_construction_inited_Flag = this.is_option_construction_inited_Flag && true;
        }
        else
        {
          this.is_option_construction_inited_Flag = false;
        }
        curr_option = this.GetNextNode();
        i++;
      }
    }
  }
  // ---------------------------------------------------------------------
  //  Итератор обновления дельты:
  // ---------------------------------------------------------------------
  double UpdateOptionConstructionDelta(const double _price)
  {
    this.total_delta = 0.0;
    if(this.Total() > 0)
    {
      TOptionBase* curr_option = this.GetFirstNode();
      while(curr_option != NULL)
      {
        this.total_delta += curr_option.UpdateDelta(_price);
        curr_option = this.GetNextNode();
      }
    }

    return(this.total_delta);
  }
  // ---------------------------------------------------------------------
  //  Создание опционной конструкции:
  // ---------------------------------------------------------------------
  virtual void CreateOptionConstruction(const double _k, const double _s, const int _digits) = 0;
};
// ---------------------------------------------------------------------

Рассмотрим его подробней. Как видим, в самом низу представленного кода записана декларация абстрактного метода CreateOptionConstruction, поэтому и сам базовый класс является абстрактным. Данный метод непосредственно создает опционную конструкцию и будет определен в классах-потомках. Метод принимает параметры _k, _s и _digits. Первые два это значения K и S в сигмоиде, эмулирующем опцион. Последний —число знаков после запятой в базовом активе.

Также, появилось перечисление для типа опционной конструкции ENUM_OPTION_CONSTRUCTION. на данном этапе оно имеет такой вид:

// ---------------------------------------------------------------------
//  Опционная конструкция:
// ---------------------------------------------------------------------
enum ENUM_OPTION_CONSTRUCTION
{
  ENUM_OPTION_CONSTRUCTION_RISING = 0,                                // Base Active Rising - Long CALL
  ENUM_OPTION_CONSTRUCTION_FALLING = 1,                               // Base Active Falling - Long PUT
  ENUM_OPTION_CONSTRUCTION_NOT_RISING = 2,                            // Base Active NOT Rising - Short CALL
  ENUM_OPTION_CONSTRUCTION_NOT_FALLING = 3,                           // Base Active NOT Falling - Short PUT
};
// ---------------------------------------------------------------------

В дальнейшем мы добавим более сложные конструкции и новые типы в перечисление. Этот тип передается как параметр в конструктор класса при создании объекта.

Метод SetOptionConstructionRange(const double& _strike[], const double& _norm_price[]) позволяет установить диапазон нормировки дельты для центрального страйка у каждого из опционов, входящих в конструкцию. Параметры значений страйков и диапазонов нормировки передаются в виде ссылок на массивы, в которые должны быть записаны соответствующие величины. Размерность массивов должна быть равна числу опционов в опционной конструкции.

Для перечисленных выше конструкций размерность всегда равна единице. В данном тестовом представлении проверка правильности размерности не делается, но ее легко добавить в рабочем варианте для реальной торговли. Поскольку опционная конструкция изначально задана, то и размерность массивов (фактически, число опционов) заранее известна.

Также, в базовом классе задается метод для обновления суммарной дельты опционной конструкции UpdateOptionConstructionDelta(const double _price), который возвращает рассчитанную суммарную дельту. Входной параметр метода — это цена базового актива. Данный метод использует методы класса CList для итерации по всем элементам списка.

Далее наследуем от базового класса уже реальные опционные конструкции. Поскольку весь функционал содержится в базовом классе, классы-наследники имеют достаточно простой вид:

// =====================================================================
//  Класс опционной конструкции типа 'Base Active Rising':
// =====================================================================
class BaseActiveRisingOptionConstruction : public TOptionConstructionBase
{
public:
  // ---------------------------------------------------------------------
  //  Конструктор:
  // ---------------------------------------------------------------------
  BaseActiveRisingOptionConstruction()
  :
  TOptionConstructionBase(ENUM_OPTION_CONSTRUCTION_RISING)
  {
  }
  // ---------------------------------------------------------------------
  //  Создание опционной конструкции:
  // ---------------------------------------------------------------------
  virtual void    CreateOptionConstruction(const double _k, const double _s, const int _digits) override
  {
    this.Add(new OptionLongCall(_k, _s, _digits));
  }
};

// =====================================================================
//  Класс опционной конструкции типа 'Base Active Falling ':
// =====================================================================
class BaseActiveFallingOptionConstruction : public TOptionConstructionBase
{
public:
  // ---------------------------------------------------------------------
  //  Конструктор:
  // ---------------------------------------------------------------------
  BaseActiveFallingOptionConstruction()
  :
  TOptionConstructionBase(ENUM_OPTION_CONSTRUCTION_FALLING)
  {
  }
  // ---------------------------------------------------------------------
  //  Создание опционной конструкции:
  // ---------------------------------------------------------------------
  virtual void    CreateOptionConstruction(const double _k, const double _s, const int _digits) override
  {
    this.Add(new OptionLongPut(_k, _s, _digits));
  }
};

// =====================================================================
//  Класс опционной конструкции типа 'Base Active NOT Rising':
// =====================================================================
class BaseActiveNotRisingOptionConstruction : public TOptionConstructionBase
{
public:
  // ---------------------------------------------------------------------
  //  Конструктор:
  // ---------------------------------------------------------------------
  BaseActiveNotRisingOptionConstruction()
  :
  TOptionConstructionBase(ENUM_OPTION_CONSTRUCTION_NOT_RISING)
  {
  }
  // ---------------------------------------------------------------------
  //  Создание опционной конструкции:
  // ---------------------------------------------------------------------
  virtual void    CreateOptionConstruction(const double _k, const double _s, const int _digits) override
  {
    this.Add(new OptionShortCall(_k, _s, _digits));
  }
};

// =====================================================================
//  Класс опционной конструкции типа 'Base Active NOT Falling':
// =====================================================================
class BaseActiveNotFallingOptionConstruction : public TOptionConstructionBase
{
public:
  // ---------------------------------------------------------------------
  //  Конструктор:
  // ---------------------------------------------------------------------
  BaseActiveNotFallingOptionConstruction()
  :
  TOptionConstructionBase(ENUM_OPTION_CONSTRUCTION_NOT_FALLING)
  {
  }
  // ---------------------------------------------------------------------
  //  Создание опционной конструкции:
  // ---------------------------------------------------------------------
  virtual void    CreateOptionConstruction(const double _k, const double _s, const int _digits) override
  {
    this.Add(new OptionShortPut(_k, _s, _digits));
  }
};

// ---------------------------------------------------------------------

Все, что нужно сделать в классе-потомке — это определить метод создания опционной конструкции CreateOptionConstruction. В этом методе мы создаем объект нужного нам опциона (или группы опционов) и добавляем созданный объект в список вызывая метод CList::Add.

Данные классы находятся в файле "OptionEmulatorA2.mqh", приложенном к данной статье.

Входные параметры

Теперь приступим к реализации собственно эксперта для эмуляции с помощью управления реальными позициями. Сначала добавим перечисление, которое будет определять интегральное (общее) состояние эксперта или состояние торговли:

// ---------------------------------------------------------------------
//  Текущее состояние торговли:
// ---------------------------------------------------------------------
enum ENUM_TRADE_MODE_STATE
{
  ENUM_TRADE_MODE_STARTED,                                            // торговля ИДЕТ, позиции ОБСЛУЖИВАЮТСЯ
  ENUM_TRADE_MODE_STOPPED,                                            // торговля ОСТАНОВЛЕНА, все позиции ЗАКРЫТЫ
  ENUM_TRADE_MODE_PAUSED,                                             // торговля ПРИОСТАНОВЛЕНА оператором, существующие позиции НЕ ОБСЛУЖИВАЮТСЯ
  ENUM_TRADE_MODE_WAITING,                                            // торговля ОЖИДАЕТ автоматического возобновления, существующие позиции ОБСЛУЖИВАЮТСЯ, ПРИ ВОЗМОЖНОСТИ
};
// ---------------------------------------------------------------------

В начальном варианте эксперта будут использоваться только два состояния: торговля остановлена и торговля идет. Торговля запускается при старте эксперта после проведения его инициализации, и останавливается после достижения времени экспирации. Будем использовать суточные опционы с обязательной экспирацией перед началом новых суток. 

Добавим в эксперт необходимые внешние параметры:

// =====================================================================
//  Внешние задаваемые параметры:
// =====================================================================
input ENUM_OPTION_CONSTRUCTION    OptionConstruction = ENUM_OPTION_CONSTRUCTION_RISING;  // Option Construction
input ulong     BaseMagic = 10000UL;                                  // Base Magic
input int       MinLotsMultiplier = 1;                                // Min Lots Multiplier
// ---------------------------------------------------------------------
input int       AddNewFromHours = 0;                                  // Add New Hours (0...23) From
input int       AddNewToHours = 24;                                   // Add New Hours (1...24) To
input int       ExpirationTimeHours = 24;                             // Expiration Time, Hours (1...24)
input int       ExpirationTimeMinutes = 0;                            // Expiration Time, Minutes (0...59)
// ---------------------------------------------------------------------
input double    ZeroDelta = 0.01;                                     // Zero Delta (0.01...0.1)
input string    ForceAutoExpirationTime = "23:50";                    // Force Auto Expiration Time (MT5 Server)
input int       ADRDaysNumber = 20;                                   // ADR Days Number
// ---------------------------------------------------------------------

Внешние параметры, которые могут вызвать вопросы:

  • BaseMagic  — базовое значение "магического" номера (при открытии позиции к нему добавляется номер уровня эмуляции опциона, умноженный на 100);
  • MinLotsMultiplier  — множитель минимального лота при определении объема позиции на каждом из уровней;
  • AddNewFromHours — начало работы эксперта внутри дня, в часах (от 0 до 23 часов);
  • AddNewToHours  — завершение работы эксперта внутри дня, в часах (от 1 до 24 часов);
  • ExpirationTimeHours  — время экспирации опционной конструкции внутри дня, в часах от 1 до 24 часов;
  • ExpirationTimeMinutes  — время экспирации опционной конструкции внутри дня, в минутах от 0 до 59 минут;
  • ForceAutoExpirationTime  — время безусловной экспирации и остановки работы эксперта, в формате "hh:mm";
  • ADRDaysNumber  — число дней для расчета исторической волатильности HV.

Торговый эксперт

Представляют интерес следующие функции торгового эксперта:

//---------------------------------------------------------------------
//    Получить нормализованный торговый объем:
//---------------------------------------------------------------------
//  • на входе требуемый лот;
//  • на выходе нормализованный лот;
//---------------------------------------------------------------------
double
NormalizeLots(const double _requied_lots)
{
  double    lots, koeff;
  int       nmbr;

  if(min_trade_volume_step > 0.0)
  {
    koeff = 1.0 / min_trade_volume_step;
    nmbr = (int)MathLog10(koeff);
  }
  else
  {
    koeff = 1.0 / min_trade_volume;
    nmbr = 2;
  }
  lots = MathFloor(_requied_lots * koeff) / koeff;

  //  Ограничение лота снизу:
  if(lots < min_trade_volume)
  {
    lots = min_trade_volume;
  }

  //  Ограничение лота сверху:
  if(lots > max_trade_volume)
  {
    lots = max_trade_volume;
  }

  lots = NormalizeDouble(lots, nmbr);
  return(lots);
}

Нормализация лота требуется из-за того, что в реальной торговле инструменты имеют дискретное изменение торгуемого объема. Кроме того, ограничены число знаков в представлении объема и минимальные/максимальные значения объема. Все эти требования учитываются в представленной выше функции NormalizeLots.

// ---------------------------------------------------------------------
//    Нормализация цены с учетом шага изменения котировок:
// ---------------------------------------------------------------------
double
NormalizePrice(const double _price)
{
  //  Минимальный размер шага изменения котировок, пунктов:
  double    min_price_step = NormalizeDouble(symbol_tick_size / Point(), 0 );

  double    norm_price = NormalizeDouble(NormalizeDouble((NormalizeDouble(_price / Point(), 0 )) / min_price_step, 0 ) * min_price_step * Point(), Digits());
  return(norm_price);
}
// ---------------------------------------------------------------------

Здесь используются значения глобальных переменных, полученных при инициализации:

double  min_trade_volume = SymbolInfoDouble(Symbol(), SYMBOL_VOLUME_MIN);
double  max_trade_volume = SymbolInfoDouble(Symbol(), SYMBOL_VOLUME_MAX);
double  min_trade_volume_step = SymbolInfoDouble(Symbol(), SYMBOL_VOLUME_STEP);
double  symbol_tick_size = SymbolInfoDouble(Symbol(), SYMBOL_TRADE_TICK_SIZE);

В основе алгоритма работы эксперта лежит обработчик события получения нового тика OnTick. Упрощенная схема обработчика приведена ниже:

//    Обработка нового тика (если выполнены все необходимые условия):
if(is_bars_loaded_Flag == true && is_adr_levels_calculated_Flag == true && option_construstion_Ptr.IsOptionConstructionInited() == true)
{
  if(SymbolInfoTick(Symbol(), tick) == true)
  {
    ask_option_construction_delta = option_construstion_Ptr.UpdateOptionConstructionDelta(tick.ask);
    bid_option_construction_delta = option_construstion_Ptr.UpdateOptionConstructionDelta(tick.bid);
    curr_option_construction_delta = option_construstion_Ptr.UpdateOptionConstructionDelta((tick.ask + tick.bid) / 2.0);

    if(is_first_ea_starting == true)
    {
      is_first_ea_starting = false;
Print("CurrDelta : ", DoubleToString(curr_option_construction_delta, 3), "  BidDelta : ", DoubleToString(bid_option_construction_delta, 3), "  AskDelta : ", DoubleToString(ask_option_construction_delta, 3));
    }

    //  Расчитаем текущий ТРЕБУЕМЫЙ ОБЪЕМ ПОЗИЦИИ с проверкой, изменился ли уровень эмуляции опционов:
    if(option_contruction_volume_Ptr.UpdateOptionLevel(curr_option_construction_delta, prev_option_level_value) == true)
    {
      //  Текущий знак уровня эмуляции опционов (+1/0/-1):
      live_option_level_sign = option_contruction_volume_Ptr.GetOptionLevelSign();
                
      //  Текущее значение (по модулю) уровня эмуляции опционов (0/1/2/3/4/5/6/7/8/9/10):
      live_option_level_value = option_contruction_volume_Ptr.GetOptionLevel();

      //  Требуется изменить объем позиции - ребалансировать опционную конструкцию:
      if(live_option_level_value > 0)
      {
        live_position_lots_abs = NormalizeLots(live_option_level_value * min_trade_volume_step * MinLotsMultiplier);
      }
      else
      {
        live_position_lots_abs = 0.0;
      }

Print("#NEW LEVEL  Position Volume : ", DoubleToString(live_option_level_value * live_option_level_sign * MinLotsMultiplier, 1), "  CurrDelta : ", DoubleToString(curr_option_construction_delta, 3), "  Levels Prev/Live: ", prev_option_level_value, "/", live_option_level_value);

      //  Если находимся в режие 'STARTED', то скорректируем совокупный объем виртуальной и реальной позиций:
      if(current_trade_mode_state == ENUM_TRADE_MODE_STARTED)
      {
        //  Если значение УРОВНЯ эмуляции опционов УВЕЛИЧИЛОСЬ, значит надо добавить позиции на новые уровени:
        if(live_option_level_value > prev_option_level_value)
        {
          //  Позиции BUY:
          if(live_option_level_sign == 1)
          {
            //  Если интервал для установки новых ордеров еще не прошел:
            if(CheckAddingNew(tick.time) == true)
            {
              //  Установим реальные ордера на новых уровнях:
              OpenBuyLevels(live_option_level_value, live_option_level_value - prev_option_level_value);
            }
          }
          //  Позиции SELL:
          else if(live_option_level_sign == -1)
          {
            //  Если разрешена торговля:
            if(is_trade_allowed_Flag == true)
            {
              //  Если интервал для установки новых ордеров еще не прошел:
              if(CheckAddingNew(tick.time) == true)
              {
                //  Установим реальные ордера на новых уровнях:
                OpenSellLevels(live_option_level_value, live_option_level_value - prev_option_level_value);
              }
            }
          }
          prev_option_level_value = live_option_level_value;
          prev_option_level_sign = live_option_level_sign;
        }
        //  Если значение УРОВНЯ эмуляции опционов УМЕНЬШИЛОСЬ, значит надо закрыть часть или все позиции на предыдущих уровнях:
        else if(live_option_level_value < prev_option_level_value)
        {
          //  Позиции BUY:
          if(live_option_level_sign == 1)
          {
            //  Если разрешена торговля:
            if(is_trade_allowed_Flag == true)
            {
              for(int curr_level = prev_option_level_value; curr_level > live_option_level_value; curr_level--)
              {
                CloseLevelPositions(Symbol(), POSITION_TYPE_BUY, curr_level);
              }
            }
          }
          //  Позиции SELL:
          else if(live_option_level_sign == -1)
          {
            //  Если разрешена торговля:
            if(is_trade_allowed_Flag == true)
            {
              for(int curr_level = prev_option_level_value; curr_level > live_option_level_value; curr_level--)
              {
                CloseLevelPositions(Symbol(), POSITION_TYPE_SELL, curr_level);
              }
            }
          }
          //  Текущее значение (по модулю) уровня дельты при эмуляции опционов стало НУЛЕВЫМ (все позиции нужно закрыть):
          else  if(live_option_level_sign == 0)
          {
            //  Если разрешена торговля:
            if(is_trade_allowed_Flag == true)
            {
              if(prev_option_level_sign == 1)
              {
                for(int curr_level = prev_option_level_value; curr_level > live_option_level_value; curr_level--)
                {
                  CloseLevelPositions(Symbol(), POSITION_TYPE_BUY, curr_level);
                }
              }
              else if(prev_option_level_sign == -1)
              {
                for(int curr_level = prev_option_level_value; curr_level > live_option_level_value; curr_level--)
                {
                  CloseLevelPositions(Symbol(), POSITION_TYPE_SELL, curr_level);
                }
              }
            }
            live_position_lots_abs = 0.0;
            live_option_level_sign = 0;
          }
        }
      }
      prev_option_level_value = live_option_level_value;
      prev_option_level_sign = live_option_level_sign;      }
    }
  }
}

Мы отслеживаем изменение уровня эмуляции опционов вызовом метода UpdateOptionLevel  — если уровень изменился, то данный метод возвращает истину. Здесь мы сравниваем текущее и предыдущее (на предыдущем тике) значения уровней эмуляции опционов.

При необходимости ребалансировки позиций, проверяем увеличился или уменьшился уровенб эмуляции опционов. Если увеличился, то тредуется добавление позиций. Если уменьшился, то требуется закрытие части позиций. Если уровень эмуляции стал нулевым, то закрываем все открытые позиции. Таким образом происходит ребалансировка совокупной позиции.

Заметим, что в качестве цены для расчета текущей дельты опционной конструкции мы берем среднюю между Bid и Ask. Это позволяет уменьшить зависимость изменений дельты от изменений спреда. С полным текстом эксперта можно ознакомиться в приложенных к данной статье файлах.

При открытии и закрытии позиций используются рыночные ордера. Это сделано для упрощения проверки работы эксперта (есть гарантия сработки ордера). В дальнейшем, рекомендуется (и будет сделано) переход к лимитным ордерам для открытия позиций. Это позволит сократить издержки на комиссии и улучшит торговые результаты за счет устранения спреда при входе в похиции.

Проверяем в реальном времени эмуляцию и торговлю

Предположим, мы решили, что внутри дня цена EURUSD будет двигаться преимущественно вверх. Установим тип опционной конструкции OptionConstruction = ENUM_OPTION_CONSTRUCTION_RISING. Пример работы эксперта, эмулирующего опционную конструкцию Base Active Rising - Long CALL приведен на рисунках ниже: рис.1 — с открытия дня, рис. 2 — крупно участок торговли. Отработались уровни эмуляции с 1 по 9. В начале работы эксперта была проведена ребалансировка уровней:

Рис.1 Отработка опционной конструкции Base Active Rising - Long CALL  — общий план.

Рис.2 Отработка опционной конструкции Base Active Rising - Long CALL  — крупно.

Рис.3 Текущее состояние позиций при эиуляции опционной конструкции Base Active Rising - Long CALL

 

Рис.4 Результат ребалансировки при эиуляции опционной конструкции Base Active Rising - Long CALL в виде сделок из истории торговли

Теперь предположим, что в следующий день мы решили, что цена развернется и пойдет вниз. Установим тип опционной конструкции OptionConstructionENUM_OPTION_CONSTRUCTION_FALLING. На этот раз удача от нас отвернулась — цена к концу дня развернулась против нас и мы получили некоторый убыток. На рис.5 мы видим отработку заданной опционной конструкции. Открывались уровни эмуляции с 1-го по 5-й. При этом размер зафиксированного убытка из-за ребалансировки составил -5.77 USD - см. Рис.6.

Рис.5 Отработка опционной конструкции Base Active Rising - Long Put  — общий план

Рис.6 Результат ребалансировки при эиуляции опционной конструкции Base Active Rising - Long Put в виде сделок из истории торговли

Максимальный совокупный объем позиций может достигать значения 0.1 = 10 уровней * 0.01 — это целевой объем опционной конструкции при значении множителя минимального лота равном единице. Как видно из рис.4, в результате ребалансировки опционной конструкции мы получили зафиксированный убыток -2.39 USD в первом случае и -5.77 USD - во втором (см. рис.6). Это аналог уплаченной премии за покупку опциона. Как задано во входном параметре эксперта ForceAutoExpirationTime = "23:50" в 23:50 произошла экспирация опционной конструкции, зафиксировав положительный результат в первом случае. Понятно, что результат торговли зависит от  конкретной ситуации на рынке и наших действий.


Заключение

Мы рассмотрели практическую реализацию эксперта, эмулирующего заданную опционную конструкцию. Убедились, что практика соответствует теоретическим положениям, приведенным в первой статье данного цикла. В следующей статье мы рассмотрим реализацию опционных стратегий, имеющих реальную практическую ценность. Они используются практикующими опционными трейдерами.

Прикрепленные файлы |
Последние комментарии | Перейти к обсуждению на форуме трейдеров (1)
Roman Shiredchenko
Roman Shiredchenko | 29 июл. 2025 в 08:25

Очень интересно - спс за информацию, читаю и изучаю подробно....

Нейросети в трейдинге: Распутывание структурных компонентов (Энкодер) Нейросети в трейдинге: Распутывание структурных компонентов (Энкодер)
Предлагаем познакомиться с продолжением реализации фреймворка SCNN, который сочетает в себе гибкость и интерпретируемость, позволяя точно выделять структурные компоненты временного ряда. В статье подробно раскрываются механизмы адаптивной нормализации и внимания, что обеспечивает устойчивость модели к изменяющимся рыночным условиям.
Передовые алгоритмы исполнения ордеров на MQL5: TWAP, VWAP и ордера Iceberg Передовые алгоритмы исполнения ордеров на MQL5: TWAP, VWAP и ордера Iceberg
Фреймворк MQL5, предоставляющий розничным трейдерам алгоритмы исполнения институционального уровня (TWAP, VWAP, Iceberg) с помощью унифицированного менеджера исполнения и анализатора эффективности для более плавного и точного разделения ордеров и аналитики.
Отправка сообщений из MQL5 в Discord, создание бота Discord-MetaTrader 5 Отправка сообщений из MQL5 в Discord, создание бота Discord-MetaTrader 5
Подобно Telegram, Discord способен получать информацию и сообщения в формате JSON, используя свои коммуникационные API. В настоящей статье мы рассмотрим, как можно использовать API Discord для отправки торговых сигналов и обновлений из MetaTrader 5 в ваше торговое сообщество Discord.
Оптимизация сообществом ученых — Community of Scientist Optimization (CoSO): Теория Оптимизация сообществом ученых — Community of Scientist Optimization (CoSO): Теория
Секреты эффективной оптимизации торговых стратегий в метаэвристических подходах. Community of Scientist Optimization — новый популяционный алгоритм, вдохновленный механизмами функционирования научного сообщества. В отличие от традиционных природных метафор, CoSO моделирует уникальные аспекты человеческой научной деятельности: публикацию результатов в журналах, конкуренцию за гранты и формирование исследовательских групп.