Skip to content

v0.3.1

Choose a tag to compare

@github-actions github-actions released this 28 Aug 06:49
· 169 commits to main since this release

Влияние: торговая логика (бот 2 и сканер) · P&L · UI · настройки/данные - выпуск накопил
212 коммитов после 0.3.0. У бота 2 сменилось правило размера сделки, уточнён учёт хеджа,
добавлены структура «стрэнгл продавца» и цепочка сделок, а маржинальный риск стал видимым
заранее, а не в момент подхода к ликвидации. Сканер получил слой записи рынка, греки из
подразумеваемой волатильности и режим «продажа»; три дефекта, из-за которых он не мог выдать
сигнал вообще, исправлены. Интерфейс получил переключатель языка RU|EN. Бота 1 затронула
только локализация
, его торговая логика не изменилась ни одной строкой.

Про бота 2 отдельно, потому что это торговая логика и деньги. Размер сделки теперь выводит
движок, а не оператор:
доля депозита deployPct в вооружении цепочки заменена стресс-правилом
(лоты подбираются так, чтобы маржа поддержания при движении спота на ±45% не превышала 80%
счёта). На профиле, где deployPct правили руками, размер входа ИЗМЕНИТСЯ. Поведение хеджа
изменится и при настройках по умолчанию, как только позиция по бессрочному фьючерсу набирается
или уменьшается несколькими сделками по разным ценам, то есть в обычной работе. Прежде движок в
такой позиции неверно считал и её дельту, и её прибыль, а при уменьшении промахивался мимо
собственной цели хеджа; теперь оба счёта точны. Дополнительно поведение меняется, если структура
открыта размером, отличным от калибровочного (полоса теперь масштабируется размером). Цифры в
журнале за прошлые сессии не пересчитываются: исправления действуют с момента обновления.

Про место на диске: записи сканера занимают порядка 80 МБ за трое суток непрерывной работы,
записи тиков бота 2 добавляются суточными файлами рядом с ними. Это новые файлы в профиле,
ранее их не было.

