Skip to content

feat(factors): add academic_corr_rewire — correlation-rewiring stability score#705

Merged
warren618 merged 2 commits into
HKUDS:mainfrom
ebujinovch:factor/corr-rewire
Jul 18, 2026
Merged

feat(factors): add academic_corr_rewire — correlation-rewiring stability score#705
warren618 merged 2 commits into
HKUDS:mainfrom
ebujinovch:factor/corr-rewire

Conversation

@ebujinovch

Copy link
Copy Markdown
Contributor

feat(factors): add academic_corr_rewire — correlation-rewiring stability score

Not a trade-timing or return-prediction signal. This is the risk-context
measurement from the correlation-regime skill (#557), Mode 4, as a zoo
factor: at each bar, how much each asset's correlation row to the rest of the
market changed — trailing 20-bar event window vs the 120 bars immediately
before it (both trailing → causal by construction), row mean of |Δρ|,
z-scored negative so correlation-stable names rank highest.

Why submit it: right now the skill's math can only be read. As a factor
it becomes something anyone can run, bench, and try to falsify — with
causality machine-checked by the look-ahead sentinel in CI, not asserted in
prose. That, not alpha, is the contribution.

Bench up front (sp500, 2020–2025, next-bar IC): ≈ zero. IC −0.001,
IR −0.009 → "dead" — as are all 12 factors in the academic zoo on this
panel (best: carhart_mom, IR +0.08, also dead). Consistent with the no-alpha
framing above; I did not flip the sign or retune after seeing it. Full table
in the fold below.

Review (4 files, +308/−7): only corr_rewire.py needs real eyes —
_window_corr (NaN handling) and the two-window slice in _rewiring_scores
(causality; a worked index example is commented at the slice).
test_corr_rewire.py pins the semantics as assertions (a decoupling asset
must rank last; low-coverage columns go NaN without poisoning peers;
column-order invariance; warmup honesty) — review the assertions, not the
arithmetic. LICENSE.md + agent/SKILL.md edits are mechanical (source
attribution; counts 461→462, academic 11→12).

Verify locally (~90 s, no network or keys) + gates run
pytest agent/tests/factors/ agent/tests/test_distribution_skill_manifest.py \
       agent/tests/test_skills.py -q          # 1073 passed, 5 skipped
black --check agent/src/factors/zoo/academic/corr_rewire.py \
              agent/tests/factors/test_corr_rewire.py
ruff check agent/src/factors/zoo/academic/corr_rewire.py \
           agent/tests/factors/test_corr_rewire.py

Includes the AST purity gate and 300-row look-ahead sentinel, both
parametrized over the new factor. Perf: 500 cols × 1250 rows with 2% NaN
holes → compute() in ~6 s. Checklist: DCO ✓ · type-annotated ✓ · Google
docstrings ✓ · <400 lines/file ✓ · purity allowlist (numpy/pandas only) ✓ ·
zoo header block ✓.

Reproducing the bench is optional and slower (first run fetches the panel,
~7 min; cached after):
vibe-trading alpha bench --zoo academic --universe sp500 --period 2020-2025

Full bench table (all 12 academic factors, same panel)

Sorted by |IR|; 503 current constituents:

id ic_mean ic_std pos ratio IR category
academic_carhart_mom +0.0190 0.239 0.56 +0.080 dead
academic_hml −0.0162 0.239 0.45 −0.068 dead
academic_bab −0.0089 0.330 0.49 −0.027 dead
academic_mkt_rf −0.0057 0.215 0.51 −0.027 dead
academic_strev +0.0057 0.215 0.49 +0.027 dead
academic_rmw −0.0062 0.284 0.48 −0.022 dead
academic_cma +0.0017 0.082 0.53 +0.021 dead
academic_high52w +0.0039 0.243 0.54 +0.016 dead
academic_illiq +0.0015 0.139 0.49 +0.011 dead
academic_corr_rewire −0.0010 0.115 0.51 −0.009 dead
academic_smb +0.0008 0.126 0.49 +0.006 dead
academic_retskew −0.0003 0.112 0.50 −0.002 dead

(Runner's own caveat applies zoo-wide: the sp500 universe is current
Wikipedia constituents, so all IC stats here are survivorship-biased
upward equally.)

Placement & roadmap context (not a commitment request)

Placed in academic/ following the bab.py precedent (single-file,
price-only, __alpha_meta__-documented). It is a house-methodology factor
rather than a paper proxy — the LICENSE.md entry says exactly that. Happy to
move it elsewhere.

Larger arc, for transparency: the natural end state of this thread is a
regime timeline on the Correlation tab (density series + fused/defused
shading — the tab is currently a static snapshot). That's real
backend+frontend work, so if there's appetite I'd open a proposal issue
first per the normal process. This factor stands entirely on its own;
merging it commits no one to anything further
— and "skip the factor,
discuss the timeline" (or neither) is a perfectly good outcome of this PR.

Risk note (per AGENT_CONTRIBUTOR_GUIDE): docs + one pure-function factor
file + its tests; no runtime, broker, credential, or network surface
touched. Authored with AI assistance; every claim above was verified by
running the listed gates and benches locally. If the zoo's bar for novel
factors is "alive", say so and I'll adjust or drop without fuss.

…ty score)

Signed-off-by: ebujinovch <ch.ebujinov@gmail.com>

# Conflicts:
#	agent/SKILL.md
… 2.x

pct_change() without fill_method forward-fills gaps on pandas 2.x (the CI
pin), silently defeating the coverage guard that test_corr_rewire's
low-coverage case asserts. Explicit fill_method=None matches the bench
runner's own forward-return convention and behaves identically on pandas 3.

Signed-off-by: ebujinovch <ch.ebujinov@gmail.com>
@ebujinovch

Copy link
Copy Markdown
Contributor Author

CI caught a real environment difference — the low-coverage semantic test failed because pct_change() forward-fills gaps under the repo's pandas 2.x pin (my local env runs pandas 3, where it doesn't), which silently defeats the coverage guard. Fixed in 56b7c1b with an explicit fill_method=None, matching the bench runner's own forward-return convention (alpha_bench_tool.py). Re-verified under both pandas 2.3.3 and 3.0.3; bench numbers in the description are unaffected (they were computed under no-fill semantics).

@warren618
warren618 merged commit b3d8306 into HKUDS:main Jul 18, 2026
1 check passed
@warren618

Copy link
Copy Markdown
Collaborator

Merged to main — thanks @ebujinovch. academic_corr_rewire is a nice addition to the academic zoo; tests pass locally. 🙏

@ebujinovch

Copy link
Copy Markdown
Contributor Author

Thanks for the review and merge, @warren618! 🙏 If anything comes up with the factor downstream, ping me — happy to maintain it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants