Crypto trading bot: engine, brokers, backtester, dashboard, deploy
CI/CD / backend (push) Successful in 5m18s
CI/CD / frontend (push) Successful in 5m2s
CI/CD / build (push) Successful in 34s
CI/CD / cleanup (push) Successful in 6s
CI/CD / deploy (push) Successful in 22s

FastAPI backend with a single-strategy async engine, paper and Binance
brokers, pure-python indicators, a backtester that shares the engine's
portfolio math, and a Vue dashboard with a live WebSocket feed. Adds the
Gitea Actions CI/CD workflow that deploys to Traefik via docker_default.
This commit is contained in:
matitos committed 2026-09-18 17:02:33 +00:00
1 parent 98028248c2
commit 9c3bee87ac
73 files changed
+9759 -1

No files matched your search

+153 -1
View File
@@ -1,2 +1,154 @@
# crypto_trading
# Crypto Trader
A small, hackable crypto trading bot with a web dashboard. Describe a strategy,
drop in one Python file, run it, and watch positions and P&L live.
- **Backend:** FastAPI, SQLAlchemy, SQLite (Postgres optional), pure-Python
indicators, `httpx` for market data.
- **Frontend:** Vue 3 + Vite + Tailwind dashboard with a live WebSocket feed.
- **Brokers:** `paper` (simulated fills, default) and `binance` (live spot).
- **Market data:** Binance public REST (no API key needed).
- **Backtesting:** replay historical candles through the same strategy interface,
with return/drawdown/win-rate/Sharpe metrics — so what you test is what runs.
> **Paper trading is the default.** Live mode places real orders and is opt-in.
> This is experimental software. Never trade more than you can afford to lose.
## How it works
```
Binance REST ──▶ MarketData ──▶ TradingEngine ──▶ Broker (paper | binance)
│
Strategy.on_candle(ctx)
│
REST /api + WebSocket /api/ws ──▶ Vue dashboard
```
The engine runs one strategy at a time. Each tick it fetches candles, updates
the mark price, enforces stop-loss/take-profit, calls the strategy, executes the
resulting intents, and persists orders, equity snapshots and events.
## Quickstart (local)
```bash
# 1. Config
cp .env.example .env
# 2. Backend
python3 -m venv .venv
.venv/bin/pip install -r backend/requirements-dev.txt
cd backend && ../.venv/bin/python -m uvicorn app.main:app --reload --port 8000
# 3. Frontend (new terminal)
cd frontend && npm install && npm run dev
```
Open http://localhost:5173. API docs are at http://localhost:8000/docs.
## Quickstart (Docker, local)
```bash
cp .env.example .env
docker compose -f docker-compose.local.yml up --build
# dashboard: http://localhost:8080 API docs: http://localhost:8000/docs
```
The default `docker-compose.yml` is the **deployment** stack (Traefik +
`docker_default`); use `docker-compose.local.yml` for a self-contained local run.
## Deployment
Merging to `main` triggers `.gitea/workflows/deploy.yml`, which tests, builds
both images, and rolls the stack out on the shared Traefik host:
- The **frontend** joins the external `docker_default` network and is published
at `crypto.${BASE_DOMAIN}` (default `crypto.matitos.org`) via Traefik, with a
Let's Encrypt cert (`certresolver=myresolvercd`).
- The **backend** stays on the internal network only; the frontend nginx proxies
`/api` (including the `/api/ws` WebSocket) to it, so API keys are never
directly exposed.
- The WebUI is protected by **fail-closed Basic auth**: the deploy aborts unless
`CRYPTO_FRONTEND_AUTH_USERS` is set (falling back to the shared
`SCA_FRONTEND_AUTH_USERS`). Generate a value with
`htpasswd -nbB user 'password'`.
- A new release is rolled back automatically if healthchecks fail.
Repo/org variables and secrets used by the deploy:
| Name | Kind | Purpose |
| --- | --- | --- |
| `CRYPTO_FRONTEND_AUTH_USERS` | var/secret | htpasswd string for the WebUI (required) |
| `BASE_DOMAIN` | secret | Base domain (default `matitos.org`) |
| `CRYPTO_MODE` | var | `paper` (default) or `live` |
| `CRYPTO_EXCHANGE` / `CRYPTO_SYMBOL` / `CRYPTO_TIMEFRAME` | var | Trading defaults |
| `CRYPTO_STARTING_BALANCE` / `CRYPTO_POLL_INTERVAL` | var | Paper account + tick rate |
| `CRYPTO_EXCHANGE_API_KEY` / `CRYPTO_EXCHANGE_API_SECRET` | secret | Required only for `live` |
| `CRYPTO_EXCHANGE_SANDBOX` | var | Use the Binance testnet |
| `CRYPTO_CORS_ORIGINS` | var | Defaults to `https://crypto.<BASE_DOMAIN>` |
| `CRYPTO_DATA_DIR` / `PERSISTENT_MOUNT` | var | Host path for the SQLite DB |
| `DOCKERHUB_USERNAME` / `DOCKERHUB_TOKEN` | secret | Optional; for authenticated pulls |
## Configuration
All settings are environment variables (see `.env.example`):
| Variable | Default | Purpose |
| --- | --- | --- |
| `MODE` | `paper` | `paper` or `live` |
| `EXCHANGE` | `binance` | Market data / execution venue |
| `SYMBOL` | `BTC/USDT` | Default trading pair |
| `TIMEFRAME` | `1m` | Candle interval |
| `POLL_INTERVAL` | `5` | Seconds between ticks |
| `STARTING_BALANCE` | `10000` | Paper account size |
| `FEE_BPS` / `SLIPPAGE_BPS` | `10` / `5` | Paper fill model |
| `DATABASE_URL` | `sqlite:///./data/trader.db` | Postgres: `postgresql+psycopg://...` |
| `EXCHANGE_API_KEY` / `EXCHANGE_API_SECRET` | — | Required only for live |
| `EXCHANGE_SANDBOX` | `false` | Use Binance testnet |
## Adding a strategy
Drop a file in `backend/app/engine/strategies/` — it is auto-discovered and
appears in the UI immediately. See **[AGENTS.md](AGENTS.md)** for the full
template and the `StrategyContext` API. Two examples ship in the repo:
`sma_cross` and `rsi_reversion`.
## API
| Method | Path | Description |
| --- | --- | --- |
| `GET` | `/api/status` | Bot status, equity, P&L |
| `GET` | `/api/strategies` | Available strategies + parameter specs |
| `POST` | `/api/bot/start` | Start a strategy |
| `POST` | `/api/bot/stop` | Stop the bot |
| `POST` | `/api/backtest` | Backtest a strategy on historical candles |
| `GET` | `/api/positions` | Positions (with unrealized P&L when open) |
| `GET` | `/api/orders` | Order history |
| `GET` | `/api/events` | Activity log |
| `GET` | `/api/equity` | Equity curve points |
| `POST` | `/api/orders` | Manual market order |
| `POST` | `/api/positions/{id}/close` | Close the open position |
| `WS` | `/api/ws` | Live status + event stream |
## Tests & lint
```bash
make test # backend pytest + frontend vitest
make lint # ruff
make build # frontend production build
```
## Project layout
```
backend/
app/
engine/ trading loop, indicators, strategies/
broker/ paper + binance execution
market/ binance + fake data feeds
api/routes.py REST + WebSocket
models.py positions, orders, equity, events
store.py persistence
tests/
frontend/
src/ Vue dashboard
```