Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
285 commits
Select commit Hold shift + click to select a range
adf63a3
test: fail hung tests with a stack dump (pytest-timeout 300s)
sijie-Z Oct 21, 2026
01e7672
fix: close the Host-header auth bypass; add corporate actions end to end
sijie-Z Oct 21, 2026
8446449
chore: upgrade FastAPI/Starlette (BadHost fixes) and axios; satisfy mypy
sijie-Z Oct 21, 2026
cf1fb3e
test: keep the kill-switch concurrency test off the real runtime DB
sijie-Z Oct 21, 2026
564401a
fix: reject cross-origin browser requests and make side-effect contro…
sijie-Z Oct 21, 2026
ec7ae6c
docs: CSRF origin guard and POST-only provider controls
sijie-Z Oct 21, 2026
0237272
chore: align secure dependency pins across requirements, pyproject an…
sijie-Z Oct 21, 2026
78c7afd
fix: close DNS-rebinding and one-sided window bypasses; harden leaks
sijie-Z Oct 22, 2026
e44bec9
docs: update test counts after security follow-up (3,328 cases)
sijie-Z Oct 22, 2026
de72820
fix: bound the OMS order book and rate-limit order endpoints
sijie-Z Oct 22, 2026
bdddf03
fix: remaining resource leaks, lazy GET starts and CSP header
sijie-Z Oct 22, 2026
894b4bf
chore: require anyio>=4.15.1 (IDN TLS advisory)
sijie-Z Oct 22, 2026
f06702a
docs: final test counts (3,333 cases)
sijie-Z Oct 22, 2026
e960645
fix: WS DNS-rebinding parity, import fan-out and OMS admission caps
sijie-Z Oct 22, 2026
3167331
chore: make requirements.txt ASCII-only so pip reads it under a GBK l…
sijie-Z Oct 22, 2026
c5bbbde
docs: test counts after red-team regressions (3,337 cases)
sijie-Z Oct 22, 2026
5ab5036
feat: echarts 6, loopback WS parity, single-flight context and 429 retry
sijie-Z Oct 22, 2026
c19d28b
docs: real-time data entry points and final test counts
sijie-Z Oct 22, 2026
a01114f
feat: purge gap and embargo isolation in WalkForwardValidator
sijie-Z Oct 22, 2026
bf02c0b
feat: walkforward CLI passes --purge-gap and --embargo to the validator
sijie-Z Oct 22, 2026
f985133
docs: note purge/embargo isolation on the README walk-forward row
sijie-Z Oct 22, 2026
563bd44
test: purge/embargo fold isolation, validation, and IC training exclu…
sijie-Z Oct 22, 2026
9ebf687
refactor: fold records carry train_days computed with the embargo mask
sijie-Z Oct 22, 2026
a91a8ca
docs: correct the embargo docstring for rolling layouts
sijie-Z Oct 22, 2026
9ba6735
feat: add validate_sweep_trials shared DSR/BH helper for parameter sw…
sijie-Z Oct 22, 2026
1bb90b1
feat: report DSR/BH multiple-testing correction from /api/sweep
sijie-Z Oct 22, 2026
d2c46a3
feat: CLI sweep prints DSR/BH columns and the selection verdict
sijie-Z Oct 22, 2026
68f8697
feat: filter walk-forward factors by IC t-test with BH-FDR control
sijie-Z Oct 22, 2026
e0f853e
docs: note DSR/BH correction in the README validation table
sijie-Z Oct 22, 2026
99cfd6b
feat: keep sweep rows when daily returns cannot feed the DSR check
sijie-Z Oct 22, 2026
cfc09f0
feat: cover DSR/BH edge paths and rank the factor fallback only on fi…
sijie-Z Oct 22, 2026
dbe1183
feat: add research holdout spec, config keys and sweep guard helper
sijie-Z Oct 22, 2026
c6da716
feat: refuse sweeps whose data window overlaps the research holdout
sijie-Z Oct 22, 2026
804f489
feat: exclude holdout dates from research validation before selection
sijie-Z Oct 22, 2026
02822e5
docs: document the research holdout discipline
sijie-Z Oct 22, 2026
70d40e2
fix: validate holdout in the config validation step; drop forward-lab…
sijie-Z Oct 22, 2026
166e70d
fix: tighten holdout warnings and the defence-in-depth mask
sijie-Z Oct 22, 2026
89030b9
feat: add per-fold factor selector to WalkForwardValidator
sijie-Z Oct 22, 2026
e7d39cb
feat: select walk-forward factors per fold on train-window ICs
sijie-Z Oct 22, 2026
68916b3
docs: note per-fold factor selection in the README walk-forward row
sijie-Z Oct 22, 2026
9b9e3ba
fix: drop baostock reports without pubDate instead of using period end
sijie-Z Oct 23, 2026
bcd7855
docs: note Baostock financials require pubDate in README limitations
sijie-Z Oct 23, 2026
6f7a7f7
fix: keep asset_growth anchored to the same quarter after dropping rows
sijie-Z Oct 23, 2026
6d9b7e4
fix: bump baostock cache version for asset_growth semantics; pin anch…
sijie-Z Oct 23, 2026
559f0d0
feat: apply per-date index membership to PIT tradability
sijie-Z Oct 23, 2026
2c40012
fix: forward-fill snapshot-dated membership masks onto the price grid
sijie-Z Oct 23, 2026
a02acb6
fix: harden membership gate against snapshot caches and wrappers
sijie-Z Oct 23, 2026
84dbbc5
fix: count membership snapshots inside the price window only
sijie-Z Oct 23, 2026
870e97b
fix: propagate index-membership exits through the snapshot forward fill
sijie-Z Oct 23, 2026
22771fe
refactor: split index membership out of tradable_mask into universe_mask
sijie-Z Oct 23, 2026
e27bd03
feat: gate buys on universe_mask but keep index exits sellable
sijie-Z Oct 23, 2026
cc029d5
chore: bump DATA_SCHEMA_VERSION to 6 for the universe PIT semantics c…
sijie-Z Oct 23, 2026
f43ded6
test: pin main forwarding of both execution masks to the engine
sijie-Z Oct 23, 2026
3995634
test: pin tradable_mask bit-equality with the no-hook baseline
sijie-Z Oct 23, 2026
4752918
docs: align universe-mask log wording and provider docstring with R6b…
sijie-Z Oct 23, 2026
eaf9a21
feat: fold applied universe_mask into research excluded_mask (R6c)
sijie-Z Oct 23, 2026
49cdb88
test: pin membership PIT in factor panels and signals
sijie-Z Oct 23, 2026
3c82472
docs: note factor/signal membership PIT in README data bullet
sijie-Z Oct 23, 2026
e89b18d
fix: compute factor levels from the uncropped price history (R6c)
sijie-Z Oct 23, 2026
6171b4f
feat: derive Baostock ST episodes from the daily isST field (R7a)
sijie-Z Oct 23, 2026
2ccee7b
fix: harden Baostock ST cache round-trip and retry semantics (R7a rev…
sijie-Z Oct 23, 2026
8a4921e
feat: add cost-aware constraint fields and config plumbing (R8)
sijie-Z Oct 23, 2026
b9756cb
feat: add cost terms and ADV capacity caps to MVO (R8)
sijie-Z Oct 23, 2026
4e17953
feat: wire ADV capacity inputs into the backtest optimizer (R8)
sijie-Z Oct 23, 2026
67ee80b
fix: clip post-turnover blend to the ADV capacity cap (R8)
sijie-Z Oct 23, 2026
1941e04
docs: note cost-aware MVO and ADV capacity cap in README (R8)
sijie-Z Oct 23, 2026
3140897
test: pin that the cost term is zero without prev_weights (R8)
sijie-Z Oct 23, 2026
c25527c
test: pin share-to-CNY conversion for the cost model (R8)
sijie-Z Oct 23, 2026
f80fba2
perf: skip the price-panel copy when no volume is supplied (R8)
sijie-Z Oct 23, 2026
39c3eb0
test: assert the capacity cap is binding, not just satisfied (R8)
sijie-Z Oct 23, 2026
19f4695
fix: compute ADV and cost-model volume in CNY from raw close (R8 revi…
sijie-Z Oct 23, 2026
eea668a
fix: reject non-finite cost-aware constraint fields (R8 review m5)
sijie-Z Oct 23, 2026
c5e5413
fix: refill capacity-clipped weights and harden no-op/short tests (R8…
sijie-Z Oct 23, 2026
6f182e7
docs: clarify capacity is engine-API only and pin zero defaults (R8 r…
sijie-Z Oct 23, 2026
3a2aa98
docs: align capacity test docstring with the raw-close basis (R8)
sijie-Z Oct 23, 2026
9186152
fix: cap the capacity refill by sector headroom (R8 re-review m1)
sijie-Z Oct 23, 2026
a18b691
fix: mirror the single-sector guard in the capacity refill (R8 review…
sijie-Z Oct 23, 2026
32e16f0
fix: harden R8 fallback reasons, volume fail-closed, and solver-cap t…
sijie-Z Oct 23, 2026
78e54df
test: make the fail-closed slippage assertion discriminating (R8 revi…
sijie-Z Oct 23, 2026
854bbdf
feat: wire volume and raw close into the backtest cost pipeline (R9)
sijie-Z Oct 23, 2026
701c066
refactor: carry R9 market panels through the shared execution-gates a…
sijie-Z Oct 23, 2026
a1f604c
docs: default.yaml max_participation comment reflects the R9 volume w…
sijie-Z Oct 23, 2026
a3f1fbc
docs: clarify impact_model scope (scalar path; vector path is square-…
sijie-Z Oct 23, 2026
e86a4b3
fix: address R9 review minors (fallback wording, impact_model scope, …
sijie-Z Oct 23, 2026
5eaef48
feat(trading): QMT lazy reconnect with broker order/trade resync (R10)
sijie-Z Oct 23, 2026
48b3f55
fix(trading): serialize QMT lazy reconnects to avoid duplicate sessions
sijie-Z Oct 23, 2026
e0949d3
fix(trading): address R10 review (reconnect reentrancy, resync race, …
sijie-Z Oct 23, 2026
0573d43
fix(trading): failed explicit QMT reconnect must not keep connected s…
sijie-Z Oct 23, 2026
3f172c9
fix(trading): close R10 round-2 minors (connect window state, session…
sijie-Z Oct 23, 2026
229d014
fix(trading): disconnect keeps return semantics when trader.stop fails
sijie-Z Oct 23, 2026
2942352
feat(core): persist daily books-vs-broker reconciliation results (R11)
sijie-Z Oct 23, 2026
68dab28
feat(operations): add broker/store position adapters for EOD reconcil…
sijie-Z Oct 23, 2026
ed1b62f
feat(core): run books-vs-broker reconciliation in the EOD path (R11)
sijie-Z Oct 23, 2026
7e50a06
docs(readme): note the daily EOD books-vs-broker reconciliation (R11)
sijie-Z Oct 23, 2026
7558c05
fix(operations): fail loud on a position row without an asset code (R11)
sijie-Z Oct 23, 2026
50f3f50
fix(operations): reject non-integral share counts in reconciliation b…
sijie-Z Oct 23, 2026
f80be55
feat(reconciliation): derive expected from startup baseline + trade l…
sijie-Z Oct 23, 2026
cee8503
test(reconciliation): cover the startup baseline + trade-ledger expec…
sijie-Z Oct 23, 2026
9052049
fix(engine): stamp the ledger baseline with the broker fill clock (R12)
sijie-Z Oct 23, 2026
9bd54c8
docs(reconciliation): note the corporate-action limitation of the tra…
sijie-Z Oct 23, 2026
2d75fc6
fix(reconciliation): address R12 adversarial review minors (R12)
sijie-Z Oct 23, 2026
5e78128
fix(store): reject whitespace-only ledger created_at (R12 review N1)
sijie-Z Oct 23, 2026
a39c15f
feat(store): sum persisted trade quantity per order (R13)
sijie-Z Oct 23, 2026
8f441d5
feat(engine): sync async broker fills into the trade ledger (R13)
sijie-Z Oct 23, 2026
7d2961f
test(engine): cover async broker fill sync (R13)
sijie-Z Oct 23, 2026
3cc1858
fix(engine): keep startup-synced fills strictly before the ledger bas…
sijie-Z Oct 23, 2026
3facfe9
docs(readme): note async fill sync for live brokers (R13)
sijie-Z Oct 23, 2026
74a1faf
fix(engine,store): close R13 review gaps (startup adoption, dedupe, b…
sijie-Z Oct 23, 2026
45677cb
fix(engine,store): scope broker-id dedupe and close round-2 review ga…
sijie-Z Oct 23, 2026
4a8a639
fix(engine,store): exclude current order from broker-id sum and close…
sijie-Z Oct 23, 2026
3f559ae
docs: session handover and platform gap assessment (R1-R13 local work)
sijie-Z Oct 23, 2026
3ed18d1
feat(data): derive Tushare ST episodes from namechange and cache them…
sijie-Z Oct 23, 2026
4be8085
fix(data): harden Tushare ST feed on the incremental path and cache i…
sijie-Z Oct 23, 2026
4e02a4b
fix(data): keep all ST merge failures non-fatal (R14 review round 1 f…
sijie-Z Oct 23, 2026
e8a6741
fix(data): encode ST availability in the cache identity and harden th…
sijie-Z Oct 23, 2026
8eaf1cc
fix(data): retire v5 ST caches and make incremental window coverage s…
sijie-Z Oct 23, 2026
c00a056
fix(data): clamp incremental ST coverage to the observable date and h…
sijie-Z Oct 23, 2026
d50342e
fix(portfolio): ridge and PSD-certification hardening for singular co…
sijie-Z Oct 23, 2026
13a7635
test(portfolio): cover the R15 singular-covariance hardening (R15)
sijie-Z Oct 23, 2026
de754df
fix(portfolio): log invalid covariances with non-positive trace (R15)
sijie-Z Oct 23, 2026
7d6c978
fix(portfolio): warn on invalid covariances and close R15 review gaps
sijie-Z Oct 23, 2026
9e11329
test(portfolio): pin the RiskParity psd_wrap wiring (R15 review round 2)
sijie-Z Oct 23, 2026
93e860c
docs(research): real-data evidence 2026-10-24 and handover update (R1…
sijie-Z Oct 23, 2026
860ecb9
feat(tools): add reproducible real-data research runner (R16)
sijie-Z Oct 24, 2026
ed77afb
docs(readme): list the real-data research tool entry (R16)
sijie-Z Oct 24, 2026
192f6b5
fix(tools): harden factor flags and date coercion after R16 review
sijie-Z Oct 24, 2026
def17e5
docs(research): neutralization, capacity, paper smoke and R16 tool re…
sijie-Z Oct 24, 2026
a2711a4
fix(tools): parse integer YYYYMMDD date levels as calendar dates (R16…
sijie-Z Oct 24, 2026
3bf7089
docs: record push, PR update and real-data neutralization results
sijie-Z Oct 24, 2026
d16ad70
docs(research): valuation factors, EP+turnover candidate and OOS capa…
sijie-Z Oct 24, 2026
3df07e6
feat(tools): daily_signal PIT target-weight tool (R17)
sijie-Z Oct 24, 2026
bf4103b
feat(tools): expose composite signal summary in daily_signal diagnostics
sijie-Z Oct 24, 2026
37e745f
docs(research): factor-zoo scan and conservative neutralized alphabet…
sijie-Z Oct 24, 2026
a4cb48f
fix(tools): fixed-denominator signal, first-build/stale warnings (R17…
sijie-Z Oct 24, 2026
44cf72d
docs(research): executable target portfolio as of the cached data end
sijie-Z Oct 24, 2026
0b64e08
polish(tools): review nits for daily_signal (stale threshold, wording…
sijie-Z Oct 24, 2026
e884d7c
docs(research): regenerate target portfolio with the fixed signal tool
sijie-Z Oct 24, 2026
61d37c7
feat(backtest): cash-aware buy sizing at execution (R18)
sijie-Z Oct 24, 2026
4d0150a
test(backtest): pin R18 cash-constrained buys and default-path golden
sijie-Z Oct 24, 2026
c3a81d6
fix(research): same-day limit gates, dual OOS benchmarks, excess DSR
sijie-Z Oct 24, 2026
120a48b
fix(backtest): treat sub-tolerance cash as zero to avoid dust orders
sijie-Z Oct 24, 2026
fb1c8cf
fix(capacity): causal volatility in the capacity estimator
sijie-Z Oct 24, 2026
a63f944
docs(readme): note corrected research-tool conventions
sijie-Z Oct 24, 2026
813dcaa
docs(research): disclose static industry map and label benchmark annu…
sijie-Z Oct 24, 2026
869f64c
fix(research): information-ratio Sharpe for the excess row
sijie-Z Oct 24, 2026
fb34297
fix(research): give the buy&hold benchmark its next-session label und…
sijie-Z Oct 24, 2026
fb1a554
test(research): cover the --end full-adj wiring for buy&hold
sijie-Z Oct 24, 2026
a13f2c5
docs(research): label the target portfolio as a style-tilt demo
sijie-Z Oct 24, 2026
61effab
docs(research): rewrite the real-data evidence with the R19b rerun
sijie-Z Oct 24, 2026
f5b33de
docs(research): address the R19b adversarial review
sijie-Z Oct 24, 2026
c5c919c
docs(research): fix the three round-2 review nits
sijie-Z Oct 24, 2026
e3177f9
feat(walkforward): add opt-in rank-normalized fold signal
sijie-Z Oct 24, 2026
8b254e2
test(walkforward): check the sector cap on optimizer targets
sijie-Z Oct 24, 2026
8d83194
docs(research): align the real-data evidence with the R20 conventions
sijie-Z Oct 24, 2026
c60b6e3
test(walkforward): cover a feasible MVO where the sector cap binds
sijie-Z Oct 24, 2026
89dfd10
docs(research): fix residual R20 wording per review
sijie-Z Oct 24, 2026
d00e091
docs(research): cite the feasible-MVO sector-cap test
sijie-Z Oct 24, 2026
5e4ebd0
feat(tools): add forward paper tracking ledger
sijie-Z Oct 24, 2026
86ee962
docs(tools): state paper_track scope and annualization basis
sijie-Z Oct 24, 2026
dc5b78e
fix(tools): correct paper_track return basis and execution gates
sijie-Z Oct 24, 2026
6f438f5
fix(tools): close paper_track round-2 review minors
sijie-Z Oct 24, 2026
4337aeb
docs(research): record the R22 volatility-target test
sijie-Z Oct 24, 2026
c9cec2f
docs(research): correct R22 exposure and yearly figures
sijie-Z Oct 24, 2026
7e0a390
docs(research): record the R23 orthogonal-alpha screen (zero result)
sijie-Z Oct 24, 2026
c88de88
docs(research): address R23 review minors (alpha range, disclosures)
sijie-Z Oct 24, 2026
fe4d0d4
feat(tools): add monthly rolling mode to paper_track (R24)
sijie-Z Oct 24, 2026
a39879a
docs(research): record the R24 rolling paper-ledger cross-check
sijie-Z Oct 24, 2026
2e30d3e
fix(tools): start the rolling ledger benchmark flat on the build row
sijie-Z Oct 24, 2026
89edaa8
docs(research): note the last-session convention in the R24 benchmark…
sijie-Z Oct 24, 2026
6514ff1
fix(tools): address R24 review minors (pending wording, zero-scale bu…
sijie-Z Oct 24, 2026
4986f58
test(tools): cover rolling commission floor and reverse ledger mixing
sijie-Z Oct 24, 2026
b7104ee
docs(research): record the R25 portfolio-construction comparison
sijie-Z Oct 24, 2026
032296f
docs(research): address the R25 review minors
sijie-Z Oct 24, 2026
429edc6
feat(tools): enforce portfolio sector cap and expose construction modes
sijie-Z Oct 24, 2026
0014ce0
docs(research): regenerate 2025-12-31 target with the 30% sector cap
sijie-Z Oct 24, 2026
0cfb25d
fix(tools): warn when a simple construction leaves a cash residual
sijie-Z Oct 24, 2026
a0e5f3b
docs(research): regenerate the rolling ledger under the 30% sector cap
sijie-Z Oct 24, 2026
6e129c2
docs(tests): address the R26 review minors
sijie-Z Oct 24, 2026
b80d1c2
docs(research): tighten the R26 rolling-target change description
sijie-Z Oct 24, 2026
12895e9
feat(tools): add resumable wide-pool fetcher (R27)
sijie-Z Oct 24, 2026
2aa3f66
test(tools): cover the R27 wide-pool fetcher with mocked providers
sijie-Z Oct 24, 2026
4156a24
docs(readme): list the R27 wide-pool fetcher
sijie-Z Oct 24, 2026
b29572d
fix(tools): validate --refresh codes and report universe errors as ex…
sijie-Z Oct 24, 2026
7964738
fix(tools): address R27 review minors (read errors, code validation, …
sijie-Z Oct 24, 2026
98e930d
fix(tools): treat unreadable-to-date parquet as ReadError and tidy R2…
sijie-Z Oct 24, 2026
618be79
docs(research): go/no-go deployment decision memo
sijie-Z Oct 24, 2026
bfeea40
fix(research): move walk-forward factor selector into CORE validation
sijie-Z Oct 24, 2026
01d5db0
test(trading): pin the exchange clock in T+1 restart tests
sijie-Z Oct 24, 2026
f4384af
docs(research): add R30 wide-pool external validity section
sijie-Z Oct 24, 2026
4e6a85f
docs: extend handover with R20-R30 results and decision memo
sijie-Z Oct 24, 2026
d7719d3
docs(research): fix R30 cost ADV basis and review nits
sijie-Z Oct 24, 2026
1db7e6d
docs(research): R30 determinism wording after round-2 review
sijie-Z Oct 24, 2026
f7af5cb
docs(research): add R31 wide-pool value study and 2026-10-23 paper ta…
sijie-Z Oct 24, 2026
5fe599a
docs(research): disclose R31 valuation vintage and determinism scope
sijie-Z Oct 24, 2026
b2cba38
docs(research): finalize R31 target vintage metadata
sijie-Z Oct 24, 2026
01d9b04
feat(tools): resolve raw-price basis in paper_track (R32)
sijie-Z Oct 24, 2026
581f5e8
test(tools): pin paper_track raw-price basis and legacy bytes (R32)
sijie-Z Oct 24, 2026
eee5200
fix(tools): address R32 review minors (price wording, guards, volume …
sijie-Z Oct 24, 2026
81b238a
docs(tools): keep the R32 VWAP note self-contained
sijie-Z Oct 24, 2026
9ec2a61
docs(research): add turnover-only forward paper target for 2026-10-23
sijie-Z Oct 24, 2026
5b99bd5
docs(research): 2026 true holdout via production paper chain
sijie-Z Oct 24, 2026
60352f2
docs(research): pre-registered trend overlay null result
sijie-Z Oct 24, 2026
087ce71
docs: record R31-R33, 2026 holdout and forward paper setup
sijie-Z Oct 24, 2026
8b91531
docs(research): seed forward paper target directories for monthly rol…
sijie-Z Oct 24, 2026
5265ffa
docs(research): overnight summary - wide pool, true 2026 holdout, for…
sijie-Z Oct 24, 2026
c7806b8
docs(ops): forward paper runbook section
sijie-Z Oct 24, 2026
a92d999
docs(research): record final full-suite verification
sijie-Z Oct 24, 2026
2629481
docs: sync overnight summary with final remote head
sijie-Z Oct 24, 2026
e38f354
docs(research): clarify production sector-neutral factor convention i…
sijie-Z Oct 24, 2026
a1c3dc2
docs(research): self-contained external review package
sijie-Z Oct 25, 2026
c9eec3a
docs(research): metric audit, benchmark matrix, freeze manifest (exte…
sijie-Z Oct 25, 2026
2c4ae64
docs(research): historical data defect ledger
sijie-Z Oct 25, 2026
3a6166a
docs(research): cost stress results and frozen ETF rotation pilot
sijie-Z Oct 25, 2026
55aee08
docs(research): PIT valuation replication (R31b) closes defect #3
sijie-Z Oct 25, 2026
b9873d7
docs(research): PIT ST replication materially lowers the stock evidence
sijie-Z Oct 25, 2026
9247e60
docs(research): board-aware price-limit gates change nothing (R31c)
sijie-Z Oct 25, 2026
a7ac72d
fix(tools): exclude ST names from daily target books
sijie-Z Oct 25, 2026
05e155f
docs(research): keep superseded v1 targets outside the paper_track scan
sijie-Z Oct 25, 2026
2ccb5ad
docs(research): pre-register convertible bond double-low study
sijie-Z Oct 25, 2026
56215af
docs(research): second external review package; 2026 holdout ST corre…
sijie-Z Oct 25, 2026
49809dd
docs(research): convertible-bond double-low fails OOS and holdout; ab…
sijie-Z Oct 25, 2026
abf2a8a
fix(trading): harden live execution and forward paper integrity
sijie-Z Oct 26, 2026
0ffcf61
fix(tools): fail clearly when the current close is unavailable
sijie-Z Oct 26, 2026
09212c7
feat(tools): add indicative realtime forward-target monitor
sijie-Z Oct 26, 2026
d488c36
docs(research): record first real forward session on 2026-10-26
sijie-Z Oct 26, 2026
a94cb13
feat(tools): track the actual forward book in realtime
sijie-Z Oct 26, 2026
692a8d1
fix(tools): close forward freshness and catch-up gaps
sijie-Z Oct 26, 2026
722a48a
test(trading): add executable QMT safety drills and runbook
sijie-Z Oct 26, 2026
c8a2938
fix(tools): tolerate transient realtime quote failures
sijie-Z Oct 27, 2026
a793f0a
fix(tools): reject stale market-data responses and repair forward day…
sijie-Z Oct 27, 2026
6597bdd
fix(tools): harden the month-end forward path before the first live r…
sijie-Z Oct 28, 2026
99819c8
docs: add QMT onboarding checklist with user vs operator split
sijie-Z Oct 28, 2026
a86d0e5
feat(tools): add freeze guard for the forward paper experiment
sijie-Z Oct 28, 2026
477b266
feat(tools): widen freeze guard to the full compute path
sijie-Z Oct 28, 2026
5c6f7bb
data(forward): record 2026-10-28 official ledger, day three
sijie-Z Oct 28, 2026
1edd094
feat(tools): restore the causal valuation refresh for EP targets
sijie-Z Oct 28, 2026
6feaf6f
data(forward): record 2026-10-29 official ledger, day four
sijie-Z Oct 29, 2026
c291602
feat(tools): add personal holdings monitor with risk alerts
sijie-Z Oct 29, 2026
4eb234e
data(forward): first live month-end rebalance — November targets and …
sijie-Z Oct 30, 2026
2a6839b
data(forward): execute the November rebalance at the 2026-11-02 close
sijie-Z Nov 2, 2026
470cf86
docs(research): freeze the evaluation spec and its only report generator
sijie-Z Nov 3, 2026
99509f8
data(forward): record 2026-11-03, day seven
sijie-Z Nov 3, 2026
43f4f96
data(forward): record 2026-11-04, day eight
sijie-Z Nov 4, 2026
0586950
data(forward): record 2026-11-05, day nine
sijie-Z Nov 5, 2026
b1de9ba
data(forward): record 2026-11-06, day ten
sijie-Z Nov 6, 2026
90e1cb3
docs(freeze): adjudicate the weekly watch's two historical flags
sijie-Z Nov 6, 2026
630a355
data(forward): record 2026-11-09, day eleven
sijie-Z Nov 9, 2026
4eba2be
data(forward): record 2026-11-10, day twelve
sijie-Z Nov 10, 2026
83081ac
data(forward): record 2026-11-11, day thirteen
sijie-Z Nov 11, 2026
5897ccd
data(forward): record 2026-11-12, day fourteen
sijie-Z Nov 12, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
11 changes: 11 additions & 0 deletions .claude/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"version": "0.0.1",
"configurations": [
{
"name": "quant-web",
"runtimeExecutable": "python",
"runtimeArgs": ["app.py", "--host", "127.0.0.1", "--port", "8000"],
"port": 8000
}
]
}
37 changes: 36 additions & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,40 @@ DEEPSEEK_API_KEY=
# Application settings
LOG_LEVEL=INFO

# Optional bearer token required for /api routes when set
# Optional bearer token. When set, every /api route except /api/health
# requires it (Authorization: Bearer <token> or X-API-Key). Enter the same
# value in the UI's Settings page — it is kept in browser localStorage and is
# NOT baked into the frontend bundle.
# When unset, every /api route is loopback-only; remote access is refused.
# The shared token authenticates a consumer; it is NOT a tenant boundary.
# Tenant-scoped reads accept X-Tenant-Id / tenant_id and default to
# "default"; cross-tenant reads require all_tenants=true from loopback.
# WebSocket auth uses the `bearer.<token>` subprotocol; a token must be
# RFC 7230-safe (letters, digits, - . _ ~ and similar) because the legacy
# ?token= query transport was removed.
QUANT_API_TOKEN=

# Optional Host-header allowlist (comma separated): quant.example.com,
# *.corp.example.com. Unset = any syntactically valid host. Set this for
# proxy/ingress deployments; path-delimiter or malformed Hosts are always
# rejected before routing.
QUANT_ALLOWED_HOSTS=

# Optional cross-origin allowlist for browser requests (comma separated,
# exact origins, case-insensitive, no wildcards): https://quant.example.com,
# http://dev-box:8080. Every request carrying an Origin header must be
# same-origin with the request Host (scheme + host + port) or listed here;
# otherwise it is rejected before routing/auth (HTTP 403, WebSocket close
# 1008). Requests without Origin (curl, server-to-server) are unaffected.
# Set this when the UI is served from a different origin than the API, or
# behind a TLS-terminating proxy that makes the upstream scheme http.
# Local `npm run dev` (Vite on :5173) is cross-origin to the API; add
# http://localhost:5173,http://127.0.0.1:5173 for that flow.
QUANT_ALLOWED_ORIGINS=

# QMT trading password (env-only — never send a password in an API body).
QMT_PASSWORD=

# QMT terminal address (operator config; request bodies cannot set it).
QMT_SERVER=localhost:58610

17 changes: 9 additions & 8 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -74,14 +74,15 @@ jobs:
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
pip install -e ./packages/quant_core
pip install -e .

# The repo root *is* the quant_platform package; putting its parent on
# PYTHONPATH is what makes `import quant_platform` resolve. Depends on
# the checkout directory being named `quant_platform`.
- name: Make quant_platform importable
run: echo "PYTHONPATH=$GITHUB_WORKSPACE/.." >> "$GITHUB_ENV"
pip install -e ./packages/quant_core --no-deps
pip install -e . --no-deps

# The editable install now maps `quant_platform` to the repo root. No
# PYTHONPATH shim: that would reintroduce the second import identity
# (`data.x` vs `quant_platform.data.x`, issue #69).
- name: Verify a single package identity
run: |
python -c "import sys; import quant_platform.data.providers.synthetic as m; assert 'data' not in sys.modules, 'flat identity is back'; print(m.__name__)"

- name: Run tests
run: |
Expand Down
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ env/

# Cache
.quant_cache/
.quant_versions/
.sentiment_cache/
.pytest_cache/
.agent_cache/
Expand All @@ -33,6 +34,10 @@ results/*.png
results/*.pdf
results/

# SQLite runtime sidecars (WAL mode leaves these next to the database)
*.db-wal
*.db-shm

# Coverage
.coverage
htmlcov/
Expand Down Expand Up @@ -72,3 +77,5 @@ baostock_run_err.log

# Generated data
frontend/data/

.scratch/
14 changes: 14 additions & 0 deletions .quant_versions/index.json
Original file line number Diff line number Diff line change
Expand Up @@ -215,5 +215,19 @@
"description": "Run: alpha=equal_weight optimizer=mean_variance",
"run_id": "",
"config_hash": "faa9846f3834"
},
"v32": {
"id": "v32",
"timestamp": "2026-10-20T20:49:04",
"description": "Run: alpha=equal_weight optimizer=mean_variance",
"run_id": "d3aaa4ea7faf",
"config_hash": "87b729e5393d"
},
"v33": {
"id": "v33",
"timestamp": "2026-10-20T20:52:53",
"description": "Run: alpha=equal_weight optimizer=mean_variance",
"run_id": "435a9843eee2",
"config_hash": "87b729e5393d"
}
}
227 changes: 125 additions & 102 deletions AGENTS.md

Large diffs are not rendered by default.

69 changes: 39 additions & 30 deletions BEGINNER_GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ Sharpe = 年化收益率 / 年化波动率
```
原始数据 (价格/财务)
↓
计算 15 个因子 (每只股票每天 15 个特征)
计算默认 21 个因子 (16 技术 + 5 基本面;注册 27 个)
↓
因子处理 (缩尾去极值 → 标准化 → 行业中性化)
↓
Expand Down Expand Up @@ -201,7 +201,7 @@ ICIR 加权合成 (预测力强的因子权重大)
5. **ST 股票**:连续亏损被特殊处理的股票,很多机构不能买
6. **手数限制**:最少买 100 股(1 手)

这些在我们的项目中全部处理了。面试官问你"回测跟实盘有什么区别",你就可以一条条讲。
这些在我们的项目中大多已处理:涨跌停/停牌按执行日阻断成交(未成交顺延),ST 用公告日 PIT 掩码,T+1 与成本模型在回测/执行层生效;整手约束在执行层强制,向量化回测仍是权重层面(已明确标注)。面试官问你"回测跟实盘有什么区别",你就可以一条条讲。

---

Expand All @@ -222,7 +222,7 @@ ICIR 加权合成 (预测力强的因子权重大)
▼
┌──────────────────────────────────────────────────────────────┐
│ ① Data Layer ② Factor Engine ③ Alpha Model │
│ 数据获取+清洗 计算15个因子 因子合成→信号 │
│ 数据获取+清洗 计算21个因子 因子合成→信号 │
│ - Synthetic生成器 - 动量/波动/RSI... - 等权/IC/ICIR │
│ - Tushare实盘 - 缩尾/标准化/中性化 - 排名归一化 │
│ - 停牌/ST/复权 - IC评估 - 输出: signal │
Expand All @@ -248,7 +248,7 @@ ICIR 加权合成 (预测力强的因子权重大)

```
quant_platform/
├── main.py # CLI 入口(6个命令)
├── main.py # CLI 入口(21 个命令)
├── config/default.yaml # 所有参数
│
├── data/ # ① 数据层
Expand All @@ -257,7 +257,7 @@ quant_platform/
│ └── pipeline.py # 数据清洗流水线
│
├── factors/ # ② 因子引擎
│ ├── technical.py # 10个技术因子
│ ├── technical.py # 22个技术因子(默认启用16个)
│ ├── fundamental.py # 5个基本面因子
│ ├── processing.py # 因子处理(缩尾/标准化/中性化)
│ └── evaluation.py # 因子评估(IC/ICIR)
Expand Down Expand Up @@ -290,7 +290,7 @@ quant_platform/
├── notebooks/
│ └── research_workflow.ipynb # Jupyter 研究流程
│
└── tests/ # 1077 个测试
└── tests/ # 193 个测试文件 / 2,662 条用例
```

### 数字一览
Expand All @@ -300,11 +300,11 @@ quant_platform/
| 股票数 | 500 只(可调) |
| 历史数据 | 5 年 (2021-2025) |
| 交易日 | ~1300 天 |
| 因子数 | 15 个标准 + 1 个 LLM |
| 因子数 | 默认 21 个(16 技术 + 5 基本面;注册 27 个)+ 可选 LLM 因子 |
| 优化器 | 3 种 |
| 单元测试 | 1077 个 |
| CLI 命令 | 6 个 |
| 代码行数 | ~40,000 行 |
| 单元测试 | 2,662 条用例(2,450 个测试函数,2026-10-20 实测) |
| CLI 命令 | 21 个 |
| 代码行数 | 约 75,000 行非测试 Python + 约 11,000 行 Vue |

---

Expand All @@ -331,7 +331,7 @@ Step 2: 因子引擎
关键:因子处理流水线(缩尾→标准化→中性化),这是量化的标准操作

Step 3: Alpha 模型
问题:15 个因子怎么合成一个信号
问题:21 个因子怎么合成一个信号
方案:ICIR 加权——预测力强的因子权重高
关键:横截面排名归一化到 [-0.5, 0.5]

Expand All @@ -350,7 +350,7 @@ Step 6: 报告
方案:文本仪表盘 + 4 张图表 + CSV 导出

Step 7: 锦上添花
- Numba 加速(5个计算内核 5-20x 提速)
- Numba 加速(6个计算内核 5-20x 提速)
- LLM 情感因子(你的 RAG 经验直接能用!)
- Pipeline 缓存(不重复计算)
- 策略对比/参数搜索
Expand All @@ -362,7 +362,7 @@ Step 7: 锦上添花
A: 事件驱动适合高频,我们做月频多因子,向量化更简单更快。一个月就调一次仓,不需要模拟每一笔订单。

**Q: 为什么默认用合成数据?**
A: 不用联网、不用注册 API、可复现。面试官让你当场跑一下,Tushare 没 token 就尴尬了。合成数据现在内置了 alpha 结构(IC~0.04),演示效果真实。
A: 不用联网、不用注册 API、可复现。面试官让你当场跑一下,Tushare 没 token 就尴尬了。注意:默认配置开启了 `embedded_alpha`(强度 0.03,IC 约 0.02-0.03),这是演示用的人造信号;做任何策略结论前必须设为 `false`,否则测的是注入的 alpha,不是策略。

**Q: 为什么要做因子中性化?**
A: 不做中性化的话,你的"好股票"可能只是某个行业的股票——你不是在选股,是在选行业。
Expand All @@ -387,22 +387,22 @@ A: 不做中性化的话,你的"好股票"可能只是某个行业的股票—
```python
# 1. 过滤 ST 股票(连续亏损的风险股)
# 2. 过滤未上市/已退市股票(幸存者偏差!)
# 3. 处理停牌(短期停牌前向填充,长期停牌剔除)
# 3. 处理停牌(短期停牌前向填充;长期停牌保留缺失、不删除历史)
# 4. 复权价格计算(close_adj = close / adj_factor)
# 5. 日收益率计算(returns = close_adj.pct_change())
```

**TushareProvider(实盘数据)**:
```python
# 需要免费注册 tushare.pro 获取 token
# 拉到 CSI 300 成分股的前复权日频数据
# 拉到 CSI 300 成分股的后复权(hfq)日频数据
# 存到 HDF5 本地缓存,下次秒加载
# 没有 token 时自动回退到合成数据
# 配置的真实数据源不可用时默认 fail closed(不会静默回退合成数据)
```

### 7.2 因子引擎 (`factors/`)

**10 个技术因子**(从价格和成交量算出):
**技术因子(注册 22 个,`config/default.yaml` 默认启用 16 个)**(从价格和成交量算出):

| 因子名 | 含义 | 怎么算 |
|--------|------|--------|
Expand All @@ -414,9 +414,12 @@ A: 不做中性化的话,你的"好股票"可能只是某个行业的股票—
| volatility_60d | 60日波动 | 同上,更长窗口 |
| turnover_20d | 换手率 | 20日平均换手率 |
| rsi_14d | RSI | 相对强弱指数 (0-100) |
| macd | MACD | 指数平滑异同移动平均线 |
| macd | MACD | 指数平滑异同移动平均线(默认配置未启用) |
| amplitude_20d | 振幅 | 20日平均(高-低)/收盘价 |

另有 efficiency_ratio、breakout_ignition、trend_stage、ma_convergence、breakout_proximity、
pure_volatility、mtf_resonance 及 5 个 K 线形态因子(klen/klow/kmid/ksft/kup),按配置启用。

**5 个基本面因子**(从财务报表算出):

| 因子名 | 含义 |
Expand Down Expand Up @@ -448,7 +451,7 @@ A: 不做中性化的话,你的"好股票"可能只是某个行业的股票—

```python
# 1. 等权:所有因子平均
signal = (factor1 + factor2 + ... + factor15) / 15
signal = (factor1 + factor2 + ... + factor21) / 21

# 2. IC 加权:IC 高的因子权重高
weight_i = IC_i / sum(所有IC)
Expand All @@ -457,7 +460,7 @@ signal = weight_1 * f1 + weight_2 * f2 + ...
# 3. ICIR 加权:IC 稳定(ICIR 高)的因子权重高
weight_i = ICIR_i / sum(所有ICIR)
signal = weight_1 * f1 + weight_2 * f2 + ...
# (这是默认方法,因为稳定性也很重要)
# (默认配置是 equal_weight;IC/ICIR 加权可按 alpha.method 启用)
```

最后做横截面排名归一化到 [-0.5, 0.5]:在所有股票中排名,排名最高的给 0.5,最低的给 -0.5。
Expand Down Expand Up @@ -531,7 +534,7 @@ LLMSentimentFactor (继承 BaseFactor)
│
├── SentimentAnalyzer (Strategy 模式,可切换)
│ ├── KeywordAnalyzer (默认,零成本,关键词打分)
│ └── OpenAIAnalyzer (真实 API,GPT-4o-mini)
│ └── OpenAIAnalyzer (真实 API,DeepSeek deepseek-chat,OpenAI 兼容 SDK)
│
├── 30 条中文财经标题模板
│ ├── 看涨:净利润同比增长50%、获得大额订单...
Expand All @@ -545,7 +548,7 @@ LLMSentimentFactor (继承 BaseFactor)
1. 每只股票每天随机生成 0-2 条财经标题(模拟新闻流)
2. 用情感分析器给每条标题打分(-1 = 极度看空,+1 = 极度看多)
3. 取平均作为当天该股票的情感因子值
4. 这个因子跟其他 15 个因子一起进入 alpha 模型
4. 这个因子跟其他因子一起进入 alpha 模型

**你怎么扩展**:
- 接入真实的新闻 API(东财、同花顺)
Expand All @@ -565,12 +568,13 @@ LLMSentimentFactor (继承 BaseFactor)
# 加速比: ~17x
```

5 个被加速的计算内核:
6 个被加速的计算内核:
1. 滚动累计收益(动量因子核心)
2. 最大回撤计算
3. 横截面缩尾
4. Spearman Rank IC
5. Ledoit-Wolf 协方差收缩
6. Z-Score 标准化

每个都有 Pandas + Numba 双实现,Numba 不可用时自动回退。

Expand All @@ -582,7 +586,11 @@ LLMSentimentFactor (继承 BaseFactor)

```bash
cd quant_platform
python -m venv .venv
.venv\Scripts\activate # Git Bash: source .venv/Scripts/activate
pip install -r requirements.txt
pip install -e ./packages/quant_core # core/store.py 依赖它
pip install -e . # 安装 quant_platform 包
```

### 最快体验(30 秒)
Expand All @@ -594,7 +602,7 @@ python main.py run --force

你会看到:
1. 生成 500 只股票的 5 年数据
2. 计算 15 个因子并评估 IC
2. 计算默认 21 个因子并评估 IC
3. 合成 alpha 信号
4. 优化持仓权重
5. 回测并输出报告
Expand Down Expand Up @@ -642,6 +650,7 @@ python main.py cache list
### Jupyter Notebook

```bash
# 可选:需要先安装 jupyter(pip install jupyter)
jupyter notebook notebooks/research_workflow.ipynb
```

Expand All @@ -653,21 +662,21 @@ jupyter notebook notebooks/research_workflow.ipynb

### 自我介绍模板(30 秒)

> "我做了一个 A 股多因子量化研究平台。端到端流水线从数据到回测,500 只股票 5 年数据,15 个因子,3 种优化器。1077 个单元测试。特色是 Numba JIT 加速、LLM 情感因子集成、10 个 A 股实盘陷阱全处理。还写了策略对比和参数搜索的 CLI 工具。"
> "我做了一个 A 股多因子量化研究平台。端到端流水线从数据到回测,500 只股票 5 年数据,默认 21 个因子(注册 27 个),3 种优化器。2,662 条测试用例。特色是 Numba JIT 加速、LLM 情感因子集成、10 个 A 股实盘陷阱全部处理或明确标注。还写了策略对比和参数搜索的 CLI 工具。"

### 可能会被问到的问题

**Q: 你的回测跟实盘有什么区别?**
> "我处理了 10 个 A 股特有的实盘陷阱:前复权、停牌、幸存者偏差、涨跌停、ST 过滤、T+1、佣金印花税、手数限制、除权除息、行业漂移。没有做的是高频 order-book 级别的流动性建模,但对月频多因子策略这不是瓶颈。"
> "我处理了 10 个 A 股特有的实盘陷阱:后复权、停牌、幸存者偏差、涨跌停、ST 过滤、T+1、佣金印花税、手数限制、除权除息、行业漂移。涨跌停/停牌按执行日阻断成交,整手在执行层强制、向量化回测仍是权重层面。没有做的是高频 order-book 级别的流动性建模,但对月频多因子策略这不是瓶颈。"

**Q: IC 是什么意思?为什么重要?**
> "Information Coefficient,因子值跟未来收益的秩相关系数。IC > 0.03 说明因子有预测力。为什么用 Rank IC 而不是 Pearson IC?因为 Rank IC 对异常值不敏感,更稳健。"

**Q: 你怎么防止过拟合?**
> "1) 因子只有 15 个,没有做因子挖掘(没有挖几万个因子然后挑显著的);2) 因子经济逻辑清晰——动量、价值、波动率都有学术支撑;3) ICIR 加权——不仅看 IC 大小还看稳定性;4) 横截面中性化防止了行业和市值的虚假相关。"
> "1) 因子只有 21 个(注册 27 个),没有做因子挖掘(没有挖几万个因子然后挑显著的);2) 因子经济逻辑清晰——动量、价值、波动率都有学术支撑;3) 默认等权合成,IC/ICIR 加权可选——不仅看 IC 大小还看稳定性;4) 横截面中性化防止了行业和市值的虚假相关。"

**Q: 你怎么做 LLM 集成的?**
> "写了一个 LLMSentimentFactor,继承 BaseFactor。用 Strategy 模式隔离了分析器:默认用关键词打分(零成本),可以切换到 OpenAI API。有 JSON 缓存避免重复调用。这个因子跟传统 15 个因子一起进入 alpha 流水线。"
> "写了一个 LLMSentimentFactor,继承 BaseFactor。用 Strategy 模式隔离了分析器:默认用关键词打分(零成本),可以切换到 DeepSeek(OpenAI 兼容接口,需 DEEPSEEK_API_KEY)。有 JSON 缓存避免重复调用。这个因子跟传统 21 个因子一起进入 alpha 流水线(默认因子集不包含它,需显式启用)。"
>
> (这是你的强项,可以展开聊 RAG pipeline 怎么改造)

Expand All @@ -678,7 +687,7 @@ jupyter notebook notebooks/research_workflow.ipynb

如果面试官发现你的策略 Sharpe 不高或回测有问题:

> "合成数据的 IC 在 0.04 左右,这是真实可信的水平。实盘 A 股多因子策略的 Sharpe 一般在 1-2 之间。超过 3 要么是天才要么有过拟合。MVO 优化器在股票数多的时候会用等权回退——这是工程上的诚实处理,不是把崩溃藏起来。"
> "合成数据的 IC 在 0.02-0.03 左右(alpha_strength=0.03),这是接近真实 A 股的信噪比水平;演示配置会注入 embedded_alpha,做结论前必须关掉。实盘 A 股多因子策略的 Sharpe 一般在 1-2 之间。超过 3 要么是天才要么有过拟合。MVO 现在优先用已安装的 CLARABEL 求解并把持仓纳入候选集,默认回测 0 次回退;如果求解失败会显式记录回退原因,而不是静默等权。"

---

Expand All @@ -689,7 +698,7 @@ jupyter notebook notebooks/research_workflow.ipynb
| Agent/RAG 技能 | 量化对应 |
|---------------|---------|
| Python 数据处理 | pandas 操作股价数据 |
| API 调用 | Tushare / OpenAI API |
| API 调用 | Tushare / DeepSeek API |
| 检索管道 | 因子计算流水线 |
| 结果排序 | Alpha 信号排名 |
| 评估指标 | IC / Sharpe / 回撤 |
Expand Down
Loading
Loading