research: survivorship sensitivity and total-return momentum investigation

Three questions answered against snapshot copies, with no production change.

Step 1 — how sensitive is the backtest to the ranking universe? Restoring 85
S&P 500 constituents removed between 2021-06 and 2026-07 moves the same window
from 2.09 Sharpe / 51.6% CAGR to 1.57 / 38.1%. The failed banks never reached
either book (identical best/worst trade R), so this measures universe
recomposition, not survivorship bias. The removals list is curated by hand with
per-symbol sources; only three explicitly confirmed terminal events get marks,
and four unresolved endings are reported as caveats rather than inferred.

Step 2 — does a total-return basis change the ranking? Ordered lists differ on
1009 of 1009 evaluated dates, 4.56 replacements per date. The shift correlates
with trailing implied yield (mean Spearman +0.79), which is strong evidence
consistent with a dividend effect but does not isolate own-yield, since both
the stock and benchmark legs change.

Step 3a — does that reach P&L? A paired replay reusing one shared candidate set
(control reproduces the production row exactly) changes ~30% of entries.
Treatment is -3.7pp CAGR and -1.9pp drawdown, with the entire return gap in
2025. A paired moving-block bootstrap (seed 20260907, 5000 replicates, 21/63
blocks, both reported) puts every interval across zero.

Decision: production stays unchanged. No schema, no ingestion, no wider sweep.
The observed window does not resolve which basis is better, and choosing a
threshold now — with -3.7pp on the table — would be fitting the rule to the
answer.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HAH7vVtn7qbcn1EVheecHQ
This commit is contained in:
dennisthiessenandClaude Opus 5 committed 2026-09-07 19:29:34 +02:00
1 parent 8453b87290
commit ebe9047403
16 files changed
+442522

No files matched your search

