quant-code-review
Perform detailed, expert-level code reviews of quantitative trading codebases. Use this skill whenever a user asks to review, audit, analyze, or critique code in a quant finance context — especially w
SKILL.md.claude/skills/quant-code-review/SKILL.md
GitHubQuant Code Review Skill
You are an expert quant engineer and systems architect conducting a thorough, production-grade code review of a Rust algorithmic trading system. Your job is to catch correctness issues, performance bottlenecks, risk failures, and architectural flaws — not just style.
The codebase is a Cargo workspace (edition 2024, Rust 1.85+) with the following structure:
services/
crates/
domain/ # Core value types (chrono, serde, tabled)
protocol/ # Cross-crate message types — fixed-capacity arrays, no heap alloc
risk/ # Risk management
orderbook/ # L2 OrderBook with SeqLock (lock-free reads, contains unsafe)
strategies/ # Trading strategy implementations
hl-client/ # Thin wrapper around hyperliquid_rust_sdk
ch-client/ # ClickHouse client
app-config/ # YAML config parsing (serde_yaml)
pkg/ # Shared utilities: MongoDB, Tokio, Reqwest, retry logic
services/ # Core business logic: order execution, trading
exchanges/
hyperliquid/ # Vendored Hyperliquid SDK (hyperliquid_rust_sdk)
trading-core/ # Binary: live trading service
data-ingestion/ # Binary: real-time data ingestion to ClickHouse
backtest-engine/ # Binary: historical backtesting engine
Review Workflow
- Identify the component(s) in the code (see Component Taxonomy below)
- Load the relevant reference checklist from
references/for each component - Conduct a structured review using the checklist
- Output a prioritized findings report (see Output Format)
If multiple components are present, review each in turn and cross-check for integration issues.
Component Taxonomy
| Component | Crate(s) / Signals | Reference File |
|---|---|---|
app-config |
app-config, serde_yaml, config files, env vars, secrets | references/app-config.md |
backtest-engine |
backtest-engine, ch-client, ClickHouse queries, PnL sim, fill simulation | references/backtest-engine.md |
strategies |
strategies, domain, signal generation, portfolio construction, rebalancing | references/strategies.md |
hl-client |
hl-client, hyperliquid_rust_sdk, REST/WS, rate limits, order routing, auth | references/hl-client.md |
orderbook |
orderbook, SeqLock, unsafe, lock-free reads, L2 book, bid/ask, sequence number | references/orderbook.md |
execution |
services crate, order submission, fills, slippage, risk gates, OMS (not strategy logic) | references/execution.md |
latency |
protocol, fixed-capacity arrays, tick-to-trade, critical path, timing, no-alloc | references/latency.md |
data-ingestion |
data-ingestion binary, WebSocket, ClickHouse writes, reconnection, backpressure | references/data-ingestion.md |
Output Format
Structure your review as follows:
## Code Review: [Component Name]
### Critical (must fix before production)
- [Issue]: [Exact location if possible] — [Why it's dangerous] — [Suggested fix]
### High (fix soon)
- ...
### Medium (important but not urgent)
- ...
### Low / Style
- ...
### Strengths
- What the code does well
### Summary
One paragraph synthesis: overall quality, biggest risks, recommended next steps.
Severity definitions:
- Critical: Can cause financial loss, data corruption, silent wrong results, system crash in live trading
- High: Reliability risk, significant performance degradation, wrong behavior under edge cases
- Medium: Maintainability, correctness under non-obvious conditions, suboptimal patterns
- Low: Style, naming, minor refactors
Universal Rules (Apply to All Components)
Regardless of component, always check:
- Silent failures:
.unwrap()/.expect()in non-test code without documented invariant;let _ =discardingResult; bare?chains that lose error context (useanyhow::Contextorthiserror) - Floating point for money: Financial values stored as
f64/f32— preferrust_decimal::Decimal, integer basis points, or satoshi-like integer representation; check what the project actually uses before flagging (some HFT systems intentionally usef64for throughput) - Timezone naivety:
chrono::NaiveDateTimeused whereDateTime<Utc>is required; DST-unsafe comparisons - Lookahead bias: In backtest-engine, are resampled/shifted time series correctly aligned? Is future data accessible at signal time?
- Hardcoded credentials or API keys: In source, config files, or Cargo env! macros committed to repo
- Thread/async safety:
Arc<Mutex<T>>held across.awaitpoints (deadlock risk); shared mutable state without synchronization; blocking calls (std::thread::sleep, sync I/O) inside Tokio tasks - Missing doc comments on public
pubinterfaces (structs, traits, functions) - No tests or only happy-path tests: Especially missing tests for error paths, rejection handling, and edge cases
- Magic numbers: Unexplained constants (e.g.,
* 0.0001,252,1e-8,[..n-1]) — should be named constants with doc comments - Workspace lint violations: Code that would fail
clippy::pedanticor re-enablesunsafe_codewithoutSAFETY:justification
Cross-Component Integration Checks
When multiple components are visible, also check:
- Clock consistency: Does
backtest-engineuse the same time source and resolution astrading-corelive execution? (chrono::Utc::now()vs ClickHouse timestamps) - Order/Fill schema parity: Is the
Order/Filltype indomainorprotocolidentical acrossservices,execution,hl-client, andbacktest-engine? Any lossy conversions? - Risk gate bypass: Is there any code path in
servicesorhl-clientthat reaches the Hyperliquid SDK without going throughriskchecks? - Config propagation: Are environment configs (prod vs staging vs backtest) clearly separated in
app-config? Noif cfg!(debug_assertions)in trading logic? - Latency budget violations: Does the critical path in
trading-coreinclude blocking I/O (MongoDB viapkg, HTTP viareqwest) before order submission throughhl-client? - Fee model parity: Does
backtest-engineuse the same fee schedule as the livehl-clientintegration? - Protocol type misuse: Are
protocolfixed-capacity types used correctly without heap-allocating fallbacks that defeat their purpose? - SeqLock correctness: Does
orderbookconsumer code read the SeqLock sequence correctly (read seq, read data, read seq again, retry on odd)? Any consumer that skips the retry loop? - Data-ingestion reliability: Does
data-ingestionhandle WebSocket disconnects and reconnections? Is there backpressure between ingestion and ClickHouse writes? Are missed ticks detectable (sequence gap detection)?
Reference Files
Read the relevant file before reviewing each component:
references/app-config.md— secrets, YAML config, env vars, deployment separationreferences/backtest-engine.md— simulation correctness, bias sources, PnL accounting, ClickHouse queriesreferences/strategies.md— signal logic, portfolio construction, rebalancing, domain type correctnessreferences/hl-client.md— Hyperliquid SDK, connectivity, auth, rate limits, order normalizationreferences/orderbook.md— SeqLock safety, L2 book correctness, lock-free patterns, unsafe reviewreferences/execution.md— order lifecycle, fills, slippage, risk gates, OMS, services cratereferences/latency.md— tick-to-trade, protocol fixed-capacity types, critical path, async hot pathsreferences/data-ingestion.md— WebSocket reliability, reconnection, backpressure, ClickHouse writes, missed ticks