feat: add split-safe fundamentals research protocol

This commit is contained in:
2026-07-23 17:27:28 +02:00
parent 7f944d718f
commit 34d6dda1ab
6 changed files with 273 additions and 64 deletions
+49 -11
View File
@@ -1,6 +1,7 @@
# Point-in-time fundamentals weight backtest
Status: pre-registered local research. Running it does not change production.
Status: initial experiment completed; split-safe follow-up registered locally.
Running either protocol does not change production.
## Question
@@ -10,7 +11,7 @@ position sizing, capacity, costs, ATR trail, and post-stop re-entry policy remai
unchanged. This isolates the incremental value of fundamentals as a ranking
overlay.
## Registered experiment
## Completed initial experiment
The control is the production 80/20 residual-momentum / volatility rank. The
runner tests three fundamental composites at weights 10%, 20%, 30%, and 40%:
@@ -28,11 +29,38 @@ tracked universe. Missing composite scores are neutral at 50. The formula is:
There are 13 registered portfolio trials including the control. That complete
count is used by the Deflated Sharpe calculation.
Historical P/E and FCF yield are excluded. Stored Alpaca bars are split-adjusted,
while filing-time EPS and shares are not guaranteed to use today's split basis;
mixing them without point-in-time split factors can manufacture valuation moves.
Earnings surprise is also excluded because the completed Dolt SUE study already
failed its promotion bar for this strategy.
No overlay passed the registered train and validation requirements. Review also
found that filing-time diluted EPS and shares are not guaranteed to use the same
split basis across periods. That makes EPS growth and share-count change unsafe
for historical ranking without point-in-time split factors. The initial result
remains an auditable rejection of its registered arms, but it is not evidence
that split-safe fundamentals have no value.
## Registered split-safe follow-up
Run with `--protocol split-safe`. This is a smaller sensitivity experiment:
- Quality: operating margin, FCF margin, and low net-debt/EBITDA. At least two
inputs must exist.
- Growth: revenue growth only.
- Balanced: equal weight to the quality and growth sub-scores. Both must exist.
- Overlay weights: 5%, 10%, and 15%.
Diluted-EPS growth and share-count change are excluded completely: they are not
ranked, do not enter composites, and do not appear in factor-IC output. Historical
P/E and FCF yield remain excluded for the same split-basis reason. Earnings
surprise remains excluded because the completed Dolt SUE study failed its
promotion bar for this strategy.
There are 10 registered portfolio trials including the control. The split-safe
report uses 10 in its Deflated Sharpe calculation. It has a separate score cache
and `fundamentals-splitsafe-*` output prefix, so it cannot be confused with or
silently reuse the initial experiment's scores.
The test window has already been inspected during the initial experiment. Keep
the original date boundaries and development selection discipline, but treat the
follow-up as sensitivity evidence. Any promotion still requires forward paper
evidence.
## Point-in-time rule
@@ -93,6 +121,8 @@ different path to the launcher.
## 3. Run it
The launcher now defaults to the registered `split-safe` follow-up:
```bash
./scripts/run_fundamentals_macbook.sh \
backtest_snapshots/fundamentals-backtest.sqlite
@@ -106,16 +136,24 @@ WORKERS=8 ./scripts/run_fundamentals_macbook.sh \
backtest_snapshots/fundamentals-backtest.sqlite
```
To reproduce the completed initial matrix instead, opt in explicitly:
```bash
PROTOCOL=original ./scripts/run_fundamentals_macbook.sh \
backtest_snapshots/fundamentals-backtest.sqlite
```
The first run builds two caches under `reports/.cache`: production candidate
replay and point-in-time fundamental scores. If interrupted, rerun the same
command; valid caches are reused. Cache keys include snapshot size and mtime, so
a new snapshot triggers a rebuild.
replay and protocol-specific point-in-time fundamental scores. If interrupted,
rerun the same command; valid caches are reused. Cache keys include the protocol,
snapshot size, and mtime, so neither a protocol switch nor a new snapshot can
reuse incompatible scores.
## 4. Bring the result back
The final line names one ZIP such as:
`reports/fundamentals-overlay-20260723-180000.zip`
`reports/fundamentals-splitsafe-20260723-180000.zip`
That ZIP contains: