arbitrage-engine/docs/ai/02-module-cheatsheet.md
fanziqi 22787b3e0a docs: add AI documentation suite and comprehensive code review report
- Generate full AI-consumable docs (docs/ai/): system overview, architecture,
  module cheatsheet, API contracts, data model, build guide, decision log,
  glossary, and open questions (deep tier coverage)
- Add PROBLEM_REPORT.md: categorized bug/risk summary
- Add DETAILED_CODE_REVIEW.md: full line-by-line review of all 15 backend
  files, documenting 4 fatal issues, 5 critical deployment bugs, 4 security
  vulnerabilities, and 6 architecture defects with prioritized fix plan
2026-03-03 19:01:18 +08:00

219 lines
11 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
generated_by: repo-insight
version: 1
created: 2026-03-03
last_updated: 2026-03-03
source_commit: 0d9dffa
coverage: standard
---
# 02 — Module Cheatsheet
## Purpose
Module-by-module index: file path, role, key public interfaces, and dependencies.
## TL;DR
- Backend has 20 Python modules; signal_engine.py is the largest and most complex (~1000+ lines).
- Frontend has 2 TypeScript lib files + 9 pages + 6 components.
- `db.py` is the only shared infrastructure module; all other backend modules import from it.
- `signal_engine.py` is the core business logic module; `live_executor.py` and `risk_guard.py` are independent processes that only use `db.py` and direct PG connections.
- Strategy configs are external JSON; no code changes needed to tune weights/thresholds.
## Canonical Facts
### Backend Modules
#### `backend/main.py` — FastAPI HTTP API
- **Role**: Primary HTTP API server; rate/snapshot/history proxy; aggTrade query endpoints; signal history.
- **Key interfaces**:
- `GET /api/health` — liveness check (public)
- `GET /api/rates` — live Binance premiumIndex for 4 symbols (public, 3 s cache)
- `GET /api/snapshots` — rate snapshot history from PG (auth required)
- `GET /api/kline` — candlestick bars aggregated from `rate_snapshots` (auth required)
- `GET /api/stats` — 7-day funding rate stats per symbol (auth required, 60 s cache)
- `GET /api/stats/ytd` — YTD annualized stats (auth required, 3600 s cache)
- `GET /api/history` — 7-day raw funding rate history (auth required, 60 s cache)
- `GET /api/signals/history``signal_logs` table (auth required)
- `GET /api/trades/meta``agg_trades_meta` (auth required)
- `GET /api/trades/summary` — aggregated OHLCV from `agg_trades` (auth required)
- Many more: paper trades, signals v52, live trades, live config, position sync, etc. (full list in saved tool output)
- **Deps**: `auth.py`, `db.py`, `httpx`, `asyncio`
- **Background task**: `background_snapshot_loop()` writes `rate_snapshots` every 2 s.
#### `backend/signal_engine.py` — V5 Signal Engine (PM2 worker)
- **Role**: Core signal computation loop; 15 s interval; in-memory rolling-window indicators; scored signal output.
- **Key classes**:
- `TradeWindow(window_ms)` — rolling CVD/VWAP calculator using `deque`; props: `cvd`, `vwap`
- `ATRCalculator(period_ms, length)` — 5-min candle ATR; props: `atr`, `atr_percentile`
- `SymbolState` — per-symbol state container holding `TradeWindow` ×3, `ATRCalculator`, large-order percentile deques
- **Key functions**:
- `load_strategy_configs() -> list[dict]` — reads JSON files from `strategies/`
- `fetch_market_indicators(symbol) -> dict` — reads `market_indicators` table
- `fetch_new_trades(symbol, last_id) -> list` — reads new rows from `agg_trades`
- `save_indicator(ts, symbol, result, strategy)` — writes to `signal_indicators`
- `paper_open_trade(...)` — inserts `paper_trades` row
- `paper_check_positions(symbol, price, now_ms)` — checks TP/SL for paper positions
- `main()` — entry point; calls `load_historical()` then enters main loop
- **Deps**: `db.py`, `json`, `collections.deque`
#### `backend/live_executor.py` — Live Trade Executor (PM2 worker)
- **Role**: Listens on PG `NOTIFY new_signal`; places Binance Futures market orders; writes `live_trades`.
- **Key functions**:
- `reload_live_config(conn)` — refreshes `RISK_PER_TRADE_USD`, `MAX_POSITIONS` from `live_config` every 60 s
- `binance_request(session, method, path, params)` — HMAC-signed Binance API call
- **Config**: `TRADE_ENV` (`testnet`/`production`), `LIVE_STRATEGIES`, `RISK_PER_TRADE_USD`, `MAX_POSITIONS`
- **Deps**: `psycopg2`, `aiohttp`, HMAC signing
#### `backend/risk_guard.py` — Risk Circuit-Breaker (PM2 worker)
- **Role**: Every 5 s; monitors PnL, balance, data freshness, hold timeouts; writes circuit-break flags.
- **Key classes**: `RiskState` — holds `status` (`normal`/`warning`/`circuit_break`), loss counters
- **Key functions**:
- `check_daily_loss(conn)` — sums `pnl_r` from today's `live_trades`
- `check_unrealized_loss(session, risk_usd_dynamic)` — queries Binance positions API
- `check_balance(session)` — queries Binance account balance
- `check_data_freshness(conn)` — checks `market_indicators` recency
- `check_hold_timeout(session, conn)` — force-closes positions held >70 min
- `trigger_circuit_break(session, conn, reason, action)` — writes to `live_events`, may flat positions
- `check_auto_resume()` — re-enables trading after cooldown
- `check_emergency_commands(session, conn)` — watches for manual DB commands
- **Deps**: `trade_config.py`, `aiohttp`, `psycopg2`
#### `backend/db.py` — Database Layer
- **Role**: All PG connectivity; schema creation; partition management.
- **Key interfaces**:
- Sync (psycopg2): `get_sync_conn()`, `sync_execute()`, `sync_executemany()`
- Async (asyncpg): `async_fetch()`, `async_fetchrow()`, `async_execute()`
- Cloud SQL sync pool: `get_cloud_sync_conn()` (non-fatal on failure)
- `init_schema()` — creates all tables from `SCHEMA_SQL`
- `ensure_partitions()` — creates `agg_trades_YYYYMM` partitions for current+next 2 months
- **Deps**: `asyncpg`, `psycopg2`
#### `backend/auth.py` — JWT Auth + Registration
- **Role**: FastAPI router at `/api`; register/login/refresh/logout endpoints.
- **Key interfaces**:
- `POST /api/register` — invite-code gated registration
- `POST /api/login` — returns `access_token` + `refresh_token`
- `POST /api/refresh` — token refresh
- `POST /api/logout` — revokes refresh token
- `GET /api/me` — current user info
- `get_current_user` — FastAPI `Depends` injector; validates Bearer JWT
- **Token storage**: HMAC-SHA256 hand-rolled JWT (no PyJWT); refresh tokens stored in `refresh_tokens` table.
- **Deps**: `db.py`, `hashlib`, `hmac`, `secrets`
#### `backend/agg_trades_collector.py` — AggTrades Collector (PM2 worker)
- **Role**: Streams Binance `aggTrade` WebSocket events; batch-inserts into `agg_trades` partitioned table; maintains `agg_trades_meta`.
- **Key functions**: `ws_collect(symbol)`, `rest_catchup(symbol, from_id)`, `continuity_check()`, `flush_buffer(symbol, trades)`
- **Deps**: `db.py`, `websockets`/`httpx`
#### `backend/market_data_collector.py` — Market Data Collector (PM2 worker)
- **Role**: Collects Binance market indicators (LS ratio, OI, coinbase premium, funding rate) via REST polling; stores in `market_indicators` JSONB.
- **Key class**: `MarketDataCollector`
- **Deps**: `db.py`, `httpx`
#### `backend/liquidation_collector.py` — Liquidation Collector (PM2 worker)
- **Role**: Streams Binance liquidation WS; aggregates into `liquidation_events` and `liquidation_agg` tables.
- **Key functions**: `ensure_table()`, `save_liquidation()`, `save_aggregated()`, `run()`
- **Deps**: `db.py`, `websockets`
#### `backend/backtest.py` — Offline Backtester
- **Role**: Replays `agg_trades` from PG to simulate signal engine and measure strategy performance.
- **Key classes**: `Position`, `BacktestEngine`
- **Key functions**: `load_trades()`, `run_backtest()`, `main()`
- **Deps**: `db.py`
#### `backend/trade_config.py` — Symbol / Qty Config
- **Role**: Constants for symbols and Binance qty precision.
- **Deps**: none
#### `backend/admin_cli.py` — Admin CLI
- **Role**: CLI for invite-code and user management (gen_invite, list_invites, ban_user, set_admin).
- **Deps**: `db.py`
#### `backend/subscriptions.py` — Subscription Query Helper
- **Role**: Helpers for querying signal history (used internally).
- **Deps**: `db.py`
#### `backend/paper_monitor.py` — Paper Trade Monitor
- **Role**: Standalone script to print paper trade status.
- **Deps**: `db.py`
#### `backend/signal_pusher.py` — Discord Notifier (PM2 worker)
- **Role**: Polls `signal_indicators` for high-score events; pushes Discord webhook notifications.
- **Deps**: `db.py`, `httpx`
#### `backend/position_sync.py` — Position Sync
- **Role**: Syncs live positions between `live_trades` table and Binance account state.
- **Deps**: `db.py`, `aiohttp`
#### `backend/fix_historical_pnl.py` — PnL Fix Script
- **Role**: One-time migration to recalculate historical PnL in `paper_trades`.
- **Deps**: `db.py`
### Frontend Modules
#### `frontend/lib/api.ts` — API Client
- **Role**: Typed `api` object with all backend endpoint wrappers; distinguishes public vs. protected fetches.
- **Interfaces exported**: `RateData`, `RatesResponse`, `HistoryPoint`, `HistoryResponse`, `StatsResponse`, `SignalHistoryItem`, `SnapshotItem`, `KBar`, `KlineResponse`, `YtdStatsResponse`, `api` object
- **Deps**: `lib/auth.tsx` (`authFetch`)
#### `frontend/lib/auth.tsx` — Auth Context
- **Role**: React context for current user; `useAuth()` hook; `authFetch()` with access-token injection and auto-refresh.
- **Deps**: Next.js router, `localStorage`
#### `frontend/app/` Pages
| Page | Route | Description |
|------|-------|-------------|
| `page.tsx` | `/` | Main dashboard: rates, kline, history, signal log |
| `dashboard/page.tsx` | `/dashboard` | (inferred) extended dashboard |
| `signals/page.tsx` | `/signals` | Signal history view (V5.1) |
| `signals-v52/page.tsx` | `/signals-v52` | Signal history view (V5.2) |
| `paper/page.tsx` | `/paper` | Paper trades view (V5.1) |
| `paper-v52/page.tsx` | `/paper-v52` | Paper trades view (V5.2) |
| `live/page.tsx` | `/live` | Live trades view |
| `history/page.tsx` | `/history` | Funding rate history |
| `kline/page.tsx` | `/kline` | Kline chart page |
| `trades/page.tsx` | `/trades` | aggTrades summary |
| `server/page.tsx` | `/server` | Server status / metrics |
| `about/page.tsx` | `/about` | About page |
| `login/page.tsx` | `/login` | Login form |
| `register/page.tsx` | `/register` | Registration form |
#### `frontend/components/`
| Component | Role |
|-----------|------|
| `Navbar.tsx` | Top navigation bar |
| `Sidebar.tsx` | Sidebar navigation |
| `AuthHeader.tsx` | Auth-aware header with user info |
| `RateCard.tsx` | Displays current funding rate for one asset |
| `StatsCard.tsx` | Displays 7d mean and annualized stats |
| `FundingChart.tsx` | Funding rate chart component |
| `LiveTradesCard.tsx` | Live trades summary card |
## Interfaces / Dependencies
### Key import graph (backend)
```
main.py → auth.py, db.py
signal_engine.py → db.py
live_executor.py → psycopg2 direct (no db.py module import)
risk_guard.py → trade_config.py, psycopg2 direct
backtest.py → db.py
agg_trades_collector.py → db.py
market_data_collector.py → db.py
liquidation_collector.py → db.py
admin_cli.py → db.py
```
## Unknowns & Risks
- [inference] Content of `frontend/app/dashboard/`, `signals/`, `paper/`, `live/` pages not read; role described from filename convention.
- [unknown] `signal_pusher.py` Discord webhook env var name not confirmed.
- [inference] `position_sync.py` exact interface not read; role inferred from name and listing.
## Source Refs
- `backend/main.py` — all API route definitions
- `backend/signal_engine.py:170-285``TradeWindow`, `ATRCalculator`, `SymbolState`
- `backend/auth.py:23-23` — router prefix `/api`
- `backend/db.py:35-157` — all public DB functions
- `frontend/lib/api.ts:103-116``api` export object
- `frontend/lib/auth.tsx` — auth context (not fully read)