Deterministic portfolio risk engine plus event-driven news analysis.
This repo tries to answer a concrete question:
Does a news-conditioned risk layer improve plain portfolio risk estimates, or does it mostly add noise?
The answer in the current state is honest:
- the engineering stack is strong and end-to-end functional
- the event-conditioned layer helps in specific families and probe batches
- the guarded integrated map still does not beat the pure baseline end-to-end in grouped aggregate backtests
That is not a code failure. It is the research result so far.
At a high level, the system has four layers:
quant risk- returns, volatility, VaR, ES, stress, Monte Carlo, backtests
news engine- ingest news, normalize, dedupe, link tickers, classify event types
fusion- map events into scenarios and recompute risk under event stress
capital sandbox- simulate simple pathing decisions with paper capital under risk/news rules
This is not a toy notebook. It is a modular research-and-operations workbench.
The strongest current statements are:
risk_v2, grouped backtests, calibration registry, operator summary, ops analytics, UI, and sandbox are implementedNewsAPI.org,The News API,Marketaux, andAlpha Vantageare wired into the provider chain- fresh and delayed validation flows are separated
replay_as_of_timestampallows time-shifted validation without looking past the cutoff- the guarded map improved archived/fresh probe compares, but still has a promotion gap versus the pure baseline in grouped aggregate research
If you only want the shortest proof path, read these:
docs/showcase_walkthrough.mdPROJECT_FINAL_STATUS.mdshowcase/probe_compare_report.mdshowcase/capital_replay_asof_1904.mdshowcase/capital_replay_batch_report.md
Setup:
python -m venv .venv
.venv\Scripts\activate
pip install -r requirements.txtThree fast runs that show the repo's core layers:
- plain risk snapshot
python scripts/run_risk_snapshot.py --portfolio-config config/portfolios/demo_portfolio.json --start 2022-01-01 --alpha 0.01- grouped event-conditioned research backtest
python scripts/run_integration_backtest.py --watchlist-config config/watchlists/demo_watchlist.yaml --mapping-variants configured calibrated source_aware --group-by event_type event_subtype source_tier- rigorous delayed replay using yesterday's clock time
python scripts/run_capital_sandbox.py --mode replay_as_of_timestamp --portfolio-config config/portfolios/demo_portfolio.json --as-of-timestamp 2026-03-05T19:04:00-03:00 --session-minutes 5 --decision-interval-seconds 60 --providers newsapiMost portfolio projects stop at static analytics or historical backtests.
This repo goes further:
- deterministic multi-provider news ingestion
- event-conditioned stress mapping
- grouped research backtests by event family and source tier
- governance and promotion gates
- real-time and time-shifted capital sandbox runs
It also keeps the uncomfortable part visible:
- the integrated layer is not promoted just because it is more complex
- if it does not beat the baseline, the docs say so
The main unresolved problem is not architecture.
It is evidence:
- more fresh supported live windows
- more coverage for promotion metrics
- stronger proof that the guarded map beats or at least justifies itself against the baseline
- more sandbox sessions with truly actionable live signal
This project contains a portfolio risk engine plus a deterministic NLP news engine:
- Price data download (Yahoo Finance with local cache)
- Log-return transformation
- EWMA volatility estimation
- Normal VaR and ES (1-day horizon)
- VaR violation tracking and baseline plots
- Portfolio config loading and validation
- Multi-asset covariance and correlation
- Historical, normal, and EWMA-normal risk snapshot
- Risk v2 with sector decomposition, regime tagging, and covariance-model comparison
- Student-t tail fitting and model comparison
- Filtered historical risk model and governance selection
- Portfolio variance contribution breakdown
- Monte Carlo simulation for forward loss distributions
- Financial news ingestion with Marketaux, The News API, NewsAPI.org, and Alpha Vantage fallback
- News normalization, deduplication, ticker linking, event taxonomy, severity, and evaluation
- Source-tier policy with strict gating for recap/opinion/press-release providers
- Event-conditioned integration between news and risk scenarios
- Sector-aware event spillover calibration between related tickers
- Grouped integration backtests by event type, subtype, story bucket, and source tier
- Versioned calibration snapshots with registry and compare support
- Live QA audit for each provider-backed batch
- Multi-window live validation and governance
- Validation trend reporting and promotion gating
- Archive-only validation for quota-blocked days
- Thematic validation symbol packs
- Operator summary across watchlist and governance layers
- Historical ops analytics across watchlist, validation, and governance outputs
- Capital sandbox with baseline path comparison, decision journal, and minute snapshots
- Retention planning for run folders
- Local Streamlit UI backed by Python services
- Study docs under
docs/ - Secret redaction in operational logs and failure manifests
- Adaptive provider fallback, Marketaux sync splitting, and archived-run reuse under quota pressure
popquant_1_month/
config/
portfolios/
data/
__init__.py
loaders.py
positions.py
returns.py
schemas.py
validation.py
models/
__init__.py
covariance.py
ewma.py
filtered_historical.py
historical.py
hierarchical_vol.py
student_t.py
backtest/
__init__.py
christoffersen.py
kupiec.py
rolling.py
scoring.py
risk/
__init__.py
decomposition.py
factors.py
model_registry.py
portfolio.py
regime.py
stress.py
var.py
es.py
simulation/
__init__.py
monte_carlo.py
scenario_paths.py
capital/
__init__.py
policy.py
reporting.py
sandbox.py
fusion/
__init__.py
calibration.py
calibration_registry.py
event_conditioned_risk.py
integration_backtest.py
integration_governance.py
mapping_variants.py
reporting.py
scenario_mapper.py
sector_mapping.py
watchlist_reporting.py
operations/
__init__.py
ops_analytics.py
operator_summary.py
retention.py
scheduler.py
event_engine/
ingestion/
live_audit.py
live_validation.py
parsing/
nlp/
redaction.py
source_policy.py
storage/
evaluation.py
pipeline.py
validation_trend_governance.py
validation_governance.py
config/
portfolios/
scenarios.yaml
event_scenario_map.yaml
news_source_policy.yaml
news_entity_aliases.csv
ticker_sector_map.csv
watchlists/
datasets/
fixtures/
labeled_events/
raw_news/
processed_news/
scripts/
manage_live_watchlist_task.py
run_week1.py
run_backtest.py
run_calibration_registry.py
run_capital_sandbox.py
run_event_calibration.py
run_event_pipeline.py
run_daily_watchlist.py
run_integration_governance.py
run_integration_backtest.py
run_live_marketaux_watchlist.py
run_live_validation_backfill.py
run_model_governance.py
run_monte_carlo.py
run_news_engine.py
run_news_evaluation.py
run_news_sync.py
run_operator_summary.py
run_ops_analytics.py
run_live_validation_suite.py
run_live_validation.py
run_live_validation_governance.py
run_integrated_risk.py
run_retention.py
run_risk_snapshot.py
run_model_compare.py
run_stress.py
run_live_watchlist_task.ps1
run_validation_trend_governance.py
run_validation_trend_report.py
run_vol_shrinkage.py
services/
capital_workbench.py
ops_workbench.py
pathing.py
portfolio_manager.py
research_workbench.py
risk_workbench.py
ui/
app.py
pages/
output/
figures/
tables/
risk_snapshots/
model_compare/
stresses/
vol_shrinkage/
backtests/
monte_carlo/
governance/
news_sync/
news_pipeline/
news_engine/
news_evaluation/
event_calibration/
event_calibration_registry/
integration/
integration_backtest/
integration_governance/
live_marketaux_watchlist/
capital_sandbox/
operator_summary/
ops_analytics/
watchlist/
tests/
python -m venv .venv
.venv\Scripts\activate
pip install -r requirements.txtpython scripts/run_week1.py --tickers AAPL MSFT SPY --start 2022-01-01 --alpha 0.01Generated outputs:
output/figures/week1_baseline.pngoutput/tables/week1_timeseries.csvoutput/tables/week1_summary.csv
python scripts/run_risk_snapshot.py --portfolio-config config/portfolios/demo_portfolio.json --start 2022-01-01 --alpha 0.01Generated outputs:
output/risk_snapshots/<run_id>/risk_snapshot.jsonoutput/risk_snapshots/<run_id>/model_metrics.csvoutput/risk_snapshots/<run_id>/risk_contributions.csvoutput/risk_snapshots/<run_id>/correlation_matrix.csvoutput/risk_snapshots/<run_id>/sector_risk_contributions.csvoutput/risk_snapshots/<run_id>/covariance_model_compare.csvoutput/risk_snapshots/<run_id>/regime_state.jsonoutput/risk_snapshots/<run_id>/positions_used.csv
python scripts/run_model_compare.py --portfolio-config config/portfolios/demo_portfolio.json --start 2021-01-01 --alpha 0.01 --window 252Generated outputs:
output/model_compare/<run_id>/model_compare_summary.csvoutput/model_compare/<run_id>/model_compare_backtest.csvoutput/model_compare/<run_id>/model_compare_report.json
python scripts/run_vol_shrinkage.py --portfolio-config config/portfolios/demo_portfolio.json --start 2022-01-01Generated outputs:
output/vol_shrinkage/<run_id>/vol_shrinkage.csvoutput/vol_shrinkage/<run_id>/vol_shrinkage_summary.json
python scripts/run_stress.py --portfolio-config config/portfolios/demo_portfolio.json --scenario-config config/scenarios.yaml --start 2022-01-01 --alpha 0.01Generated outputs:
output/stresses/<run_id>/stress_summary.csvoutput/stresses/<run_id>/stress_asset_detail.csvoutput/stresses/<run_id>/stress_report.json
python scripts/run_backtest.py --portfolio-config config/portfolios/demo_portfolio.json --start 2021-01-01 --alpha 0.01 --window 252Generated outputs:
output/backtests/<run_id>/formal_backtest_summary.csvoutput/backtests/<run_id>/formal_backtest_timeseries.csvoutput/backtests/<run_id>/formal_backtest_report.json
python scripts/run_model_governance.py --portfolio-config config/portfolios/demo_portfolio.json --start 2021-01-01 --alpha 0.01 --window 252Generated outputs:
output/governance/<run_id>/governance_summary.csvoutput/governance/<run_id>/governance_decision.json
python scripts/run_monte_carlo.py --portfolio-config config/portfolios/demo_portfolio.json --start 2021-01-01 --horizon-days 10 --n-sims 8000 --alpha 0.01Generated outputs:
output/monte_carlo/<run_id>/monte_carlo_paths.csvoutput/monte_carlo/<run_id>/monte_carlo_summary.json
python -m pytest tests -qDefault behavior uses the local fixture for deterministic validation.
python scripts/run_news_engine.pyGenerated outputs:
datasets/raw_news/*.jsondatasets/processed_news/canonical_documents.jsonldatasets/processed_news/events.jsonloutput/news_engine/<run_id>/news_engine_report.jsonoutput/news_engine/<run_id>/events.csv
Requires MARKETAUX_API_TOKEN.
python scripts/run_news_sync.py --symbols AAPL MSFT SPY --published-after 2026-03-01 --published-before 2026-03-05 --limit 3 --max-pages 1Official source docs:
The sync runner also writes:
output/news_sync/<run_id>/news_sync_manifest.jsonoutput/news_sync/<run_id>/run_log.jsonloutput/news_sync/<run_id>/failure_manifest.jsonon failure
The sync layer now:
- batches larger symbol sets into smaller upstream requests
- recursively splits a batch when Marketaux returns
402 - redacts
api_tokenvalues from logs and failure manifests
python scripts/run_news_evaluation.pyGenerated outputs:
output/news_evaluation/<run_id>/news_evaluation_detail.csvoutput/news_evaluation/<run_id>/news_evaluation_summary.json
Default behavior uses the local news fixture and the latest selected governance map. If no governed map exists, it falls back to config/event_scenario_map.yaml.
python scripts/run_integrated_risk.pyGenerated outputs:
output/integration/<run_id>/integrated_report.jsonoutput/integration/<run_id>/integrated_summary.csvoutput/integration/<run_id>/integrated_stress_detail.csvoutput/integration/<run_id>/integrated_report.mdoutput/integration/<run_id>/integration_manifest.json
Uses the historical demo fixture to estimate forward return and volatility behavior by event type.
python scripts/run_event_calibration.pyGenerated outputs:
output/event_calibration/<run_id>/event_impact_observations.csvoutput/event_calibration/<run_id>/event_calibration_summary.csvoutput/event_calibration/<run_id>/event_sector_calibration_summary.csvoutput/event_calibration/<run_id>/recommended_event_scenario_map.yamloutput/event_calibration/<run_id>/event_calibration_report.json
The calibration runner also writes a versioned snapshot into:
output/event_calibration_registry/snapshots/<snapshot_id>/output/event_calibration_registry/registry.csvoutput/event_calibration_registry/registry.json
Rebuild the snapshot registry:
python scripts/run_calibration_registry.pyCompare two snapshots:
python scripts/run_calibration_registry.py --left-snapshot-id <left> --right-snapshot-id <right>Runs grouped event-level backtests comparing baseline normal VaR against the event-conditioned stressed VaR.
python scripts/run_integration_backtest.pyGenerated outputs:
output/integration_backtest/<run_id>/integration_backtest_timeseries.csvoutput/integration_backtest/<run_id>/integration_backtest_summary.jsonoutput/integration_backtest/<run_id>/integration_backtest_by_event_type.csvoutput/integration_backtest/<run_id>/integration_backtest_by_event_subtype.csvoutput/integration_backtest/<run_id>/integration_backtest_by_story_bucket.csvoutput/integration_backtest/<run_id>/integration_backtest_by_source_tier.csvoutput/integration_backtest/<run_id>/integration_backtest_variant_compare.csvoutput/integration_backtest/<run_id>/integration_backtest_portfolio_compare.csvoutput/integration_backtest/<run_id>/integration_backtest_report.md
The grouped backtest supports:
- single portfolio or multi-portfolio runs
- watchlist-driven pooled runs
- mapping variants
configured,manual,calibrated,source_aware - horizons
1d,3d, and5d
Builds a calibrated map, compares it against the manual map on event-day backtests, and selects the active variant automatically.
python scripts/run_integration_governance.pyGenerated outputs:
output/integration_governance/<run_id>/event_calibration_summary.csvoutput/integration_governance/<run_id>/event_impact_observations.csvoutput/integration_governance/<run_id>/manual_backtest.csvoutput/integration_governance/<run_id>/calibrated_backtest.csvoutput/integration_governance/<run_id>/integration_governance_decision.jsonoutput/integration_governance/<run_id>/selected_event_scenario_map.yaml
Builds a ranked, multi-portfolio daily report using the latest selected integration map.
python scripts/run_daily_watchlist.pyGenerated outputs:
output/watchlist/<run_id>/watchlist_summary.csvoutput/watchlist/<run_id>/watchlist_events.csvoutput/watchlist/<run_id>/watchlist_report.jsonoutput/watchlist/<run_id>/watchlist_report.mdoutput/watchlist/<run_id>/watchlist_manifest.json
Event rows expose:
direct_tickersevent_sectorssector_peer_tickers
so the report shows whether a scenario hit the name directly or arrived through sector spillover.
The default watchlists now cover 15 portfolios, including:
- consumer
- internet/platform
- technology
- financials
- healthcare
- industrials
- energy
- digital-assets/financials
- semis
- software
- defensives
- rates-sensitive
The validation symbol config now supports thematic packs:
core_market_packfinancial_energy_packhealth_industrials_packconsumer_internet_packsemis_software_packdefensives_packrates_sensitive_pack
Runs the live sync, NLP pipeline, QA audit, and multi-portfolio watchlist in one command.
Uses an ordered provider chain. By default:
marketauxthenewsapinewsapialphavantage
For full fallback coverage, set:
MARKETAUX_API_TOKENTHENEWSAPI_API_TOKENNEWSAPI_API_KEYALPHAVANTAGE_API_KEY
NewsAPI.org is useful as a quota fallback and for delayed windows. The free plan is not truly live; it applies a 24-hour delay.
Alpha Vantage now uses:
- primary
tickersqueries for symbol-directed coverage - official
topicsfallback (financial_markets,economy_macro) when the ticker query is sparse - a small built-in pacing delay to respect the free-tier burst limit before the fallback request
python scripts/run_live_marketaux_watchlist.pyGenerated outputs:
output/live_marketaux_watchlist/<run_id>/watchlist_summary.csvoutput/live_marketaux_watchlist/<run_id>/watchlist_events.csvoutput/live_marketaux_watchlist/<run_id>/watchlist_report.mdoutput/live_marketaux_watchlist/<run_id>/live_marketaux_manifest.jsonoutput/live_marketaux_watchlist/<run_id>/run_log.jsonloutput/live_marketaux_watchlist/<run_id>/failure_manifest.jsonon failureoutput/live_marketaux_watchlist/<run_id>/live_event_audit_summary.jsonoutput/live_marketaux_watchlist/<run_id>/live_zero_link_events.csvoutput/live_marketaux_watchlist/<run_id>/live_filtered_events.csvoutput/live_marketaux_watchlist/<run_id>/live_suspicious_link_events.csv
Event rows and QA bundles now expose source metadata:
source_domainsource_tiersource_bucketsource_adjustmentsource_low_signal
Runs the live watchlist workflow across multiple date windows and aggregates a scorecard.
Fresh sync can use the same provider chain as the live watchlist.
Validation now reorders that chain by window freshness:
- delayed windows prefer
newsapifirst to exploit the free-plan 24h-delayed coverage - fresher windows keep
alphavantageahead ofnewsapi
python scripts/run_live_validation.py --windows 2 --window-days 3 --step-days 2Use a provider subset explicitly when quota pressure makes the full chain wasteful:
python scripts/run_live_validation.py --windows 1 --window-days 1 --step-days 1 --symbol-pack core_market_pack --providers alphavantage --symbol-batch-size 8 --max-pages 1Run without touching the API by reusing exact-match archived windows only:
python scripts/run_live_validation.py --archive-only --windows 2 --window-days 3 --step-days 2 --as-of 2026-03-06 --symbols AAPL MSFT NVDA GOOGL JPM COIN BAC GS UNH JNJ PFE HON CAT DE XOM CVX SPY QQQ XLEGenerated outputs:
output/live_validation/<run_id>/validation_window_summary.csvoutput/live_validation/<run_id>/taxonomy_gap_samples.csvoutput/live_validation/<run_id>/validation_summary.jsonoutput/live_validation/<run_id>/validation_report.mdoutput/live_validation/<run_id>/run_log.jsonl
When fresh sync fails because Marketaux blocks the request, the runner can reuse an exact-match archived live window from prior successful runs. Reused windows are marked with:
reused_from_archivereused_run_dirwindow_originfresh_sync_requestedquota_blocked
Runs a paper-trading sandbox with:
cash_onlybenchmark_holdportfolio_holdevent_quant_pathingsector_basketbenchmark_timingcapped_risk_long
Main mode: run a real-time session with R$100, one decision per minute, and minute snapshots:
python scripts/run_capital_sandbox.py --mode live_session_real_time --initial-capital 100 --decision-interval-seconds 60 --session-minutes 5 --news-refresh-minutes 2The live mode now:
- refreshes the news layer during the session
- only enters risk when an eligible event is also confirmed by the quant gate
- writes
live_session_status.jsonwith refresh counts, stale-price steps, and the current best path - writes
capital_sandbox_equity_curve.live.pngon every live update - archives minute-by-minute PNG snapshots under
minute_snapshot_images/
Launch 5m, 15m, and 30m real-time sessions in parallel:
python scripts/start_capital_sandbox_live_batch.py --session-minutes 5 15 30 --decision-interval-seconds 60Research mode: replay the latest intraday window without waiting on the clock:
python scripts/run_capital_sandbox.py --mode replay_intraday --initial-capital 100 --decision-interval-seconds 10 --session-minutes 5Time-shifted research mode: replay "yesterday at the same clock time" without looking past that cutoff:
python scripts/run_capital_sandbox.py --mode replay_as_of_timestamp --initial-capital 100 --decision-interval-seconds 60 --session-minutes 5 --providers newsapi --as-of-timestamp 2026-03-05T19:04:00-03:00Compare 5m, 15m, and 30m in one replay run:
python scripts/run_capital_sandbox.py --mode replay_intraday --initial-capital 100 --decision-interval-seconds 10 --compare-session-minutes 5 15 30Batch multiple as_of replays into one evidence pack:
python scripts/run_capital_replay_batch.py --providers newsapi --session-minutes 5 --as-of-timestamps 2026-03-05T15:30:00-03:00 2026-03-05T16:30:00-03:00 2026-03-05T17:30:00-03:00 2026-03-05T19:04:00-03:00Use a historical fixture-backed run instead:
python scripts/run_capital_sandbox.py --mode historical_daily --news-fixture datasets/fixtures/sample_marketaux_news_history.json --fixture-provider marketauxGenerated outputs:
output/capital_sandbox/<run_id>/capital_sandbox_summary.csvoutput/capital_sandbox/<run_id>/decision_journal.csvoutput/capital_sandbox/<run_id>/path_equity_curve.csvoutput/capital_sandbox/<run_id>/capital_minute_snapshots.csvoutput/capital_sandbox/<run_id>/capital_sandbox_report.md
If all news providers fail, the sandbox falls back to a degraded no-news mode instead of aborting the session. In that case the pathing policy stays defensive and the sync error is preserved in the run metadata.
The sandbox now also reorders providers automatically by freshness:
- delayed/historical windows prefer
newsapifirst - fresher live windows keep
alphavantageahead ofnewsapi
Compare-mode outputs:
output/capital_sandbox/<run_id>/capital_compare_summary.csvoutput/capital_sandbox/<run_id>/capital_compare_journal.csvoutput/capital_sandbox/<run_id>/capital_compare_equity_curve.csvoutput/capital_sandbox/<run_id>/capital_compare_snapshots.csvoutput/capital_sandbox/<run_id>/capital_compare_report.md
Replay batch outputs:
output/capital_replay_batch/<run_id>/replay_batch_summary.csvoutput/capital_replay_batch/<run_id>/replay_batch_paths.csvoutput/capital_replay_batch/<run_id>/replay_batch_report.mdoutput/capital_replay_batch/<run_id>/replay_batch_manifest.json
Assesses a live-validation run against explicit health thresholds.
python scripts/run_live_validation_governance.pyGenerated outputs:
output/live_validation_governance/<run_id>/live_validation_governance.jsonoutput/live_validation_governance/<run_id>/live_validation_governance.md
Aggregates all governed live-validation history into a drift and health report.
python scripts/run_validation_trend_report.pyGenerated outputs:
output/validation_trends/<run_id>/validation_trend_runs.csvoutput/validation_trends/<run_id>/validation_trend_summary.jsonoutput/validation_trends/<run_id>/validation_trend_report.md
Uses the trend report as a promotion gate instead of relying on a single validation batch.
python scripts/run_validation_trend_governance.pyGenerated outputs:
output/validation_trend_governance/<run_id>/validation_trend_governance.jsonoutput/validation_trend_governance/<run_id>/validation_trend_governance.md
Runs or reuses a live-validation batch, then executes single-run governance, trend reporting, and trend governance in one command.
python scripts/run_live_validation_suite.py --windows 2 --window-days 3 --step-days 2You can also forward a specific provider chain through the suite:
python scripts/run_live_validation_suite.py --windows 1 --window-days 1 --step-days 1 --symbol-pack core_market_pack --providers alphavantage --symbol-batch-size 8 --max-pages 1Reuse the latest validation batch without new API calls:
python scripts/run_live_validation_suite.py --skip-validationRun the suite fully offline against archived validation windows:
python scripts/run_live_validation_suite.py --archive-only --windows 2 --window-days 3 --step-days 2 --as-of 2026-03-06 --symbols AAPL MSFT NVDA GOOGL JPM COIN BAC GS UNH JNJ PFE HON CAT DE XOM CVX SPY QQQ XLEGenerated outputs:
output/live_validation_suite/<run_id>/live_validation_suite_manifest.jsonoutput/live_validation_suite/<run_id>/run_log.jsonloutput/live_validation_suite/<run_id>/failure_manifest.jsonon failure
Runs multiple suite executions across descending as-of dates to accumulate governed validation history.
python scripts/run_live_validation_backfill.py --start-as-of 2026-03-06 --end-as-of 2026-03-04 --cadence-days 1By default, the backfill runner writes into an isolated workspace under output/backfill_workspace, so historical research runs do not contaminate the live promotion gate.
Generated outputs:
output/live_validation_backfill/<run_id>/backfill_runs.csvoutput/live_validation_backfill/<run_id>/backfill_summary.jsonoutput/live_validation_backfill/<run_id>/backfill_report.mdoutput/live_validation_backfill/<run_id>/run_log.jsonloutput/live_validation_backfill/<run_id>/failure_manifest.jsonon failure
Preview the task definition:
python scripts/manage_live_watchlist_task.py create --print-onlyCreate the default task:
python scripts/manage_live_watchlist_task.py createInspect the installed task:
python scripts/manage_live_watchlist_task.py showDelete the task:
python scripts/manage_live_watchlist_task.py deleteThe scheduled task calls:
scripts/run_live_watchlist_task.ps1
Wrapper logs land in:
output/scheduled_task_logs/*.log
Build one compact operator report from a watchlist run plus the latest validation, governance, and capital sandbox outputs.
python scripts/run_operator_summary.py --watchlist-run output/watchlist_probe/<run_id>Generated outputs:
output/operator_summary/<run_id>/operator_summary.jsonoutput/operator_summary/<run_id>/operator_summary.md
The operator summary now exposes:
- validation freshness split (
fresh_sync,archive_reuse,failed) - capital sandbox live-session health
- latest capital compare block when a compare run exists
- concise "why ranked high" labels for top portfolios and top events
Aggregate historical watchlist, validation, governance, and capital sandbox outputs:
python scripts/run_ops_analytics.pyGenerated outputs:
output/ops_analytics/<run_id>/ops_analytics_runs.csvoutput/ops_analytics/<run_id>/ops_analytics_watchlist_runs.csvoutput/ops_analytics/<run_id>/ops_analytics_capital_runs.csvoutput/ops_analytics/<run_id>/ops_analytics_path_leaderboard.csvoutput/ops_analytics/<run_id>/ops_analytics_summary.jsonoutput/ops_analytics/<run_id>/ops_analytics_report.md
Preview which run folders are safe to prune:
python scripts/run_retention.pyApply the cleanup:
python scripts/run_retention.py --applyGenerated outputs:
output/retention/retention_plan.json
Use these files when dissecting the repo outside Codex:
PROJECT_FINAL_STATUS.mddocs/architecture.mddocs/backtest_research.mddocs/calibration_registry.mddocs/data_flow.mddocs/reading_order.mddocs/quant_risk.mddocs/risk_v2.mddocs/event_engine.mddocs/fusion.mddocs/local_ui.mddocs/ops_validation.mddocs/github_publish.md
Lightweight publish-friendly examples live under:
showcase/week1_baseline.pngshowcase/operator_summary.mdshowcase/ops_analytics_report.mdshowcase/probe_compare_report.mdshowcase/capital_5m_realtime.mdshowcase/capital_5m_realtime_equity_curve.pngshowcase/capital_replay_asof_1904.mdshowcase/capital_replay_asof_1904_equity_curve.pngshowcase/capital_replay_batch_report.md
streamlit run ui/app.pyThe UI is local-only and uses:
services/portfolio_manager.pyservices/risk_workbench.pyservices/research_workbench.pyservices/ops_workbench.py
Recent UI additions:
- latest ops analytics block on
Overview - latest capital compare block on
OverviewandCapital Sandbox - path leaderboard and capital-run tables on
Ops - weight-sum preview on
Portfolios - local provider-token config in
config/local/provider_tokens.json(git-ignored) - replay batch lab on
Capital Sandbox - live PNG tracking and minute-snapshot gallery on
Capital Sandbox - replay timestamp auto-aligns to
now - 24hforNewsAPI, and to live current time for other providers - live snapshots accumulate by session step even when the market timestamp is stale
Capital Sandboxexposes a quant/risk panel from the decision journal- live runs start in background from the UI, with auto-refresh and a session countdown
This repo now includes a MkDocs site for GitHub Pages.
Local serve:
pip install -r requirements-docs.txt
mkdocs serveWindows shortcut:
powershell -ExecutionPolicy Bypass -File scripts/run_docs_site.ps1Local build:
mkdocs build --strictMain config:
mkdocs.ymldocs/index.md.github/workflows/docs.yml
For GitHub Pages deployment, set:
Settings -> Pages -> Build and deployment -> Source = GitHub Actions
The core MVP, operator layer, grouped research backtests, versioned calibration registry, local UI, and real-time capital sandbox are in place.
What still remains:
- more fresh governed live evidence once provider quotas reset
- final promotion of the guarded integrated map only if it improves beyond the pure baseline on broader evidence
- more fresh-session validation of the richer sandbox paths with actionable live signal
- continued provider/source refinement from new live samples rather than archived runs alone
Repository note:
- the codebase is ready for GitHub publication
- the project directory has its own
.gitrepository - publication now is a workflow step, not a missing engineering step
Latest research state:
- canonical calibration registry:
output/event_calibration_registry/ - latest guardrail report:
output/backtest_guardrails/20260306T164754Z/guardrail_report.json - latest guarded backtest:
output/integration_backtest_guarded/20260306T164830Z/integration_backtest_report.md - latest archived-live probe compare:
output/integrated_risk_probe_compare/20260306T172102Z/probe_compare_report.md
Current takeaway:
earningsstill benefits from the calibrated stress layermacroandguidancewere over-stressed in the raw calibrated map- a guarded hybrid map that damps those two families reduces the overshoot materially, but still does not beat the pure baseline end-to-end
- on the archived live Marketaux batch used for spot validation, the guarded candidate improved
3/3portfolios (benchmark_heavy,tech_sector,digital_assets_finance) - on the latest fresh live-validation window driven by
Alpha Vantage, the guarded candidate improved14/15portfolios in a direct selected-vs-guarded probe compare - reprocessing that same fresh Alpha-driven batch with the latest taxonomy rules drives the batch
othercount from9to0without touching the watchlist-active set - that fresh window still does not justify promotion by itself because the grouped aggregate research baseline remains stronger and the trend gate is still sensitive to recent quota failures
MIT. See LICENSE.