V8 - Balance Sheet Strength & Dilution Filter Research
Page ID: 33cd5568-29bd-81c4-8110-d88e8198aba2
Created: 2026-04-08T15:53:00.000Z
Last Edited: 2026-04-08T15:53:00.000Z
URL: https://www.notion.so/V8-Balance-Sheet-Strength-Dilution-Filter-Research-33cd556829bd81c48110d88e8198aba2
Properties
- Phase: None
- Status: None
- Key Finding:
- Date: None
- Name: V8 - Balance Sheet Strength & Dilution Filter Research
Content
Grid Search V8 — Balance Sheet Strength & Dilution Filter Research
Run date: 2026-04-09
Data range: 2016-01-01 to 2025-06-30
OOS split: 2024-01-01
Runtime: 61s
Objective
Test whether additional balance-sheet/dilution filters improve universe quality beyond the existing cash/mcap filter. Five candidate metrics evaluated:
| # | Metric | Formula | Rationale |
|---|---|---|---|
| 1 | net_cash_to_mcap | (cash + STI - debt) / mcap | Existing core filter; benchmark |
| 2 | cash_to_debt | (cash + STI) / debt | Balance sheet strength |
| 3 | debt_to_mcap | total_debt / mcap | Leverage relative to valuation |
| 4 | shares_growth_1y | shares_now / shares_1y_ago - 1 | 1-year dilution |
| 5 | issuance_to_mcap | sum(issuance_of_stock, 4Q) / mcap | Stock issuance burden |
Methodology
- Base universe: ATH drawdown ≤ -90%, MCap ≥ $7M, Phase 2+, IPO ≥ 2Y, SEC filing history. No cash/mcap filter — that’s what we’re testing.
- Fixed entry: bottom_bounce 20%, cooldown 90d.
- Fixed exit: TP=100%, SL=-50%, max_days=365.
- Each candidate filter applied on top of the base universe at various thresholds. Trade-level metrics compared.
Stage 1: Metric Coverage & Distribution
1,293 symbol-date observations sampled (19 dates, every 6 months).
| Metric | Coverage | P10 | P25 | P50 | P75 | P90 |
|---|---|---|---|---|---|---|
| net_cash_to_mcap | 100% | -0.019 | 0.029 | 0.213 | 0.631 | 1.372 |
| cash_to_debt | 88% | 0.71 | 2.12 | 6.52 | 38.8 | 145 |
| debt_to_mcap | 100% | 0.000 | 0.002 | 0.023 | 0.150 | 0.455 |
| shares_growth_1y | 100% | -0.48 | 0.01 | 0.16 | 0.63 | 5.92 |
| issuance_to_mcap | 100% | 0.000 | 0.003 | 0.076 | 0.349 | 0.758 |
Key observations:
- All metrics have excellent coverage (88-100%). No sparsity concerns.
- Median biotech in our base universe has 16% share dilution/year and ~21% net cash relative to mcap.
cash_to_debtis highly skewed (many biotechs have minimal debt), reducing its discriminative power.
Stage 2: Filter Sweep Results
34 filter configs tested. Baseline: 787 trades, Mean=+10.3%, Win=39.1%, Sharpe=0.126.
Top 15 by Sharpe
| # | Metric | Direction | Threshold | Univ | Trades | Mean Ret | Win% | Sharpe | IS Mean | OOS Mean |
|---|---|---|---|---|---|---|---|---|---|---|
| 1 | net_cash_to_mcap | top 5% | 5 | 4.0 | 55 | +56.0% | 67.3% | 0.649 | +55.5% | +57.0% |
| 2 | net_cash_to_mcap | top 10% | 10 | 7.6 | 107 | +49.5% | 58.9% | 0.513 | +49.6% | +49.3% |
| 3 | net_cash_to_mcap | top 15% | 15 | 11.0 | 156 | +38.5% | 53.2% | 0.416 | +41.4% | +31.1% |
| 4 | net_cash_to_mcap | top 20% | 20 | 14.6 | 193 | +34.5% | 51.8% | 0.386 | +36.0% | +30.3% |
| 5 | net_cash_to_mcap | above | 0.5 | 21.2 | 292 | +33.2% | 51.0% | 0.379 | +35.8% | +28.9% |
| 6 | net_cash_to_mcap | top 30% | 30 | 21.6 | 276 | +28.3% | 48.6% | 0.328 | +29.9% | +24.5% |
| 7 | net_cash_to_mcap | above | 0.3 | 30.4 | 386 | +27.1% | 48.2% | 0.315 | +29.3% | +23.4% |
| 8 | net_cash_to_mcap | above | 0.2 | 36.1 | 427 | +25.7% | 47.5% | 0.301 | +27.7% | +22.0% |
| 9 | net_cash_to_mcap | top 50% | 50 | 35.8 | 422 | +23.5% | 46.4% | 0.279 | +22.8% | +25.1% |
| 10 | net_cash_to_mcap | above | 0.1 | 44.0 | 493 | +23.0% | 46.2% | 0.273 | +23.3% | +22.4% |
| 11 | shares_growth_1y | below | 0.20 | 41.9 | 483 | +14.6% | 42.2% | 0.181 | +12.9% | +18.2% |
| 12 | shares_growth_1y | below | 0.10 | 33.9 | 387 | +13.6% | 41.9% | 0.170 | +11.8% | +17.1% |
| 13 | issuance_to_mcap | below | 0.0 | 9.9 | 106 | +13.5% | 43.4% | 0.169 | +18.1% | +1.8% |
| 14 | shares_growth_1y | below | 0.50 | 54.2 | 605 | +13.1% | 41.0% | 0.161 | +12.9% | +13.6% |
| 15 | shares_growth_1y | bottom 75% | 75 | 53.2 | 600 | +12.9% | 41.0% | 0.159 | +11.5% | +16.2% |
Metric Rankings (best single-metric Sharpe)
- net_cash_to_mcap — Sharpe 0.649 (top 5%), dominates all other metrics by a wide margin
- shares_growth_1y — Sharpe 0.181 (≤20% growth), modest but consistent IS/OOS
- issuance_to_mcap — Sharpe 0.169 (≤0%), but poor OOS (+1.8% vs +18.1% IS)
- cash_to_debt — Sharpe 0.133 (≥2.0), minimal improvement over baseline
- debt_to_mcap — Sharpe 0.031 (≤0.05), worse than baseline — low-debt stocks underperform
Underperforming filters
- cash_to_debt: Nearly all thresholds produce Sharpe 0.10-0.13, barely different from baseline 0.126. The metric is too skewed (median 6.5x) to be discriminative.
- debt_to_mcap: All thresholds below baseline Sharpe. Requiring low debt actually hurts returns — possibly because some leveraged biotechs with debt (from convertible notes near catalysts) are profitable trades.
- issuance_to_mcap below 0.05/0.1: These ranges produce negative or near-zero mean returns, worse than baseline. The
below 0.0threshold (net buyback) is small but has IS/OOS divergence.
Stage 2B: Two-Filter Combinations
10 combinations of best-per-metric configs tested.
| Combo | Univ | Trades | Mean Ret | Sharpe |
|---|---|---|---|---|
| net_cash_to_mcap + debt_to_mcap | 3.8 | 52 | +52.0% | 0.598 |
| net_cash_to_mcap + cash_to_debt | 3.2 | 43 | +48.3% | 0.560 |
| net_cash_to_mcap + shares_growth_1y | 2.7 | 38 | +44.8% | 0.540 |
| shares_growth_1y + issuance_to_mcap | 7.8 | 86 | +15.7% | 0.195 |
| cash_to_debt + shares_growth_1y | 26.5 | 309 | +14.8% | 0.186 |
| debt_to_mcap + shares_growth_1y | 40.2 | 451 | +11.8% | 0.147 |
| debt_to_mcap + issuance_to_mcap | 9.5 | 102 | +11.1% | 0.139 |
| cash_to_debt + issuance_to_mcap | 6.2 | 74 | +10.9% | 0.134 |
| cash_to_debt + debt_to_mcap | 47.6 | 520 | +10.0% | 0.123 |
No combination beats the best single net_cash_to_mcap filter. Adding a second filter to net_cash_to_mcap reduces universe size and trade count without meaningfully improving Sharpe.
Stage 3: Portfolio Simulation
Top 5 configs with portfolio-level deduplication (10% per position, max 10 concurrent, 90d cooldown).
| # | Config | Univ | Raw Trades | Port Trades | Total Return | Max DD | IS Return | OOS Return |
|---|---|---|---|---|---|---|---|---|
| 1 | BASELINE | 71.4 | 787 | 162 | -37.8% | -86.3% | +48.8% | -35.3% |
| 2 | top 5% cash/mcap | 4.0 | 55 | 50 | +1,015% | -14.2% | +436% | +109% |
| 3 | top 10% cash/mcap | 7.6 | 107 | 92 | +2,164% | -27.6% | +1,076% | +114% |
| 4 | top 15% cash/mcap | 11.0 | 156 | 108 | +982% | -44.6% | +686% | +36% |
| 5 | top 20% cash/mcap | 14.6 | 193 | 120 | +1,183% | -38.1% | +690% | +62% |
Best portfolio: top 10% cash/mcap — 2.26M, 92 trades, -27.6% max DD, strong OOS (+114%).
Key Findings
-
net_cash_to_mcapis the dominant filter — it outperforms every other candidate by 2-5x on Sharpe. The top 5-15% percentile range is the sweet spot. This confirms and strengthens the v5 finding. -
shares_growth_1yis the only other useful metric — filtering for ≤10-20% annual dilution provides modest improvement (Sharpe 0.17-0.18 vs 0.126 baseline). Importantly, IS/OOS consistency is good (+12.9% IS / +18.2% OOS at ≤20%), suggesting this captures a real effect: heavily diluted biotechs underperform. -
cash_to_debtanddebt_to_mcapare not useful — the debt-based metrics add no alpha.debt_to_mcapactually hurts performance, possibly because convertible-note-funded biotechs near catalysts are good trades. -
issuance_to_mcapis unreliable — the only threshold that beats baseline (≤0, net buyback) has severe IS/OOS divergence (18.1% vs 1.8%), and the universe is too small (9.9 avg). -
Combinations don’t help — pairing net_cash_to_mcap with any other filter just reduces trade count without improving risk-adjusted returns.
Recommendations
-
Keep net_cash_to_mcap top 10-15% as the primary filter (confirms v5). The top 10% provides the best portfolio result with good OOS stability.
-
Consider adding shares_growth_1y ≤ 20% as a soft secondary filter — it improves mean return modestly (+14.6% vs +10.3%) with good OOS consistency. However, when combined with net_cash_to_mcap, the marginal benefit disappears (combo Sharpe 0.540 < solo 0.649), so it’s only useful if replacing the cash/mcap filter, not supplementing it.
-
Do not add debt-based filters (cash_to_debt, debt_to_mcap). They reduce the universe without improving returns.
-
Do not add issuance_to_mcap. Poor IS/OOS stability and small universe.
-
Next step: Test shares_growth_1y as a filter for the entry signal rather than universe — e.g., skip signals on stocks that diluted >50% in the past year. This would be a signal-level filter rather than universe-level, potentially more targeted.
Output Files
| File | Description |
|---|---|
run_grid_search_v8.py | Runner script |
run_meta.json | Run metadata |
stage1_metric_distributions.csv | Raw metric values for all sampled symbol-dates |
stage1_coverage_stats.json | Coverage and percentile stats per metric |
stage2_filter_sweep.csv | All 34 single-filter configs with metrics |
stage2b_combo_results.csv | Two-filter combination results |
stage3_portfolio_results.csv | Portfolio simulation for top 5 |
filter_impact_sharpe.png | Sharpe by metric and threshold |
universe_vs_sharpe.png | Universe size vs Sharpe scatter |
is_vs_oos.png | In-sample vs out-of-sample returns |