Тема
Harvester v1 — план до рабочего, протестированного, единого бота
Цель: ОДИН бот, доведённый до измеримого вердикта о доходности Harvester, с конечным объёмом работ и видимым концом. ОГОВОРКА 2026-08-21: слова о бэктестах в этом плане недействительны — офлайн-бэктест снят решением оператора, проверка идёт на живых сессиях и телеметрии. Это документ-план-of-record. История правок — в git/memory, не здесь (SSOT-правило).
Статус на 2026-08-22.
- Переход pm-bot → pm-engine завершён. Крейты
pm-bot/pm-dashboardудалены; проверенный live-срез (order-клиент, redeem, closure, orderbook, order trace) перенесён вpm-engine. Пункт 2 «Ратифицированного решения» ниже предполагал сохранитьpm-botдонором — этого не произошло, донор удалён.- Ф1–Ф3 пройдены, Ф4 идёт: движок торгует РЕАЛЬНЫМИ деньгами. Инстанс
harvester-engineработает в единственном live execution path; налитые ордера, открытые позиции и закрытия по цели подтверждены в боевойengine.db. Ограничение капитала —directional.total_budget_micro_usdв config.db.- A/B на двух инстансах (пункт 4 решения) НЕ выполняется: боевой инстанс один. Требование «сверено на ≥2 инстансах» из финишной черты остаётся невыполненным.
- Финишная черта не достигнута. Вердикт
edge_margin > 0с нижней границей кластерного доверительного интервала выше нуля на ≥238 кластерах «город-дата» не собран: форвард-данных такого объёма нет, а каждый выкат обнуляет форвардное окно.Наблюдаемость — что вердикт стало чем измерять (обновление 22.08).
- Вопросы ОТБОРА отвечаются на боевых данных уже сейчас. Воронка входа ведётся в хранилище: за наблюдаемый период 9.3 млн оценок, и видно поимённо, где рынки отсеиваются (остановка входа 4.4 млн, фильтр исхода 2.4 млн, ценовой коридор 1.3 млн, расстояние до фаворита 873 тыс.). Наполнены десять таблиц: попытки входа с формой книги, кадры стоп-решений, витрины заявок и позиций, переходы, разрывы доставки.
- Вопросы ИСПОЛНЕНИЯ до выката не отвечаются. Механизмы написаны и проверены, но в бою их нет: причина снятия заявки (все отмены в бою без причины), принадлежность несостоявшегося входа событию, история отбора целиком, срабатывания защит отдельным фактом, здоровье лент во времени.
- ★ГЛАВНОЕ ОГРАНИЧЕНИЕ ПОСЛЕ ВЫКАТА — ЧИТАТЕЛЬ, А НЕ ДАННЫЕ.
scripts/analysis/forensics.shходит в SQLite движка по SSH, а не в хранилище. Данные будут, ответов на торговые вопросы поверх них не будет: только ручной SQL. Перевод форензики — самая ценная работа после выката.- Эпоха как средство против обнуления форвардного окна. Каждая строка наблюдения несёт идентичность эпохи (версия конфигурации + счётчик сбросов). Это НЕ отменяет риск «forward-clock reset trap» из раздела «Риски» — правки config.db по-прежнему рвут окно, — но делает разрыв ВИДИМЫМ в данных, а сравнение разных эпох — явной ошибкой, а не незаметной.
- Выборка для вердикта пока мала: в витрине позиций шесть строк. Ни один вывод о доходности на таком объёме не обоснован.
Ратифицированное решение (2026-06-24)
- Единый продукт v1 = pm-engine (архитектура + стратегия Harvester) — он же будущий хребет под другие стратегии. Bake-off закрывается слиянием в один бот, не вечным сравнением.
- pm-bot останавливается и отключается на стенде. Double-spend исчезает, кошелёк свободен для pm-engine. pm-bot остаётся как донор проверенного live-кода (order-клиент, redeem, RTDS) для будущего слияния — не удаляется.
- Сначала ответ про деньги, потом слияние. Вердикт «зарабатывает ли Harvester» НЕ требует слияния F1–F10. Сначала доводим pm-engine до доверенного EV-вердикта минимальной подготовкой; полное слияние live-кода (F1–F10) — ТОЛЬКО после +EV.
- Вердикт собираем на pm-engine + pm-engine-2 (A/B-инстанс). Так вердикт меряет именно того бота, которого запустим, и переносится корректно (у pm-bot и pm-engine разные модели филла — вердикт pm-bot на pm-engine не переносится).
- Стоп v1 = hold-to-resolution / FOK-kill-and-hold. На стоп не опираемся (режет будущих победителей через mean-reversion). Отсутствие RTDS в engine → НЕ блокер v1. Обратимо (config.db), пересматриваем на финальном вердикте.
Финишная черта (измеримая, не «на глаз»)
Harvester «готов и зарабатывает» = чистый +EV-вердикт по эталонной модели harvester_yield (crates/pm-analytics/src/harvester_yield.rs; формула — docs/strategies/harvester-yield.md; docs/Harvester Yield Calculator v2.pdf — исторический файл, не SSOT):
edge_margin = w − w* > 0, где w* = (p_e − r·s_eff)/(exit_price − r·s_eff), при всех условиях:
- Нижняя граница bootstrap-доверительного интервала > 0 на ≥238 кластерах «город-дата» (наивный счёт по рынкам завышает в ~9×: одно показание температуры решает целую лестницу).
- Garbage-in исключён:
w/p_eиз fill-checked realised-исходов; открытые проигравшие резолвить (никакого survivorship);r/s_effиз реальных стоп-филлов; никакого ride-to-resolution counterfactual. p_e= фактическая цена исполненного BUY, связанная с decision-timebest_askв live-телеметрии и order trace, НЕ Gamma-mid. Край ~2¢ внутри спреда ~10¢ — это убийца, не сноска.exit_price = 0.99(maker-harvest), НЕ 1.0 (redeem@1.0 — UMA-риск, взаимоисключим).- Минус комиссии (сейчас 0, несущие) и проскальзывание; устойчиво к ~2–3% ошибок UMA-резолюции.
- Замерено форвардом на замороженном бинаре, сверено на ≥2 инстансах (pm-engine + pm-engine-2) под объявленным config-freeze; REFUSE-VERDICT при
n < min.
Финиш определяется входным краем + охватом, НЕ эффективностью стопа.
Откуда берётся край (замер 2026-08-12, живые стаканы CLOB)
Источник края — надбавка рынка: сумма лучших предложений «да» по всем корзинам события превышает единицу. Замер по четырём событиям погодной лестницы (11 корзин каждое) дал ΣAsk = 1.096…1.107, то есть надбавку +9.6…+10.7 %.
Практическое следствие, определяющее конструкцию входа:
- покупка всех «нет» пассивно (по своей цене,
entry_price_base=BestBid) — примерно +1.0 % на вложенное за цикл; - покупка тех же «нет» агрессивно (по чужой цене) — примерно −0.2 %.
Край целиком лежит в спреде. Отсюда два ограничения, которые нельзя обойти тюнингом: край забирается только полным набором корзин события (неполный набор теряет арифметическую определённость «одна проигрывает, остальные выигрывают»), и только той частью, которая переживает отбор при наливе — пассивную заявку исполняют тогда, когда кто-то хочет продать, то есть систематически перед движением против нас.
Границы замера: одна временная точка, четыре события, оценка вероятностей — середина стакана с нормировкой к единице. Это обоснование конструкции, НЕ вердикт о доходности; вердикт по-прежнему требует условий финишной черты выше.
Честная правда (не обещание прибыли)
- Утверждение «оба бота реальными деньгами не торговали ни разу» устарело и снято. pm-engine исполняет сделки за реальные деньги; боевой путь подтверждён налитыми ордерами и закрытиями по цели выхода. Runtime-симуляция филлов и
--dry-runудалены 2026-08-22. - Переход к реальным деньгам сам по себе вердиктом не является. Он снял риск «симфиллы ≠ реальные филлы», но не заменил требуемый объём наблюдений.
- План ведёт к решаемому вердикту, который может быть NO-GO. Обещается не прибыль, а конец неопределённости.
Bug-hunt 2026-06-24 (verdict-tooling): −EV оказался багом измерения
Первый прогон forensics.sh ev --engine дал edge=−0.244 (катастрофа). Это баг измерения, подтверждён через Gamma ground-truth по всем 174 позициям:
forensics evвзял дефолт r=0/s_eff=0, хотя в данных 60 реальных стопов (s_eff=0.587, r=0.857), и посчитал стоп-выходы как полные resolution-убытки.- engine.db расходится с Gamma на 34 позиции — стоп-выходы, что выиграли бы при hold-to-resolution, но записаны убытками. Стоп срезал 34 победителя.
- p_e ЧИСТ: записанный entry == фактический BUY-филл == limit, бит-в-бит.
- Истинный hold-to-resolution: w=138/174=0.793 (не 0.598); edge≈−0.04 (exit 1.0); 95% ДИ w=[0.733,0.853] включает break-even → статистически неотличимо от +EV на n=174.
Следствия: (1) −EV красный флаг снят — это была контаминация стопом, не стратегия. (2) Hold-to-resolution валидирован эмпирически — стоп строго −EV. (3) Остаточные −0.04 — шум + вероятно entry-timing (falling-knife: 34% входов сразу падали к 0.59) → драйвер для fix-directional-admission-pipeline (Ф2). (4) forensics ev дефолт r=0 на стоп-данных — footgun; для hold-to-resolution вердикта стоп-позиции ре-резолвить к terminal-исходу.
Историческая последовательность до отказа от симуляторов
Раздел до «Ближайшего порядка работ» сохранён как история решения и отменён 2026-08-22.
dry-run, Backtest, replay, capture и симуляционный A/B больше не являются фазами проекта или доказательством. Текущий путь — неизменяемые когорты реальных сессий, factual order trace, подтверждённые fill/settlement и эталонная EV-модель.
Главный вопрос — стратегический (входной край + охват), а слияние F1–F10 — это водопровод исполнения и расширяемость под будущие стратегии. Ставить ~2 месяца слияния перед ответом «зарабатывает ли стратегия» — риск рефакторить архитектуру под убыток. Поэтому: дешёвый стратегический ответ first; дорогое слияние — только если +EV. Дополнительный выигрыш: dry-run-сбор не рискует капиталом — если стратегия не +EV даже в симуляции, останавливаемся, не потратив ни доллара.
Исторические фазы (отменены)
Ф0 Ратификация + этот план + ре-бакетинг openspec 1–2 дня [сделано]
выход: решение зафиксировано; F1–F10 → отложено за вердикт; прочее → extension-later
Ф1 pm-engine backtest-готов (dry-run A/B) ~1 неделя [сделано, КРОМЕ A/B]
[VERIFIED 2026-06-24] живой harvester-engine ТОРГУЕТ: 333 FILLED ордера, 174 позиции,
свежие directional-entry + stoploss-confirmed → engine-не-торгует ОПРОВЕРГНУТО.
gamma empty-cid (~3.5%) — benign, корректно пропускается, НЕ блокер.
- поднять pm-engine-2 (второй dry-run инстанс для A/B)
- подтвердить НАТИВНЫЙ backtest движка на ЕГО captures (EngineReplayDriver / --capture-only);
cross-bot replay-compare фиделити-баг (engine=0 решений через мост pm-bot→engine) ОТЛОЖЕН
как инструмент ретайред-bake-off, не на критическом пути
- базовая безопасность капитала (secrets/auth, budget single-source) — старт
выход: pm-engine + pm-engine-2 крутят Harvester в dry-run; нативный backtest даёт результат
[кошелёк pm-engine + pm-bot off → перенесено в Ф4: dry-run не делает реальных ордеров,
double-spend невозможен до реальных денег]
Ф2 Доверенный бэктест: sim↔live паритет + maker-вход ~2 недели [maker-вход сделан]
- sim partial-fill ≥5-или-0; бэктест и live мерят ОДНУ модель филла
- вход maker (post-only); честный admission (без silent ZERO→LowProb, stale-Gamma)
выход: dry-run pm-engine = доверенная модель; replay даёт EV без фантомных филлов
Ф3 Config-freeze + форвард-сбор → ПРЕДВАРИТ. вердикт ≥1–2 недели календарных, БЕЗ рестартов
[НЕ ВЫПОЛНЯЕТСЯ: config-freeze не объявлялся, выкаты и правки config.db идут постоянно,
форвардное окно обнуляется каждым из них. Это реализовавшийся риск «forward-clock reset
trap» из раздела «Риски» — пока он не закрыт дисциплиной заморозки, вердикт недостижим
независимо от качества стратегии.]
- pm-engine + pm-engine-2 без рестартов; входы fill-checked, без survivorship
выход: harvester_yield на форвард-данных; предварит. знак EV (на симфиллах, без капитала)
Ф4 Проба реальными деньгами → ФИНАЛ 2–4 дня (потолок твой) [ИДЁТ]
[Начата БЕЗ предварительного +EV-вердикта Ф3 — условие «ЕСЛИ предв. +EV» не выполнялось.
Решение оператора; зафиксировано здесь, чтобы последовательность не читалась как пройденная.
Реальные BUY и SELL исполнены, симфиллы против реальных филлов больше не гипотеза.]
- ТОЛЬКО ЗДЕСЬ: pm-bot off + кошелёк → pm-engine (real-money устраняет double-spend)
- перед пробой решить: перенести проверенный order-клиент pm-bot (тонкий срез) vs
capped native — выбираем по состоянию live-пути pm-engine после Ф2
- ≥1 реальный BUY+SELL FILLED подтверждает: симфиллы ≈ реальные → вердикт переносится
выход: финальный вердикт. CI-нижняя > 0 → v1 ЗАРАБАТЫВАЕТ. Иначе → тюнинг полосы (config.db) / стоп
ЕСЛИ предв. NO-GO → крутим полосу входа (config.db) и пересбор, либо стоп. Капитал не тронут.
─────────────────────────────────────────────────────────────────────────────────
Ф5+ ТОЛЬКО ЕСЛИ +EV: слияние F1–F10 — engine как робастный хребет 3–5 недель
перенос проверенного live-кода pm-bot (order/redeem/positions/closure/orderbook/sim)
через shared-порты; убрать дублирование I/O. Фундамент под «добавлять другие стратегии».Реалистично до go/no-go: ~4–6 недель (чуть больше «быстрой дороги через pm-bot» из-за gamma-фикса и sim-паритета pm-engine, но радикально меньше ~9–11 недель «сначала слияние»). Слияние F1–F10 — отдельные ~3–5 недель после подтверждённого +EV.
Ближайший порядок работ (обновлено 22.08)
Не фаза плана, а очередь на сегодня — то, что стоит между текущим состоянием и возможностью что-либо утверждать о доходности.
- Выкат наблюдаемости. Всё перечисленное в статусе как «написано, но в бою нет» доезжает одним выкатом. До него пять живых приёмок заявки
analytics-fidelity-and-table-inventoryзакрыть нечем — а без них заявка не считается выполненной: три из пяти дефектов предыдущей работы вскрылись именно на живом прогоне, а не на тестах. - Перевод форензики на хранилище (
analytics-telemetry-to-clickhouse§9). Без него выкат даёт данные, но не ответы. Самая ценная работа очереди. - Дисциплина заморозки конфигурации для набора форвардного окна. Пока правки config.db идут в произвольный момент, вердикт недостижим независимо от качества стратегии и полноты наблюдения — это по-прежнему главный риск.
Отложено
- F1–F10 полное слияние — за вердикт (Ф5+, только при +EV).
- flow-imbalance-стоп, нативная пересборка engine без переноса, все стратегии кроме directional/Harvester, оставшиеся pm-engine-only hardening не на пути к вердикту.
- Поверхность чтения для анализа (
analytics-mcp-read-surface) — заявка есть, сделано 5 задач из 43. Её ценность появляется только после пункта 2 очереди выше: читать нечего, пока читатель не переведён.
Риски (держать в голове на каждой фазе)
- Только live-телеметрия доказывает поведение на бирже: order trace, подтверждённые fills, settlement и денежная сверка обязательны; тестовые doubles доказывают лишь контракт кода.
- Край тонкий и хрупкий: ~2¢ в спреде ~10¢; taker-комиссия / ошибка UMA / замер по Gamma-mid вместо исполнимого ask — любой переворачивает знак.
- Статистический мираж: без кластер-bootstrap «+EV» вероятно шум.
- Forward-clock reset trap: каждый деплой обнуляет форвард-данные. Без дисциплины config-freeze (Ф3) проект зацикливается навсегда.
- pm-engine к вердикту — больше подготовки, чем pm-bot: gamma-гидрация сломана, live-путь не торговал, история stop-disabled→−EV. Ф1–Ф2 это закрывают, но это реальная работа.
- Net-negative baseline: возможно, стратегия НЕ +EV при исполнимых ценах. План обязан уметь вернуть NO-GO.
Решения оператора, отложенные до своих фаз (config.db, твой выбор тогда)
- Потолок реальных денег для пробы Ф4 — РЕШЕНО, живёт в
directional.total_budget_micro_usd(config.db). Прежняя авторизация $20 отменена; действующее значение смотреть в боевой config.db, а не здесь (RULE-NEW-01: единственный источник — config.db). - Длина окна config-freeze (Ф3) — ОТКРЫТО и блокирует вердикт. Задаёт календарную дату вердикта и
n. Пока не объявлено, Ф3 не может начаться. - Полоса входа v1 — РЕШЕНО для текущего эксперимента, действующие границы — в config.db (
entry_price_band_lower_milli/max_entry_price_milli, сторона входаentry_outcome_filter). Историческая оценка [0.80,0.85] относилась к другой стороне и другому набору ручек; сравнивать с текущими значениями напрямую нельзя.