Skip to content

Latest commit

 

History

History
962 lines (704 loc) · 38.2 KB

File metadata and controls

962 lines (704 loc) · 38.2 KB

Откат v1.14 → v1.13e (multi-position → single-position)

Когда нужен: если paper trading показывает что MAX=5 ухудшает edge, или если перед переходом на live ($300, Этап 7) надо вернуть консервативные параметры. Также этот документ — общий чек-лист перед live.


TL;DR — три шага отката

cd /opt/crypto-event-bot

# 1. Откатить код (бот вернётся к MAX=1)
git revert 1e5aa91 25ecdc0 98a9d1f --no-commit
git commit -m "revert(v1.14): откат на single-position для live $300"
git push origin main

# 2. Вернуть депозит на $300
docker compose exec -T redis redis-cli SET trading:deposit_usd 300

# 3. Перезапустить бот и dashboard
docker compose restart bot dashboard

После этого:

  • MAX_OPEN_POSITIONS=1, MAX_POSITIONS_PER_SYMBOL=1
  • trading:deposit_usd=300
  • Dashboard показывает $300 equity вместо $2000

Что было сделано в v1.14 (1 мая 2026)

После того как бот за первые 30 часов после v1.13e+2 (фикс indicators.valid) поймал 2 B5-сетапа в одном 8-часовом окне (BNB и ATOM), причём ATOM был более качественным (wick=0.383% vs 0.009%) но отвергнут MAX_OPEN=1 — мы решили временно расширить paper-режим для ускорения сбора статистики.

Изменения в коде

Коммит 1e5aa91feat(v1.14):

Файл Изменение Зачем
bot/config.py MAX_OPEN_POSITIONS: 1 → 5 Multi-position
bot/config.py + MAX_POSITIONS_PER_SYMBOL = 1 Защита от дубля
bot/trading/risk_manager.py + _count_open_positions_for_symbol Per-symbol проверка
bot/trading/risk_manager.py + per-symbol check ДО global Fail-fast
dashboard/app.py + секция "Баланс" Equity/Free/Locked/Floating
dashboard/app.py + get_realized_pnl_usd() Real-time PnL
dashboard/app.py + sidebar real-time equity Live баланс
tests/test_risk_manager.py +4 регрессионных теста Защита от backsliding
CLAUDE.md Депозит шапки $300 → $2000 paper Документация

Коммит 25ecdc0feat(backtest v1.14):

Файл Изменение
scripts/backtest.py MAX_OPEN_POSITIONS глобал → DEFAULT_MAX_OPEN_POSITIONS
scripts/backtest.py BacktestEngine принимает max_open_positions, max_per_symbol
scripts/backtest.py Размер позиции от free_balance, не от deposit
scripts/backtest.py Per-symbol skip в цикле
scripts/backtest.py CLI --max-open, --deposit, --max-per-symbol
tests/test_backtest_multi_position.py +5 регрессионных тестов

Коммит 98a9d1ffix(backtest):

Файл Изменение
scripts/backtest.py + --reversal-mode CLI
scripts/backtest.py + --disable-btc-stopper CLI

Изменения в Redis

# До v1.14:
trading:deposit_usd = "300.00"

# После v1.14 (paper):
trading:deposit_usd = "2000.00"

Backtest-результаты v1.14 (1 мая 2026)

Все прогоны: 1095 дней (3 года), --reversal-mode --allowed-triggers lower_bb_reversal,bb_squeeze_breakout

Метрика MAX=1, $300 MAX=5, $2000
Total Trades 470 1622
Win Rate 38.72% 35.33%
Net Return +178% +308%
Max Drawdown 18.26% 18.90%
Profit Factor 1.346 1.294
Sharpe-like 0.143 0.111

Walk-forward (90-day windows, MAX=5): только 1 из 11 окон в плюсе, avg окна −30.86%. Стратегия выживает в 3-летнем прогоне за счёт compound growth + 1-2 крупных bull-окон.

Вывод: MAX=5 даёт больше абсолютной прибыли (compound), но не улучшает per-trade edge (WR/PF/Sharpe хуже). Проверяем в paper.


Полный откат v1.14 → v1.13e (детально)

Шаг 1. Откат кода (Git)

cd /opt/crypto-event-bot
git fetch origin
git log --oneline -10  # увидеть последние коммиты