Добавлено

  • [BTC-Options] Маржин-колл стал видимым и заблаговременным (ревизия 2026-08-25: живая сделка
    прошла пик 104.5% утилизации MM, а пятилетний замер дал зону ликвидации, MM от 100% equity,
    в 13 сделках из 84 при deployPct 0.70). Счёт движка теперь отдаёт оценку цены ликвидации
    liq_price_est (цена индекса, на которой MM догоняет equity; модель: внутренняя стоимость ноги
    плюс текущая временная, решается точно по кусочной линейности формулы Deribit) и запас в
    долларах mm_headroom_usd. Карточка «Маржа и риск» показывает строку «ликвидация (MM = equity)
    при BTC ≈ $X (+Y%)», запас и цветовые зоны бара утилизации (до 60% зелёная, 60-80 жёлтая, от
    порога алерта красная); чип бота 2 на «Обзоре» при утилизации от порога несёт «МАРЖА N%»
    вместо фазы - прежде алерт жил только внутри вкладки. Пересечение порогов 80% и 90% вверх
    пишет строку margin-alert в журнал операций (гистерезис 5 п.п.: строка на пересечение, а не
    на тик) и шлёт системную нотификацию. Карточка «Маржа и риск» переехала из секции гипотез в
    сетку живого результата парой к кокпиту (она показывает бумажный счёт, а стояла под шапкой
    «гипотеза» в последней трети страницы; таблица ног заняла полный ряд). Под баром утилизации -
    шкала пути цены «вход · ликвидация»: заполнение равно пройденной доле пути от индекса входа
    (новое поле структуры entryIndex; старые позиции читаются через entryUnderlying) к оценке
    ликвидации, зоны цвета те же; та же метка LIQ рисуется на графике payoff открытой структуры
    (на гипотезе-превью её нет - живой риск не смешивается с конструктором). Пятилетняя книга
    движка после правок побайтово та же - добавлена только наблюдаемость, ни одно решение не
    изменилось.

  • [BTC-Options] Измерители маржинального пути в репозитории. npm run margin:path
    (scripts/margin-path.mjs): живой движок по записи, таблица «пик MM · сделок MM≥80/90/100%»
    по уровням deployPct (это она показала 244% пика при 0.70 и чистые пять лет только у 0.20),
    плюс режим --size-rule stress - замер правила размера от стресс-маржи (лоты от «MM при споте
    ×(1+X%) не выше cap·equity» вместо доли IM на входе; кандидат на замену deployPct). У эталона
    hist-sellhedge.mjs появился --liquidation: симуляция счёта с принудительным закрытием при
    MM от 100% equity на любом часе пути сделки, чтобы «×N за 5 лет» перестал быть условным
    (на записи 2021-2026 у $20k: ×14.1 вместо ×15.5, 13 ликвидаций). Протяжка walkSellTrade
    получила опциональный наблюдатель шага onStep - читает и не меняет (закреплено тестом
    «итог не меняется ни на бит»; без наблюдателя отчёты прежние до байта).

  • [BTC-Options] Автономный размер продавца: лоты каждой сделки цепочки считает ДВИЖОК
    двухсторонним стресс-правилом (lotsByStressMargin в margin.js: максимум q, при котором
    maintenance-маржа на споте ×(1±45%) не превышает 80% счёта; модель марка та же, что у оценки
    цены ликвидации; продавца колла связывает верхняя сторона, пары - худшая из двух). Операторского
    числа deployPct в вооружении цепочки больше нет: билет передаёт правило, размер выводится из
    живых величин ног на каждом входе, отказ называет расчёт числом («MM при ±45% $X за лот против
    80% счёта $Y»). Константы 45/0.8 НЕ выбраны на глаз: сетка eval-accel --size-rule stress на
    пяти годах дала 45% как наименьший запас, при котором пик MM-утилизации записи не превышает 0.8
    у обеих схем (колл 76.6%, стрэнгл 73.9%) при нуле ликвидаций и росте, равном внутривыборочной
    калибровке deployPct (×2.48 против ×2.59 и ×4.12 против ×4.09); cap 1.0 даёт ликвидации почти
    во всех клетках; ±45% читается как «переживи повтор худшего наблюдённого хода» (январь 2023:
    +47% внутри сделки). Правило deploy живёт в движке дефолтом - им сняты книги сверок, и они
    побайтово те же; паспорт соответствия показывает действующее правило размера строкой. Прежний
    замерный stressLots из margin-path заменён вызовом движковой функции. Плюс автономный фолбэк
    цепочки стрэнгла: структурное отсутствие пары (нет пута в допуске при живом колле) открывает
    колл, и структура честно несёт kind sell-call - на пятилетней записи случай не встречался ни
    разу, это страховка живого рынка от зависания цепочки, а не изменение замера.

  • [BTC-Options] Структура «стрэнгл продавца» (sell-strangle): колл 0.45 + пут 0.45 одной
    экспирации с одним перп-хеджем по НЕТТО-дельте пары - перенос кандидата из исследования
    «ускорение оборота» (при равном хвосте пик MM ≤ 0.8 пара даёт ×4.09 против ×2.59 у одиночного
    колла за пять лет, перевес держится при стрессах исполнения; механизм: корреляция дневных P&L
    ног 0.515 плюс маржинный пол пута). Отдельного исполнителя у пары НЕТ: правила пары живут в
    sellstrangle.js (очередь пар для санитарии §1.8 - вето любой ноги переключает пару целиком),
    строитель в structure.js, дальше та же ветка продавца - decideHedge по нетто-дельте с полосой
    0.03·q, залог суммой ног тем же legMargin, общий расчёт в экспирацию, та же цепочка перевхода
    (билет цепочки теперь вооружает и ВИД структуры; старые цепочки без него читаются коллом).
    В тулбаре бота 2 третья кнопка схемы «стрэнгл»; карточки гипотезы и цепочки называют обе ноги
    через «+». Сверка пятилетних книг «эталон против живого движка» для пары пройдена ЖЁСТЧЕ
    планки sell-call: 84/84 сделки совпали по инструментам, датам, лотам и зоне, итог разошёлся на
    1.15% (у sell-call 4.9%) и целиком в двух известных конвенциях (база фандинга, целые контракты
    перпа); обе книги базовой схемы после правок движка побайтово те же; живой смоук UI на реальном
    Deribit чист (13 проверок, включая честные отказы скважности окна и «за лот пары не помещается»).
    По умолчанию ничего не меняется: схема включается только тумблером, боевой прогон на mbp15 не
    переключён - решение отдельное.

  • [OTM-Scanner] Инструментарий исследования «ускорение оборота» схемы продавца (2026-08-26),
    целиком офлайн - живые тракты ботов не тронуты, пятилетние книги базовой схемы после правок
    побайтово те же. Правило выбора ноги получило тип legType (дефолт колл; «P» существует для
    замеров, живой тракт его не передаёт), МтМ шага сделки вынесен в движок (stepMtm - одна
    формула на режим ликвидации эталона и офлайн-оценщик). Эталон умеет --leg C|P и --deploy,
    margin-path - окно срока --expiry через sellCfg. Новый модуль движка sellstrangle.js:
    правила стрэнгла продавца (пара «колл + пут одной экспирации», вход суммой ног, хедж по
    нетто-дельте; своей протяжки нет - walkSellTrade ведёт пару через составную цену). Новый
    вызывающий scripts/eval-accel.mjs: сравнение вариантов схемы ПРИ РАВНОМ ХВОСТЕ - размер
    каждого калибруется под пик MM-утилизации за запись не выше порога (по умолчанию 0.8), затем
    тенор, путы, стрэнгл и лестница экспираций меряются ростом, тиковой просадкой и корреляциями
    при одинаковом хвостовом риске; стрессы исполнения флагами --perp-fee/--exec/--spread-scale.

  • [OTM-Scanner] Столбец «зона» в книге сделок и разрез --zones у эталона схемы продавца.
    Перечень гейтов отвечает на вопрос «что будет, если не входить в плохом режиме», а вторая
    половина цитаты в шапке sell-scan.js («худшая зона давала +2.71% залога за сделку против
    +4.93% в среднем при просадке 26.7% против 13.5%») спрашивает другое - сколько принесли сделки,
    открытые В НЁМ. Теперь считается и это: книга несёт зону входа каждой сделки, а --zones печатает
    разрез по зонам (сделок, доля, средняя, медиана, худшая, итог, просадка). Заодно правило зоны
    стало функцией sellerZone в sellhedge.js и вызывается ОБОИМИ трактами: прежде оно жило
    выражением внутри computeSellScan, то есть чип «зона продавца» в карточке сканера и строка
    отчёта были бы двумя написаниями одного сравнения. Поведение живого сканера не менялось ни на
    бит (то же сравнение, те же тесты); «нет данных» осталось отдельным значением, а не тихим
    зачислением в благополучную зону - в начале записи RV7d ещё не набрал недельное окно. Столбец
    добавлен и в книгу replay-sellhedge.mjs: формат книг обязан быть одним на обе стороны, иначе
    compare-books.mjs перестал бы сверять их построчно, а так сверка заодно проверяет, что движок и
    эталон видят один режим рынка (сверка за год: зона 16/16). Прогон 2026-08-24 на пятилетней записи
    выяснил, ЧТО именно меряют числа худшей зоны в цитате: они сняты с цепочки, которая торгует
    только эту зону (59 сделок, +2.71% за сделку, просадка 26.7% - сошлось до второго знака), а не с
    разреза базовой цепочки по зоне входа (26 сделок из 84, +3.76%, просадка 7.6%). Это разные наборы
    сделок: гейт рождает свои входы, а метка называет режим тех, которые породила экспирация
    предыдущей сделки. Обе трактовки теперь в шапке sell-scan.js с числами, потому что раньше
    цитата не говорила, которая из них имелась в виду, а разница вдвое.

  • [OTM-Scanner] Флаг --gate и таблица --gate-sweep у эталона схемы продавца
    (npm run hist:sellhedge): входной гейт по разрыву IV-RV, импульсу и скосу теперь можно ПРОГНАТЬ,
    а не цитировать. Вывод «входные гейты цепочку только ухудшают» (база ×46.5 против ×34 у лучшего
    гейта) жил в проекте комментарием со ссылкой на замер 2026-08-18, которого в репозитории нет:
    перепроверить его на новой записи или пересчитать после правки издержек было нечем, а решение
    «спред IV-RV идёт информацией, а не запретом» на нём основано. Таблица печатает рядом с базой
    сделки, итог, просадку, среднюю сделку, ВНЕ РЫНКА и число отклонённых входов - последние два
    столбца и показывают механизм: гейт не выбирает ногу и не меняет размер, он умеет только отложить
    вход, и платит за это простоем, поэтому средняя сделка может вырасти при упавшем итоге. Величины
    осей не пересчитываются: rv7 и импульс берутся из строки тика (их посчитал computeRvBundle при
    сборке записи), скос считается из снимка поверхности определением У7, но на экспирации НОГИ -
    гейтить продавца скосом чужого срока значило бы судить схему числом, которого она не видит.
    «Нет данных» является вето, но идёт отдельным столбцом: «гейт отклонил 300 входов» и «у гейта не
    было данных на 300 входах» - разные факты, и второй означает дефект записи, а не свойство рынка.
    Живого тракта правка не касается: у схемы входных гейтов нет, новый модуль hist-gate.js не
    импортируется ни движком бота 2, ни main-процессом, а отчёт без новых флагов остался побайтово
    прежним (сверен прогоном до и после). Первый прогон на пятилетней записи (2026-08-24,
    2021-08-09..2026-08-12, 43919 часовых снимков) цитируемый вывод ПОДТВЕРДИЛ: база 84 сделки
    ×45.64 при просадке 13.5% и простое 0.5% времени, лучший из девяти гейтов ×33.38 (цитата
    говорила «×46.5 против ×34»), худший ×5.68 при простое 58.6%; ни одна клетка не выше базы, а
    средняя сделка у всех девяти лежит в полосе 4.65-4.94% против базовых 4.90% - гейт отбирает те
    же сделки, но теряет их число. Числа прогона вписаны в шапку sell-scan.js вместе с командой
    воспроизведения, поэтому вывод перестал быть ссылкой на отсутствующий в репозитории замер.

  • [OTM-Scanner] Локализация: вкладка сканера переведена на словари целиком - сигнал и его
    машина фаз, карточка продажи, чеклист У1-У14, кандидаты с экономикой, журнал сигналов,
    санитария схемы продавца, редактор порогов с валидатором, панель честности, здоровье данных,
    график RV/IV и все 9 справок. В английской локали подписи условий нумеруются C1..C14
    (машинные ключи «У…» в данных, телеметрии и отчётах не меняются). Ратифицированные правки
    русской терминологии: подпись У8 снова «дисбаланс стакана перпа» (renderer потерял слово
    «перпа» и разошёлся с движком), «глубина стакана» вместо «глубины книги», «стакан лучшего
    кандидата» вместо «стакана финалиста», «кольцо 1000 переходов» вместо не соответствовавшего
    коду «кольца 200» (journalMax = 1000), «вето переключает инструмент» вместо «контракта».
    Потолок ratchet-теста опущен с 1156 до 827; остаток - почти целиком русские fallback-тексты
    внутри размеченных элементов, они уходят только вместе с Ф4/Ф5 (коды причин движка и main).

  • [BTC-Options] Локализация: вид BTC-опционов переведён на словари целиком - обе зоны
    (цепочка продавца с тикетом включения, непрерывность опроса, кокпит, ноги, греки,
    хедж-движок, журнал хеджей, конструктор, паспорт соответствия, IV-режим, payoff, превью,
    тикеты, свип, стресс), все рендеры и 20 справок «?». Заодно ратифицированные правки русской
    терминологии: «цепочка опционов» вместо «цепочки Deribit» (option chain больше не путается
    с цепочкой сделок продавца), «инструмент (выбор правила)» вместо третьего значения слова
    «контракт», «дедбэнд» вместо «полосы» в правилах схемы и паспорте, «equity счёта» вместо
    двусмысленного «депозит · equity», подпись греков «greeks Deribit» вместо «Black-Scholes»
    (значения приходят из тикера биржи, а не считаются локально), «одна экспирация» вместо
    «одного экспиратора». Потолок ratchet-теста опущен с 1648 до 1156.

  • [Funding-Arb] Локализация: вид Funding-arb переведён на словари целиком - разметка обеих зон,
    журнал операций, все рендеры (герой, матрица, рынки, сводка, издержки, скринер), попап
    апдейтера и все 18 справок «?». Английские тексты следуют терминологии деривативов. Заодно
    применены ратифицированные правки русской терминологии: единый «фандинг» вместо пары
    финансирование/фандинг («Чистый спред фандинга», «Ставка фандинга»), единое написание
    «GMX-карри», заголовок кокпита исправлен на «P&L позиции · с момента запуска (t0)» (он
    показывает выбранную позицию, а не счёт - подпись врала), в легенде кривой капитала
    «депозит» заменён на «стартовый капитал». Новый ratchet-тест не даёт добавлять русские
    строки мимо словарей (потолок видимой кириллицы только убывает).

  • [App] Локализация интерфейса, фаза 1: переключатель языка RU|EN в шапке рядом с темой.
    Каркас словарей без сборщика (i18n.js + locales/ru.js|en.js, классические скрипты - файл
    по-прежнему работает офлайн и в selector-oracle), выбор хранится в settings.json (ui.locale)
    и применяется до первой отрисовки тем же приёмом, что тема. Переведены шапка, вкладки, статусы
    живых данных и вид «Обзор»; остальные виды пока по-русски и мигрируют по фазам плана
    локализации. Английские подписи следуют профессиональной терминологии деривативов, не
    дословному переводу. Новый тест чётности словарей следит, что наборы ключей ru/en совпадают,
    плейсхолдеры согласованы и мёртвых ключей нет.

  • [OTM-Scanner] Режим «продажа»: тумблер стратегии в тулбаре переключает сканер с чеклиста
    покупки на наблюдение ноги схемы продавца (колл 336-672 ч, |дельта| у 0.45). Правила не
    дублируются: ногу, санитарную очередь и издержки входа собирает тот же buildSellStructure,
    которым бот 2 открывает структуру, размер считает lotsByMargin от залога - сигнал сканера по
    построению совпадает с ногой, которую открыл бы бот 2 в ту же метку (прогон по 90 суткам
    записи: 2184 проверки, 0 расхождений). Сканер по-прежнему не торгует. Сигнал живёт той же
    машиной dwell/TTL/кулдаун, журнал общий; карточка показывает ногу, санитарию очереди, размер
    от залога с минимальным депозитом и спред IV-RV как информацию, не гейт (замер пяти лет:
    входные гейты цепочку только ухудшают, зона «RV выше IV» - предупреждение о худшем режиме
    продавца). Состояние режима в отдельном файле otm-scanner-sell.json; покупательский чеклист,
    его пресеты, запись рынка и телеметрия не тронуты, правила схемы (sellhedge/sanity/economics)
    не изменены ни строкой. Основание: анализ 2026-08-18 на пятилетней записи - у покупки края нет
    (0 прибыльных клеток из 360 после издержек), измеренный край проекта лежит у продажи.

  • [BTC-Options] Запись тиков бота 2: суточные файлы s1tick-*.ndjson рядом с записью сканера,
    строка на каждый тик опроса - сырые котировки всех опрашиваемых инструментов (ноги, полоса,
    кандидаты продавца), перп с фандингом и вычисленное решение хеджа (want/have/полоса/вердикт).
    Леджер хранит только РЕШЁННОЕ, а перепроверка живой цепочки задним числом упиралась бы в
    восстановление рынка из архива биржи с его модельными bid/ask; теперь месяц прогона можно
    переиграть движком по живым котировкам. Объём порядка 5-15 МБ в сутки при кадансе 15 секунд;
    ошибка записи тик не роняет.

  • [BTC-Options] Санитария инструмента у схемы продавца. Перед открытием нога проверяется по
    трём осям: возраст котировки, спред, глубина книги. Вето переключает контракт на следующий в
    допуске по дельте, а не останавливает цепочку: живое снабжение берёт настоящие тикеры и книги до
    трёх кандидатов одним заходом. Не прошла ни одна нога - схема ждёт и называет причину; ожидание
    дольше четырёх часов открывает лучшую доступную с постоянной пометкой «ухудшенная санитария» на
    сделке цепочки, потому что единственная измеренно дорогая потеря схемы это разрыв цепочки, а не
    качество одной котировки. Проверки и пороги живут в движке (sanity.js), прогон записи исполняет
    ту же функцию с выключенными настройкой осями: книга пяти лет после врезки сверена побайтово.
    «Данных нет» и «не прошло» оба являются вето, но различимы в отчёте проверки.

  • [BTC-Options] Режим цепочки «одна сделка»: переключатель в тулбаре схемы продавца и строка в
    тикете включения. После расчёта единственной сделки схема останавливается сама с причиной «одна
    сделка: цепочка завершена». Нужен сверке книг, первому показу и отладке без ожидания недель;
    непрерывный режим остаётся дефолтом замера.

  • [BTC-Options] Перерывы опроса получают причину по закрытому словарю: «сон машины» (окно
    suspend..resume от powerMonitor; внутри окна возможны тики тёмных пробуждений macOS, поэтому это
    окно, а не длительность сна), «приложение не работало» (метка бута процесса внутри перерыва,
    включая рестарт при обновлении), «нет ответа биржи» (серия отказов источника), «причина не
    установлена». В карточке непрерывности появилась таблица перерывов с причинами. Причина не
    выдумывается никогда: не покрыл ни один хинт - честное «не установлена».

  • [OTM-Scanner] Карточка «Санитария схемы продавца»: последняя проверка, сделанная ботом 2 при
    поиске очередной ноги (инструмент, вердикты осей, число кандидатов). Данные приходят пушем
    бота 2, а не тиками сканера: открытие сделок не зависит от показа вкладки сканера. На чистом
    профиле карточка скрыта.

  • [BTC-Options] Экран цепочки: пульт со стоянием схемы, лентой сделок и следующей сделкой;
    карточка «Цепочка · итог» с доходностью на залог рядом с эталонными числами замера; карточка
    «Непрерывность опроса» с покрытием, эффективным кадансом и перерывами; паспорт соответствия
    измеренной конфигурации, который построчно сравнивает действующие правила с теми, на которых
    схема измерена, и называет цену каждого отклонения числом. Включение схемы идёт через тикет,
    который прямо говорит, что она делает без оператора; остановка одним кликом с отменой (текущая
    сделка доживает до экспирации), а досрочное закрытие осталось двухшаговым и красным, потому что
    выводит результат за пределы измеренного. Проверка интерфейса живьём: npm run e2e:chain,
    23 проверки через настоящий IPC на изолированном профиле.

  • [BTC-Options] Схема продавца ведёт ЦЕПОЧКУ сделок, а не одну. Годовой результат схемы делают
    16-17 сделок подряд: правило пятилетнего замера звучит «закрылась сделка, в тот же день
    открывается следующая». У живого бота такого правила не было вовсе - расчёт в экспирацию обнулял
    структуру, и следующую не открывал никто, то есть оператор должен был бы шестнадцать раз в год
    сам поймать момент вскоре после экспирации. Теперь решение о перевходе принимает движок
    (shouldOpenNext в sellhedge.js), и ту же функцию зовёт офлайн-прогон записи. Цепочка включается
    настройкой, остановка оператором не закрывает текущую сделку: она доживает до экспирации, а
    следующая не открывается. Причина неудачного перевхода хранится и показывается, потому что
    молчащая цепочка неотличима от работающей.

  • [BTC-Options] Настройки, при которых схема продавца измерена, стали КОДОМ и замораживаются
    при открытии структуры. Прежде эти шесть чисел существовали только внутри офлайн-скрипта, а живой
    профиль давал другие: полосу 0.1 BTC на контракт вместо калиброванных 0.03, фильтр выгоды λ 1.25,
    триггеры цены и времени и блэкаут расчёта. Цена расхождения измерена парной сверкой на пяти годах
    и 84 сделках: полоса по умолчанию давала рост залога в 24.2 раза против 46.5 при просадке 20.1%
    против 13.5%, добавка λ и триггеров ещё около 12% итога. Побочно снят конфликт: блэкаут расчёта
    запрещает открытие в окне 08:00 UTC, а экспирации Deribit наступают ровно в 08:00 UTC, то есть
    перевход упирался бы в собственный блэкаут.

  • [OTM-Scanner] Слой записи рынка. Сканер пишет на диск срез ВСЕЙ поверхности опционов (все
    страйки всех экспираций: bid/ask/mark, IV, форвард, открытый интерес, объём) раз в 5 минут одним
    запросом к бирже, плюс строку контекста на каждом тике опроса. Прежде на диск попадали только
    распределения по тем инструментам, которые прошли фильтры пресета, поэтому по записи нельзя было
    проверить ни один чужой набор порогов, а квантили были смещены собственным отбором.

  • [OTM-Scanner] Греки по Блэку-76 из подразумеваемой волатильности и форварда. Сверены с
    биржевыми на живых данных: дельта и вега расходятся не более чем на 0.13%, тета совпадает на всех
    экспирациях от полутора суток. Сканер сверяет их с биржевыми в каждом снимке и пишет расхождение,
    поэтому точность подтверждается данными прогона, а не разовой проверкой.

  • [OTM-Scanner] Пресет «Дельта v1» - новый пресет по умолчанию для чистого профиля.
    Страйк отбирается по дельте 0.35-0.55 вместо дистанции в сигмах, окно экспираций 2-14 суток,
    пороги премии и спреда пересчитаны по живому замеру рынка. Причина: старое σ-окно 1.2-1.5 и полоса
    дельты 0.35-0.55 не пересекаются вообще, а на дальних страйках тета съедала до 25% премии в сутки.
    Существующие профили сохраняют свой выбор пресета.

  • [OTM-Scanner] Редактор порогов получил переключатель «чем меряется страйк» и окно дельты -
    раньше эти поля существовали только в пресете и не были видны в интерфейсе.

  • [OTM-Scanner] Условие У8 (дисбаланс стакана) включено в режиме «инфо» и меряется по стакану
    бессрочного фьючерса. Прежде оно было выключено из-за отсутствия ратифицированного определения, а
    по книгам опционов не набиралось выборки: они берутся не более чем двум финалистам за тик.

  • [OTM-Scanner] Отчёт по записи npm run report:records: распределения рынка целиком по полосам
    дельты и срокам, точность греков по сегментам, границы применимости данных.

  • [OTM-Scanner] Оценщик продажи волатильности npm run eval:sell - офлайн-проверка стратегии,
    противоположной сканеру, по той же записи. Ничего не исполняет и в сеть не ходит.

  • [OTM-Scanner] Переменная окружения SCN_AUTOSTART=1 заводит опрос при старте приложения без
    открытия вкладки «Сканер» - для многосуточных прогонов на отдельной машине.

  • [OTM-Scanner] Правила продажи опциона с дельта-хеджем вынесены в движок отдельным модулем:
    выбор контракта, размер по залогу, полоса хеджа, удержание до экспирации. Прежде единственная
    прибыльная на пятилетней истории конфигурация существовала только внутри офлайн-скрипта, то есть
    перенос её в бой означал бы написать те же правила заново. Сам отчёт офлайн-проверки после
    переноса остался побайтово тем же. Ничего не исполняется: сделок эта часть пока не открывает.

  • [OTM-Scanner] Парная сверка npm run parity:sellhedge: прогоняет по одной и той же записи
    решения офлайн-эталона и решения живого движка хеджа и печатает, где они разошлись. На пяти годах
    движок с одной только полосой совпал с эталоном полностью, ни одного расхождения из 43 тысяч
    проверок. Каждое расхождение остальных вариантов поэтому указывает на конкретное правило.

  • [BTC-Options] Бот 2 умеет вести структуру из одной проданной ноги, а не только четырёхногую.
    Контракт выбирает и размер считает то же правило, что и офлайн-эталон, поэтому вторая реализация
    схемы не появилась. Расчёт в экспирацию перестал быть привязан к геометрии четырёхногой структуры
    и считается по её ногам, какими бы они ни были. Заодно бот 2 впервые учитывает издержки входа в
    опцион: прежде структура открывалась по цене марка без комиссии и спреда, то есть вход был
    бесплатным только на бумаге. Открыть такую структуру из интерфейса пока нельзя, кнопки и
    экрана у неё нет: движок её исполнить может, оператор её завести не может.

  • [BTC-Options] Прогон истории через живой движок: scripts/replay-sellhedge.mjs кормит бота 2
    записью рынка вместо биржи и получает книгу сделок, а scripts/compare-books.mjs сверяет её с
    книгой офлайн-эталона строка в строку. Прежде сверялись только ОТДЕЛЬНЫЕ решения хеджа, а вопросы
    «выбрал бы движок тот же контракт», «вошёл бы в тот же момент», «дал бы тот же размер» оставались
    без ответа. За пять лет инструмент, момент входа, момент выхода, число лотов и залог совпали на
    всех 84 сделках; расхождения остались только там, где движок и эталон считают по-разному
    осознанно (фандинг движок начисляет на номинал позиции, как биржа, а эталон приближает его
    дельтой; целые контракты бессрочного фьючерса эталон не моделирует вовсе).

  • [BTC-Options] Пресет дедбэнда «продавца»: полоса 0.03 BTC на контракт, та самая, на
    которой измерена схема продажи колла. Прежние три пресета дают 0.05, 0.10 и 0.20 на контракт, то
    есть самый тесный из них шире калиброванной в 1.67 раза, и хедж шёл бы не по тому правилу, каким
    схема мерилась. Число не универсально: его оптимум зависит от стоимости перекладки (при мейкере
    теснее всегда лучше, при 10 б.п. лучше шире), 0.03 это оптимум при реалистичных 2.5 б.п.
    Побочно: сетка свипа выводится из той же таблицы пресетов, поэтому она выросла со 108 комбинаций
    до 144, и полный свип теперь идёт примерно на треть дольше.