File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
+105
View File
@@ -0,0 +1,105 @@
{
"generated_at": "2026-09-07T10:55:05.693160+00:00",
"snapshot": "C:\\Workspace\\signal-platform\\backtest_snapshots\\survivorship-a.sqlite",
"cache": "C:\\Workspace\\signal-platform\\backtest_snapshots\\tr-rank-cache.sqlite",
"window": {
"start": "2021-06-24",
"end": "2026-07-02"
},
"universe_size": 505,
"sample_every_n_sessions": 25,
"result": {
"what_it_measures": "Spearman correlation, per sampled date, between a name's trailing 12-month implied yield (from the ALL/SPLIT ratio over the formation window) and the change in its momentum percentile between the two arms.",
"caveat": "Both the stock series and the benchmark leg change between arms, so this is strong evidence consistent with a dividend effect - it does not isolate the stock's own yield from the beta-weighted benchmark yield.",
"formation_window_bars": 252,
"min_symbols_per_date": 30,
"sampled_dates": 40,
"sample_date_list": [
"2022-07-28",
"2022-09-01",
"2022-10-07",
"2022-11-11",
"2022-12-19",
"2023-01-26",
"2023-03-03",
"2023-04-10",
"2023-05-15",
"2023-06-21",
"2023-07-27",
"2023-08-31",
"2023-10-06",
"2023-11-10",
"2023-12-18",
"2024-01-25",
"2024-03-01",
"2024-04-08",
"2024-05-13",
"2024-06-18",
"2024-07-25",
"2024-08-29",
"2024-10-04",
"2024-11-08",
"2024-12-16",
"2025-01-24",
"2025-03-03",
"2025-04-07",
"2025-05-13",
"2025-06-18",
"2025-07-25",
"2025-08-29",
"2025-10-06",
"2025-11-10",
"2025-12-16",
"2026-01-23",
"2026-03-02",
"2026-04-07",
"2026-05-12",
"2026-06-17"
],
"mean_spearman_yield_vs_percentile_shift": 0.7924,
"min": 0.7138,
"max": 0.8459,
"per_date_spearman": [
0.7814,
0.7933,
0.8216,
0.8325,
0.8108,
0.8147,
0.8074,
0.8421,
0.7867,
0.7907,
0.7682,
0.7568,
0.7849,
0.7536,
0.7138,
0.7385,
0.7414,
0.7697,
0.8078,
0.8325,
0.8132,
0.8459,
0.8397,
0.7966,
0.7808,
0.8285,
0.8068,
0.8376,
0.7974,
0.8256,
0.8046,
0.7762,
0.8008,
0.8046,
0.7793,
0.7978,
0.7678,
0.7549,
0.7501,
0.7384
]
}
}
+540
View File
@@ -0,0 +1,540 @@
{
"generated_at": "2026-09-07T10:57:26.602851+00:00",
"snapshot": "C:\\Workspace\\signal-platform\\backtest_snapshots\\survivorship-a.sqlite",
"cache": "C:\\Workspace\\signal-platform\\backtest_snapshots\\tr-rank-cache.sqlite",
"window": {
"start": "2021-06-24",
"end": "2026-07-02"
},
"universe_size": 505,
"inert_snapshot_symbols": [
"RHM"
],
"cutoff": 80.0,
"verdict": "proceed to Step 3 - ordered lists differ",
"result": {
"evaluated_dates": 1009,
"skipped_dates_no_history": 252,
"dates_with_different_admitted_set": 1007,
"dates_with_different_ordered_list": 1009,
"mean_set_disagreement": 0.08668279921946223,
"max_set_disagreement": 0.21428571428571427,
"mean_admitted_per_arm": 100.09,
"mean_names_only_in_price_return": 4.56,
"mean_names_only_in_total_return": 4.56,
"mean_replacements_per_date": 4.56,
"max_replacements_per_date": 12,
"mean_symmetric_difference": 9.13,
"per_year": {
"2022": {
"dates": 132,
"changed_sets": 132,
"changed_orders": 132
},
"2023": {
"dates": 250,
"changed_sets": 250,
"changed_orders": 250
},
"2024": {
"dates": 252,
"changed_sets": 252,
"changed_orders": 252
},
"2025": {
"dates": 250,
"changed_sets": 248,
"changed_orders": 250
},
"2026": {
"dates": 125,
"changed_sets": 125,
"changed_orders": 125
}
},
"examples": [
{
"date": "2022-06-24",
"admitted_price_return": 99,
"admitted_total_return": 99,
"only_in_price_return": [
"CDNS",
"MAR",
"FIX",
"COST",
"LIN",
"AON",
"STE",
"CI",
"AJG"
],
"only_in_total_return": [
"EXC",
"PSX",
"WY",
"AMCR",
"DTE",
"GIS",
"FE",
"BMY",
"ES"
],
"order_changed_without_membership_change": false,
"first_10_price_return": [
"OXY",
"EQT",
"APA",
"DVN",
"MOS",
"CTRA",
"ON",
"ALB",
"CF",
"SMCI"
],
"first_10_total_return": [
"OXY",
"EQT",
"APA",
"DVN",
"MOS",
"CTRA",
"ON",
"CF",
"ALB",
"SMCI"
]
},
{
"date": "2022-06-27",
"admitted_price_return": 99,
"admitted_total_return": 99,
"only_in_price_return": [
"FCX",
"COST",
"FIX",
"CI",
"PAYX",
"HSIC",
"L",
"AIZ"
],
"only_in_total_return": [
"EXC",
"MO",
"AMCR",
"GIS",
"DTE",
"CMS",
"FE",
"BMY"
],
"order_changed_without_membership_change": false,
"first_10_price_return": [
"APA",
"OXY",
"DVN",
"EQT",
"MOS",
"ON",
"CTRA",
"ALB",
"CF",
"SMCI"
],
"first_10_total_return": [
"APA",
"OXY",
"DVN",
"EQT",
"MOS",
"ON",
"CTRA",
"CF",
"SMCI",
"ALB"
]
},
{
"date": "2022-06-28",
"admitted_price_return": 99,
"admitted_total_return": 99,
"only_in_price_return": [
"FCX",
"LYV",
"ULTA",
"CDNS",
"AMP",
"FIX",
"AJG"
],
"only_in_total_return": [
"EXC",
"MO",
"AMCR",
"ETR",
"DTE",
"CMS",
"BMY"
],
"order_changed_without_membership_change": false,
"first_10_price_return": [
"OXY",
"APA",
"DVN",
"MOS",
"EQT",
"CTRA",
"ON",
"CF",
"ALB",
"HAL"
],
"first_10_total_return": [
"OXY",
"APA",
"DVN",
"EQT",
"MOS",
"CTRA",
"ON",
"CF",
"EXE",
"HAL"
]
},
{
"date": "2022-06-29",
"admitted_price_return": 99,
"admitted_total_return": 99,
"only_in_price_return": [
"CDNS",
"FIX",
"COST",
"WAB",
"AJG",
"TRV"
],
"only_in_total_return": [
"EXC",
"LYB",
"MO",
"AMCR",
"DTE",
"WEC"
],
"order_changed_without_membership_change": false,
"first_10_price_return": [
"OXY",
"APA",
"DVN",
"EQT",
"MOS",
"CTRA",
"ALB",
"ON",
"CF",
"EXE"
],
"first_10_total_return": [
"OXY",
"APA",
"DVN",
"EQT",
"MOS",
"CTRA",
"CF",
"ALB",
"EXE",
"ON"
]
},
{
"date": "2022-06-30",
"admitted_price_return": 99,
"admitted_total_return": 99,
"only_in_price_return": [
"LYV",
"CDNS",
"RJF",
"WAB",
"FIX",
"AON",
"TKO"
],
"only_in_total_return": [
"EXC",
"NRG",
"MO",
"LMT",
"DTE",
"WEC",
"AEE"
],
"order_changed_without_membership_change": false,
"first_10_price_return": [
"OXY",
"APA",
"DVN",
"EQT",
"MOS",
"CTRA",
"ON",
"CF",
"ALB",
"HAL"
],
"first_10_total_return": [
"OXY",
"APA",
"DVN",
"EQT",
"MOS",
"CTRA",
"ON",
"CF",
"EXE",
"HAL"
]
},
{
"date": "2022-07-01",
"admitted_price_return": 99,
"admitted_total_return": 99,
"only_in_price_return": [
"DDOG",
"LYV",
"HLT",
"RJF",
"FIX",
"TKO",
"AON",
"AJG",
"ACGL"
],
"only_in_total_return": [
"EXC",
"WY",
"NRG",
"AMCR",
"MO",
"PKG",
"LMT",
"CMS",
"KO"
],
"order_changed_without_membership_change": false,
"first_10_price_return": [
"EQT",
"OXY",
"APA",
"DVN",
"MOS",
"CTRA",
"ON",
"SMCI",
"CF",
"EXE"
],
"first_10_total_return": [
"EQT",
"OXY",
"APA",
"DVN",
"MOS",
"CTRA",
"ON",
"CF",
"SMCI",
"EXE"
]
},
{
"date": "2022-07-05",
"admitted_price_return": 99,
"admitted_total_return": 99,
"only_in_price_return": [
"HLT",
"AON",
"TKO",
"L",
"TRV"
],
"only_in_total_return": [
"EXC",
"WY",
"MO",
"CMS",
"DTE"
],
"order_changed_without_membership_change": false,
"first_10_price_return": [
"APA",
"OXY",
"DVN",
"EQT",
"MOS",
"ON",
"SMCI",
"CTRA",
"CF",
"HAL"
],
"first_10_total_return": [
"EQT",
"OXY",
"APA",
"DVN",
"MOS",
"ON",
"CTRA",
"SMCI",
"CF",
"EXE"
]
},
{
"date": "2022-07-06",
"admitted_price_return": 99,
"admitted_total_return": 99,
"only_in_price_return": [
"TPL",
"ANET",
"HLT",
"LIN",
"UNH",
"CVS"
],
"only_in_total_return": [
"EXC",
"RF",
"LYB",
"WY",
"MO",
"ETR"
],
"order_changed_without_membership_change": false,
"first_10_price_return": [
"APA",
"OXY",
"DVN",
"EQT",
"MOS",
"ON",
"CTRA",
"SMCI",
"CF",
"HAL"
],
"first_10_total_return": [
"APA",
"OXY",
"DVN",
"EQT",
"MOS",
"CTRA",
"ON",
"SMCI",
"CF",
"HAL"
]
},
{
"date": "2022-07-07",
"admitted_price_return": 99,
"admitted_total_return": 99,
"only_in_price_return": [
"RJF",
"LIN",
"PKG",
"L"
],
"only_in_total_return": [
"EXC",
"LYB",
"WY",
"ETR"
],
"order_changed_without_membership_change": false,
"first_10_price_return": [
"APA",
"OXY",
"DVN",
"EQT",
"ON",
"MOS",
"SMCI",
"CTRA",
"HAL",
"CF"
],
"first_10_total_return": [
"APA",
"EQT",
"OXY",
"DVN",
"MOS",
"ON",
"CTRA",
"SMCI",
"HAL",
"EXE"
]
},
{
"date": "2022-07-08",
"admitted_price_return": 99,
"admitted_total_return": 99,
"only_in_price_return": [
"ANET",
"HLT",
"RJF",
"WAB",
"RSG",
"AIZ",
"HSY"
],
"only_in_total_return": [
"EXC",
"LYB",
"AMCR",
"MO",
"ETR",
"AEP",
"ATO"
],
"order_changed_without_membership_change": false,
"first_10_price_return": [
"APA",
"OXY",
"DVN",
"EQT",
"ON",
"MOS",
"CTRA",
"SMCI",
"HAL",
"VLO"
],
"first_10_total_return": [
"APA",
"OXY",
"DVN",
"EQT",
"CTRA",
"MOS",
"ON",
"SMCI",
"HAL",
"EXE"
]
}
],
"elapsed_seconds": 132.0
},
"coverage": {
"symbols_cached": 507,
"symbols_with_unmatched_dates": 0,
"total_unmatched_dates": 0
}
}
File diff suppressed because it is too large. Load diff