Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 69 additions & 0 deletions .github/workflows/refresh-dashboard.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
name: Refresh live-forward dashboard

on:
schedule:
# 6:30 PM Toronto during standard time; 5:30 PM during daylight time.
- cron: "30 22 * * 1-5"
workflow_dispatch:

permissions:
contents: write
pages: write
id-token: write

concurrency:
group: github-pages
cancel-in-progress: false

jobs:
refresh:
name: Refresh official closes and deploy
runs-on: ubuntu-latest
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- name: Check out the default branch
uses: actions/checkout@v7
with:
ref: ${{ github.event.repository.default_branch }}

- name: Set up Python
uses: actions/setup-python@v7
with:
python-version: "3.12"
cache: pip

- name: Install public-refresh dependencies
run: python -m pip install "numpy>=1.26" "pandas>=2.1" "yfinance>=0.2.31"

- name: Refresh sanitized cohort evidence
run: python -m src.experiments.public_cohort_refresh --site-dir site

- name: Validate sanitized public bundle
run: python -m src.experiments.public_dashboard_validation --site-dir site

- name: Commit refreshed public data
shell: bash
run: |
if git diff --quiet -- site/data/dashboard.json site/data/manifest.json; then
echo "The public monitor is already current."
exit 0
fi
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git add site/data/dashboard.json site/data/manifest.json
git commit -m "Refresh live-forward dashboard"
git push origin HEAD

- name: Configure GitHub Pages
uses: actions/configure-pages@v6

- name: Upload dashboard artifact
uses: actions/upload-pages-artifact@v5
with:
path: site

- name: Deploy dashboard
id: deployment
uses: actions/deploy-pages@v5
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,12 @@ dashboard, and regenerates the sanitized GitHub Pages bundle:
python -m src.cli run-live-forward-daily --as-of YYYY-MM-DD
```

The public monitor also refreshes automatically at 22:30 UTC on weekdays. The
scheduled job rebuilds the same frozen-cohort paths from sanitized selections,
fails closed on missing prices, validates the bundle, and deploys the refreshed
site. The default Portfolio vs Benchmark chart now follows this monitoring path,
so its latest date advances even though stock selection remains frozen.

The **Holding-period laboratory** can keep any dated list unchanged or compare
custom 1-60-session replacement horizons, including 5/10/20-session presets.
Ridge and XGBoost can be toggled independently while SPY remains permanently
Expand Down
14 changes: 14 additions & 0 deletions docs/GITHUB_PAGES_DEPLOYMENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,20 @@ deploying. After merge, the resulting push to `main` runs the same validation,
uploads the Pages artifact, and deploys it to the `github-pages` environment.
The deploy job is explicitly restricted to `refs/heads/main`.

The scheduled public refresh runs at 22:30 UTC on weekdays, after the regular
US market close. It reconstructs the frozen-cohort monitor from the sanitized
portfolio selections already committed in `site/data/dashboard.json`, downloads
only their adjusted closes and SPY, validates the bundle, commits changed public
JSON, and deploys that exact version. It does not access the ignored `reports/`
directory, model files, news data, API credentials, or local caches. On market
holidays, the refresh detects that the latest official close is already
published and leaves the site unchanged.

The scheduled workflow is
[`refresh-dashboard.yml`](../.github/workflows/refresh-dashboard.yml). It can
also be launched manually from GitHub Actions when a scheduled run needs to be
repeated.

## One-time repository setting

In the GitHub repository, open **Settings > Pages** and set **Source** to **GitHub Actions**. After
Expand Down
7 changes: 7 additions & 0 deletions docs/LIVE_FORWARD_MONITOR.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,13 @@ interval. Five-, 10-, and 20-session presets are provided, and the horizon compa
every 1–20-session candidate side by side. SPY is permanent and begins from the same zero-return
decision-close baseline as each portfolio.

The main **Portfolio vs Benchmark** chart uses the archived one-session policy
while frozen-cohort monitoring is active. It therefore extends through every
new official close even though no new stock list is generated after July 27.
The date controls and KPI cards are rebased to the selected monitoring window.
The stock-level table and experiment history remain immutable records of the
original one-session snapshots.

The displayed **replacement turnover** excludes the unavoidable initial purchase. An unchanged
cohort therefore correctly shows 0% replacement turnover. Scheduled policies use the same
$1 million capital, 8 bps one-way cost, $10 fixed trade fee, and 0.25% minimum trade-weight rule.
Expand Down
Loading