Skip to content

feat: integrate alphalens factor analysis - #12

Merged
cloudQuant merged 66 commits into
masterfrom
dev
Aug 15, 2026
Merged

feat: integrate alphalens factor analysis#12
cloudQuant merged 66 commits into
masterfrom
dev

Conversation

@cloudQuant

Copy link
Copy Markdown
Owner

Fincore Alphalens Integration

Implements the full iteration plan
docs/plans/2026-08-13-fincore-alphalens-integration.md:
a traceable, testable, independently installable integration of the local
Alphalens factor-research capability into fincore, with every pinned upstream
test scenario rewritten as a strongly-asserted fincore compatibility test.

59 commits, 104 files changed, ~40.7k insertions. All 12 tasks (1, 1.5, 2–11, 12)
complete and accepted.

Frozen source identity

  • Profile: cloudquant-local-3fa17ad
  • Alphalens checkout pinned at commit 3fa17ad4c3edb025d1410de7aeba9673cba7791c
    (the reported v0.4.0 / 1.0.0+dev strings are recorded as conflicting
    evidence; the full commit is the identity)
  • 64 frozen definitions: 61 functions + 3 classes across performance,
    utils, plotting, tears
  • Fixtures: tests/compat/fixtures/alphalens-0.4.0-cloudquant-*.json;
    docs: docs/compatibility/alphalens-0.4.0-cloudquant.md

Architecture

  • fincore.alphalens — lightweight strict façade preserving the legacy module
    paths, signatures, call grammar (incl. hidden set_context and the dual
    quantize_factor signature), exceptions, stdout/plt.show() projections.
  • fincore.factor_analysis — canonical enhanced domain: data preparation,
    calendar, performance kernels, compute-once FactorAnalysisModel,
    lazy Matplotlib renderer, 7 tear-sheet workflows, prepare_factor_data(),
    analyze_factor().
  • PyfolioFactorInputs / create_pyfolio_input — bridges factor output into
    the existing real fincore.pyfolio workflow. No external
    empyrical/pyfolio/alphalens runtime dependency; the one upstream
    ep.cum_returns call is re-routed to the fincore internal kernel.
  • Import budget enforced: import fincore, import fincore.alphalens load no
    statsmodels/Matplotlib/Seaborn/IPython; no matplotlib.use(); no writes to
    package/source/site-packages.
  • New extras: fincore[factor-analysis] (compute incl. alpha/beta regression),
    fincore[alphalens] (rendering stack); all is the exact normalized union.

Compatibility levels (C0–C4)

LevelResult
C064/64 frozen definitions resolve
C1all freezable callables/constructors: introspection signature + accepted-call grammar
C2/C3utils (forward returns/cleaning/quantization) and performance (IC/weights/returns/turnover/events/alpha-beta) kernels with pd.testing/numpy.testing assertions
Plotting21/21 APIs with structural/data assertions (no smoke-only)
C47/7 tear sheets run the real compute → model → render → sheet chain; bridge runs the real fincore Pyfolio workflow

Pinned upstream test migration

  • Inventory generated by static AST from the pinned Git blobs (never imports the
    sibling package): 117 active declared rows (116 diagnostic-collectible + 1
    source-shadowed) + 24 dormant tear rows expanding to 96 internal invocations.
  • All 141 source rows and 96 invocation IDs map 1:1 to strongly-asserted
    fincore targets (rewritten_strict / rewritten_invariant / rebuilt_c4);
    no skip, xfail, smoke_only, raw_copy, bare .equals(), or sibling
    test import.
  • Audited by scripts/check_alphalens_upstream_test_migration.py --scope all
    with controlled collection proof + non-xdist result JSON
    (--alphalens-upstream-result-json), HEAD-bound.

Test plan

Executed at HEAD 2bf6d00 (Darwin/arm64, Anaconda base: Python 3.11.8,
NumPy 1.26.4, pandas 3.0.3, SciPy 1.17.1, Matplotlib 3.10.9, statsmodels 0.14.6):

