Commit Graph

38 Commits

Author SHA1 Message Date
Yuxuan Yan 39a93259e1 Add JoinQuant browser backtest automation 2026-07-04 18:08:31 +08:00
Yuxuan Yan 5388359dc8 Automate local JoinQuant smoke prep 2026-07-04 17:55:19 +08:00
Yuxuan Yan c200508f9e Align JoinQuant targets to execution dates 2026-07-04 17:50:55 +08:00
Yuxuan Yan f25db279bf Add JoinQuant comparison plugin 2026-07-04 17:43:09 +08:00
Yuxuan Yan 528620b271 Raise coverage threshold to 95% and expand test coverage
- pyproject.toml: fail_under 80 → 95
- test_alpha: +79 lines
- test_cli_workflow: +226 lines
- test_derived: +121 lines
- test_downloader_contracts: +169 lines
- test_features: +16 lines
- test_minute_downloader: +81 lines
- test_portfolio: +208 lines
2026-06-16 21:10:30 +08:00
Yuxuan Yan b5c8c0b8da Improve offline coverage for data boundaries 2026-06-16 17:42:20 +08:00
Yuxuan Yan 31baa18ce5 Add offline workflow and coverage tests 2026-06-16 17:37:16 +08:00
Yuxuan Yan 8d908477e2 Add daily derived data pipeline 2026-06-16 15:55:30 +08:00
Yuxuan Yan 83a006bbe4 Add minute bar feature pipeline 2026-06-16 13:57:17 +08:00
Yuxuan Yan 17fa75495d Restore reversal tutorial wording 2026-06-12 22:58:22 +08:00
Yuxuan Yan 3c58a1372e Use next-open returns for research eval 2026-06-12 18:41:18 +08:00
Yuxuan Yan 16b4988f16 Rewrite reversal report as tutorial 2026-06-12 17:12:29 +08:00
Yuxuan Yan 2c0ca53bd6 Document cost bps as one-way per-trade, not round-trip
The simulator charges (cost_bps + slippage_bps) on each fill, so a full
round trip is charged twice. Correct the cost-model doc, the reversal_5d
report, and the report generator to state the rate is one-way per-trade
(~20 bps round trip for 5+5), rather than mislabeling it round-trip.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-11 21:46:41 +08:00
Yuxuan Yan 2ceac82325 Add pipeline invariant checks for look-ahead, execution, PnL, and lot rules
Ten network-free correctness tests mapping 1:1 to the review checks:
reversal look-ahead, next-open execution date, PnL decomposition,
realized-not-target threading, blocked-trade zero cost, causal universe
mask, one-way cost bps, raw-price accounting, adjustment-invariant alpha,
and lot-lattice repair.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-11 21:46:29 +08:00
Yuxuan Yan b7dd94b032 Add 5-day reversal end-to-end pipeline report and repro scripts
Runs the 5-day reversal signal through data→alpha→combo→portfolio on the
full A-share universe and documents the finding: the naive z-score book
loses to outlier concentration, rank weighting on a liquid universe
recovers a real edge, and turnover-driven cost is the binding constraint.
Includes the e2e driver and figure generator that produce the report.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-11 17:40:52 +08:00
Yuxuan Yan 07ed6ad917 Add outlier-robust reversal_rank alpha and investable-universe filter
reversal_rank weights the 5-day reversal signal by bounded cross-sectional
rank instead of z-score, so a few extreme A-share pct_change outliers
(newly listed / post-suspension / limit-up names) can no longer dominate
the book. compute_alpha gains an optional per-date investable-universe
mask (tradable, non-ST, seasoned, top-liquidity) applied to the signal
before weighting, exposed via --liquid-universe/--universe-top-n.

combo combine now accepts a single alpha as an identity passthrough so a
one-alpha pipeline run needs no synthetic second input.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-11 17:40:28 +08:00
Yuxuan Yan 0a6f367fbf Evaluate weights against next-period returns to avoid look-ahead
Weights formed from close[t] now earn the t→t+1 return: forward returns
are computed on the full market calendar before selecting signal dates,
so a sparse signal grid earns the next available return rather than the
next signal date, and the final signal date (no forward return) is
dropped. Signal pct_change uses fill_method=None so suspended names do
not inherit stale prices.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-11 17:39:55 +08:00
Yuxuan Yan 534b91aaa4 Document and abstract portfolio trading costs 2026-06-10 15:41:38 +08:00
Yuxuan Yan 4a477b8f75 Make Backtrader an optional extra 2026-06-10 15:13:11 +08:00
Yuxuan Yan 459336b6cc Document implemented portfolio workflow 2026-06-10 15:04:34 +08:00
Yuxuan Yan 98a4f99300 Fix portfolio construction NaN handling 2026-06-10 14:58:06 +08:00
Yuxuan Yan 94ab679a75 feat: add portfolio phase — discretize alpha weights into tradable positions
Adds a fourth pipeline phase modeling A-share microstructure: lot sizes,
the 2023-08-10 Main Board increment change, STAR 200-share minimum/odd-lot
rules, limit-up/down, suspensions, volume caps, costs, and slippage.