Должны быть видны (новые сверху):

98a9d1f fix(backtest): добавить --reversal-mode CLI флаги
25ecdc0 feat(backtest v1.14): multi-position режим
1e5aa91 feat(v1.14): paper-режим расширен — MAX_OPEN_POSITIONS=5
c1112c9 docs: обновить устаревший docstring event_detector.py
29c37b4 fix(critical #2): indicators.py не писал поле 'valid'
4cf60e8 fix(critical): event_detector._should_skip_claude блокировал B5/B3

Откат:

git revert 98a9d1f 25ecdc0 1e5aa91 --no-commit
git commit -m "$(cat <<'EOF'
revert(v1.14): откат multi-position на MAX=1 + $300

Возвращаемся к v1.13e+2 (комит c1112c9) состоянию:
- MAX_OPEN_POSITIONS = 1
- Депозит paper $2000 → $300 (требуется ручной SET в Redis)
- Backtest без --max-open параметра (default = 1)
- Dashboard равенство equity = start_deposit (нет multi-pos логики)

Причина отката: [укажи здесь]
EOF
)"
git push origin main

Шаг 2. Вернуть депозит в Redis

Важно: код вернётся к default $300, но в Redis всё ещё $2000. Логика _get_current_deposit() читает из Redis. Нужно явно перезаписать:

docker compose exec -T redis redis-cli SET trading:deposit_usd 300
docker compose exec -T redis redis-cli GET trading:deposit_usd
# должно вернуть "300"

Опасно: если у нас открытые позиции > $300, их размер уже не помещается. Перед откатом:

# Закрыть все открытые позиции (продать на бирже + DB update)
docker compose exec bot python scripts/kill_switch.py

Либо подождать пока позиции закроются по SL/TP/time_stop естественно.

Шаг 3. Restart

docker compose restart bot dashboard

В логах должно появиться:

📍 Position Tracker: запуск, проверка каждые 60s (mode=paper)
RiskManager: депозит $300.00, MAX=1

Шаг 4. Проверка

# В Redis депозит правильный
docker compose exec -T redis redis-cli GET trading:deposit_usd
# → "300"

# В коде MAX=1
docker compose exec bot python -c "from bot.config import MAX_OPEN_POSITIONS; print(MAX_OPEN_POSITIONS)"
# → 1

# Тесты зелёные
make test

Чек-лист перед LIVE (Этап 7)

Этот чек-лист обязателен перед переключением TRADING_MODE=live. Если хоть один пункт не выполнен — НЕ запускать.

Код

  • bot/config.py: MAX_OPEN_POSITIONS = 1 (или 2)
  • bot/config.py: MAX_POSITIONS_PER_SYMBOL = 1
  • bot/config.py: LEVERAGE_ALLOWED = False
  • bot/config.py: FUTURES_ALLOWED = False
  • bot/config.py: 9 пар в ALLOWED_PAIRS (без XRP, AVAX)

Redis

  • trading:deposit_usd = 300
  • bot:kill_switch = 0 (или нет ключа)
  • Все pending_trade:* ключи зачищены

.env

  • TRADING_MODE=live
  • BINANCE_TESTNET=false
  • BINANCE_API_KEY и BINANCE_API_SECRET заполнены prod-ключами
  • ANTHROPIC_API_KEY заполнен
  • TELEGRAM_BOT_TOKEN для алертов
  • FRED_API_KEY для macro

Тесты и сборка

  • make test все тесты зелёные
  • docker compose build --no-cache (пересборка)
  • docker compose up -d

Метрики paper-периода (минимум 30 сделок)

  • WR ≥ 40% (если меньше — переписывать стратегию)
  • Net Return % ≈ backtest (или лучше)
  • MaxDD ≤ 25%
  • Хотя бы 1 положительная неделя
  • Дневной Claude расход ≤ 15% от профита

После запуска live

  • В логах: mode=live (не paper)
  • В логах: Депозит: $300.00
  • В Telegram: тестовое сообщение пришло
  • Watchdog активен (heartbeat есть)
  • Position Tracker мониторит (даже если 0 открытых)
  • Dashboard работает на 8501

Откат отката (если передумали)

Если откатили v1.14, но потом передумали:

git revert HEAD --no-commit  # отменяет последний revert
git commit -m "restore(v1.14): возврат multi-position"
git push origin main