Исправлено

  • [BTC-Options] Справочная спот-цена снапшота (поле S тиковой записи) перестала залипать на
    замороженном тикере истёкшего инструмента. Живой прогон 24-25.08.2026: S держалась равной
    77394.16 суммарно ~20.6 часа (2200 тиков, 86 эпизодов) при живом индексе. Механика: Deribit ещё
    около суток отвечает на тикер истёкшего инструмента (state "delivered") застывшими на моменте
    экспирации underlying_price и timestamp; спотом снапшота становилась «первая попавшаяся» нога,
    то есть исход каждого тика решала гонка параллельных запросов; а полоса опроса (ATM-инструменты
    карточки IV-режима) оставалась прибитой к истёкшей экспирации, потому что кэш цепочки
    инструментов обновляется только по требованию и дневные экспирации в нём кончаются за пару суток
    безоператорного удержания. На P&L дефект не влиял (проверено полным реплеем); страдали центровка
    полосы опроса, гейт хеджа по ходу цены, стресс-строки, запись и показ. Исправление тройное:
    спотом становится нога с новейшей меткой тикера (гонка больше не решает), метка старше 60 с
    означает протухание и подмену живым индексом перпа (тот же фолбэк, которым уже жили движок и
    маржа) с заметкой в кластере соединения; строители структур предпочитают индекс споту,
    помеченному протухшим; полоса опроса, не нашедшая замены умершей экспирации, сама обновляет кэш
    цепочки (это же лечит слепоту карточки IV-режима при долгом удержании). Тиковая запись несёт
    возраст и источник спота (sAge/sSrc).

  • [BTC-Options] Красный жетон «СТОП» цепочки продавца снова загорается при нехватке счёта
    на живом правиле размера. Карточка распознавала настоящую остановку разбором русского текста
    причины (регэксп «залог/депозит»), а автономное стресс-правило пишет отказ другими словами
    («Стресс-правило не даёт ни лота…»), поэтому цепочка, которой не хватает счёта даже на один
    лот, вечно показывала «ПОДБОР», как будто ждёт подходящую ногу. Теперь правило размера отдаёт
    рядом с текстом машинный код no-lots (обе ветки: deploy и stress), код едет с причиной до
    карточки, и жетон судит по нему; разбор текста остался фолбэком для причин без кода. Найдено
    сверкой руководства с кодом (2026-08-27).

  • [BTC-Options] Токен состояния схемы («В СДЕЛКЕ») больше не переносится на две строки на
    узких окнах (замечено оператором на MacBook Pro 15, окно 1440x900 с постоянным скроллбаром).
    Причина была двойная: глобальный .stamp с nowrap на длинных примечаниях третьей колонки
    цепочки замораживал её на ширине текста (~780px), сжимая колонку токена до нулевого запаса, а
    fr-колонки без min-width:0 не сжимаются ниже max-content («ОСТАНОВКА» распирала сетку). Фикс:
    min-width:0 на колонки, токену nowrap и шрифт по ширине окна (clamp 24-38px в scope цепочки;
    большой токен решения остаётся 44px), примечаниям цепочки разрешён многострочный перенос -
    иначе с ужатой колонкой их резал бы overflow:hidden карточки. Проверено на обеих локалях и
    ширинах 1081-1600. Заодно по UI-ревью: KPI кокпита несёт утилизацию MM с цветом зон и
    суб-строкой «MM · ликвидация»; цена ликвидации и IM/MM/equity в полных долларах (k-сокращение
    стоило до ±$500 на числах, которые сравнивают с индексом); все тревожные поверхности (бар,
    чип, вердикт, новая красная точка вкладки и sr-статус) красятся по ступени с гистерезисом
    margin_alert_level, а не по голому флагу - у порога ничего не мигает; строка margin-alert в
    журнале несёт «—» вместо «$0.00» в P&L; статусная строка карточки бота на «Обзоре» при алерте
    дополняется запасом и ценой ликвидации. На треке утилизации появились засечки границ зон
    (60% и порог алерта; порог приходит из движка полем margin_alert_pct, так что настройка
    двигает засечку вместе с логикой) - деление зон видно и без различения цветов. Карточка
    «Непрерывность опроса» в полностью здоровом состоянии (вердикт в норме, ни одного перерыва,
    каданс без замедления) прячется - её дублирует пилюля «опрос N%» в шапке цепочки; первый же
    перерыв или деградация каданса раскрывают её до конца сделки.

  • [BTC-Options] Тик со снимком без перпа больше не гибнет целиком при удерживаемой позиции.
    Живой случай бумажного прогона (mbp15, ~7 тиков в сутки): REST перпа отвечает 503, опционные
    ноги отвечают, buildDeribitSnapshot отдаёт perp = null - решение хеджа верно вставало в
    SKIP, но безусловная атрибуция P&L падала в markPerp на чтении contractSize, и тик гиб
    вместе с записью, персистом и пушем (отсюда 5757 строк записи в сутки вместо 5760). Теперь
    перп без цены у markPerp - та же ветка нулей, что плоская позиция («маркировать нечем»);
    тик выживает, решение остаётся SKIP. Такой тик НЕ фолдится в метрики прогона: его net не
    содержит MtM перпа, и фолд вписал бы в Sharpe/maxDD фантомный провал на всю нереализованную
    прибыль позиции с восстановлением следующим тиком (до правки такие тики до фолда не доживали,
    так что поведение метрик не изменилось - изменился только способ выживания тика).

  • [BTC-Options] Тик без оценённого перпа не двигает часы начисления фандинга. Прежде
    lastIngestAt продвигался и на таком тике, хотя начисление пройти не могло: интервал до него
    выпадал из фандинга молча - ни строки, ни счётчика (за восемь дней прогона mbp15 так потерялось
    около четверти часа позиции). Теперь часы двигает только тик, на котором начисление возможно:
    следующий оценённый тик доначисляет весь разрыв, а разрыв больше анти-catch-up клампа виден
    строкой funding-gap, как и предписывает закон А6 R3 «деградация видима». Пятилетняя книга
    переигровки обеих правок не касается ни байтом: в записи перп есть в каждом снимке (сверено
    прогоном до и после).

  • [BTC-Options] Чип «Обзора» считает запуском ОПРОС, а не открытую структуру. Цепочка продавца
    законно живёт днями в подборе ноги без позиции (окно 336-672 ч бывает пусто по сетке экспираций
    Deribit), и бот, принимающий решения каждые 15 секунд, значился «НЕ ЗАПУЩЕН». Строка статуса
    карточки теперь называет фазу: «цепочка продавца · подбор ноги» с причиной. Найдено первым днём
    бумажного прогона.

  • [BTC-Options] Профили, записанные до появления цепочки, не содержали её накопителя, и попытка
    включить схему отвечала «состояние цепочки не поднято» (открытие структуры чинило то же молча).
    Накопитель поднимается на буте, при включении и при открытии одной функцией движка. Найдено
    развёртыванием на машине прогона.

  • [BTC-Options] Поправка сверки с delivery-ценой доезжает до строки СВОЕЙ сделки цепочки.
    Прежде она книжилась только в общий счёт: строка сделки навсегда несла предварительный итог по
    индексу-прокси, а если цепочка уже переоткрылась (перевход идёт через полминуты, delivery
    публикуется и сверяется позже), поправка искажала процент СЛЕДУЮЩЕЙ сделки. Общий счёт и леджер
    были верны, искажалась ровно та по-сделочная таблица, которой цепочка сверяется с эталоном.
    Теперь строка сделки хранит ссылку на свой расчёт, до прихода поправки несёт пометку «итог
    предварительный», а замер уже открытой следующей сделки сдвигается вместе с поправкой.

  • [BTC-Options] Предупреждение о перерыве опроса срабатывает и от самого длинного перерыва.
    Прежде порог ключился только на СРЕДНЕМ интервале между решениями: перерыв в четыре часа у
    сделки, прожившей недели на кадансе 15 секунд, средним не ловится, и спроектированный
    амбер-блок не появился бы никогда. Цена перерыва называется по измеренной сетке кадансов
    (4 ч ×26.5 · 12 ч ×22.3 · 24 ч ×16.2 против ×46.5).

  • [BTC-Options] Превью тикета продавца судит по той же замороженной конфигурации схемы, что и
    исполнитель. Прежде превью звало предторговую проверку без патча схемы: в окне 08:00 UTC оно
    отвечало «открытие в блэкаут запрещено», хотя открытие и перевход это окно проходят.

  • [BTC-Options] Остановка цепочки перепроверяется у точки фиксации открытия. Снабжение
    асинхронно, и уже летящая попытка могла открыть сделку после того, как оператор остановил схему.

  • [BTC-Options] Живой перевход спрашивается ДО оценки тика, как объявляет контракт модуля
    правил и как делает прогон записи: следующая сделка открывается следующим тиком, а не той же
    меткой, что расчёт предыдущей.

  • [BTC-Options] Пульт цепочки больше не делит id с карточкой «Рыночные данные Deribit»
    (дубликат id в DOM: стили пульта красили обе карточки).

  • [OTM-Scanner] Мёртвая кнопка «Передать в бот 2» (disabled с обещанием «появится в S4»)
    удалена по ратифицированному решению: перебор входных правил на истории не дал ни одной
    выжившей клетки, и сканер момент входа для схемы продавца не выбирает. На её месте заметка,
    называющая фактические отношения модулей: схема продавца получает от сканера санитарию
    конкретного инструмента.

  • [OTM-Scanner] Сверка книг (compare-books.mjs) сравнивает денежные столбцы в разрядах
    печати. Прежде сравнение сырых double проглатывало расхождение ровно в один цент примерно в
    половине случаев (1961.40 против 1961.39 признавались равными). На парность 84/84 переизмерение
    не повлияло: семь решающих столбцов держат 84/84 и при точном поцентовом сравнении.

  • [BTC-Options] Фильтр издержек хеджа заряжался карри ВСЕЙ позиции вместо цены самой заявки.
    В стоимость решения переложиться шёл фандинг целевой позиции за восемь часов, хотя он платится
    независимо от этого решения. Следствий было два. Первое: фиксированная полоса становилась
    плавающей и разъезжалась вслед за ставкой (замер при полосе 0.03 и споте $100 тыс.: при нулевом
    фандинге движок перекладывался на 1.05 полосы, при пяти базисных пунктах за восемь часов на 3.03
    полосы), то есть хедж шёл не по тому правилу, каким схема измерена. Второе: при отрицательной
    ставке сумма издержек уходила ниже нуля, и фильтр пропускал сделку при любой выгоде, включая
    нулевую. Теперь в цену заявки входит фандинг ПРИРАЩЕНИЯ, карри всей позиции показывается
    отдельной справочной статьёй, а сравнение идёт с издержками, зажатыми снизу нулём.

  • [BTC-Options] Выгода перекладки мерилась избытком дельты за полосой, а её цена - полным
    остатком, который заявка и снимает. Две разные величины в двух половинах одного неравенства давали
    систематический пропуск ровно на краю полосы, где избыток стремится к нулю, а торгуемый объём равен
    всей полосе. Обе половины считаются на фактически торгуемом объёме.

  • [BTC-Options] Доля опциона вне денег в расчёте маржи считалась от форварда его экспирации, а
    формула биржи целиком стоит на индексной цене. Расхождение росло со сроком, а у схемы продавца
    срок 14-28 суток; знак был разный для коллов и путов, то есть требование залога двигалось в разные
    стороны для разных ног одного счёта. На восстановленной записи, где индекс и форвард совпадают,
    числа не меняются: правка касается живого тракта.

  • [BTC-Options] Стресс-сценарии по цене смешивали две системы отсчёта: мгновенная оценка считалась
    при хедже, а терминальная по одному опциону, без хеджа. На структуре с короткой гаммой это врало в
    обе стороны сразу - верхний хвост показывал нехеджированный убыток, нижний чистую гамма-оценку.
    Терминальная ветка теперь включает вклад держимого бессрочного фьючерса на том же движении.

  • [BTC-Options] Множитель спреда 1.10 применялся к настоящим биржевым котировкам. Он заведён как
    поправка на МОДЕЛЬНЫЕ котировки восстановленной записи (они занижают круг издержек на 6%), а на
    живых bid/ask раздувал уже наблюдённый спред ещё на десятую часть. В живом тракте множитель равен
    единице; офлайн-скрипты своё значение задают сами, поэтому эталонные числа не сдвинулись.

  • [BTC-Options] Отказ схемы продавца по залогу называет нужный депозит, а не только факт нехватки:
    бумажный счёт по умолчанию $100 не даёт ни одного лота при залоге около $92-102 за лот, и на чистом
    профиле схема не открывалась никогда без объяснения, сколько именно надо завести.

  • [BTC-Options] Открытая позиция оставалась без хеджа после перезагрузки машины. Опрос
    котировок заводился только из интерфейса (кнопка LIVE), при открытии структуры или переменной
    окружения, поэтому после любого рестарта структура из состояния поднималась, а источник цен нет,
    и дельта ехала без присмотра, пока человек не нажмёт кнопку. Для схемы продавца это не теория:
    она держит короткий колл неделями. Теперь открытая структура или включённая цепочка заводят опрос
    сами. Цена простоя измерена: каданс решения раз в сутки роняет пятилетний результат с роста
    залога в 46.5 раза до 16.2 при просадке 30.6% против 13.5%.

  • [BTC-Options] Дельта позиции по бессрочному фьючерсу считалась по текущей цене, а не по
    средней цене входа. Эти два числа расходятся ровно настолько, насколько цена ушла от входа, и
    расхождение попадало прямо в проверку нейтральности: после движения на 10% оно достигало 9% от
    дельты позиции. Практически это возвращало в книгу направленную ставку - ровно ту, ради снятия
    которой хедж и существует. Замер на пятилетней истории: вариант со старым правилом выигрывал на
    растущем рынке и проигрывал на падающем, то есть его результат следовал за направлением рынка.
    Размер позиции по-прежнему показывается по текущей цене, как в терминале биржи.

  • [BTC-Options] Полоса хеджа не масштабировалась размером структуры и не говорила, для какого
    размера она откалибрована. Одно и то же число значило разные вещи в рабочем примере (размер 1) и
    в настройках по умолчанию (размер 0.01), различаясь в сто раз. Теперь калибровочный размер задан
    явной настройкой, а полоса растёт вместе со структурой, поэтому её теснота относительно позиции
    не зависит от того, сколько денег заведено. При текущих настройках полоса не изменилась.

  • [BTC-Options] Порог ценового триггера служил одновременно масштабом ожидаемой выгоды от
    перекладки, поэтому настроить одно, не сдвинув другое, было нельзя. Масштаб выгоды стал отдельной
    настройкой; профили, менявшие порог, сохраняют прежнее поведение.

  • [BTC-Options] Средняя цена входа по бессрочному фьючерсу усреднялась как обычное среднее цен,
    хотя у обратного контракта и прибыль, и дельта зависят от обратной величины цены. Совпадало это
    только когда вся позиция набрана по одной цене, а именно этот случай и проверялся. На позиции,
    набранной по разным ценам, и показанная дельта, и прибыль оказывались занижены. Замер: позиция из
    двух частей по 47000 и 48000 показывала прибыль 2369.34 вместо 2370.00.

  • [BTC-Options] Перевод нужного изменения дельты в число контрактов делался по текущей цене
    даже тогда, когда позиция УМЕНЬШАЕТСЯ, хотя закрываемые контракты держат цену своего входа.
    Из-за этого хедж снимал не столько, сколько просил, и промахивался мимо собственной цели тем
    сильнее, чем дальше цена ушла от средней цены входа. Промах доходил до 3.7% ширины полосы и
    однажды перевернул решение: правило требовало переложиться, а движок остался стоять. Знак ошибки
    следовал за направлением рынка, то есть это была та же направленная ставка, ради снятия которой
    хедж и существует. Побочно чинилось закрытие позиции: оно считало объём по текущей цене и
    оставляло небольшой хвост вместо нуля. Дефект найден прогоном истории через живой движок.

  • [OTM-Scanner] Условие У12 (глубина книги) навсегда оставалось «данных нет»: книги стакана
    доставались первым кандидатам, прошедшим предварительную проверку, а «лучшим» движок выбирал
    другого - по вердиктам всех условий. Два выбора расходились, лучший кандидат оставался без книги, а
    «данных нет» в строгом режиме запрещает сигнал. Сканер не мог выдать сигнал вообще.

  • [OTM-Scanner] Движок видел только ОДНУ экспирацию из окна: живую волатильность получали лишь
    ближняя и дальняя, остальные отбрасывались целиком. Расширение окна до 14 суток из-за этого не
    работало, а единственная экспирация с приемлемой тетой в кандидаты не попадала никогда.