Files
gridbot/LIVE_CHECKLIST.md.bak.v1.5_20260626_2354

330 lines
17 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# LIVE TRADING CHECKLIST — grid-bot BTC-USDT.IMEX
**Дата создания:** 2026-06-26 23:30 GMT+7
**Last update:** 2026-06-26 23:41 GMT+7 — ответы @KAndrew на open questions
**Бот:** grid-bot v0.13.x (PID 1552921, mode=demo, peak=$375.68)
**Цель:** выход на реальную торговлю через Cifra Markets (BY) / Tradernet
**Целевой размер позиции (от @KAndrew):** $135
> ⚠️ **Текущий статус: НЕ ГОТОВ.** Ниже — что должно быть сделано перед переключением `LIVE_TRADING_DRY_RUN=false`.
---
## 🚦 Блокеры (без них live = деньги на ветер)
### 1. Подтвердить fees Cifra Markets ✅ ЗАКРЫТ (26.06 23:54)
- [x] Зайти в ЛК **cifra.by** → раздел «Тарифы» / «Комиссии» — @KAndrew подтвердил ~0.15%
- [x] Записать **точные %** для BTC-USDT: **0.15% taker** (по @KAndrew)
- [x] Обновить `.env`: `FEE_RATE_PERCENT=0.15`, `FEE_SAFETY_MULTIPLIER=1.5` (было 0.2 / 1.25)
- [ ] **Уточнить** — это **taker**, **maker** или **общая** цифра? Round-trip = 0.30% (taker×2) или 0.15% (round-trip)
- [ ] При следующем рестарте бота подхватится автоматически
**Расчёт margin:** step=0.5% − round-trip fee=0.30% = **0.20% запаса** (40% step'а). TP=2% − fees=0.30% = **1.70% net profit** на цикл. Безопасно.
### 2. Накопить demo-метрики
- [ ] Минимум **30 закрытых сделок** (сейчас 13) — не дни, а TP-fill-ы
- [ ] Минимум **14 дней** непрерывной работы в demo без критических багов
- [ ] **Win-rate > 50%** (TP-fill / total fills)
- [ ] **Avg PnL per trade > 0** после учёта fees
- [ ] **Max DD < 8%** за весь период (у нас сейчас −4.86% от peak)
### 3. Настроить kill switch для live
- [ ] `LIVE_KILL_CLOSE_POSITION=true` (сейчас `false` — это риск)
- [ ] `LIVE_KILL_DD_PCT=5.0` (сейчас не задан → fallback на 10%)
- [ ] Проверить TG-polling работает: `/api/kill-switch/status` → `tg_poll_sec: 30`
- [ ] Протестировать `/api/kill-switch/test` с reason=`live_test` (на demo!)
### 4. Code review (см. секцию ниже)
- [ ] Пройтись по всем fix-точкам из MEMORY.md (`*100`-баги, anchor-формулы, percent-конверсии)
- [ ] Сверить все места с `take_profit_percent` (был баг ×4 → anchor $260K)
- [ ] Проверить формулы asymmetric split (3:2 / 2:3)
### 5. Live API smoke test (см. секцию ниже)
- [ ] Тестовый BUY на минимальный lot с ручным отменом через ЛК
- [ ] Тестовый SELL (TP-fill) на минимальный lot
- [ ] Проверить, что `urllib`-запросы реально доходят до Tradernet, нет 403/timeout
---
## ⚙️ Pre-live .env настройки (что поменять)
```bash
# === ОБЯЗАТЕЛЬНО изменить перед live ===
# 1. Trading mode
DEMO_MODE=false # было: true
LIVE_TRADING_DRY_RUN=false # было: true — это переключатель на реальные ордера
# 2. Real Tradernet API credentials (НЕ дефолтные)
TRADERNET_PUBLIC_KEY=<real_key> # отозвать старые demo-ключи
TRADERNET_PRIVATE_KEY=<real_key>
TRADERNET_LOGIN=<real_login>
TRADERNET_PASSWORD=<real_pass>
# 3. Kill switch — ОБЯЗАТЕЛЬНО
LIVE_KILL_CLOSE_POSITION=true # было: false
LIVE_KILL_DD_PCT=5.0 # 5% (было: не задано → 10%)
KILL_DD_PCT=10.0 # для demo остаётся 10%
# 4. Fee rate (после подтверждения в ЛК Cifra)
FEE_RATE_PERCENT=0.2 # ОБНОВИТЬ после проверки точных %
FEE_SAFETY_MULTIPLIER=1.5 # было: 1.25 — увеличить запас
# 5. Strategy — для live понизить агрессивность
STRATEGY_LOCK_PCT=1.5 # было: 2.0 — раньше блокировать
STRATEGY_LOCK_COOLDOWN_SEC=1800 # было: 900 — реже переключаться
# 6. Inactivity rebuild — для live ВЫКЛЮЧИТЬ
INACTIVITY_RESTART_HOURS=999 # было: 6 — на live пусть работает как есть
INACTIVITY_PRICE_DRIFT_PCT=99.0 # было: 0.25 — фактически отключить
# 7. Kronos — пока НЕ включать на live
KRONOS_LIVE_ENABLED=false # оставить false, пока не подтверждена статистика
# === Что НЕ менять ===
GRID_STEP_PERCENT=0.005 # 0.5% — нормально для fee 0.2%
GRID_TAKE_PROFIT_PERCENT=2.0 # 2% TP — нормально
GRID_LEVELS=10 # дефолт (но у нас сейчас 3 в state.json)
STRATEGY_CENTER_MODE=sma # OK
```
> После правок — **обязательно** перезапустить бота с `kill -9 PID` + новый запуск через `nohup ./venv/bin/python main.py >> bot.log 2>&1 < /dev/null & disown`
---
## 🔍 Code review checklist (что перепроверить в коде)
### Pattern 1: Percent vs ratio confusion (исторически баг ×4)
```bash
# Найти все места, где take_profit_percent или step_percent умножаются:
grep -n "take_profit_percent\|step_percent" /root/grid-bot/main.py /root/grid-bot/grid.py
```
**Проверить каждое вхождение:**
- Если переменная хранится в **процентах** (2.0 = 2%), формула должна быть `value / 100.0`
- Если в **долях** (0.02 = 2%), формула должна быть `value` напрямую
- В `grid.py:pnl_percent()` — уже `*100`, значит внутри ratio
### Pattern 2: Anchor calculation
```bash
grep -n "sell_anchor\|entry_price.*1\.\|anchor_for_filled" /root/grid-bot/main.py
```
- Убедиться что **anchor = entry_price × (1 + take_profit_percent / 100)**
- НЕ `entry_price * (1.0 + take_profit_percent)` (это и был баг 17.06, anchor × 4)
### Pattern 3: Live order placement
```bash
grep -n "_place_live_buy\|_place_live_sell\|_live_cancel" /root/grid-bot/main.py /root/grid-bot/grid.py
```
- Проверить, что `LIVE_TRADING_DRY_RUN=false` реально идёт в код, не в логику демо
- Проверить обработку ошибок `403 / 429 / timeout` — бот должен ретраить ИЛИ тихо отменять (не падать)
- Проверить, что при ошибке API бот НЕ дублирует ордер
### Pattern 4: Asymmetric grid split
```bash
grep -n "STRATEGY_ASYMMETRY\|buy.*sell\|split" /root/grid-bot/main.py /root/grid-bot/grid.py
```
- bias=up → 3 BUY / 2 SELL (anchor выше)
- bias=down → 2 BUY / 3 SELL (anchor ниже)
- bias=range → 3 BUY / 2 SELL (default)
### Pattern 5: Peak equity reset
```bash
grep -n "peak_equity\|_peak_lock" /root/grid-bot/main.py
```
- При live-старте вызвать `kill_switch.reset()` — peak начнёт отсчитываться от live-баланса
- Без reset — KS может триггернуться сразу (peak=$375.68 demo, на live у нас меньше)
### Pattern 6: 403 авто-pause (требует НОВОГО кода) ⭐
**Требование @KAndrew:** при HTTP 403 от Tradernet API → авто-pause бота, НЕ kill.
**Сейчас:** KS считает все API errors одинаково (`api_errors_threshold=5` за 600 сек → kill).
**Что нужно сделать:**
- [ ] Разделить счётчики ошибок: `api_errors_403` (auth/perm) vs `api_errors_5xx` (infra)
- [ ] При `api_errors_403 >= 1` → bot_running=false (pause), KS НЕ triggered, reason=`auth_403`
- [ ] При `api_errors_5xx >= 5` за 600 сек → KS trigger (как сейчас)
- [ ] При resume (после ручного `/api/bot/start`) — счётчики сбрасываются
- [ ] TG-алерт при любой 403: «⚠️ 403 от Tradernet — бот поставлен на паузу»
**Файл для правки:** `/root/grid-bot/main.py` — секция API error tracking (см. grep `_api_errors`)
**Smoke test после фикса:**
```bash
# На demo: подменить API ключ на невалидный, дождаться 403 → бот должен встать на паузу
sed -i 's/TRADERNET_PUBLIC_KEY=.*/TRADERNET_PUBLIC_KEY=INVALID_KEY/' /root/grid-bot/.env
kill -9 $(pgrep -f 'python.*main.py'); cd /root/grid-bot && nohup ./venv/bin/python main.py >> bot.log 2>&1 < /dev/null & disown
sleep 60
curl -s -u kolpakov:GrinderBot1090 https://gridbot.kolp.pro/api/status | grep bot_running
# → должно быть bot_running: false, reason: auth_403
# Восстановить ключ!
```
### Pattern 7: TG-уведомления на сделку (требует НОВОГО кода) ⭐
**Требование @KAndrew:** каждая сделка (BUY fill / SELL fill / TP-fill) → TG-сообщение с деталями.
**Сейчас:** TG вызывается только при `tg_notify()` в `main.py:384` (KS-alerts, важные изменения). Сами сделки НЕ спамят.
**Что нужно сделать:**
- [ ] Хук в `check_fill_buy` / `check_fill_sell` / `check_take_profit` после успешного fill → `tg_notify(...)` с шаблоном:
- BUY: `🟢 BUY fill @ $XXX (qty Y, balance $Z)`
- SELL: `🔴 SELL fill @ $XXX (pnl +$W)`
- TP-fill: `🎯 TP @ $XXX (pnl +$W, total trades: N)`
- [ ] Anti-spam: не слать TG если fill дубликат (idempotency по order_id)
- [ ] Quiet hours НЕ применяются (24/7 по решению @KAndrew)
- [ ] Тест: дождаться следующего BUY fill на demo → проверить TG
**Файлы для правки:** `/root/grid-bot/main.py` (buy/sell fill handlers) + `/root/grid-bot/grid.py` (TP logic)
---
## 🧪 Smoke test (перед переключением на live)
### Pre-flight (на demo)
```bash
# 1. Kill switch готов?
curl -u kolpakov:GrinderBot1090 https://gridbot.kolp.pro/api/kill-switch/status
# → enabled=true, triggered=false, reason=none, peak=$375.68
# 2. Тест KS в demo (НЕ в live!)
curl -u kolpakov:GrinderBot1090 -X POST https://gridbot.kolp.pro/api/kill-switch/test
# → reason="test:..." triggered=true
curl -u kolpakov:GrinderBot1090 -X POST https://gridbot.kolp.pro/api/kill-switch/reset
# → reason="none"
# 3. API ключи валидны?
curl -u kolpakov:GrinderBot1090 https://gridbot.kolp.pro/api/account
# → account_id, balance > 0, currency=USDT
```
### Live dry-run (минимальная позиция)
```bash
# 1. Переключить на live dry-run
sed -i 's/LIVE_TRADING_DRY_RUN=true/LIVE_TRADING_DRY_RUN=false/' /root/grid-bot/.env
# (НЕ ТРОГАТЬ DEMO_MODE — оставить true чтобы не запускать боевую логику)
# 2. Запустить, наблюдать 1 час
kill -9 $(pgrep -f 'python.*main.py')
cd /root/grid-bot && nohup ./venv/bin/python main.py >> bot.log 2>&1 < /dev/null & disown
sleep 3600
# 3. Проверить логи
grep -E 'LIVE_|PLACE|ERROR' /root/grid-bot/bot.log | tail -30
# 4. Откатить если что-то не так
sed -i 's/LIVE_TRADING_DRY_RUN=false/LIVE_TRADING_DRY_RUN=true/' /root/grid-bot/.env
kill -9 $(pgrep -f 'python.*main.py')
```
---
## 🚀 Phased rollout plan (целевой размер $135)
### Phase 0 — Smoke (1 день)
- `DEMO_MODE=true`, `LIVE_TRADING_DRY_RUN=false` (только меняем флаг, не логику)
- Наблюдаем 1 день — бот реально стучится в Tradernet API, ордера не размещает
- Проверяем логи на 403/timeout/retry
### Phase 1 — Micro-live Week 1 (5–7 дней)
- **$40** (≈30% от $135)
- `GRID_LEVELS=3`, `GRID_STEP_PERCENT=0.005`, `GRID_TAKE_PROFIT_PERCENT=2.0`
- `LIVE_KILL_DD_PCT=5.0`, `LIVE_KILL_CLOSE_POSITION=true`
- `KRONOS_LIVE_ENABLED=false` (default, осторожно)
- 24/7 (по решению @KAndrew)
- Авто-pause при 403 (после код-фикса)
- Ежедневный отчёт в TG (PnL, win-rate, max DD, #trades) — `@Kolp` генерит сам
### Phase 2 — Half Week 2 (5–7 дней)
- **$90** (≈67% от $135)
- Если Phase 1: PnL > 0 И DD < 3% И win-rate > 50%
- Иначе: остаёмся на $40 ещё на неделю
### Phase 3 — Full Week 3-4
- **$135** (100%)
- Если Phase 2 стабильно PnL > 0 И DD < 3%
- Включить `KRONOS_LIVE_ENABLED=true` (опционально, после подтверждения Kronos-метрик в demo)
### Steady state
- 100% ($135), 24/7, full automation
- Weekly отчёт в TG (можно выключить если утомит)
> ❌ **Откатить на Phase N-1 (или в demo) если:** DD > 5%, > 3 API errors подряд, любой phantom-order баг, > 5 trades подряд в убыток, TG spam от kill-switch.
---
## ↩️ Rollback plan (если что-то пошло не так)
```bash
# 1. Остановить бота
kill -9 $(pgrep -f 'python.*main.py')
# 2. Откатить .env на demo
sed -i 's/DEMO_MODE=false/DEMO_MODE=true/' /root/grid-bot/.env
sed -i 's/LIVE_TRADING_DRY_RUN=false/LIVE_TRADING_DRY_RUN=true/' /root/grid-bot/.env
# 3. Вручную закрыть все висящие ордера через ЛК cifra.by → «Активные заявки»
# 4. Запустить demo снова
cd /root/grid-bot && nohup ./venv/bin/python main.py >> bot.log 2>&1 < /dev/null & disown
# 5. Сделать snapshot кода
cp -r /root/grid-bot /root/grid-bot.live-fail-$(date +%Y%m%d_%H%M%S)
# 6. Проверить убытки в ЛК cifra.by → История сделок
```
---
## ✅ Решения (ответы @KAndrew, 26.06 23:41 GMT+7)
| # | Вопрос | Решение |
|---|---|---|
| 1 | Размер позиции на live | **$135** (целевой финальный размер) |
| 2 | Одновременно ордеров | **3** (как сейчас в state.json) |
| 3 | Kronos live | **Вариант А — выключить навсегда** (подтверждено @KAndrew). Код оставить как legacy, `STRATEGY_BIAS_SOURCE=trend` |
| 4 | Ночной режим | **24/7** (без QUIET_HOURS) |
| 5 | Если API 403 | **авто-pause** (НЕ kill) — требует код-фикса, см. Code review §6 |
| 6 | TG-отчёты | **(a) каждое сообщение на сделку** (подтверждено @KAndrew) — BUY/SELL/TP-fill → отдельный TG. Требует код-фикса, см. Code review §7 |
> Все defaults можно переопределить — скажи явно.
---
## 📊 Текущие метрики (для сравнения с live)
| Метрика | Demo сейчас | Live минимум |
|---|---|---|
| Total trades | 13 | 30+ (закрытых) |
| Total PnL | $3.06 | > $0 за неделю |
| Peak equity | $375.68 | — |
| Max DD | −4.86% | < 5% |
| Win-rate | 1/1 = 100% (n=1) | > 50% (n≥20) |
| Avg TP-fill time | ~2ч | — |
| Avg step fill | ~30 мин | — |
| Days running | ~14 | 14+ |
| Uptime | ~95% (были рестарты) | > 98% |
---
## 🔗 Связанные файлы
- `/root/grid-bot/.env` — основные настройки
- `/root/grid-bot/config.py` — defaults (все через `os.getenv`)
- `/root/grid-bot/main.py` — trading loop + KS + state.json
- `/root/grid-bot/grid.py` — grid logic, TP, fills
- `/root/grid-bot/api.py` — Tradernet REST client
- `~/.openclaw/workspace/MEMORY.md` — патчи, баги, решения
- `~/.openclaw/workspace/memory/2026-06-*.md` — daily notes
---
**Автор:** Kolp (OpenClaw + M3)
**Версия:** 1.1 (обновлено 2026-06-26 23:41 GMT+7)
**История:**
- v1.0 (23:30) — первая версия, open questions
- v1.1 (23:41) — ответы @KAndrew: $135, 3 ордера, 24/7, 403→pause; TODO: код-фикс auto-pause
- v1.2 (23:42) — TG-отчёты на сделку (Pattern 7); Kronos пока PENDING
- v1.3 (23:45) — Kronos = Вариант А (выключить); TG-формат уточняется
- v1.4 (23:48) — все 6 open questions закрыты. Готовность к go-live = блокер #1 (fees Cifra)
- v1.5 (23:54) — **блокер #1 закрыт**: fees=0.15%, обновлён `.env` (подхватится при рестарте)
**Следующий шаг:** уточнить у @KAndrew maker/taker/round-trip + стартовать код-фиксы (Pattern 6 + Pattern 7)