feat: add split-safe fundamentals research protocol
This commit is contained in:
@@ -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:
|
||||
|
||||
|
||||
Reference in New Issue
Block a user