От сканера к живой торговле: как опционный бот научился управлять портфелем — MajoTrade
MajoTrade

От сканера к живой торговле: как опционный бот научился управлять портфелем

За три недели с момента последнего обновления опционный бот прошёл путь от пассивного сканирования волатильности до полноценной живой торговли опционами на MOEX. В проекте за это время — 301 коммит, значительная часть из которых посвящена live-эволюции опционного бота: серия safety fixes (BUG-090 — BUG-116), запуск живой торговли и начало сбора данных для машинного обучения.

Живая торговля опционами: CNY/RUB

Бот торгует опционами на юань (CRM6@RTSX) в режиме sell-vol — продаёт переоценённую волатильность через вертикальные спреды. Стратегия автоматическая: бот сканирует рынок каждые 60 секунд, находит кандидатов и принимает решение о входе.

На момент публикации портфель состоит из нескольких опционных позиций (calls + puts), остаётся около дельта-нейтрального с положительной тетой — бот зарабатывает на временном распаде проданных опционов.

За три недели бот прошёл через несколько циклов: от стартовой позиции с 6 orphan-позициями до управляемого портфеля со спредами, собранными через автоматический entry pipeline.

Quality Gate: бот фильтрует сделки

Не каждый спред стоит открывать. Раньше бот входил в позицию, если было место по бюджету. Теперь перед каждым входом работает quality gate — фильтр, который оценивает:

  • Theta/Risk ratio — сколько тета-дохода приносит спред на единицу риска. Минимум 0.2% в день. Если спред добавляет 0.5 RUB тета при 250 RUB риска — это плохая сделка, и gate её отклоняет.
  • Post-trade Greeks — как изменятся дельта, гамма, вега портфеля после сделки. Если дельта уйдёт за ±1.0 — отклонение.

Калибровка threshold на реальных CNY спредах показала: call спреды дают ratio 0.001-0.005, put спреды 0.003-0.009. Порог 0.002 отсекает мусор, но пропускает нормальные сделки.

Первый live результат: CR11.25BF6/CR11BF6 bear call, ratio=0.0033, theta=0.84 RUB/день — PASS.

Managed Residual: бот выходит из deadlock

Главная проблема предыдущих недель — execution lock. После перезапуска бот видел orphan-позиции (длинные опционы без пары), BUG-110 блокировал все входы (“есть residual long — не покупай”), и бот зависал в бесконечном ожидании.

Решение — managed residual mode. Бот теперь определяет, когда orphan-портфель стабилен: нет активных спредов, нет ордеров в работе, broker reconcile прошёл, нет naked short. В этом состоянии BUG-110 ослабляется — бот может открывать новые спреды через quality gate.

Цепочка: E1a (детекция) → E1d (ослабление BUG-110) → Quality Gate (фильтрация) → start_spread().

Post-Trade Admissibility: защита от каскадных потерь

В день деплоя managed residual mode бот открыл спред, который прошёл quality gate, но вызвал цепную реакцию: payoff портфеля вышел за бюджет → T-51 принудительно ликвидировал orphan long по 0.062 (вход был 0.102, убыток ~40 RUB) → bucket стал naked → BUG-111 выкупил short по рынку.

Причина: quality gate проверял marginal Greeks, но не симулировал post-trade payoff всего портфеля.

Исправление — BUG-116: перед каждым входом бот клонирует портфель, добавляет обе ноги спреда, и проверяет: не выйдет ли payoff за бюджет? не появится ли naked short? Если симуляция показывает forced action — вход отклоняется.

После деплоя BUG-116 — ноль принудительных ликвидаций.

Серия safety fixes: BUG-090 — BUG-116

За три недели закрыта серия BUG-090 через BUG-116 — safety guards, каждый из которых закрывал конкретный сценарий потери денег:

  • BUG-108: singleton lock — два бота не запустятся на одном счёте
  • BUG-110: residual inventory gate — нет новых покупок при неуправляемых orphan
  • BUG-111: portfolio-level naked short detection — не считаем naked если в bucket достаточно longs
  • BUG-112: convert path не продаёт уже зашорченные страйки
  • BUG-113: двухуровневый payoff gate — нет buyback если shorts покрыты
  • BUG-114: convert guard не считает building sell дважды
  • BUG-115: enrichment entry_price через Trades API — более точная оценка payoff risk
  • BUG-116: post-trade admissibility — симуляция портфеля до входа

Все guards работают как слои: каждый следующий ловит то, что пропустил предыдущий.

Premium Ledger: точный учёт денег

Раньше P&L считался приблизительно — по entry_price позиций. Теперь каждый fill записывается в таблицу option_fills как денежный поток: символ, сторона, цена, количество, point_value, cashflow в рублях.

Бот начал вести fill-based учёт и периодически логирует три метрики: - Net premium collected — разница между собранной и потраченной премией - Estimated close cost — сколько стоит закрыть все позиции по текущему рынку - Carry — net premium минус close cost (оценка прибыли при закрытии)

Ledger запущен и накапливает данные. Дальше нужна верификация: сверка ledger с реальным P&L и backfill исторических fills для полной картины.

ML Data Collection: подготовка к машинному обучению

Каждое решение бота теперь записывается в options_decision_log: какой кандидат рассматривался, какие были метрики (theta, risk, Greeks), какое состояние портфеля, и какое решение принято (PASS / REJECT с причиной).

Это training data для будущей ML-модели: regime classifier (Random Forest) определит рыночный режим, signal scorer (LightGBM) оценит качество каждого кандидата. Модуль будет advisory-only — рекомендует, но не торгует.

Данные копятся автоматически. Через 4-6 недель можно будет оценить, хватает ли данных для первой regime-модели.

Smile Pro: расширенная визуализация

Вкладка Smile на дашборде получила обновление — отдельные линии Bid IV / Ask IV / Mid IV для каждого страйка, точки с размером пропорциональным объёму в стакане, подсветка staleness (старые данные затемняются), calls и puts отображаются разными стилями линий.

Технический стек

Весь бот — один Rust binary (~13 МБ в release). Ключевые компоненты:

  • options_bot — основной процесс: сканер, стратегия, ордера, risk management
  • PostgreSQL — хранение fills, decisions, scanner signals, Greeks history
  • systemd — управление процессами с memory limits и auto-restart
  • Finam API — gRPC SDK для котировок и ордеров, REST для позиций

Quality gate, BUG-116 simulation и ML logging добавили ~500 строк кода. Все изменения прошли через Codex review с автоматической инъекцией trading review checklist.

Что дальше

  • Per-position IV — использовать smile-aware implied volatility вместо flat HV для точных Greeks
  • Увеличение risk budget — с 1000 до 1500 RUB при капитале 17K RUB
  • ML Phase 1 — regime classifier после накопления 4-6 недель данных
  • Premium Ledger verification — сверка ledger с реальным P&L

Дашборд доступен на bot.majotrade.net. Вкладки Options (цепочка + Greeks) и Smile (IV surface) обновляются автоматически.