f/fundlab
Greg Pomerantz d0ae2ec348 Drawdown-resilience screen: who was positive when equities crashed
fundlab/drawdown.py detects the severe equity drawdown scenarios from
the index (IVV) rather than hard-coding them: one worst peak->trough
per calendar year since 2022, min depth 8% (a 10% floor would silently
drop the 2023 rate shock at -9.9% and the 2024 Aug-5 dip at -8.4%).
Detected: 2022 bear mkt (-24.5%), 2023 rate shock (-9.9%), 2024 vol
spike (-8.4%), 2025 tariff crash (-18.8%), 2026 Q1 drawdown (-8.9%).

For each of the 2,384 screened funds it computes that fund's own-NAV
return over each peak->trough window (first print after the peak to
the last print on/before the trough) and ranks the 250 CANDIDATEs by
# scenarios positive.

Key finding: positive in all 5 scenarios = only 7 funds, all
ultra-short/cash (BILS, QCMMRX, PULS, FHCOX, FHMIX, SAFEX, COIAX).
Drawdown resilience at the top tier is a duration property, not alpha.
The interesting tier is 4/5 WITH real 5y alpha: HMEZX merger arb
(+1.5% 2022, +3.1% 2023, t5 +7.1), MERVX, CBHCX market-neutral, SCFZX
securitized credit (t5 +8.4), ENIAX (t5 +10.1), WMNUX (t5 +6.9), RCTIX.

App: Fund Lab "Drawdown resilience" expander (scenario table +
candidate table). Output: fundlab/drawdown_results.json.
Tests: test_drawdown() added (4 checks). 88/32 suites green.
2026-08-27 13:29:01 -04:00
..
nport_cache N-PORT cross-check: verify top candidates' actual holdings 2026-08-27 12:43:17 -04:00
pool Fund Lab: returns-based strategy decomposition for the 16 shortlist funds 2026-08-26 11:59:59 -04:00
__init__.py fundlab: EDGAR investment-objective fetcher + curated fallback 2026-08-25 18:15:48 -04:00
cluster_kmeans.json Factor screen (v2, 35 drivers) + return-driver clusters 2026-08-27 08:35:42 -04:00
cluster_tree.json Factor screen (v2, 35 drivers) + return-driver clusters 2026-08-27 08:35:42 -04:00
cluster.py Factor screen (v2, 35 drivers) + return-driver clusters 2026-08-27 08:35:42 -04:00
dbmine.py Find candidate funds NOT in the DB: exhaustive EDGAR 497-universe pass 2026-08-26 15:22:52 -04:00
decompose_results.json Fund Lab: returns-based strategy decomposition for the 16 shortlist funds 2026-08-26 11:59:59 -04:00
decompose.py Alpha search: mine + screen the local DB for idiosyncratic alpha complements 2026-08-26 13:34:34 -04:00
drawdown_results.json Drawdown-resilience screen: who was positive when equities crashed 2026-08-27 13:29:01 -04:00
drawdown.py Drawdown-resilience screen: who was positive when equities crashed 2026-08-27 13:29:01 -04:00
edgar_universe.py Find candidate funds NOT in the DB: exhaustive EDGAR 497-universe pass 2026-08-26 15:22:52 -04:00
edgar.py fundlab: extract strategy sections from EDGAR docs; --strategy CLI mode 2026-08-25 23:06:13 -04:00
factor_results.json Factor screen (v2, 35 drivers) + return-driver clusters 2026-08-27 08:35:42 -04:00
factors.log Factor screen (v2, 35 drivers) + return-driver clusters 2026-08-27 08:35:42 -04:00
factors.py Factor screen (v2, 35 drivers) + return-driver clusters 2026-08-27 08:35:42 -04:00
fundinfo.py fundlab: extract strategy sections from EDGAR docs; --strategy CLI mode 2026-08-25 23:06:13 -04:00
funds_curated.json fundlab: EDGAR investment-objective fetcher + curated fallback 2026-08-25 18:15:48 -04:00
harvest.py Alpha search: mine + screen the local DB for idiosyncratic alpha complements 2026-08-26 13:34:34 -04:00
nport_manifest.json N-PORT cross-check: verify top candidates' actual holdings 2026-08-27 12:43:17 -04:00
nport.py N-PORT cross-check: verify top candidates' actual holdings 2026-08-27 12:43:17 -04:00
overnight.log Overnight comprehensive screen COMPLETE: 2,384 funds, 250 candidates, RESEARCH.md results + next iterations 2026-08-27 06:56:33 -04:00
overnight.py Watchdog: pidfile liveness (pgrep -f was fooled by shells quoting the pattern); per-batch download fault isolation 2026-08-26 22:09:20 -04:00
pool.py fundlab: EDGAR investment-objective fetcher + curated fallback 2026-08-25 18:15:48 -04:00
RESEARCH.md Drawdown-resilience screen: who was positive when equities crashed 2026-08-27 13:29:01 -04:00
resolved_tickers.json Alpha search: mine + screen the local DB for idiosyncratic alpha complements 2026-08-26 13:34:34 -04:00
search_all.json Overnight comprehensive screen COMPLETE: 2,384 funds, 250 candidates, RESEARCH.md results + next iterations 2026-08-27 06:56:33 -04:00
search_external.json Find candidate funds NOT in the DB: exhaustive EDGAR 497-universe pass 2026-08-26 15:22:52 -04:00
search_harvest.json Alpha search: mine + screen the local DB for idiosyncratic alpha complements 2026-08-26 13:34:34 -04:00
search_mined.json Alpha search: mine + screen the local DB for idiosyncratic alpha complements 2026-08-26 13:34:34 -04:00
search_results.json Alpha search: mine + screen the local DB for idiosyncratic alpha complements 2026-08-26 13:34:34 -04:00
search.py Alpha search: mine + screen the local DB for idiosyncratic alpha complements 2026-08-26 13:34:34 -04:00
searchlist.py Alpha search: mine + screen the local DB for idiosyncratic alpha complements 2026-08-26 13:34:34 -04:00
tickers.py Alpha search: mine + screen the local DB for idiosyncratic alpha complements 2026-08-26 13:34:34 -04:00
watchdog.log Overnight comprehensive screen COMPLETE: 2,384 funds, 250 candidates, RESEARCH.md results + next iterations 2026-08-27 06:56:33 -04:00
watchdog.sh Watchdog: pidfile liveness (pgrep -f was fooled by shells quoting the pattern); per-batch download fault isolation 2026-08-26 22:09:20 -04:00
xcheck_report.json N-PORT cross-check: verify top candidates' actual holdings 2026-08-27 12:43:17 -04:00
xcheck.py N-PORT cross-check: verify top candidates' actual holdings 2026-08-27 12:43:17 -04:00