Skip to content

Commit fc19fe9

Browse files
authored
Merge pull request #4 from HanSun103/live-forward-test-2026-07-17
Deploy live-forward dashboard with GitHub Pages
2 parents 4cd464b + 495ba1d commit fc19fe9

22 files changed

Lines changed: 961 additions & 17 deletions
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
name: Deploy live-forward dashboard
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
paths:
8+
- "site/**"
9+
- "src/experiments/public_dashboard_validation.py"
10+
- ".github/workflows/deploy-dashboard.yml"
11+
workflow_dispatch:
12+
13+
permissions:
14+
contents: read
15+
16+
concurrency:
17+
group: github-pages
18+
cancel-in-progress: false
19+
20+
jobs:
21+
validate:
22+
name: Validate and package dashboard
23+
runs-on: ubuntu-latest
24+
steps:
25+
- name: Check out repository
26+
uses: actions/checkout@v4
27+
28+
- name: Set up Python
29+
uses: actions/setup-python@v5
30+
with:
31+
python-version: "3.12"
32+
33+
- name: Validate sanitized public bundle
34+
run: python -m src.experiments.public_dashboard_validation --site-dir site
35+
36+
- name: Configure GitHub Pages
37+
uses: actions/configure-pages@v5
38+
39+
- name: Upload dashboard artifact
40+
uses: actions/upload-pages-artifact@v4
41+
with:
42+
path: site
43+
44+
deploy:
45+
name: Deploy dashboard
46+
needs: validate
47+
runs-on: ubuntu-latest
48+
permissions:
49+
pages: write
50+
id-token: write
51+
environment:
52+
name: github-pages
53+
url: ${{ steps.deployment.outputs.page_url }}
54+
steps:
55+
- name: Deploy to GitHub Pages
56+
id: deployment
57+
uses: actions/deploy-pages@v4

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,3 +37,5 @@ data/raw/fnspid_source/
3737
# OS/editor noise
3838
.DS_Store
3939
Thumbs.db
40+
41+
/pokestock-catalog-fix/

README.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,8 @@ python -m src.cli run-live-forward-daily --as-of 2026-07-22
253253

254254
The [live-forward operating guide](docs/LIVE_FORWARD_MONITOR.md) documents the close-data guard,
255255
frozen-snapshot contract, dashboard timestamps, model-overlap metrics, and generated artifacts.
256+
The [GitHub Pages deployment guide](docs/GITHUB_PAGES_DEPLOYMENT.md) documents the public-data
257+
boundary, static-site publication, validation gate, and one-time repository configuration.
256258

257259
The daily command first refreshes the latest prior Ridge and XGBoost portfolios against the
258260
completed session. Yahoo's final hourly bar begins at 15:30, so the command requires that bar and
@@ -310,6 +312,17 @@ and SPY on one multi-session chart, provides date-range controls, identifies the
310312
portfolios whose returns are pending, and shows human-readable model and stock-level evidence. It
311313
is refreshed by the daily pipeline, snapshot, intraday-report, and evaluation commands.
312314

315+
Publish and validate the sanitized GitHub Pages bundle without retraining:
316+
317+
```bash
318+
python -m src.cli publish-live-dashboard
319+
python -m src.cli validate-live-dashboard-site
320+
```
321+
322+
The daily pipeline runs the publication step automatically. Only `site/` is deployed; private
323+
research evidence under `reports/live_forward/`, cached inputs, trained artifacts, and local paths
324+
remain outside the public bundle.
325+
313326
Build the earlier conservative final-reference package:
314327

