All checks were successful
deploy / deploy (push) Successful in 7s
Live HL data → in-browser TA → 4-agent committee → LONG/SHORT/SKIP verdict. Terminal grid command bar + interactive agent-workflow graph. Paper-trading worker reuses the browser brain (dry-run + Telegram). Forgejo static deploy. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
72 lines
3.1 KiB
Markdown
72 lines
3.1 KiB
Markdown
# Paper-trading worker
|
|
|
|
The always-on runtime that makes the swarm **real** — without real-money risk.
|
|
|
|
It reuses the exact browser brain (`src/lib/hyperliquid.ts` · `ta.ts` · `signals.ts`,
|
|
pure functions, no DOM) on a server loop, paper-trades the verdict against **live
|
|
Hyperliquid prices**, and broadcasts every fill to **Telegram**. This turns the site's
|
|
biggest fiction — the performance track record — into an honest, verifiable record.
|
|
|
|
```
|
|
real candles → real TA → 4 agents vote → verdict → paper open/close → Telegram + JSON
|
|
(L1) (L2) (L3) (L4) (L5 paper) (L6)
|
|
```
|
|
|
|
## Run
|
|
|
|
```bash
|
|
pnpm worker # run forever, polling every QUANT_POLL_MS (default 60s)
|
|
pnpm worker:once # single tick then exit (smoke test)
|
|
```
|
|
|
|
No setup required — with no Telegram configured it runs head-less and prints every
|
|
signal/fill to stdout. Add a bot to broadcast (see below).
|
|
|
|
## Telegram (optional)
|
|
|
|
1. Create a bot with [@BotFather](https://t.me/BotFather) → copy the token.
|
|
2. Message the bot once, then get your chat id from [@userinfobot](https://t.me/userinfobot).
|
|
3. Put both in `.env.local`:
|
|
```
|
|
TELEGRAM_BOT_TOKEN=123456:ABC-...
|
|
TELEGRAM_CHAT_ID=123456789
|
|
```
|
|
4. `pnpm worker`. The bot posts on open/close and answers commands:
|
|
`/status` · `/positions` · `/pnl` (a.k.a. `/learn`) · `/help`.
|
|
|
|
## What's real vs. paper
|
|
|
|
- **Real:** market data, candles, every indicator, the agent votes, the verdict, the
|
|
entry/exit *prices*, and therefore the PnL.
|
|
- **Paper:** no order is ever signed or sent. `mode` is fixed to `dry-run`. Positions are
|
|
marked to market against the live price; TP/SL are assumed filled at the level. This is
|
|
the deliberate 80/20 line — all the credibility, none of the key-management / loss risk.
|
|
|
|
## Config (env, all optional)
|
|
|
|
| var | default | meaning |
|
|
|---|---|---|
|
|
| `QUANT_COINS` | `BTC,ETH,SOL` | universe |
|
|
| `QUANT_INTERVAL` | `1h` | candle timeframe |
|
|
| `QUANT_POLL_MS` | `60000` | tick cadence |
|
|
| `QUANT_EQUITY_START` | `10000` | starting paper bankroll (USD) |
|
|
| `QUANT_LEVERAGE` | `5` | applied to `sizePct` → notional |
|
|
| `QUANT_CONF_FLOOR` | `0.55` | min verdict confidence to open |
|
|
| `QUANT_MAX_OPEN_PER_COIN` | `1` | concurrent positions per coin |
|
|
| `QUANT_DATA_FILE` | `worker/data/state.json` | persisted state |
|
|
|
|
## State
|
|
|
|
A single JSON file (`worker/data/`, gitignored) written atomically each tick:
|
|
`equity`, open `positions`, `closed` trades, `signals` log, and an `equityCurve`. It is
|
|
exactly the shape a future `/api/equity` · `/api/signals` endpoint would serve so the
|
|
site's Performance section and "recent fills" can read the real record instead of the
|
|
seeded one.
|
|
|
|
## Next 20% (deliberately skipped)
|
|
|
|
- **Live execution:** sign + send real Hyperliquid orders. Needs an account, key
|
|
management, and accepts real loss — keep behind a flag, `dry-run` stays default.
|
|
- **`/api/*` + frontend wiring:** serve this state and point `Performance` / fills at it.
|
|
- **Claude in the loop:** LLM-written reasoning per verdict and a real LLM `/learn`
|
|
retrospective (off the risk path).
|