Risk controls, alerts, API token, more exchanges, presets
- RiskManager halts + flattens on max daily loss / drawdown, caps position size and trades per day; adds a manual kill switch (POST /api/bot/kill). - Telegram and webhook notifications on trades, errors and halts. - Optional API bearer token on /api, injected server-side by the frontend nginx so the browser never sees it. - Kraken and Coinbase market data (public); Coinbase live broker. Live on an unsupported exchange now errors instead of silently falling back to paper. - Strategy presets backed by the StrategyConfig table (CRUD API + UI). - Idempotent additive-column migration so existing SQLite databases upgrade in place (fixes the new strategy_configs.name column).
This commit is contained in:
1 parent
9c3bee87ac
commit
03dfa369e5
35 files changed
+1409
-45
No files matched your search
@@ -84,6 +84,10 @@ Repo/org variables and secrets used by the deploy:
|
||||
| `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_MAX_DAILY_LOSS` / `CRYPTO_MAX_DRAWDOWN_PCT` / `CRYPTO_MAX_POSITION_PCT` / `CRYPTO_MAX_TRADES_PER_DAY` | var | Risk limits |
|
||||
| `CRYPTO_TELEGRAM_BOT_TOKEN` | secret | Telegram alerts |
|
||||
| `CRYPTO_TELEGRAM_CHAT_ID` | var/secret | Telegram chat id |
|
||||
| `CRYPTO_NOTIFY_WEBHOOK_URL` | secret | Generic webhook alerts |
|
||||
| `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 |
|
||||
@@ -104,6 +108,52 @@ All settings are environment variables (see `.env.example`):
|
||||
| `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 |
|
||||
| `MAX_DAILY_LOSS` | `0` | Halt+flatten after this daily loss (quote ccy); 0 disables |
|
||||
| `MAX_DRAWDOWN_PCT` | `0` | Halt+flatten after this % drop from peak; 0 disables |
|
||||
| `MAX_POSITION_PCT` | `1.0` | Cap a single position at this fraction of equity |
|
||||
| `MAX_TRADES_PER_DAY` | `0` | Max new entries per UTC day; 0 disables |
|
||||
| `TELEGRAM_BOT_TOKEN` / `TELEGRAM_CHAT_ID` | — | Telegram alerts (both required) |
|
||||
| `NOTIFY_WEBHOOK_URL` | — | Generic webhook alerts |
|
||||
| `API_TOKEN` / `API_TOKEN_HEADER` | — | Bearer token required on `/api` when set |
|
||||
|
||||
## Exchanges
|
||||
|
||||
Market data works out of the box on **Binance**, **Kraken** and **Coinbase**
|
||||
(public REST, no API key). Set `EXCHANGE` to `binance`, `kraken` or `coinbase`.
|
||||
|
||||
Live execution (`MODE=live`) is implemented for **Binance** (spot, optional
|
||||
testnet via `EXCHANGE_SANDBOX`) and **Coinbase** (Advanced Trade; set
|
||||
`EXCHANGE_API_SECRET` to the CDP EC private key in PEM). Kraken is
|
||||
market-data-only for now — `MODE=live` on Kraken raises a clear error.
|
||||
|
||||
## API token (defense-in-depth)
|
||||
|
||||
Set `API_TOKEN` to require a bearer token on all `/api` routes (health stays
|
||||
open). The frontend nginx injects it server-side, so the browser never sees it
|
||||
and the dashboard keeps working unchanged. This sits *behind* the Traefik Basic
|
||||
auth, not instead of it.
|
||||
|
||||
## Risk controls
|
||||
|
||||
The engine enforces limits on every tick and **halts + flattens** when one trips:
|
||||
|
||||
- **`MAX_DAILY_LOSS`** — absolute loss since the start of the UTC day.
|
||||
- **`MAX_DRAWDOWN_PCT`** — percentage fall from peak equity.
|
||||
- **`MAX_POSITION_PCT`** — position size cap as a fraction of equity.
|
||||
- **`MAX_TRADES_PER_DAY`** — new-entry budget per UTC day.
|
||||
|
||||
A halt is sticky: the position is closed, the bot stops, a red banner appears in
|
||||
the dashboard, and a notification is sent. Restarting the bot resets the limits.
|
||||
The dashboard also has a manual **Kill switch** button (`POST /api/bot/kill`)
|
||||
that flattens and halts immediately.
|
||||
|
||||
## Notifications
|
||||
|
||||
Set `TELEGRAM_BOT_TOKEN` + `TELEGRAM_CHAT_ID` and/or `NOTIFY_WEBHOOK_URL` to
|
||||
receive alerts on trades, stop-outs, errors and halts. Notifications are
|
||||
best-effort: a failing channel never affects trading. For Telegram, create a bot
|
||||
with [@BotFather](https://t.me/BotFather), message it once, then read the chat id
|
||||
from `https://api.telegram.org/bot<token>/getUpdates`.
|
||||
|
||||
## Adding a strategy
|
||||
|
||||
@@ -120,6 +170,7 @@ template and the `StrategyContext` API. Two examples ship in the repo:
|
||||
| `GET` | `/api/strategies` | Available strategies + parameter specs |
|
||||
| `POST` | `/api/bot/start` | Start a strategy |
|
||||
| `POST` | `/api/bot/stop` | Stop the bot |
|
||||
| `POST` | `/api/bot/kill` | Kill switch: flatten + halt |
|
||||
| `POST` | `/api/backtest` | Backtest a strategy on historical candles |
|
||||
| `GET` | `/api/positions` | Positions (with unrealized P&L when open) |
|
||||
| `GET` | `/api/orders` | Order history |
|
||||
@@ -127,6 +178,8 @@ template and the `StrategyContext` API. Two examples ship in the repo:
|
||||
| `GET` | `/api/equity` | Equity curve points |
|
||||
| `POST` | `/api/orders` | Manual market order |
|
||||
| `POST` | `/api/positions/{id}/close` | Close the open position |
|
||||
| `GET`/`POST` | `/api/presets` | List / save strategy presets |
|
||||
| `DELETE` | `/api/presets/{id}` | Delete a preset |
|
||||
| `WS` | `/api/ws` | Live status + event stream |
|
||||
|
||||
## Tests & lint
|
||||
|
||||
Reference in new issue
Block a user