315328
```bash

docs/GITHUB_PAGES_DEPLOYMENT.md

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
# GitHub Pages Dashboard Deployment
2+
3+
## Architecture
4+
5+
The live-forward pipeline keeps research artifacts and the public website separate:
6+
7+
```text
8+
Yahoo Finance and cached inputs
9+
|
10+
v
11+
Daily live-forward pipeline
12+
- evaluate prior frozen portfolios
13+
- tune and refit Ridge and XGBoost
14+
- freeze tomorrow's top-40 lists
15+
- calculate stability diagnostics
16+
|
17+
+--> reports/live_forward/ private, ignored research evidence
18+
|
19+
+--> public sanitizer and validator
20+
|
21+
v
22+
site/ committed static bundle
23+
|
24+
v
25+
GitHub Actions / Pages
26+
```
27+
28+
`reports/live_forward/` remains the full local evidence store. The publisher uses explicit field
29+
allowlists to create `site/data/dashboard.json`; it does not copy local paths, cached input names,
30+
raw feature rows, model files, credentials, or candidate-trial details. The public bundle is then
31+
validated for required files, duplicate holdings, forbidden private strings, and a SHA-256 digest.
32+
33+
## Daily publication
34+
35+
The standard daily command now refreshes both the local dashboard and the public bundle:
36+
37+
```bash
38+
python -m src.cli run-live-forward-daily --as-of YYYY-MM-DD
39+
```
40+
41+
To rebuild the public bundle without retraining:
42+
43+
```bash
44+
python -m src.cli publish-live-dashboard \
45+
--live-root reports/live_forward \
46+
--output-dir site
47+
```
48+
49+
Validate exactly what will be published:
50+
51+
```bash
52+
python -m src.cli validate-live-dashboard-site --site-dir site
53+
```
54+
55+
Commit `site/` after reviewing the generated changes. A push to `main` that changes the public
56+
bundle starts `.github/workflows/deploy-dashboard.yml`. The workflow validates the bundle again,
57+
uploads it as a Pages artifact, and deploys it to the `github-pages` environment.
58+
59+
## One-time repository setting
60+
61+
In the GitHub repository, open **Settings > Pages** and set **Source** to **GitHub Actions**. After
62+
the workflow succeeds, the expected project URL is:
63+
64+
`https://hansun103.github.io/AI-Driven-Portfolio-Optimization-Backtesting-System/`
65+
66+
Deployment intentionally runs from `main`, so work on the live-forward branch must be reviewed and
67+
merged before it becomes public. The browser fetches only static JSON, CSS, and JavaScript; no API
68+
server, token, database, or LLM service is required.
69+
70+
## Failure behavior
71+
72+
The workflow does not deploy when the sanitizer output is absent, malformed, contains a blocked
73+
private marker, contains duplicate selected tickers, or does not match its deployment-manifest
74+
hash. A failed deployment leaves the previously successful Pages version online.

docs/LIVE_FORWARD_MONITOR.md

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ python -m src.cli run-live-forward-daily --as-of YYYY-MM-DD
1818

1919
The command performs these steps in order:
2020

21-
1. Incrementally refreshes market data and evaluates portfolios frozen before the current session.
21+
1. Incrementally refreshes market data and evaluates portfolios frozen before the current session,
22+
including one holding-level return record per selected stock.
2223
2. Waits for the final 15:30 hourly bar and verifies the official daily close is available.
2324
3. Rebuilds price features through the decision date.
2425
4. Builds forward-return training labels only where the future outcome was already known before the
@@ -27,6 +28,7 @@ The command performs these steps in order:
2728
configurations, and freezes both top-40 lists for the next evaluation session.
2829
6. Writes model-agreement and day-over-day selection-stability diagnostics.
2930
7. Rebuilds `reports/live_forward/dashboard.html`.
31+
8. Publishes and validates the sanitized static bundle under `site/` for GitHub Pages.
3032

3133
If final market data is unavailable, the command retries and then fails closed. It must not create a
3234
snapshot from a partial trading day.
@@ -52,6 +54,11 @@ previous official close, not to the session open.
5254
The date controls aggregate every completed observation in the selected range. Because the top-40
5355
holdings can change each day, each session uses the list frozen before that session.
5456

57+
The stock-level view defaults to the newest decision date with a completed holding-level evaluation.
58+
The newest frozen portfolios remain available in the selector with a `Pending` label until their next
59+
session closes. Experiment history defaults to the newest evaluation date and can be filtered by
60+
evaluation date or selected model, limited to a compact number of rows, and sorted by any column.
61+
5562
## Selection-stability metrics
5663

5764
All dashboard insights are deterministic calculations; no LLM API is required.
@@ -76,9 +83,15 @@ Generated outputs remain under the ignored `reports/live_forward/` directory:
7683
- dated Ridge and XGBoost snapshot directories with manifests, tuning results, predictions, and
7784
selected holdings;
7885
- intraday and close-to-close evaluation files for each frozen portfolio;
86+
- holding-level returns, benchmark-relative returns, and beat-SPY indicators for completed sessions;
7987
- `selection_stability_YYYY-MM-DD.json`;
8088
- `dashboard.html`.
8189

90+
The daily command also refreshes the tracked `site/` directory. It contains only the allowlisted
91+
dashboard fields and split static assets required by GitHub Pages. See the
92+
[deployment guide](GITHUB_PAGES_DEPLOYMENT.md) for the privacy boundary, validation command, and
93+
one-time repository setting.
94+
8295
Keep source code, configurations, tests, and documentation in Git. Do not commit cached prices,
8396
trained artifacts, generated reports, credentials, or temporary pytest directories.
8497

docs/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
- [2026-07-16 consolidation release notes](RELEASE_NOTES_2026-07-16.md)
77
- [GitHub push plan](GITHUB_PUSH_PLAN.md)
88
- [Live-forward monitoring and daily operations](LIVE_FORWARD_MONITOR.md)
9+
- [GitHub Pages dashboard deployment](GITHUB_PAGES_DEPLOYMENT.md)
910

1011
## Branch Policy
1112

pokestock-catalog-fix

Lines changed: 0 additions & 1 deletion
This file was deleted.

site/.nojekyll

Whitespace-only changes.

site/assets/dashboard.css

Lines changed: 21 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)