216 lines
17 KiB
Markdown
216 lines
17 KiB
Markdown
# Crypto Spot TradeBot
|
||
|
||
Spot-бот для демо-торговли криптовалютой на реальных данных Bybit. По умолчанию работает только в `paper`-режиме со стартовым балансом `100 USDT`; live-режим заблокирован до явного включения через env-переменные.
|
||
|
||
## Что реализовано
|
||
|
||
- Реальные market data Bybit Spot: REST bootstrap и WebSocket-обновления.
|
||
- Автовыбор популярных USDT spot-пар по `turnover24h`.
|
||
- Paper trading с учетом cash, комиссий, проскальзывания, stop-loss, take-profit и trailing stop.
|
||
- Spot-only логика: покупка базовой монеты за USDT и продажа обратно, без short и без плеча.
|
||
- Live spot-ордеры явно отправляются без плеча: `category=spot`, `isLeverage=0`.
|
||
- Анализ шаблонов рынка: трендовый откат, пробой вверх/вниз, ускоренное падение, боковик, перепроданность с разворотом и объемный всплеск.
|
||
- Обучение на закрытых сделках: статистика PnL и win rate по символам и шаблонам входа корректирует уверенность новых входов в заданных пределах.
|
||
- LLM Advisor выключен по умолчанию; стратегия, обучение, grid и rebound работают без запросов к Ollama.
|
||
- Динамический размер позиции: стратегия записывает в сигнал размер входа в пределах `MIN_POSITION_USDT`..`MAX_POSITION_USDT`, а брокер ограничивает суммарную экспозицию по паре через `MAX_SYMBOL_EXPOSURE_USDT`.
|
||
- Автоматический grid-режим: бот включает grid-входы на боковике, покупает только в нижней части диапазона и выключает grid при падающих/опасных режимах.
|
||
- Вероятностный rebound-вход: после снижения бот отдельно оценивает стабилизацию, отскок от локального low, RSI, объем и рыночные ограничения; такой вход ограничен меньшим размером позиции.
|
||
- Прогнозирование временных рядов: walk-forward выбор между `naive`, `drift`, `EWMA`, `AR(1)`, `AR(3)` и легким `lstm`-кандидатом для ожидаемой доходности плюс EWMA/GARCH-like прогноз волатильности. Прогноз влияет и на новые покупки, и на раннюю продажу при ухудшении ожидаемого движения.
|
||
- Защитные блокировки входа: явно отрицательные LONG-шаблоны и setups с сильной отрицательной статистикой обучения запрещают новые покупки.
|
||
- Быстрый режим торговли: отдельный короткий интервал цикла, короткий cooldown после выхода и лимит новых входов в минуту; выходы по риску этим лимитом не блокируются.
|
||
- Веб-dashboard на русском: equity, cash, PnL, позиции, сделки, сигналы, события, свечные графики, переключатель быстрой торговли и индикаторы работы обучения.
|
||
- SQLite runtime-хранилище в `runtime/tradebot.sqlite3`.
|
||
- Health endpoint `/api/health` и Prometheus-compatible `/metrics`.
|
||
- Docker Compose для установки на Raspberry Pi 5 или другой Linux-хост.
|
||
- Live trading guard: live не стартует без `ENABLE_LIVE_TRADING=true`, `LIVE_TRADING_CONFIRM=I_ACCEPT_REAL_RISK` и Bybit API-ключей.
|
||
|
||
## Источники и принятые параметры
|
||
|
||
Официальная документация Bybit V5 указывает, что единый V5 API использует параметр `category`, включая `spot`; поэтому бот везде запрашивает `category=spot` и не использует futures/linear endpoints: <https://bybit-exchange.github.io/docs/v5/intro>.
|
||
|
||
Список инструментов Bybit Spot берется из `/v5/market/instruments-info`; документация Bybit описывает для Spot поля `baseCoin`, `quoteCoin`, `status`, `priceFilter`, `lotSizeFilter`, `basePrecision` и `minOrderAmt`, поэтому размеры paper/live-ордеров в коде валидируются по данным инструмента: <https://bybit-exchange.github.io/docs/v5/market/instrument>.
|
||
|
||
Популярность пар определяется через `/v5/market/tickers`, потому что Bybit Spot ticker возвращает `turnover24h`, `volume24h`, `bid1Price`, `ask1Price` и `lastPrice`: <https://bybit-exchange.github.io/docs/v5/market/tickers>.
|
||
|
||
Лучшие bid/ask берутся из `/v5/market/orderbook`; документация Bybit описывает `GET /v5/market/orderbook` с `category=spot`: <https://bybit-exchange.github.io/docs/v5/market/orderbook>.
|
||
|
||
WebSocket-стакан использует topic `orderbook.{depth}.{symbol}`; Bybit документирует snapshot/delta-поведение и частоты push для Spot depth 1/50/200/1000: <https://bybit-exchange.github.io/docs/v5/websocket/public/orderbook>.
|
||
|
||
Live market orders используют `/v5/order/create`; Bybit документирует для Spot `orderType=Market`, `side`, `qty`, `category=spot`, а для market buy по умолчанию qty может быть в quote currency через `marketUnit=quoteCoin`: <https://bybit-exchange.github.io/docs/v5/order/create-order>.
|
||
|
||
Функции уровня коммерческих automated trading systems взяты из проверяемых источников:
|
||
|
||
- Investopedia перечисляет важные свойства algo trading software: real-time market data, low latency, configurability, backtesting, broker/exchange integration, fees/costs и APIs: <https://www.investopedia.com/articles/active-trading/090815/picking-right-algorithmic-trading-software.asp>.
|
||
- Investopedia отдельно указывает, что automated trading systems задают правила entry/exit/money management, но требуют мониторинга и несут риск mechanical failures и over-optimization: <https://www.investopedia.com/articles/trading/11/automated-trading-systems.asp>.
|
||
- QuantInsti описывает типовой путь разработки: стратегия, backtesting, paper trading, затем live trading, плюс GUI, order management и risk management: <https://www.quantinsti.com/articles/automated-trading-system/>.
|
||
- Документация `statsmodels` описывает ARIMA как общий интерфейс для AR/MA/ARMA/ARIMA/SARIMA-моделей; в боте используется легкий AR(1)/AR(3) вариант без добавления тяжелой зависимости `statsmodels`: <https://www.statsmodels.org/stable/generated/statsmodels.tsa.arima.model.ARIMA.html>.
|
||
- Документация `arch` описывает GARCH(p,q) как модель для прогнозирования волатильности; в боте используется фиксированная GARCH(1,1)-подобная рекурсия без MLE-оценки параметров, чтобы сохранить легкий runtime на Raspberry Pi: <https://arch.readthedocs.io/en/stable/univariate/univariate_volatility_forecasting.html>.
|
||
- RiskMetrics описывает EWMA-подход к оценке волатильности через коэффициент затухания; в боте `TIME_SERIES_EWMA_LAMBDA=0.94` используется как настраиваемое значение по умолчанию: <https://www.msci.com/documents/10199/d0905614-2771-46dc-b000-1a033146586a>.
|
||
- Hochreiter и Schmidhuber описали LSTM как recurrent neural network architecture для последовательностей; в боте используется легкая LSTM-reservoir рекурсия с ridge-readout, а не полноценное PyTorch/TensorFlow обучение внутри Docker: <https://direct.mit.edu/neco/article/9/8/1735/6109/Long-Short-Term-Memory>.
|
||
|
||
Я не могу подтвердить, что эта стратегия будет прибыльной. Источники выше описывают технические свойства и риски автоматической торговли, но не гарантируют прибыль.
|
||
|
||
## Быстрый старт локально
|
||
|
||
```powershell
|
||
python -m venv .venv
|
||
.venv\Scripts\Activate.ps1
|
||
pip install -r requirements.txt
|
||
Copy-Item .env.example .env
|
||
python -m crypto_spot_bot.main
|
||
```
|
||
|
||
Dashboard: <http://127.0.0.1:8787/>
|
||
|
||
## Локальное обучение LSTM-кандидата
|
||
|
||
Обучение можно запускать на основной машине, а Raspberry Pi оставлять только для исполнения торгового цикла. Команда ниже берет spot-свечи Bybit, перебирает `lookback`, `units` и `ridge`, оценивает LSTM-кандидат через walk-forward MAE и сохраняет параметры в `runtime/lstm_forecaster.json`:
|
||
|
||
```powershell
|
||
python tools\train_lstm_forecaster.py --symbols BTCUSDT,ETHUSDT,SOLUSDT,XRPUSDT,LTCUSDT --limit 1000
|
||
```
|
||
|
||
Файл из `TIME_SERIES_LSTM_MODEL_PATH` читается ботом автоматически. Даже если LSTM-параметры сохранены, сделка меняется только тогда, когда текущая walk-forward проверка в `crypto_spot_bot/time_series.py` показывает качество лучше baseline.
|
||
|
||
Для более тяжелого локального обучения можно использовать настоящий PyTorch `LSTM/GRU` trainer. PyTorch нужен только на машине обучения; в JSON экспортируются веса, а runtime на Raspberry Pi считает inference обычным Python-кодом:
|
||
|
||
```powershell
|
||
.\.venv\Scripts\python.exe -m pip install torch --index-url https://download.pytorch.org/whl/cpu
|
||
.\.venv\Scripts\python.exe tools\train_torch_recurrent_forecaster.py `
|
||
--symbols BTCUSDT,ETHUSDT,SOLUSDT,XRPUSDT,LTCUSDT `
|
||
--limit 1000 `
|
||
--architectures lstm,gru `
|
||
--lookbacks 32,64 `
|
||
--hidden-sizes 16,32 `
|
||
--layers 1 `
|
||
--epochs 60
|
||
```
|
||
|
||
Экспортированные модели появляются в dashboard как `torch_lstm` или `torch_gru`; легкий `lstm`-кандидат остается доступен как fallback.
|
||
|
||
Автопереобучение запускает тот же train-скрипт, пишет лог в `runtime/lstm_retrain.log` и защищается от параллельных запусков:
|
||
|
||
```powershell
|
||
powershell -ExecutionPolicy Bypass -File tools\run_lstm_retrain.ps1
|
||
powershell -ExecutionPolicy Bypass -File tools\install_windows_lstm_retrainer.ps1
|
||
```
|
||
|
||
На Linux/Raspberry Pi можно включить user systemd timer:
|
||
|
||
```bash
|
||
bash tools/run_lstm_retrain.sh
|
||
bash tools/install_lstm_retrainer_systemd.sh
|
||
```
|
||
|
||
По умолчанию Windows-расписание переобучает PyTorch `LSTM/GRU` каждые 6 часов с `--limit 1000`; Windows-установщик фиксирует пары `BTCUSDT,ETHUSDT,SOLUSDT,XRPUSDT,LTCUSDT`, чтобы первый scheduled run был предсказуемым. Параметры можно переопределить через env: `LSTM_RETRAIN_SYMBOLS`, `LSTM_RETRAIN_LIMIT`, `LSTM_RETRAIN_LOOKBACKS`, `LSTM_RETRAIN_ARCHITECTURES`, `LSTM_RETRAIN_HIDDEN_SIZES`, `LSTM_RETRAIN_LAYERS`, `LSTM_RETRAIN_DROPOUTS`, `LSTM_RETRAIN_EPOCHS`, `LSTM_RETRAIN_PATIENCE`, `LSTM_RETRAIN_INTERVAL`, `LSTM_RETRAIN_ENV`. Для старого легкого trainer можно запустить `tools\run_lstm_retrain.ps1 -Trainer reservoir`.
|
||
|
||
## Docker
|
||
|
||
```bash
|
||
cp .env.example .env
|
||
docker compose up -d --build
|
||
docker compose logs -f tradebot
|
||
```
|
||
|
||
Dashboard: `http://<host>:8787/`
|
||
|
||
Для Raspberry Pi 5 проект использует `python:3.12-slim`, без Node.js build step. Runtime-данные лежат в volume `./runtime:/app/runtime`; на внешнем диске можно разместить папку проекта или заменить volume на абсолютный путь внешнего диска.
|
||
|
||
## Основные env-параметры
|
||
|
||
```env
|
||
TRADING_MODE=paper
|
||
STARTING_BALANCE_USDT=100
|
||
AUTO_SELECT_SYMBOLS=true
|
||
TOP_SYMBOLS_COUNT=6
|
||
BASE_INTERVAL=1
|
||
LOOP_INTERVAL_SECONDS=5
|
||
FAST_TRADING_ENABLED=false
|
||
FAST_LOOP_INTERVAL_SECONDS=1
|
||
FAST_ENTRY_COOLDOWN_SECONDS=20
|
||
MAX_ENTRIES_PER_MINUTE=12
|
||
WEBSOCKET_ENABLED=true
|
||
MIN_SIGNAL_CONFIDENCE=0.64
|
||
PATTERN_ANALYSIS_ENABLED=true
|
||
PATTERN_SCORE_WEIGHT=0.18
|
||
LEARNING_ENABLED=true
|
||
LEARNING_LOOKBACK_TRADES=120
|
||
LEARNING_MIN_SAMPLES=3
|
||
LEARNING_MAX_ADJUSTMENT=0.12
|
||
MIN_POSITION_USDT=1
|
||
MAX_POSITION_USDT=20
|
||
MAX_SYMBOL_EXPOSURE_USDT=20
|
||
MAX_TOTAL_EXPOSURE_USDT=80
|
||
MAX_OPEN_POSITIONS=80
|
||
MAX_POSITIONS_PER_SYMBOL=20
|
||
GRID_TRADING_ENABLED=true
|
||
GRID_ENTRY_CONFIDENCE=0.58
|
||
GRID_BUY_ZONE=0.45
|
||
GRID_MAX_POSITION_USDT=8
|
||
REBOUND_TRADING_ENABLED=true
|
||
REBOUND_ENTRY_CONFIDENCE=0.58
|
||
REBOUND_MIN_PROBABILITY=0.58
|
||
REBOUND_MAX_POSITION_USDT=6
|
||
TIME_SERIES_FORECAST_ENABLED=true
|
||
TIME_SERIES_MIN_CANDLES=120
|
||
TIME_SERIES_VALIDATION_WINDOW=30
|
||
TIME_SERIES_FORECAST_HORIZON=3
|
||
TIME_SERIES_EWMA_LAMBDA=0.94
|
||
TIME_SERIES_MIN_EDGE_PERCENT=0.04
|
||
TIME_SERIES_MAX_ADJUSTMENT=0.08
|
||
TIME_SERIES_LSTM_ENABLED=true
|
||
TIME_SERIES_LSTM_LOOKBACK=32
|
||
TIME_SERIES_LSTM_UNITS=6
|
||
TIME_SERIES_LSTM_RIDGE=0.0001
|
||
TIME_SERIES_LSTM_MODEL_PATH=runtime/lstm_forecaster.json
|
||
STOP_LOSS_PERCENT=0.02
|
||
TAKE_PROFIT_PERCENT=0.035
|
||
TRAILING_STOP_PERCENT=0.015
|
||
MIN_HOLD_SECONDS=180
|
||
ENTRY_COOLDOWN_SECONDS=180
|
||
MAX_DAILY_DRAWDOWN_USDT=6
|
||
TAKER_FEE_RATE=0.001
|
||
SLIPPAGE_RATE=0.0003
|
||
```
|
||
|
||
## Быстрая торговля
|
||
|
||
Быстрый режим включается через web-переключатель или через `FAST_TRADING_ENABLED=true`. Тогда фактический цикл принятия решений берется из `FAST_LOOP_INTERVAL_SECONDS`, а cooldown после закрытия позиции — из `FAST_ENTRY_COOLDOWN_SECONDS`. Параметр `MAX_ENTRIES_PER_MINUTE` ограничивает только новые покупки; продажи по stop-loss, take-profit, trailing stop и другим правилам выхода не блокируются этим лимитом.
|
||
|
||
Для быстрого режима рекомендуется оставлять `WEBSOCKET_ENABLED=true`: WebSocket дает частые рыночные обновления, а REST используется как периодическая сверка. Я не могу подтвердить, что быстрый режим повысит прибыльность; он только уменьшает техническую задержку реакции стратегии.
|
||
|
||
## Live-режим
|
||
|
||
Live-режим специально заблокирован. Для включения нужны все значения:
|
||
|
||
```env
|
||
TRADING_MODE=live
|
||
ENABLE_LIVE_TRADING=true
|
||
LIVE_TRADING_CONFIRM=I_ACCEPT_REAL_RISK
|
||
BYBIT_API_KEY=...
|
||
BYBIT_API_SECRET=...
|
||
LIVE_ORDER_MAX_USDT=10
|
||
```
|
||
|
||
Текущее live-исполнение отправляет market buy/sell в Bybit и ведет локальную shadow-позицию для dashboard и правил выхода. Для промышленной торговли реальными средствами следующий обязательный шаг — reconciliation с реальным wallet/order history Bybit, чтобы локальное состояние сверялось с фактическими fills и балансами.
|
||
|
||
## API
|
||
|
||
- `GET /api/health` — healthcheck.
|
||
- `GET /api/status` — статус бота, account snapshot, позиции.
|
||
- `GET /api/markets` — пары, ticker, свечи, инструменты.
|
||
- `GET /api/trades` — последние сделки.
|
||
- `GET /api/signals` — последние сигналы стратегии.
|
||
- `GET /api/events` — события.
|
||
- `GET /api/config` — безопасная конфигурация без секретов.
|
||
- `POST /api/config/fast-trading` — включение/выключение быстрой торговли из dashboard.
|
||
- `POST /api/control/start` — старт цикла.
|
||
- `POST /api/control/stop` — остановка цикла.
|
||
- `GET /metrics` — Prometheus-compatible метрики.
|
||
|
||
## Проверка
|
||
|
||
```bash
|
||
python -m pytest
|
||
```
|