feat(factors): P3-1 multi-factor pipeline + first real price+financial baseline - #9
Merged
Merged
Conversation
…l baseline
The pipeline previously consumed only the FIRST enabled factor. P3-1 makes it
consume every enabled factor and adds the first real multi-factor baseline
(momentum_20 + roe + netprofit_yoy on SSE50), still combined by the
equal-weight alpha. No parameter search, no learned weights, not a
performance claim.
Pipeline:
- _build_factors instantiates EVERY enabled factor (config order; duplicate
names are a readable config error). Single-factor configs unchanged.
- _maybe_enrich_financials batches ALL financial fields into ONE
fina_indicator fetch + ONE asof_financials pass (each field independently
honours ann_date <= trade_date). Demo + financial factor still raises a
readable error (no fabricated financials).
- _compute_factor_panel writes one column per factor; processing
(drop_missing / neutralize / zscore) is already per-column. drop_missing
requires ALL enabled factors per name/date (disclosed).
- _factor_analytics now returns per-factor {ic, ic_ir, quantiles, coverage}
plus combo-score analytics (forward returns computed once). Top-level
metrics stay the PRIMARY (first-enabled) factor's -- byte-identical for
single-factor configs; the std (alphalens) cross-check stays on the primary
raw factor.
Baseline + report:
- config/phase3_real_multifactor.yaml (SSE50, 2023-07~2024-06, same window as
phase2 for comparability); output.baseline_report_name keeps the phase3
report file separate from the phase2 one.
- Report gains: active factor list, per-factor coverage/IC/quantile tables,
combo-score diagnostics, and per-field ann_date coverage labelled TRADED
factor vs diagnostic-only.
Real runs (not in CI):
- Phase2 single-factor regression rerun: annual -10.19% / IC 0.0083 / PIT
SW-L1 98.53% -- unchanged (no regression).
- Phase3 multi-factor: annual -9.05%, per-factor IC momentum_20 0.0083
(identical across runs) / roe 0.0006 / netprofit_yoy 0.0001, combo -0.0038,
financial ann_date coverage 100% on both fields. Financial ICs ~0 on this
small cross-section / short window -- disclosed as plumbing validation.
Tests: 249 passed (was 234): +10 multifactor pipeline, +1 multi-field as-of,
+4 baseline report surface. Demo numbers unchanged (ic 0.96 / annual 0.84).
StackOverFlow11
added a commit
that referenced
this pull request
Jun 10, 2026
docs: mark PR #9 (P3-1) merged in progress docs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
P3-1 — first REAL multi-factor baseline (price + PIT financials). The pipeline previously consumed only the FIRST enabled factor; this PR makes it consume every enabled factor and adds the first real multi-factor baseline:
momentum_20+roe+netprofit_yoyon SSE50, still combined by the same equal-weight alpha. No parameter search, no learned weights, not a performance claim — this validates the multi-factor plumbing against real data.What changed
_build_factors(was_build_factor): instantiates every enabled factor in config order; duplicate factor names are a readable config error. Single-factor configs are byte-stable (primary = the only factor)._maybe_enrich_financialscollects ALL financial-factor fields and does onefina_indicatorfetch + oneasof_financialspass — each field independently honoursann_date <= trade_date; no per-factor refetch. Demo + financial factor still raises a readable error (no fabricated financials).drop_missingrequires all enabled factors per name/date — disclosed in DOWNGRADES, never scored on partial data._factor_analyticsnow returns per-factor{ic_mean, ic_ir, quantile_returns, coverage}plus combo-score analytics (forward returns computed once). Top-level metrics remain the PRIMARY (first-enabled) factor's → identical for all existing configs. The alphalens cross-check stays on the primary raw factor (report-only, P2-4 contract intact).TRADED financial factorvsdiagnostic only.output.baseline_report_namekeeps the phase3 report file separate from phase2's.config/phase3_real_multifactor.yaml(SSE50, 2023-07 ~ 2024-06 — same window as phase2 for comparability; neutralize PIT SW-L1; top_n 20). Runs via the sharedrun-phase2-baselinereal-baseline runner.Real-data results (manual, not in CI)
Regression — phase2 single-factor rerun (13.6 min): UNCHANGED
annual −10.19% · IC 0.0083 · PIT SW-L1 coverage 98.53% — identical to the P2-3 baseline. Demo also unchanged (ic 0.96 / annual 0.84).
Phase3 multi-factor (14.3 min):
momentum_20roenetprofit_yoymomentum_20IC identical across the two runs (0.0083) — cross-run consistency evidence for the per-factor pathQuality gates
pytest -p no:cacheproviderruff check .validate-config×4 (demo / example_tushare / phase2 / phase3)run-phase0demorun-phase2-baseline(phase2 config)run-phase2-baseline(phase3 config)Tests (network-free)
test_multifactor_pipeline.py(10): factor list build (order / disabled / duplicate / none), single-fetch batched financials + as-of correctness + input immutability, demo+financial readable error, e2e demo multi-factor panel + per-factor/combo analytics + primary==first, report factor list + combo + no-secret, single-factor legacy shape.test_pit_financials.py(+1): multiple fields as-of aligned in one call.test_phase2_baseline.py(+4): active-factor list, per-field role labels, per-factor table, configurable baseline report name.Docs
RUNBOOK (Phase 3-1 section), TEST_REPORT (counts + P3-1 notes), BIAS_AUDIT (multi-factor ann_date / combination disclosure, regenerated from renderer), CLAUDE.md / AGENTS.md progress.