Astrobot
v1.0 · 2026-05
02 · Pipeline

Как работает

Под капотом — две дорожки: research (как модель обучали и тестировали на истории) и live (как ровно та же модель работает на бирже сейчас). Принципиально важно: используется один и тот же файл модели, поэтому решения на бирже совпадают с симуляцией с точностью до копейки — никакой подмены не происходит. Дальше — пошагово, что происходит внутри каждой дорожки.

1
Загрузка котировок
26 тикеров MOEX (blue chips) × часовые бары × 2016-01..2025-06 (~30k баров на тикер). Источник OHLCV — T-Invest API (история через backtrader.ru bundle для consistency)
2
Расчёт стратегий (long+short FSM)
2 773 параметризованных стратегий на тикер: 12 skip-list + 10 direction-aware + 55 candle patterns × сетки параметров. FSM (Finite State Machine) поддерживает long+short с event shift(1) для anti-leakage. Каждая выдаёт signed position ∈ {−1, 0, +1}
3
Отбор top-50 стратегий
Ранжирование по feature importance на TRAIN+VAL (CatBoost feature_importance после первого pass). Замена v6.0 подхода (top-100 by Sharpe с квотами 9+11+80) — importance-ranked отбор отсёк CDLDOJI шум, оставил действительно informative стратегии
4
Сборка обучающего датасета
73 фичи × ~615k строк × 26 тикеров. Состав: 50 raw {sid}_position (signed) + 8 raw indicators (RSI/ADX/NATR/CHOP/MACD/CCI/BB) + 6 hourly ctx + 6 daily ctx + 2 macro (dividend + CBR) + ticker_id. Target: forward 20-bar log return ансамбля (clip ±10%)
5
Обучение CatBoost RMSEWithUncertainty
Regression с RMSEWithUncertainty loss. Cross-ticker — одна модель на все 26 тикеров (ticker_id как categorical). Output на каждый бар: μ̂ (ожидаемый возврат) + σ̂² (uncertainty). Early stopping на VAL 2023. Seed=42, 45s train
6
Расчёт целевых позиций (kelly_vol L+S)
meta_pos = clip(kelly_fraction · μ̂ / σ̂² × vol_target/realized_vol, −1, +1) × cost_gate × turnover_filter. kelly_fraction=0.5, target_vol_annual=0.15, halflife=20, cost_hurdle=0.0003, min_change=0.20. long_only=False — signed positions сохраняются
7
Asymmetric hurdle entry filter
Кандидат заходит в priority queue если pred_mean > +18 bps (long) ИЛИ pred_mean < −12 bps (short). Asymmetric (18L/12S) — short side более тонкий gate, т.к. распределение pred_mean смещено в long (~67% положительных)
8
Симуляция портфеля (10-slot priority rotation L+S)
10 fixed slots. 4 actions: {BUY, SELL_TO_CLOSE, SELL_SHORT, BUY_TO_COVER}. Каждый бар: топ-10 по |meta_pos| → slots; слабейший вытесняется при появлении сильнее (forced exit); при |target_pos| ≤ EPS_ACTIVE=0.10 — natural exit. Borrow cost 20%/год учтён overnight для shorts. Комиссия 5 bps/side
9
Shared cash pool (cb=0.30)
Explicit cash переменная. slot_equity = total × 0.70 / 10 ≈ 7%. Cash buffer 30% всегда зарезервирован под margin/borrow. Открытые позиции компаундятся per-slot по mark-to-market. signed qty_lots в state
10
KPI / multi-seed evaluation
Sharpe, CAGR, MaxDD, Calmar; monthly returns; per-ticker contribution. 5-seed sweep обязателен (D_4 amplifier std ~0.4-0.7 — single-seed = lottery). Shuffle leakage test (label shuffle) PASS +13.88σ above null

Тот же inference pipeline, но на свежих часовых барах с T-Invest. Запускается cron'ом каждый час (close of bar + 5 мин buffer) в торговые часы MOEX. С 13.05.2026 — Phase 3 sandbox live (DRY_RUN=0, ENABLE_SHORT=1).

1
cron каждый час (торговые часы MSK)
runner.py — idempotent по bar_ts: один бар — один полный цикл. ENABLE_SHORT=1 в env (иначе main.py default long-only)
2
Проверки: halt-флаг и новый бар
Если halted.flag присутствует или нового бара ещё нет — выход без действий. KILL_SWITCH тригеры: DD>10%, quote gap >2h, >3 exceptions/час, position age >30d
3
Загрузка котировок (T-Invest)
UTC cache → MSK-naive parquet, формат как в research. Кэш incremental — догружается только дельта. Trailing window WARMUP=2000 bars (для ADX/UI convergence)
4
Расчёт индикаторов и стратегий
Trailing 2000 баров для top-50 стратегий из bundle + 8 семейств raw indicator. Subprocess wrapper над Meta_model/strategy_indicator_calc/main.py --mode live. Те же strategy_id, что и при обучении
5
Inference модели
73-фичевая X-матрица → тот же CatBoost artifact (bit-exact parity с research) → kelly_vol L+S sizer → signed meta_pos per ticker (20 тикеров в live, top-20 ликвидных MOEX)
6
Asymmetric hurdle filter (18L / 12S bps)
Кандидат на entry проходит если pred_mean > +18 bps ИЛИ pred_mean < −12 bps. Уже открытые позиции не трогает. Params: HURDLE_BPS_ENTRY=18, HURDLE_BPS_ENTRY_SHORT=12
7
Расчёт целевого портфеля
N_SLOTS_FIXED=10. Priority по |meta_pos|, force-exit weakest, shared cash pool 70% / 10 slots = 7% per slot. Signed qty_lots в sizer_state. EPS_ACTIVE=0.10 для natural exit
8
Отправка ордеров (sandbox)
4 actions {BUY, SELL_TO_CLOSE, SELL_SHORT, BUY_TO_COVER} → broker_side {BUY, SELL} для T-Invest API. broker.post_market_order в T-Invest sandbox (account 9616c0fa-...-5d9b8befd0ad, 1M RUB)
9
Мониторинг + Telegram
KILL_SWITCH (DD 10% / quote gap 2h / 3+ exceptions/час / position age 30d) → halted.flag. Уведомления по entry/skip/exit/replace + утренний и вечерний отчёт + HALT. observation_sanity.py — 6-check pipeline correctness (parity, state, sign distr, hurdle hit, turnover, action coverage)