10 KiB
Trade Autopilot
Торговый бот-автопилот для криптобиржи CoinEx с веб-панелью администратора. Сервис в непрерывном цикле опрашивает рынки, считает технические индикаторы, формирует торговые решения и исполняет их на виртуальном демо-счёте, ведя учёт позиций, реализованного и нереализованного PnL. Предназначен для одного владельца-администратора, разворачивается на своём сервере через Docker Compose.
Режимов два: demo (виртуальный баланс, симулированные ордера — работает полностью) и live (реальный счёт CoinEx). Live-режим доведён до уровня «сигналы и защитные проверки работают, реальное выставление ордеров не реализовано» — подробности в разделе «Что не доделано».
Исходный README автора сохранён в README.upstream.md.
Стек
- Python 3.12, FastAPI, Uvicorn, Pydantic Settings
- SQLAlchemy 2.0 + PostgreSQL 16 (psycopg 3), Redis 7 (объявлен в compose и настройках, в коде приложения не используется)
- httpx, websockets — HTTP и WebSocket-клиенты CoinEx; ccxt — добавлен для live-адаптера
- Frontend — один статический файл
app/static/index.htmlбез сборки и фреймворков - Docker, Docker Compose
- Внешний API: CoinEx v2 — публичный HTTP (
https://api.coinex.com/v2) и spot WebSocket (wss://socket.coinex.com/v2/spot)
Структура
| Путь | Назначение |
|---|---|
app/main.py |
FastAPI-приложение, ~40 эндпоинтов /api/v1/*, WebSocket /ws/market/{market}, отдача дашборда |
app/core.py |
Настройки через pydantic-settings, свойства live_enabled, markets |
app/db.py |
Сессии SQLAlchemy, init_db() и «безопасные патчи схемы» — самописные ALTER-миграции вместо Alembic |
app/models.py |
15 таблиц: демо-счёт, сделки, позиции, состояние бота, решения ИИ, новостные сигналы, логи, правила рынков, история графика, стратегии воркера, настройки CoinEx/Telegram, статус системы |
app/coinex.py |
HTTP-клиент CoinEx (kline, ticker, market info) и live WebSocket-стрим с HTTP-fallback |
app/ai_bot.py |
Основная логика бота: индикаторы, скоринг сигналов, ротация рынков, риск-чек, торговые решения |
app/monitor.py |
Фоновый асинхронный цикл: раз в 10 с обходит рынки, применяет решения, пишет человекочитаемый лог |
app/demo_account.py |
Демо-счёт: баланс, позиции, полное закрытие по рынку, расчёт realized/unrealized PnL |
app/legacy_bot.py |
Слой «legacy trading bot»: дашборд-KPI, открытые/закрытые сделки, стратегии, история графика |
app/market_rules.py |
Синхронизация торговых правил CoinEx: мин. объём, точность цены/количества, комиссии |
app/live_execution.py |
LiveExecutionGuard — проверки готовности к live-торговле перед отправкой ордера |
app/auth.py |
HTTP Basic-авторизация, применена ко всем эндпоинтам |
app/static/index.html |
Админ-панель: график свечей, KPI, позиции, лимиты, переключатель Demo/Live, логи бота |
scripts/fix_monitor_start.py |
Разовый патч для устранения гонки при быстром stop/start монитора на сервере |
Dockerfile, docker-compose.yml |
Образ API и сервисы api + postgres + redis |
project.sw |
Рабочие заметки автора: статус реализации, договорённости по UI, следующие шаги |
Как запустить
cp .env.example .env
# отредактировать .env: ADMIN_PASSWORD обязательно, ключи CoinEx — при необходимости
docker compose up -d --build
Проверка:
curl http://localhost:8000/health
curl -u admin:<пароль> http://localhost:8000/api/v1/demo/account
curl -u admin:<пароль> "http://localhost:8000/api/v1/market/kline?market=BTCUSDT&period=1min&limit=100"
Панель: http://localhost:8000/ (HTTP Basic).
Отдельные миграции запускать не нужно: при старте init_db() создаёт таблицы и применяет добавление недостающих колонок. Alembic не используется.
Обновление на сервере:
cd /opt/trade
git pull
docker compose down
docker compose up -d --build
Монитор автоторговли стартует автоматически при запуске приложения; управление — POST /api/v1/monitor/start и /stop.
Конфигурация
Все переменные — из .env (образец в .env.example), значения по умолчанию — в app/core.py.
| Переменная | Назначение | Пример |
|---|---|---|
APP_NAME |
Имя приложения в заголовке FastAPI | Trade Autopilot |
APP_ENV |
Метка окружения | local |
TRADE_MODE |
Режим торговли | demo / live |
ENABLE_LIVE_TRADING |
Второй флаг-предохранитель live-режима; live включается только при TRADE_MODE=live И true |
false |
DEMO_INITIAL_BALANCE |
Стартовый виртуальный баланс | 10000 |
DEMO_QUOTE_ASSET |
Котируемый актив демо-счёта | USDT |
COINEX_API_BASE |
База HTTP API CoinEx | https://api.coinex.com/v2 |
COINEX_WS_SPOT |
WebSocket spot CoinEx | wss://socket.coinex.com/v2/spot |
DEFAULT_MARKET |
Рынок по умолчанию для графика и запросов | BTCUSDT |
MARKET_UNIVERSE |
Стартовый список рынков; после синхронизации правил заменяется всеми активными USDT-рынками | BTCUSDT,ETHUSDT,SOLUSDT,... |
DATABASE_URL |
Строка подключения к БД; без Docker по умолчанию SQLite | postgresql+psycopg://trade:trade@postgres:5432/trade |
REDIS_URL |
Redis (сервис поднимается, приложением не используется) | redis://redis:6379/0 |
COINEX_ACCESS_ID |
Access ID CoinEx для подписанных запросов | см. .env |
COINEX_SECRET_KEY |
Secret Key CoinEx | см. .env |
AUTH_ENABLED |
Включить HTTP Basic | true |
ADMIN_USERNAME |
Логин админа | admin |
ADMIN_PASSWORD |
Пароль админа; в .env.example стоит admin — обязательно заменить |
см. .env |
Пароли PostgreSQL в docker-compose.yml захардкожены как trade:trade, порты 5432 и 6379 публикуются наружу — для сервера в интернете это нужно исправить.
Состояние
Прототип, доведённый до рабочего состояния в демо-режиме. 87 коммитов, все датированы одним днём — 2026-05-08, последний коммит того же числа. Проект написан за один заход и с тех пор не развивался.
Demo-контур функционален: сбор рыночных данных, индикаторы, автоматические сделки, учёт позиций и PnL, живой график, авторизация, панель. Live-контур не завершён.
Что не доделано
- Реальное исполнение ордеров на live-счёте отсутствует.
LiveExecutionGuard.execute_guarded_live_order()проходит все проверки и возвращаетmode='live_adapter_pending',executed=False— низкоуровневый адаптер подписанных запросов CoinEx (GET /assets/spot/balance,POST /spot/order) не написан. Библиотекаccxtдобавлена в зависимости, но не подключена. GET /api/v1/live/account— заглушка: реальный баланс live-счёта не отдаётся.- Redis объявлен в настройках и compose, но в коде не используется.
- Сборщик новостей (RSS) не реализован — новостные сигналы вводятся только вручную через
POST /api/v1/signals/manual, хотя «анализ открытых новостей» заявлен как цель проекта. - Настройки Telegram-уведомлений есть в модели
TelegramSettingsи в UI, отправки уведомлений в коде нет. - Тестов нет; CI нет; линтеров нет.
- Миграции — самописные ALTER-патчи в
app/db.py; Alembic не подключён, откат схемы невозможен. app/main.pyиспользует устаревший@app.on_event('startup').- Гонка при stop/start монитора чинится внешним скриптом
scripts/fix_monitor_start.py, а не исправлена в коде. - Незавершённые пункты из
project.sw: вывод статуса синхронизации правил рынков в UI, маркеры сигналов и кривая эквити, тесты и CI.