Доска опционов

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

Доска опционов с колл- и пут-сторонами вокруг страйков

Создание и обновление

import {
  OptionDeskWidget,
  type TradingHost,
} from '@stocksharp/trading-controls';

declare const host: TradingHost;

const desk = OptionDeskWidget.create(
  document.querySelector<HTMLElement>('#option-desk')!,
  {},
  { host },
);

desk.update(
  [{
    strike: 68_000,
    call: {
      symbol: 'BTC-68000-C',
      bid: 1_240,
      ask: 1_265,
      last: 1_250,
      theoretical: 1_248,
      volume: 320,
      openInterest: 1_480,
      ivBid: 0.42,
      ivAsk: 0.44,
      ivLast: 0.43,
      historicalVolatility: 0.39,
    },
    put: {
      symbol: 'BTC-68000-P',
      bid: 820,
      ask: 845,
      volume: 210,
      openInterest: 960,
      ivLast: 0.47,
    },
  }],
  {
    assetPrice: 68_420,
    timeToExpiry: 0.08,
    riskFree: 0.05,
    dividend: 0,
  },
);

Единственная зависимость — host; необязательных зависимостей у контрола нет. Второй аргумент create — состояние панели, контрол его не использует.

update(strikes, context) заменяет всю цепочку. Оба аргумента передаются вместе: цепочка и цена базового актива — одно наблюдение, и раздельное обновление показало бы греки, посчитанные от уже сместившейся цены. context необязателен и по умолчанию пуст.

Контекст цепочки

OptionChainContext описывает, относительно чего оценивается серия: assetPrice — цена базового актива, timeToExpiry — время до экспирации в годах, riskFree и dividend — ставки долями (0.05 — это пять процентов). Без assetPrice доска по-прежнему показывает котировки, но внутренняя стоимость равна нулю, а строки не делятся на «в деньгах» и «вне денег». Без assetPrice или timeToExpiry греки не рассчитываются, и ячейка остаётся пустой, а не нулевой.

Греки

Греки приходят одним из двух способов. Если хост считает их сам, он передаёт готовый объект greeks в стороне страйка, и доска показывает то, что получила. Если хост присылает волатильность, греки считаются на месте по Блэку — Шоулзу от первого доступного значения в порядке ivLast, ivBid, ivAsk, historicalVolatility. Ни один из вариантов не является запасным для другого — это две формы хоста.

Число знаков после запятой подбирается по данным: четыре значащих цифры для наименьшего значения в столбце, но не меньше двух и не больше восьми знаков. Счёт один на весь столбец и общий для обеих сторон, поэтому дельта не превращается в 0.0000, а гамма и её зеркальная колонка пишутся одинаково.

Столбцы и представление

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

По умолчанию скрыты столбцы callRho, callTheta, callHv, callTheor и их зеркальные putRho, putTheta, putHv, putTheor — их возвращает контекстное меню таблицы.

Полосы масштабируются по-разному. Объём и открытый интерес — отдельно по каждой стороне, потому что коллы и путы торгуются разными размерами. Волатильности — одной шкалой сразу по обеим сторонам, иначе перекос между сторонами исчезает. Полоса рисуется шириной элемента, без canvas.

Строке присваивается класс option-itm-call для страйков ниже цены актива и option-itm-put для остальных; при отсутствующей assetPrice — только option-row. Волатильности выводятся процентами с двумя знаками, цены — общим форматом цены пакета.

Настройки доска не хранит: обращений к host.preferences и host.cache у неё нет, набор столбцов и сортировка живут в текущем экземпляре.

Что делает хост

Весь видимый текст берётся из host.t — заголовок панели, подписи столбцов, надпись пустой таблицы, пункты контекстного меню. Кнопка закрытия вызывает host.close(): панель себя не удаляет. При создании контрол вызывает host.register(this), при dispose()host.unregister(this). Кнопка на боковой панели выгружает цепочку в XLSX.

Контрол не подписывается на данные и не отправляет заявок: цепочку и контекст ему передаёт хост методом update.

Публичные методы

  • OptionDeskWidget.create(hostEl, state, deps) — построить панель и добавить её в контейнер.
  • update(strikes, context) — заменить цепочку и контекст оценки.
  • rows() — вернуть строки в том виде, в каком их хранит доска: с рассчитанными шкалами полос и внутренней стоимостью.
  • dispose() — освободить ресурсы и снять регистрацию в хосте.
  • OptionDeskWidget.TYPE — идентификатор типа контрола, ControlTypes.OptionDesk.

Экспортируемые функции

Расчётная часть доступна отдельно от панели:

  • scaleChain(strikes, context) — за один проход по цепочке считает максимумы для полос и внутреннюю стоимость каждого страйка.
  • sideGreeks(row, which, context) — греки одной стороны страйка: переданные хостом либо рассчитанные из его волатильности; null, когда ни то ни другое невозможно.
  • greekPlaces(values) — число знаков после запятой для столбца значений.
  • greekScales(rows, context) — число знаков для каждого грека, измеренное сразу по обеим сторонам цепочки.

Смотрите также