# И депозит обратно
docker compose exec -T redis redis-cli SET trading:deposit_usd 2000
docker compose restart bot dashboard

Откат v1.15 (Vision API + News Clustering) — БЕЗ git revert

В отличие от v1.14, Phase 1+2 (v1.15) можно отключить через feature-флаги без отката кода. Это специально — чтобы быстро проверить эффект.

Отключить Vision API только

# В .env на сервере:
ENABLE_VISION_API=false

docker compose restart bot

После этого Opus получает только текстовый промпт (как до v1.15). News clustering продолжает работать.

Отключить News Clustering только

# В .env:
ENABLE_NEWS_CLUSTERING=false

docker compose restart bot

NewsFilter перестаёт делать embeddings → каждое news_raw идёт в Haiku. Vision API продолжает работать.

Отключить обе фичи

# В .env:
ENABLE_VISION_API=false
ENABLE_NEWS_CLUSTERING=false

docker compose restart bot

Полный откат v1.15 кода (если нужен)

cd /opt/crypto-event-bot
git log --oneline | grep "v1.15" | head -5  # найти коммиты v1.15
git revert <commit_hash> --no-commit
git commit -m "revert(v1.15): откат vision + clustering"
git push origin main
docker compose restart bot

Изменить порог дедупа новостей (без отката)

# В .env:
NEWS_CLUSTERING_THRESHOLD=0.90  # строже (меньше дубликатов засчитывается)
# или
NEWS_CLUSTERING_THRESHOLD=0.75  # мягче (больше дубликатов отсеивается)

docker compose restart bot

Откат v1.16 Phase B (Perpetual Futures paper)

Phase B — параллельная подсистема для perp. НЕ ВЛИЯЕТ на spot.

Полный откат Sub-phase B1 (если Phase B решили не делать)

cd /opt/crypto-event-bot

# 1. Остановить бот
docker compose stop bot

# 2. Откатить миграцию БД
docker compose exec postgres psql -U cryptobot -d cryptobot -c "DROP TABLE trades_perp CASCADE;"

# 3. Удалить Redis ключи perp-режима
docker compose exec -T redis redis-cli DEL perp:trading_deposit_usd perp:kill_switch

# 4. Откатить код
git revert <hash_of_perp_b1_commit>
git push origin main

# 5. Перезапустить
docker compose up -d

После этого spot-бот продолжает работать как до Phase B.

Подготовка к запуску Sub-phase B1

Шаг 1 — применить миграцию БД (создаёт таблицу trades_perp):

docker compose exec bot alembic upgrade head

Должно вывести Running upgrade 0001 -> 0002, Add trades_perp table.

Шаг 2 — Binance Futures DEMO ключи (доступно из EU):

ВАЖНО: используем demo.binance.com, не testnet.binancefuture.com. Testnet geo-locked для EU; demo доступен глобально с собственным API endpoint demo-fapi.binance.com.

  1. Открой https://demo.binance.com/en/my/settings/api-management
  2. Login через свой Binance аккаунт (или регистрация)
  3. Create API → имя crypto-event-bot-perp
  4. Скопируй Secret Key СРАЗУ — он показывается один раз!
  5. На сервере добавить в .env:
echo "BINANCE_FUTURES_API_KEY=<твой_API_Key>" >> .env
echo "BINANCE_FUTURES_API_SECRET=<твой_Secret_Key>" >> .env
echo "BINANCE_FUTURES_MODE=demo" >> .env
docker compose restart bot

Шаг 3 — установить стартовый депозит (по умолчанию $1000):

docker compose exec -T redis redis-cli SET perp:trading_deposit_usd 1000

Шаг 4 — проверить тесты:

make test

Должно быть 340+ passed.

Откат Sub-phase B2 (PerpPositionTracker)

Если хочется откатить только B2 (мониторинг), оставив B1 (фундамент):

cd /opt/crypto-event-bot

# 1. Остановить бот
docker compose stop bot

# 2. git revert Sub-phase B2 коммита (НЕ revert B1)
git log --oneline | head -5  # найти hash коммита B2
git revert <hash_of_perp_b2_commit>
git push origin main

