Instruction file imported from chingis1227/Portfolio-Xray (
.cursor/rules/stress-factor-rolling-betas.mdc). Copyright stays with the author.
Rolling factor betas — mandatory on every run
Whenever a portfolio stress/metrics run produces stress_report.json (Main via run_report.py / run_optimization.py, Equal-Weight / Risk-Parity via run_portfolio_report_for_weights), the pipeline must:
Windows (single source)
- 3Y ≈ 156 weekly observations →
FACTOR_WEEKS_3Yinsrc/stress_factors.py - 5Y ≈ 260 weekly observations →
FACTOR_WEEKS_5Y - 10Y ≈ 520 weekly observations →
FACTOR_WEEKS_10Y
Each horizon is a separate rolling OLS time series (portfolio weekly return on weekly factor matrix); do not merge windows into one series.
Artifacts (always refresh on run)
Write per variant output folder (e.g. Main portfolio/, equal-weight portfolio/results_csv + variant root for HTML/PNG):
- CSV —
rolling_factor_betas_3y.csv,rolling_factor_betas_5y.csv,rolling_factor_betas_10y.csv(underoutput_dir_csv/ variantresults_csv/) - Summary CSV —
rolling_factor_betas_summary.csv(mean, median, p10, p90 per beta per window) - HTML —
rolling_factor_betas.html(optional interactive) - PNG —
rolling_factor_betas_3y.png,rolling_factor_betas_5y.png,rolling_factor_betas_10y.png(underoutput_dir_final)
stress_commentary.txt and stress_commentary PDF
write_stress_commentary (used by run_report.py and run_optimization.py) must embed, when present in stress_report.json:
- 5Y and 10Y portfolio factor regression: β, t, p, 95% CI, R², adj R², n_obs (same fields as
factor_regression_5y/factor_regression_10y). - Rolling 3Y/5Y/10Y summary (
factor_betas_rolling_summary): mean, median, p10, p90 per factor; artifact filenames; and Markdown image links torolling_factor_betas_{3y,5y,10y}.pngusing paths relative topdf_md_sources/so Pandoc can embed figures in*_stress_commentary.pdf.
After optimization, stress_commentary.txt is refreshed together with stress_report.json. If --no-report, try_rebuild_pdfs_after_main_report still runs so PDFs track the new commentary.
stress_report.json
Must include (when computation succeeds):
factor_betas_rolling_windows_weeks(maps labels 3y / 5y / 10y to week counts)factor_betas_rolling_summaryfactor_betas_rolling_artifacts(paths or filenames for CSV summary, HTML, PNG map)
On failure, set factor_betas_rolling_error (no silent omission of the block intent).
Optimization path
run_optimization.py must call export_stress_report after building stress_report (including rolling block) so artifacts stay current even when --no-report skips run_report.py. A later full run_report.py may overwrite stress_report.json with the same logical content.