Live и walk-forward¶
Главное требование v42: offline replay должен идти тем же путем, что live.
Если replay использует другой press, другой MTF, другую session reset policy или другой director, результат нельзя напрямую сравнивать с live.
Live entrypoint¶
Текущий live runner:
store/market/tools/whaler_s300_stage_live.py
Он по умолчанию использует:
DEFAULT_BAKE = store/market/personalities/whaler_v42_mtf_s300_short_wide_may01_20.d8p
DEFAULT_LABELS = store/market/runs/v42_mtf_s300_short_wide_may01_20/v42_mtf_s300_short_wide.tsv
Live пишет run-дир вида:
store/market/runs/live/s300_stage_BTCUSDT_YYYYMMDD_HHMMSS/
Внутри должны появляться:
frames.mtf.s300.jsonl
tape.mtf.s300.raw8.vsb
mtf.s300.html
frames.mtf.s1800.jsonl
tape.mtf.s1800.raw8.vsb
mtf.s1800.html
director.json
director.tsv
director.html
Offline live-equivalent replay¶
Текущий offline runner:
store/market/tools/whaler_live_replay_walkforward.py
Он делает:
historical frames
-> closed MTF s300/s1800
-> d8_agent_cli v42
-> phase director
-> optional catalog filter
-> optional inventory journal
Это не старый research replay. Это parity runner, который должен повторять live-связку.
Откуда взялся s1800¶
В all-history отчете:
store/market/runs/v42_mtf_s300_short_wide_all_history_2026-01-01_2026-05-30/tf_signal_compare.html
сравнивались фазовые слои:
s300
s900
s1800
s3600
на моментах sparse s300-сигналов. Сводка отчета:
days=150
base_points=43200
signals=150
signal_days=97
s300_long_at_signals=79
s300_short_at_signals=71
s900_long_at_signals=81
s900_short_at_signals=69
s1800_long_at_signals=68
s1800_short_at_signals=82
s3600_long_at_signals=66
s3600_short_at_signals=84
Визуально и по phase-sim sweep лучшим практическим слоем стал s1800. Например phase_s1800_lb224_th0.json на том же all-history прогоне:
frames=43200
phase_frames=7200
signals=150
trades=150
return=+25.63%
win=51.33%
profit_factor=1.45
max_drawdown=13.74%
Для сравнения, s900 с тем же lb224/th0 дал отрицательный результат:
return=-11.02%
win=38.67%
profit_factor=0.83
max_drawdown=29.81%
А s3600 был положительным, но хуже s1800:
return=+10.98%
win=50.0%
profit_factor=1.19
max_drawdown=19.95%
Вывод: s1800 не является отдельным swarm в текущем live, но его роль как HTF-фазы подтверждена экспериментом.
Почему закрытые bucket важны¶
В live нельзя знать будущее незакрытого 5-минутного окна.
Поэтому offline тоже не должен использовать неполный bucket так, будто он был закрыт.
Правило:
Decima получает только закрытый s300 bucket
директор получает только закрытый s1800 bucket
Если это нарушить, walk-forward станет оптимистичным и перестанет быть проверкой live.
Session reset¶
Текущий replay использует:
--swarm-session-reset utc-day
--swarm-session-frames 288
Почему это важно:
- Decima имеет внутреннее состояние;
- долгий непрерывный replay без reset может отличаться от live-дней;
- reset по UTC-day ближе к дневной торговой дисциплине;
- 288 s300-кадров = 24 часа.
Если поменять reset policy, это уже новая проверка.
Level-v3 invariant¶
Для истории level-v3 должен давать:
86400 frames per day
Это было специально исправлено, потому что без этого MTF и walk-forward могут "терять" пустые секунды и давать другой слух.
Проверка ETHUSDT после исправления:
150 дней
каждый день: 86400 frames.level-v3.jsonl
Пример ETHUSDT transfer¶
Команда:
python3 store/market/tools/whaler_live_replay_walkforward.py \
--frames-glob 'store/market/runs/ETHUSDT-2026-*/frames.level-v3.jsonl' \
--start 2026-01-01 \
--end 2026-05-30 \
--out-dir store/market/runs/v42_transfer_ETHUSDT_levelv3_fixed_2026-01-01_2026-05-30
Результат:
raw_frames=12960000
s300 closed_frames=43200
s1800 closed_frames=7200
short signals=138
trades=68
pnl=+13.6846
return=+13.68%
win=64.7%
dd=19.22%
equity=113.6846
position=flat
Помесячно:
2026-01: trades=13 pnl=+10.0041 win=76.9%
2026-02: trades=15 pnl=-6.2165 win=46.7%
2026-03: trades=15 pnl=+2.6741 win=60.0%
2026-04: trades=16 pnl=+5.3470 win=68.8%
2026-05: trades=9 pnl=+1.8759 win=77.8%
Вывод: ETH transfer не идеален, но положительный. Это полезный стресс-тест переносимости.
Что сравнивать live vs replay¶
Минимальный parity checklist:
одинаковая .d8p
одинаковый labels TSV
одинаковый MTF scale
одинаковые closed bucket rules
одинаковая bootstrap policy
одинаковая session reset policy
одинаковый phase lookback
одинаковая комиссия
одинаковый same-side режим
одинаковый catalog-фильтр, если он включен
одинаковое carry/close at EOF
Сравниваемые выходы:
s300 frame count
s1800 frame count
signals count
pattern ids
director decisions
position transitions
realized pnl
mark pnl
drawdown
Почему live может временно молчать¶
v42 может долго не давать торговых действий:
- s300 прогревается;
- s1800 прогревается еще дольше;
- phase может быть neutral;
- боковик не проходит фильтры;
- Decima может услышать сигнал, но директор решит
skip; - позиция может быть уже открыта, а same-side не дает причины закрыть.
Это нормальное поведение. Молчание в боковике - часть стратегии.
Что должно быть видно в HTML¶
director.html должен быть мониторингом, а не просто картинкой результата.
Минимально он должен показывать:
run id
symbol
env
start time
uptime
last update time
websocket messages
trades received
frames
reconnects
s300 frames
s1800 frames
signals
position
equity
realized pnl
mark pnl
drawdown
last decision
last reason
paths to JSON/TSV/HTML
Для VPS это станет главным экраном здоровья.
Когда live "ок"¶
Live считается технически здоровым, если:
- WebSocket не завис;
ws_messagesрастет;tradesрастут;framesрастут;reconnectsне растут бесконтрольно;- s300 и s1800 файлы обновляются;
director.json/htmlобновляются;- inventory не расходится с директором;
- нет неожиданных exceptions;
- свободное место на диске не заканчивается.
Когда live не "ок"¶
Нужно вмешиваться, если:
- WebSocket сообщений нет;
- trades не растут при живом рынке;
- frames не растут;
- s300/s1800 html не обновляется;
- director не пишет новые отчеты;
- reconnects растут часто;
- position в inventory отличается от биржи;
- диск почти заполнен;
director.jsonбитый или пустой;- live использует не ту
.d8pили labels.
Правило для будущих экспериментов¶
Любой новый v43+ эксперимент должен отвечать:
чем он отличается от v42?
какой слой изменен?
сохраняется ли live/replay parity?
какой baseline replay?
какой transfer по ETHUSDT?
какой риск хуже, чем у v42?
Без этого v42 остается базой.