# 3. (опционально) очистить tracker-флаги в Redis
docker compose exec -T redis redis-cli --scan --pattern 'perp:trailing*' | xargs docker compose exec -T redis redis-cli DEL
docker compose exec -T redis redis-cli --scan --pattern 'perp:funding_applied*' | xargs docker compose exec -T redis redis-cli DEL

# 4. Перезапустить
docker compose up -d

Спот и Sub-phase B1 остаются. Tracker не запустится (отсутствует), supervisor вернётся к 15 задачам. Открытые trades_perp останутся в БД, но за ними никто не следит — их нужно закрыть руками через Binance UI или через make perp-kill-switch.

Откат Sub-phase B3 (short detectors)

Если хочется выключить B5_short / B3_short детекторы (например, оказалось что Opus возвращает плохие решения для shorts) — оставив B1+B2:

cd /opt/crypto-event-bot

# 1. Остановить бот
docker compose stop bot

# 2. git revert Sub-phase B3 коммита
git log --oneline | head -5  # найти hash коммита B3
git revert <hash_of_perp_b3_commit>
git push origin main

# 3. (опционально) удалить накопленные short-события из БД
docker compose exec postgres psql -U cryptobot -d cryptobot -c "
  DELETE FROM events WHERE event_type IN ('upper_bb_rejection_4h', 'bb_squeeze_breakdown_4h');
"

# 4. Перезапустить
docker compose up -d

После revert: long-варианты B5/B3 продолжают работать, perp-tracker (B2) тоже, но short-события не детектятся → trades_perp пустая для shorts.

Soft-disable без revert (если хочется быстро отключить):

# Выставляем фиктивный TTL дедуп ключ на много часов = детектор не сработает
docker compose exec -T redis redis-cli SET detector:dedup:upper_bb_rejection_4h:BTCUSDT 1 EX 86400
# Повторить для всех 9 пар × 2 типа = 18 ключей

Это grubое решение, но без правок кода. Чище — фича-флаг (TODO в B4).

Откат Sub-phase B4 (PerpTrader координатор)

Если хочется откатить только B4 (отключить открытие perp-сделок), оставив B1+B2+B3 (фундамент, мониторинг, детекторы продолжают работать):

cd /opt/crypto-event-bot

# 1. Остановить бот
docker compose stop bot

# 2. ВАЖНО: закрыть все открытые perp-позиции вручную через demo.binance.com
# Иначе они останутся открытыми и без мониторинга (PerpPositionTracker
# B2 продолжит работать но без новых сделок).

# 3. git revert B4 коммита (НЕ revert B1/B2/B3)
git log --oneline | head -10  # найти hash коммита B4
git revert <hash_of_perp_b4_commit>
git push origin main

# 4. Очистить Redis ключи перп-trader'а
docker compose exec -T redis redis-cli --scan --pattern 'pending_perp_trade:*' | xargs -r docker compose exec -T redis redis-cli DEL
docker compose exec -T redis redis-cli --scan --pattern 'decision:processed_by_spot:*' | xargs -r docker compose exec -T redis redis-cli DEL

# 5. Перезапустить
docker compose up -d

После revert:

  • Spot trader снова при side='short' будет mark executed=True с reason='spot_no_shorts' (старое поведение)
  • Detectorы B5_short/B3_short продолжают регистрировать события (через B3)
  • PerpPositionTracker (B2) продолжит мониторить trades_perp
  • НО новых perp-сделок не будет открываться

Soft-disable без revert: PERP_ENABLED=False в bot/config.py → PerpTrader идёт в idle loop, не подключается к API.

Откат Sub-phase B5 (dashboard tab "Perp")

Самый безопасный откат — B5 затрагивает только дашборд, не торговый flow.

cd /opt/crypto-event-bot

# 1. Остановить только dashboard контейнер (бот продолжает работать)
docker compose stop dashboard

# 2. git revert
git log --oneline | head -5
git revert <hash_of_perp_b5_commit>
git push origin main

# 3. Обновить и запустить заново
git pull origin main
docker compose up -d dashboard

После revert: страница "📐 Perp" исчезнет, но perp_trader / perp_position_tracker продолжат работать в фоне. Данные смотреть через psql trades_perp напрямую или через Telegram-алерты.

Soft-disable не требуется — если Perp не используется (нет API ключей), вкладка показывается, но open positions пустые, equity = $1000 (default).

Откат Phase D Variants I + J (trend-following + small-cap funding arb)

