← Playbook · machine-readable: guide.md · openapi.json
Base URL: https://playbook.db3hk.com Playbook: HSI Reclaim Debit v1.6 · Ledger schema: 1.6 · All times HKT (Asia/Hong_Kong)
This service stores trading state (the ledger) and issues v1.6 work orders. It does not place orders, fetch market data, or compute indicators. Human transmits on IB.
Every endpoint requires a static bearer token:
Authorization: Bearer <TOKEN>401 {"ok": false, "error": "unauthorized"}{schema_version, account_hkd, updated_at, cool_off_until, cool_off_reason, open_position, last_closed, history[]}open_position is null. Max 1 open position.stop, or a scratch with pnl_pct <= -15, no new entries until the next HKT day-session date.can_new_entry = in day session AND no open position AND (cool_off_until is null OR < today).GET /ledger/status — call this FIRST before any GOcurl -s -H "Authorization: Bearer $TOKEN" https://playbook.db3hk.com/ledger/status{
"can_new_entry": false,
"reason": "outside_day_session",
"cool_off_until": null,
"has_open": false,
"in_day_session": false,
"now_hkt": "2026-09-07T16:00:18+08:00"
}reason values: ok, position_open, cool_off, outside_day_session.
Reason priority (highest first): position_open → cool_off → outside_day_session → ok. So with an open position after hours, reason is position_open (not outside_day_session); during cool-off after hours it is cool_off. in_day_session and has_open are always reported separately — use them, not reason, if you need the raw facts.
GET /ledger — full ledger JSONcurl -s -H "Authorization: Bearer $TOKEN" https://playbook.db3hk.com/ledgerPUT /ledger — replace ledger (after manual reconciliation)Body = full ledger JSON. schema_version must equal 1.6 or the request is rejected with 422 schema_version_mismatch. Server overwrites updated_at.
POST /check — single trigger for a new entrycurl -s -X POST -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{"book":"Tactical","target":25500,"horizon":"tomorrow","side":"bull_call","vhsi":18.5,"notes":"optional"}' \
https://playbook.db3hk.com/checkRequired fields: book, target, horizon, side. Input is validated before the session/state gate — missing fields → 422 missing_fields at any time of day (agents always get a clear error). Optional: vhsi, notes.
If can_new_entry is false → returns NO-GO and stops:
{"ok": false, "mode": "check_now", "decision": "NO-GO", "reason": "cool_off", "cool_off_until": "2026-09-08", "status": { }}Otherwise returns a work order (this service never trades):
{
"ok": true, "mode": "check_now",
"book": "Tactical", "target": 25500, "horizon": "tomorrow", "side": "bull_call", "vhsi": 18.5,
"steps": [
"1. TradeScope/TV: Gates A/B/C + panic-print (1x 15m close)",
"2. OpenD or IB: propose 1-lot HSI width-100 structure, DTE 4-10, remaining DTE>=3",
"3. IBKR agent: authoritative combo mid; debit<=2500; NAV%<=25%",
"4. Day session + tradable combo only",
"5. Fill decision row; GO/NO-GO; if GO human transmits on IB",
"6. POST /ledger/open after fill"
],
"playbook": "v1.6"
}POST /ledger/open — record a fillcurl -s -X POST -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{"book":"Tactical","side":"bull_call","expiry":"2026-09-11","long_strike":25400,"short_strike":25500,"width":100,"entry_debit_pts":43,"entry_debit_hkd":2150,"named_level":25500,"horizon":"tomorrow","stop_debit_pts":28,"lower_tp_debit_pts":52,"washout_low":25100,"remaining_dte_at_entry":4}' \
https://playbook.db3hk.com/ledger/openBody is stored as open_position verbatim; entry_time_hkt is added if absent. If a position is already open → 409 position_already_open. Recommended fields: book, side, expiry, long_strike, short_strike, width, entry_debit_pts, entry_debit_hkd, named_level, horizon, stop_debit_pts, lower_tp_debit_pts, washout_low|washout_high, remaining_dte_at_entry.
POST /manage — manage the open position (never suggests new entries)curl -s -X POST -H "Authorization: Bearer $TOKEN" https://playbook.db3hk.com/manageFlat → {"ok": false, "reason": "flat"}. Open → position fields + reminders (mark vs −35% stop, lower TP / named level, ½-DTE, day-session exits only, no new entry) + status.
POST /ledger/close — record an exitcurl -s -X POST -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{"result":"stop","pnl_pct":-40}' \
https://playbook.db3hk.com/ledger/closeresult ∈ tp | stop | scratch | manual (else 400 invalid_result)409 no_open_positionopen_position → last_closed, appends to history[]result=stop always; result=scratch with pnl_pct <= -15; sets cool_off_until = next HKT day-session date (weekends + configured HKEX holidays skipped){"ok": false, "error": "unauthorized|not_found|schema_version_mismatch|missing_fields|invalid_result|position_already_open|no_open_position|server_error"}HTTP codes: 200 ok · 400 invalid result on close · 401 auth · 404 unknown path · 409 state conflict · 422 missing fields on /check, or schema_version mismatch on PUT /ledger · 500 server error.
GET /ledger/status — before any GO. If can_new_entry is false, stop.POST /check — with target + horizon → follow steps (TradeScope chart gates → OpenD/IB structure → IBKR combo mid → decision row).POST /ledger/open with the fill.POST /manage (or GET /ledger). Manage mode never proposes new entries.POST /ledger/close with result + pnl_pct. Cool-off is enforced automatically.check now → chart gates only. NO-GO stops the chain.check now (paste TS numbers + target + horizon). IB mid = debit. Open position → manage only.POST /ledger/open or /ledger/close. Mismatch → no write. 409 → reconcile, no new ticket.GET /guide.md (Markdown), GET /openapi.json (OpenAPI 3.0)./ shows live status (server-rendered, no token) — safe to fetch for a quick check, but /ledger/status is authoritative.