Two layers: research (continuous weights → return/Sharpe/turnover/Fitness,
no IC per repo convention) and execution (state-dependent lot rounding +
two-stage greedy exposure repair + next-open reference simulator).

Wires `portfolio build/simulate/eval` into the CLI and adds the
POSITION/FILL/PNL schema contracts. Covered by tests/test_portfolio.py.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-10 11:23:04 +08:00
Yuxuan Yan 7faeb77c50 chore: manage env with uv (pyproject + lockfile)
Migrate dependency management from requirements.txt to uv. Runtime deps
move to pyproject.toml with pytest in the dev group; uv.lock pins the
resolved set. Docs updated to use `uv sync` / `uv run`.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-09 16:20:08 +08:00
Yuxuan Yan 0c524c6987 feat: add alphaview tool to show alpha weights alongside bar data
Joins the bar dataset with one or more alpha parquet files on (symbol, date)
for a given symbol and date range. Standalone tools/alphaview.py wired as
`cli.py alphaview`, plus README docs.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-09 15:45:06 +08:00
Yuxuan Yan f4b7ef3ae6 feat: add pqcat helper to inspect parquet files
A standalone tools/pqcat.py (head/tail/columns/info) wired as `cli.py pqcat`
and runnable directly via a PATH symlink, plus README docs.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-09 15:33:55 +08:00
Yuxuan Yan de43444ad4 feat: enrich daily bar schema with valuation/status fields + VWAP
Batch download now pulls baostock's preclose, turn, pctChg, tradestatus,
isST, and peTTM/pbMRQ/psTTM/pcfNcfTTM on top of OHLCV+amount, plus a
derived daily VWAP (amount/volume). VWAP is raw-price scale and not
comparable with adjusted OHLC under qfq/hfq — documented in the schema.

Richer fields live only in the batch path (download_daily_batch ->
download_universe); single-symbol download_daily keeps the legacy
8-column schema that test_downloader.py pins. Also flags intraday/L1-L2
microstructure data as a future phase in the README roadmap.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-09 14:25:38 +08:00
Yuxuan Yan 419114b87b fix: keep baostock session alive across bulk downloads
baostock drops a session after a few hundred queries; every later query
then returned 用户未登录 and the symbol failed. download_daily_batch now
refreshes the session every relogin_every symbols and re-logs in + retries
once on a detected session loss. akshare fallback now defaults off in the
batch path since it is slow/unreliable on this network and the re-login
keeps baostock as the fast primary.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-09 14:10:51 +08:00
Yuxuan Yan 1caa63faeb refactor: class-based alpha factory + month-partitioned data pipeline
Replace the old signal/strategy/backtest modules with a decoupled
data → alpha → combo pipeline (parquet between phases, .pq extension).

Alphas:
- BaseAlpha + @register_alpha factory/plugin registry; one file per
  built-in (reversal, reversal_vol, momentum); external alphas via
  --alpha-module. Alphas are z-scored position weights, not predictors.

Data:
- baostock primary / akshare fallback, treated consistently.
- New --universe all (~5000 A-shares via query_all_stock, filtered).
- login-once batch downloader; empty-string OHLCV coerced to NaN.
- Month-partitioned dataset {output_dir}/{universe}/month=YYYY-MM/*.pq
  with chunked durability flushes; --data-path is the dataset dir.

CLI logs at INFO by default (--log-level) so progress is visible.
Docs (README, CLAUDE.md) updated incl. pipeline diagram and roadmap
TODOs for portfolio construction / backtest / paper trading.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-09 14:07:07 +08:00
Yuxuan Yan 769cf25daa feat: dump alpha values + daily PnL as parquet (pyarrow) 2026-06-07 10:48:20 +08:00
Yuxuan Yan 7033da131b change: rank allocator top_n=5 -> top_pct=0.2 (20% of universe) 2026-06-07 10:06:49 +08:00
Yuxuan Yan edcc4e4b73 results: CSI500 reversal + reversal_vol multi-horizon IC 2026-06-07 10:04:14 +08:00
Yuxuan Yan 241683cc54 feat: CSI500 universe + reversal_vol signal + argparse CLI 2026-06-07 10:01:41 +08:00
Yuxuan Yan aedc019d23 fix: IC chart cumulative mean + forward return horizon matching + multi-horizon eval
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-07 09:54:31 +08:00
Yuxuan Yan bd0605072f fix: rank-based allocator + momentum signal (reversal->momentum flip) 2026-06-07 09:50:08 +08:00
Yuxuan Yan da01312292 feat: signal abstraction layer + sizer + HS300 universe + PnL/IC reports 2026-06-07 09:44:33 +08:00
Yuxuan Yan 085e51abf1 feat: add 5-day reversal strategy
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-07 09:26:35 +08:00
Yuxuan Yan fd86190e9a feat: phase 1 — data downloader, backtrader runner, SMA strategy
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-07 09:21:16 +08:00
Yuxuan Yan 338c912029 init: chinese equity quant research framework 2026-06-07 09:14:50 +08:00