git revert <hash_of_variants_ij_commit>
git push origin main
# Опционально удалить small-cap данные
rm -f data/perp/candles/{PEPE,INJ,JUP,WIF,TIA,SEI}USDT_1h.csv
rm -f data/perp/funding/{PEPE,INJ,JUP,WIF,TIA,SEI}USDT.csv

Удаляются: scripts/backtest_trend_1d.py, scripts/backfill_smallcaps.py; modification --symbols в backtest_funding_arb.py возвращается. Bot не трогается.

Откат Phase D Variants F/G/H (no-SL, pair trading, inverse whale)

git revert <hash_of_variants_fgh_commit>
git push origin main

Удаляются: scripts/backtest_liq_fade_no_sl.py, backtest_pair_trading.py, backtest_inverse_whale.py + Makefile цели. Bot не затрагивается.

Откат Phase D Variants C/D/E (3 нестандартные стратегии)

Все 3 новых скрипта изолированы в scripts/. Откат — простой revert:

cd /opt/crypto-event-bot
git revert <hash_of_variants_cde_commit>
git push origin main

После revert: scripts/backtest_liquidation_fade.py, backtest_whale_flow_proxy.py, backtest_funding_flip.py + tests/test_phase_d_variants.py удаляются. Bot не затрагивается. Phase B + предыдущие Phase D эксперименты остаются.

Откат Phase D Variant A (funding arbitrage)

