tradermonty/residual-edge-analyzer
Separate a strategy return series into declared baseline exposure and residual edge with returns-based OLS attribution, HAC inference, rolling stability, alternate-baseline sensitivity, and regime breakdowns. Use when evaluating whether backtest, out-of-sample, or live returns contain independent alpha beyond market, equal-weight, momentum, sector, or user-supplied factor returns; when explaining whether a drawdown came from baseline exposure or strategy-specific behavior; or when a strategy needs an attribution quality gate after backtesting. Do not use for holdings-based Brinson attribution, feature-level Shapley explanations, or analysis from summary metrics without a dated return series.
npx skills add https://github.com/tradermonty/claude-trading-skills --skill residual-edge-analyzer
Test whether a strategy's apparent performance survives explicit comparison with
predeclared baseline return series. Produce an auditable JSON artifact and a concise
Markdown report without fetching data or changing trading exposure.
Treat this as a falsification gate after backtest-expert, not as trade authorization.
the same row.
references/input-contract.md.
summary metrics.
State the claimed independent edge in one sentence. Select a primary baseline that is a
plausible simple copy of the strategy, then select at least one alternate baseline model.
Record these declarations in the config:
baseline_selection: predeclaredstrategy_return_basis and baseline_return_basis: both gross or both netanalysis_scope: out_of_sample, live, or in_sampleuniverse_data: point_in_time, current_constituents, or not_applicableEvery declaration is mandatory for a decision-grade verdict. Omitting one is treated as
undeclared, not as benign, and drops the report to REVIEW_REQUIRED. not_applicable
exists so that a baseline with no universe membership can be declared explicitly rather
than left blank.
Do not choose a baseline because it gives the preferred residual result.
Require:
Stop if the input lacks a dated strategy return series. Report summary-only input as
insufficient rather than inventing observations.
python3 skills/residual-edge-analyzer/scripts/analyze_residual_edge.py \
--input reports/strategy_returns.csv \
--config reports/residual_edge_config.json \
--output-json reports/residual_edge_report.json \
--output-markdown reports/residual_edge_report.md
The script runs the predeclared primary model and all sensitivity models in one execution.
It uses an intercept OLS model and HAC/Newey-West standard errors. It reports the residual
edge ratio as annualized alpha divided by annualized residual volatility; do not calculate
a Sharpe ratio from raw OLS residual mean because an intercept makes that mean zero.
Use the four statuses as diagnostic labels:
RESIDUAL_EDGE: alpha, residual edge ratio, and rolling stability clear configuredthresholds.
BASELINE_EXPLAINED: baseline R-squared is high while residual evidence is weak.RESIDUAL_FRAGILE: results fail one or more robustness gates or change across declaredbaseline models. Also use this status when rolling analysis is disabled, unavailable,
incomplete, or no sensitivity model was supplied.
INSUFFICIENT_EVIDENCE: the sample is below the configured minimum.Read decision_eligibility separately. A statistically interesting result remains
REVIEW_REQUIRED when critical provenance, cost-basis, sample, or multicollinearity
warnings exist, when rolling evidence is unavailable, or when no alternate baseline was
tested.
Inspect:
backtest-expert.signal-postmortem.trade-performance-coach.and interaction effects require historical holdings, benchmark weights, and constituent
returns.
point-in-time.
confirm findings out of sample.
and implementation value require separate evidence.
scripts/analyze_residual_edge.py — deterministic CSV-to-JSON/Markdown analyzer.references/input-contract.md — CSV/config contract and runnable example.references/methodology.md — statistical definitions, interpretation, and limitations.Take tradermonty/residual-edge-analyzer from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.