# strict/enhanced/bridge gates
MPLBACKEND=Agg conda run -n base python -m pytest -o addopts='' \
tests/compat/test_alphalens_upstream_test_migration.py \
tests/compat/alphalens tests/test_factor_analysis -q --tb=short --maxfail=0 \
--alphalens-upstream-result-json build/alphalens-upstream-migration-results.json
# -> 993 passed, 122 warnings
MPLBACKEND=Agg conda run -n base python -m pytest -o addopts='' \
tests/compat tests/test_empyrical tests/test_pyfolio \
tests/test_metrics tests/test_tearsheets -q --tb=short --maxfail=0
# -> 2709 passed, 1 skipped# upstream migration audit (inventory rebuilt from pinned blobs, then scope=all)
conda run -n base python scripts/generate_alphalens_upstream_test_inventory.py \
--source <alphalens checkout> --commit 3fa17ad4c3edb025d1410de7aeba9673cba7791c \
--check tests/compat/fixtures/alphalens-0.4.0-cloudquant-upstream-test-inventory.json
# -> inventory check OK
conda run -n base python scripts/check_alphalens_upstream_test_migration.py \
--inventory <inventory.json> --migration <migration.json> --scope all \
--write-collection-proof build/alphalens-all-upstream-collection.json
conda run -n base python scripts/check_alphalens_upstream_test_migration.py \
--inventory <inventory.json> --migration <migration.json> \
--collection-proof build/alphalens-all-upstream-collection.json \
--results build/alphalens-upstream-migration-results.json --scope all
# -> executed migration audit OK: scope=all targets=213# static gates
conda run -n base python -m ruff check fincore tests scripts examples benchmarks # all pass
conda run -n base python -m ruff format --check fincore tests scripts examples benchmarks # 554 formatted
conda run -n base python -m mypy fincore --ignore-missing-imports # 0 issues
conda run -n base python -m compileall -q fincore # ok
NO_MKDOCS_2_WARNING=1 conda run -n base python -m mkdocs build --strict --site-dir build/mkdocs-alphalens # ok# (Material/MkDocs 2.0 announcement suppressed via the tool's supported env var; not a project warning)# packaging / fresh-wheel gates
conda run -n base python -m pytest -o addopts='' tests/packaging -q --tb=short --maxfail=0 # 37 passed
conda run -n base python -m build --outdir build/alphalens-dist # wheel + sdist
conda run -n base python scripts/test_installed_wheel.py --dist build/alphalens-dist \
--profiles core factor-analysis alphalens alphalens-pyfolio all # 5/5 passed
conda run -n base python scripts/check_release_consistency.py --dist build/alphalens-dist # OK# docs / quality / regression
MPLBACKEND=Agg conda run -n base python -m pytest -o addopts='' \
tests/docs tests/quality -q --tb=short --maxfail=0 # 75 passed
conda run -n base python -m pytest -o addopts='' \
tests/test_factor_analysis/test_pandas3_regressions.py \
tests/benchmarks/test_factor_analysis_performance.py -q --tb=short --maxfail=0 # 33 passed# full trusted baseline (regenerated by scripts/collect_quality_baseline.py, disposable copy)# -> outcome: pass; trusted-baseline 4374 passed; non-serial-single/xdist 4368+4368# (count-matched); branch-coverage 4374 passed / 55.0%; all integrity True

TODOs before release (explicit human gates — release remains blocked)

  • Alphalens license/NOTICE/SPDX human review (docs/upstream-provenance.md,
    checklist item 7.4): root MIT text vs file-level Quantopian Apache-2.0
    headers; destination header/NOTICE decision pending.
  • Factor benchmark baseline human approval
    (benchmarks/factor-analysis-baseline.json keeps approved_by /
    approved_at empty; checklist item 6.5) before any performance claim.
  • CI multi-platform / fresh-wheel matrix artifacts on this commit.
  • Docs/examples human spot-check.
  • Version decision by the release owner (this PR does not bump 0.3.0, tag,
    or claim Stable/Production/1.0).

Remaining gates

All engineering gates are green. The human license, benchmark-approval, CI
artifact, and version gates above are intentionally open; per the plan the
release candidate stays Beta at 0.3.0 until they are closed.

Provenance / license impact

  • Pinned blob SHA256 register in docs/upstream-provenance.md and the compat
    fixtures; static AST extraction only, no sibling imports, no network.
  • No external alphalens/empyrical/pyfolio or Git URL runtime dependencies.
  • No legal conclusion is made in this PR.

Owned files (by track)

  • Track A: fincore/alphalens/, scripts/generate_compat_manifest.py,
    scripts/generate_alphalens_upstream_test_inventory.py,
    scripts/check_alphalens_upstream_test_migration.py,
    tests/compat/{fixtures/alphalens-*,alphalens/,test_alphalens_upstream_test_migration.py},
    tests/conftest.py
  • Track B: fincore/factor_analysis/{calendar,data,exceptions}.py,
    fincore/contracts/factor_analysis.py
  • Track C: fincore/factor_analysis/{performance,portfolio}.py
  • Track D: fincore/factor_analysis/{models,analysis,render_matplotlib,tears}.py
  • Track E: pyproject.toml, requirements*.txt, tests/packaging/,
    scripts/{test_installed_wheel,check_release_consistency}.py,
    .github/workflows/{ci,publish}.yml, docs, examples, benchmarks

🤖 Generated with Claude Code

@cloudQuant
cloudQuant merged commit 77804bd into masterAug 15, 2026
28 checks passed
Sign up for freeto 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.

1 participant

@cloudQuant