cd /opt/crypto-event-bot
git revert <hash_of_funding_arb_commit>
git push origin main
# (опционально) удалить funding history если место нужно
rm -rf data/perp/funding/*.csv

После revert: scripts/backfill_funding_history.py, scripts/backtest_funding_arb.py и tests/test_backtest_funding_arb.py удаляются. Bot не затрагивается.

Откат Phase D Variant B (1h scalp)

Это просто параметризация существующего scalp скрипта. Достаточно не запускать с --timeframe 1h. Если хочется убрать совсем:

git revert <hash_of_1h_param_commit>
git push origin main

После revert: backtest_scalp.py возвращается к версии "только 15m".

Откат Phase D (scalp эксперимент)

Phase D — эксперимент, не production. Очень безопасный откат:

cd /opt/crypto-event-bot

# 1. git revert
git log --oneline | head -5
git revert <hash_of_phase_d_commit>
git push origin main

# 2. (опционально) удалить 15m свечи если место нужно
rm -rf data/perp/candles/*_15m.csv

# 3. Бот перезапускать НЕ НУЖНО — Phase D трогает только scripts/, не bot/.

После revert:

  • Spot и perp бот продолжают работать как обычно (Phase B полностью независима)
  • Файлы scripts/backtest_scalp.py и tests/test_backtest_scalp.py удаляются
  • Цели Makefile backtest-scalp* исчезают
  • 15m свечи в data/perp/candles/ остаются на диске (можно удалить вручную)

Soft-disable: просто не запускать make backtest-scalp — никто не возражает.

Полный откат Phase B (B1 + B2 + B3 + B4 + B5 + всё что после)

Если решили совсем не делать Phase B:

  1. Остановить бот: docker compose stop bot
  2. Закрыть все perp-позиции вручную на demo.binance.com
  3. git revert коммитов B1 и B2 (от новейшего к старейшему)
  4. DROP TABLE trades_perp CASCADE; (см. раздел B1 выше)
  5. Удалить Redis ключи: redis-cli DEL perp:trading_deposit_usd perp:kill_switch
  6. Удалить FUTURES ключи из .env
  7. docker compose up -d

Отключить Phase B на лету (через флаг)

В bot/config.py: PERP_ENABLED: bool = False → перезапуск бота. Весь perp-код пропускается, spot работает. Tracker уходит в idle loop без подключения к Binance API.


История этого документа

  • 1 мая 2026 (создан): первая версия — описывает откат v1.14 → v1.13e на момент после деплоя multi-position режима.
  • 1 мая 2026 (вечер): добавлен раздел отката v1.15 через feature-флаги (Vision API + News Clustering можно отключить без git revert).
  • 1 мая 2026 (поздний вечер): добавлен раздел подготовки и отката v1.16 Phase B Sub-phase B1 (фундамент paper-perp).
  • 1 мая 2026 (ночь): добавлен раздел отката v1.16 Phase B Sub-phase B2 (PerpPositionTracker) — отдельно от B1, чтобы можно было откатить только мониторинг при сохранении инфраструктуры.
  • 1 мая 2026 (поздняя ночь): добавлен раздел отката v1.16 Phase B Sub-phase B3 (short detectors B5_short/B3_short). Можно откатить через git revert или soft-disable через Redis dedup keys.
  • 2 мая 2026 (раннее утро): добавлен раздел отката v1.16 Phase B Sub-phase B4 (PerpTrader координатор). Soft-disable через PERP_ENABLED=False, hard-rollback через git revert. ВАЖНО: перед откатом нужно вручную закрыть все открытые perp-позиции через demo.binance.com.
  • 2 мая 2026 (утро): добавлен раздел отката v1.16 Phase B Sub-phase B5 (dashboard tab "Perp"). Самый безопасный откат — затрагивает только визуализацию, торговый flow продолжает работать.
  • 3 мая 2026 (день): добавлен раздел отката Phase D (scalp эксперимент). Самый изолированный откат — только scripts/ + tests/, не трогает bot/ и production-flow.
  • 3 мая 2026 (вечер): добавлены разделы Phase D Variant A (funding arb) и Variant B (1h scalp). Оба тоже изолированы от production.
  • 3 мая 2026 (день): добавлен раздел отката v1.17 (Donchian Trend-Following). Soft-disable через TREND_ENABLED=False, hard-rollback через git revert + DROP TABLE trades_trend.
  • 3 мая 2026 (поздняя ночь): добавлен раздел отката v1.18.2 (calibrated hard skip-rules). Soft-disable через комментирование rules в _check_hard_skip_rules, hard-rollback через git revert.

v1.18.2 Откат: Calibrated Hard Skip-Rules

v1.18.2 добавил программные skip-rules в event_analyzer._check_hard_skip_rules:

  • R1_B3_BEAR (regime < 0.50)
  • R3_B3_ALT_BTC_DEEP (alt при BTC<-3% от EMA-200)
  • R11_BTC_CASCADE (BTC ATR > 5%)

Эти правила применяются ДО вызова Opus. Если правило срабатывает — auto-skip с записью claude_model='hard_rule_v1.18' в bot_decisions без Claude API call.

Если правила слишком жёсткие в production

Возможный сценарий: в bull-фазе R1 не должен срабатывать (regime > 0.50), но если regime classifier даёт неточные scores — может блокировать B3 events которые могли бы быть wins.

Soft-disable одного правила:

# В bot/agents/event_analyzer.py:_check_hard_skip_rules
# Закомментировать конкретное правило:
# if regime_score < 0.50:
#     return f"B3_REJECT [R1]: ..."

После — docker compose restart bot. Правило отключено, остальные работают.

Полный откат всех hard skip-rules

Если v1.18.2 полностью провалится в production (B5 wins резко падают, WR < 30% на reversal-сетапах через 30+ trades):

  1. Soft-disable всех: вернуть в _check_hard_skip_rules return None как первая строка функции — все события идут в Opus.

  2. Git revert:

    git log --oneline | grep "v1.18"
    git revert <commit-hash> <commit-hash>  # все v1.18 commits
    git push
  3. После git revert: docker compose restart bot → старая логика без hard rules.

Что НЕ затрагивается откатом

  • TaskSupervisor (19 задач остаются)
  • Phase B perp shorts (другая подсистема)
  • v1.17 Donchian trend (другая подсистема)
  • Существующие decisions в БД (claude_model='hard_rule_v1.18' просто metadata)

Метрики "когда откатить v1.18.2"

После 30 дней production:

  • Keep: WR proceed-trades ≥ 35%, 0+ Net PnL
  • ⚠️ Investigate: WR 30-35% — возможно нужны мягче пороги
  • Rollback: WR < 30% на 30+ trades, Net PnL < -10%

В replay-30d (proxy): WR 37.5%, Net +$84. В production может быть лучше (news context) или хуже (live execution slippage). Через 30-60 дней увидим.


v1.17 Откат: Donchian Trend-Following

v1.17 добавил третью параллельную стратегию к Phase B (spot reversal) и Phase B (perp shorts). Архитектурная изоляция означает что откат тривиальный — никакие spot/perp компоненты не затрагиваются.

Что было добавлено

  • Новый модуль bot/trend_following/ (5 файлов):
    • donchian_strategy.py — pure logic (compute_donchian_signal/exit)
    • trend_risk_manager.py — TrendRiskManager + Redis keys
    • trend_trader.py — автономный координатор (00:05 UTC daily)
    • trend_position_tracker.py — exit signal monitoring (раз в час)
    • __init__.py — re-exports
  • Новая модель TradeTrend + Alembic migration 0003_trades_trend_table.py
  • Конфиг расширен: TREND_* константы в bot/config.py
  • TaskSupervisor 17 → 19 задач (добавлены trend_trader + trend_position_tracker)
  • Telegram-нотификации: notify_trend_position_opened/closed
  • Dashboard вкладка "📈 Trend" + sidebar секция
  • Makefile цели: trend-status, trend-deposit, trend-signal, trend-kill-switch, trend-kill-switch-reset, trend-set-deposit
  • Тесты: tests/test_trend_following.py (~19 тестов)

Soft-disable v1.17 (без git revert)

Самый быстрый способ — отключить через config-флаг:

# В bot/config.py:
TREND_ENABLED: bool = False  # было True

Затем docker compose restart bot → TrendTrader и TrendPositionTracker уходят в idle loop без подключения к Binance API. Spot и perp продолжают работать как обычно. Открытых trend-позиций не будет, существующие (если есть) останутся в БД с status='open' но не будут обновляться.

Soft-disable через Redis (даже без рестарта)

Если есть открытая trend-позиция и нужно её закрыть сейчас:

# Активируем kill-switch
redis-cli SET trend:kill_switch 1

# Через 1 час (на следующем poll'е) TrendPositionTracker
# закроет все open позиции с reason='kill_switch'

Снять kill-switch:

redis-cli DEL trend:kill_switch

Hard-rollback через git revert

Если решили совсем убрать v1.17:

  1. Закрыть все open trend-позиции (если есть):

    redis-cli SET trend:kill_switch 1
    sleep 3700  # ждём пока tracker закроет
  2. Остановить бот: docker compose stop bot

  3. Git revert коммита v1.17:

    git log --oneline | grep "v1.17\|trend"
    git revert <commit-hash>
    git push
  4. DROP TABLE trades_trend:

    docker compose exec postgres psql -U cryptobot -d cryptobot -c "DROP TABLE IF EXISTS trades_trend;"
  5. Удалить Redis ключи:

    redis-cli DEL trend:trading_deposit_usd trend:kill_switch trend:last_check_date
    redis-cli --scan --pattern "trend:*" | xargs -r redis-cli DEL
  6. Откатить миграцию (опционально):

    docker compose exec bot alembic downgrade -1
  7. Перезапуск: docker compose up -d

После этого TaskSupervisor вернётся к 17 задачам (15 spot + 2 perp).

Что НЕ затрагивается откатом

  • Spot reversal: trades, Trader, PositionTracker, B5/B3 long
  • Perp shorts: trades_perp, PerpTrader, PerpPositionTracker, B5_short/B3_short
  • Существующие decisions в bot_decisions (TradeTrend НЕ связана с BotDecision через FK — намеренно, чтобы откат был чище)

Метрики "когда откатить"

  • Через 30 дней: 0 закрытых сделок — норма для D55 (стратегия редкая). Не откатываем.
  • Через 60 дней: если 1-3 сделки и средний результат в expected range (+/- 5pp от backtest) — keep.
  • Через 90 дней: если 0 сделок (нет breakout) — keep, ждём bull-фазы.
  • Через 180 дней: если 5+ сделок и WR <25% или MaxDD >40% — soft-disable через TREND_ENABLED=False.

Откат v1.18.21 — Funding Arbitrage (Phase D Variant K)

Когда откатывать

Жёсткие условия (по результатам 90 дней forward test на $500):

  • ❌ N≥30 trades И WR < 40%
  • ❌ N≥30 trades И Net < -$50
  • ❌ Любое количество trades И MaxDD > 30%

Soft-disable (без отката кода, через .env):

  • 🟡 N≥30 И WR 40-44% (marginal) — disable, переписать SYSTEM_PROMPT
  • 🟡 Funding rates на small-caps стали стабильно > -0.05% (рынок изменился)

Что откат НЕ затрагивает:

  • Spot reversal (trades, Trader, PositionTracker, B5/B3 long) — НЕ ТРОГАЕТСЯ
  • Perp shorts (trades_perp, PerpTrader, PerpPositionTracker) — НЕ ТРОГАЕТСЯ
  • Trend-following (trades_trend, TrendTrader) — НЕ ТРОГАЕТСЯ

Soft-disable (без отката кода)

# 1. Выключить через .env
cd /opt/crypto-event-bot
sed -i 's/^FUNDING_ARB_ENABLED=true/FUNDING_ARB_ENABLED=false/' .env

# 2. Закрыть все open позиции через kill-switch
make funding-arb-kill-switch

# 3. Перезапустить
docker compose restart bot

# 4. Проверить логи (должно быть 'idle')
make logs-bot | grep funding_arb
# ожидаем:
#   💸 FundingMonitor: funding_arb_enabled=false → idle режим
#   💸 FundingArbTrader: funding_arb_enabled=false → idle режим
#   💸 FundingArbPositionTracker: funding_arb_enabled=false → idle

После этого:

  • Все 3 funding-arb задачи в idle (не делают API calls)
  • TaskSupervisor по-прежнему 22 задач, но funding-arb потребляют 0 ресурсов
  • БД таблицы trades_funding_arb/funding_payments/funding_rates_live остаются для аналитики

Полный откат с DROP TABLE (катастрофический сценарий)

cd /opt/crypto-event-bot

# 1. Закрыть все позиции
make funding-arb-kill-switch
sleep 60  # дать tracker'у закрыть

# 2. Откатить commit
git log --oneline | grep v1.18.21
# → fec3f17 feat(v1.18.21): Phase D Variant K — Inverse Funding Arbitrage production module

git revert fec3f17 --no-commit
git commit -m "revert(v1.18.21): откат Inverse Funding Arbitrage после провала forward test"
git push origin main

# 3. На сервере
docker compose down
git pull
docker compose build
docker compose up -d

# 4. DROP TABLE через alembic downgrade
docker compose exec bot alembic downgrade 0003

# 5. Очистить Redis funding_arb namespace
docker compose exec redis redis-cli --scan --pattern "funding_arb:*" | \
  xargs docker compose exec -T redis redis-cli DEL

# 6. Удалить .env переменную
sed -i '/^FUNDING_ARB_ENABLED=/d' .env

# 7. Перезапуск
docker compose restart bot dashboard

После этого TaskSupervisor вернётся к 19 задачам (15 spot + 2 perp + 2 trend).

Что НЕ затрагивается откатом

  • Spot reversal: trades, Trader, PositionTracker, B5/B3 long
  • Perp shorts: trades_perp, PerpTrader, PerpPositionTracker
  • Trend: trades_trend, TrendTrader, TrendPositionTracker
  • BotDecision записи (TradeFundingArb НЕ связана с BotDecision — намеренно)

Метрики "когда откатить vs продлить"

Сценарий после 90 дней Действие
✅ N≥30 И WR≥45% И Net>+$30 Upgrade $500 → $1000
✅ N≥50 И WR≥50% И Net>+$80 Upgrade $1000 → $3000
🟡 N≥30 И WR 40-44% Soft-disable, переписать threshold
🟡 N<30 (рынок спокойный) Продлить ещё 90 дней
❌ N≥30 И (WR<40% или Net<-$50) Полный откат + DROP TABLE
❌ MaxDD > 30% в любой момент Немедленный kill-switch + investigation

Recovery после crash в funding apply

Если процесс упал между apply_funding_payment и DB INSERT:

  • UNIQUE constraint (trade_id, funding_time) защитит от дубля при повторе
  • При старте FundingArbPositionTracker повторит проверку через cached rate
  • В крайнем случае ручной фикс через SQL:
    -- Найти trade без последнего payment
    SELECT t.id, t.symbol, t.last_funding_applied_at, t.total_funding_payments
    FROM trades_funding_arb t
    WHERE t.status = 'open'
      AND (t.last_funding_applied_at < NOW() - INTERVAL '8 hours'
           OR t.last_funding_applied_at IS NULL);
    
    -- Вручную добавить payment если нужно
    INSERT INTO funding_payments (trade_id, funding_time, funding_rate, ...)
    VALUES (X, '2026-05-05 16:00:00+00', -0.0008, ...);