learn(iterate): 2026-04-13 — automated iteration run

This commit is contained in:
github-actions[bot] 2026-04-13 07:52:59 +00:00
parent ddb2a010e7
commit 17e45df41a
4 changed files with 38 additions and 8 deletions

View File

@ -1,6 +1,6 @@
# Learnings Index
**Last analyzed run:** 2026-04-12
**Last analyzed run:** 2026-04-13
| Domain | File | Last Updated | One-line Summary |
|--------|------|--------------|-----------------|
@ -13,7 +13,7 @@
| early_accumulation | scanners/early_accumulation.md | 2026-04-12 | Sub-threshold (score=60); no catalyst → structurally score-capped by ranker |
| social_dd | scanners/social_dd.md | 2026-04-12 | Sub-threshold (score=56); BUT 55% 30d win rate — diverges from social_hype; ranker may be suppressing it incorrectly |
| volume_accumulation | scanners/volume_accumulation.md | — | No data yet |
| short_squeeze | scanners/short_squeeze.md | — | No data yet — new scanner, research: high SI (>20%) + catalyst = squeeze risk; not a directional signal alone |
| short_squeeze | scanners/short_squeeze.md | 2026-04-13 | First real data: 60% 7d win rate, +2.15% avg 7d (n=10) — best 7d performer; DTC now surfaced in context |
## Research

View File

@ -3,18 +3,35 @@
## Current Understanding
Identifies stocks with structurally high short interest (>15% of float by default, CRITICAL at >30%)
where short sellers are vulnerable to forced covering on any positive catalyst. The scanner uses
Finviz for discovery (screener filters) + Yahoo Finance for exact SI% verification.
Finviz for discovery (screener filters) + Yahoo Finance for exact SI% and days-to-cover (shortRatio)
verification.
Key distinction: High SI alone predicts *negative* long-term returns on average (academic consensus).
The scanner is a squeeze-risk flag, not a directional buy signal. Value comes from cross-scanner
confluence: a stock appearing here AND in options_flow or earnings_calendar is significantly stronger
than either signal alone.
However, first real P&L data (n=10) shows 60% 7d win rate and +2.15% avg 7d — best 7d performer in
the pipeline. This may reflect that discovery-pipeline filtering (technical confirmation, enrichment)
already adds the catalyst signal needed to convert squeeze-risk into a directional trade. Cross-scanner
confluence (short_squeeze + options_flow or earnings_calendar) remains a stronger signal than either
alone and is the primary confluence hypothesis under test.
## Evidence Log
_(populated by /iterate runs)_
### 2026-04-13 — P&L review (first real outcome data)
- 10 tracked recommendations, 5/10 1d wins (50% win rate), 6/10 7d wins (60% win rate).
- Avg 7d return: +2.15%. This makes short_squeeze the **best 7d performer** among scanners with ≥5 samples.
- Outperforms analyst_upgrade (50% 7d), insider_buying (46.4% 7d), options_flow (45.6% 7d).
- The scanner is producing positive outcomes as a standalone signal, not only as a cross-scanner modifier.
- However, ranker prompt says "Focus on days to cover" but context string only shows SI%. DTC value is available in Yahoo Finance (`shortRatio`) but was not being fetched or passed through — gap confirmed.
- Confidence: medium (small sample n=10; 30d data will be more conclusive; DTC gap has been fixed)
### 2026-04-13 — Code fix: days_to_cover surfaced in context
- Added `days_to_cover` extraction (`shortRatio` from Yahoo Finance) to `finviz_scraper.py`.
- Applied `min_days_to_cover` filter (previously accepted as parameter but never enforced).
- Updated `short_squeeze.py` context string to include DTC value so ranker can use "days to cover" criterion.
- Confidence: high (this is a clear context gap between ranker criteria and available data)
## Pending Hypotheses
- [ ] Does short_squeeze + options_flow confluence produce better 7d win rate than either scanner alone?
- [ ] Does short_squeeze + earnings_calendar (SI>20%) produce better outcomes than earnings alone? (See earnings_calendar.md pending hypothesis)
- [ ] Is there a volume threshold (e.g., market cap <$2B small-cap) that sharpens the signal?
- [ ] Does DTC >5 (now surfaced in context) predict better outcomes than DTC 2-5 within the scanner?
- [ ] Does standalone short_squeeze (no cross-scanner confluence) continue to outperform at 7d as sample grows?

View File

@ -67,6 +67,7 @@ class ShortSqueezeScanner(BaseScanner):
continue
si_pct = item.get("short_interest_pct", 0)
dtc = item.get("days_to_cover", 0.0)
signal = item.get("signal", "low_squeeze_potential")
label = _SIGNAL_LABELS.get(signal, signal)
@ -78,8 +79,9 @@ class ShortSqueezeScanner(BaseScanner):
else:
priority = Priority.MEDIUM.value
dtc_str = f"{dtc:.1f}" if dtc else "N/A"
context = (
f"Short interest {si_pct:.1f}% of float{label}"
f"Short interest {si_pct:.1f}% of float, {dtc_str} days to cover{label}"
" | squeeze risk elevates if catalyst arrives"
)
@ -91,6 +93,7 @@ class ShortSqueezeScanner(BaseScanner):
"priority": priority,
"strategy": self.strategy,
"short_interest_pct": si_pct,
"days_to_cover": dtc,
"squeeze_signal": signal,
}
)

View File

@ -115,6 +115,15 @@ def get_short_interest(
market_cap = info.get("marketCap", 0)
volume = info.get("volume", info.get("regularMarketVolume", 0))
# Days to cover (short ratio): shares short / avg daily volume
days_to_cover = info.get("shortRatio")
if days_to_cover is None or not isinstance(days_to_cover, (int, float)):
days_to_cover = 0.0
# Apply days-to-cover filter
if days_to_cover < min_days_to_cover:
return None
# Categorize squeeze potential
if short_pct >= 30:
signal = "extreme_squeeze_risk"
@ -131,6 +140,7 @@ def get_short_interest(
"market_cap": market_cap,
"volume": volume,
"short_interest_pct": short_pct,
"days_to_cover": days_to_cover,
"signal": signal,
}
except Exception: