Initial import: grid-bot — grid trading bot for BTC-USDT on Cifra Markets

This commit is contained in:
Kolp
2026-09-24 13:22:23 +07:00
commit 642cc11a9f
18968 changed files with 5683248 additions and 0 deletions
+261
View File
@@ -0,0 +1,261 @@
# LIVE TRADING CHECKLIST — grid-bot BTC-USDT.IMEX
**Дата создания:** 2026-06-26
**Бот:** grid-bot v0.13.x (PID 1552921, mode=demo, peak=$375.68)
**Цель:** выход на реальную торговлю через Cifra Markets (BY) / Tradernet
> ⚠️ **Текущий статус: НЕ ГОТОВ.** Ниже — что должно быть сделано перед переключением `LIVE_TRADING_DRY_RUN=false`.
---
## 🚦 Блокеры (без них live = деньги на ветер)
### 1. Подтвердить fees Cifra Markets
- [ ] Зайти в ЛК **cifra.by** → раздел «Тарифы» / «Комиссии»
- [ ] Записать **точные %** для BTC-USDT: maker / taker, market / limit
- [ ] Если fee > 0.25% per side → обновить `FEE_RATE_PERCENT` и пересмотреть `GRID_STEP_PERCENT`
- [ ] Учесть спред bid/ask (сейчас по quote: 0.09% — мелкий, проверить на реальных сделках)
### 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 у нас меньше)
---
## 🧪 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
### Week 1 (после всех блокеров выше)
- Live с **$50–100** (5% от целевого капитала)
- Только дневная сессия (07:00–22:00 GMT+7)
- `GRID_LEVELS=3`, `step=0.5%`, `TP=2%`
- Ежедневный отчёт в TG: PnL, win-rate, max DD, #trades
### Week 2
- Если Week 1 PnL > 0 И DD < 3% → увеличить до **$200–300**
- То же самое
### Week 3-4
- Если непрерывный PnL > 0 → довести до **50% целевого капитала**
- Включить Kronos live (`KRONOS_LIVE_ENABLED=true`)
### Steady state
- 100% целевого капитала
- Ночной режим (без изменений — бот работает 24/7)
> ❌ **Откатить на demo если:** DD > 5%, > 3 API errors подряд, любой phantom-order баг, 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 → История сделок
```
---
## ❓ Open questions (нужны ответы перед go-live)
1. **Какой размер позиции на live?** $100 / $500 / $1000 / другая сумма?
2. **Сколько ордеров одновременно на live?** Оставить 3 (как сейчас) или 10 (дефолт)?
3. **Kronos live: да/нет/позже?** Сейчас `KRONOS_LIVE_ENABLED=false` — оставляем?
4. **Что делать ночью?** Бот работает 24/7, или добавить `QUIET_HOURS=23:00–07:00`?
5. **Что если Tradernet API начнёт возвращать 403?** Авто-pause или auto-kill?
6. **Частота отчётов в TG?** Раз в час / раз в сделку / только при алертах?
---
## 📊 Текущие метрики (для сравнения с 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)
**Следующий review:** когда Андрей даст ответы на Open questions