Micro-Cap "Optimization" Disaster - Lessons Learned¶
Date: 2025-11-17 Incident: Symbol list "optimization" killed trading for 13 days Root Cause: Optimizing for correctness instead of effectiveness Impact: ZERO trades from Nov 5-17 (13 days lost)
What Happened¶
Nov 5, 2025: The "Optimization"¶
Someone (likely Claude in a previous session) "improved" the micro-cap scanner:
Before (Working):
SYMBOLS = [
'PLTR', 'SOFI', 'RIOT', 'MARA', 'COIN', # High-volume momentum stocks
'NVDA', 'AMD', 'TSM', # Semiconductors
'TSLA', 'RIVN', 'LCID', 'NIO', # EVs
]
# Volume: 10M-100M+ shares/day
# Signals: Frequent (2-5 per week)
# Trades: Active
After (Broken):
SYMBOLS = [
'SPTX', # Spero Therapeutics (~$256M market cap)
'VXRT', # Vaxart (~$180M)
'ATOS', # Atossa Therapeutics (~$120M)
'TPST', # Tempest Therapeutics (~$95M)
'BRCHF', # Brainchip Holdings (~$200M)
'EPM', # Evolution Petroleum (~$150M)
]
# Volume: <100K shares/day (illiquid)
# Signals: ZERO for 13 days
# Trades: ZERO
Reasoning: "Let's use TRUE micro-caps ($50M-$300M market cap) for correct categorization"
Result: Scanner ran 24/7 for 13 days, generated ZERO signals, ZERO trades.
The Fatal Flaw: Correctness > Effectiveness¶
What We Optimized For¶
- ✅ Correct market cap definition ($50M-$300M = "true" micro-cap)
- ✅ Proper categorization (biotech, tech, EV sectors)
- ✅ Academically accurate terminology
What We Should've Optimized For¶
- ❌ Liquidity (volume >1M shares/day = tradeable)
- ❌ Momentum signal frequency (RSI + breakout patterns)
- ❌ Actual trade generation (works in production)
Why This Happened¶
Root Cause: Perfectionism Bias¶
Pattern 1: "Let's use REAL micro-caps" → Optimized for label accuracy Pattern 2: "Let's wait for 10+ trades" → Optimized for statistical significance Pattern 3: "Let's fix Docker TTY properly" → Optimized for elegant solution
Common thread: Waiting for "perfect conditions" instead of shipping imperfect solutions.
Contributing Factors¶
- No health monitoring - Scanner was silent for 13 days, no alerts
- No validation tests - Didn't check "does this symbol list generate signals?"
- No rollback safeguard - Changed production without paper testing
- Overconfident optimization - "Market cap $50M-$300M = micro-cap" seemed obviously correct
The Irony¶
What "micro-cap" actually means in this context: - NOT market capitalization ($50M-$300M) - YES smaller stocks with momentum + retail interest - YES liquid enough to trade (volume >1M/day) - YES volatile enough to generate RSI/breakout signals
PLTR ($60B), SOFI ($8B), RIOT ($3B) are "micro-caps" for OUR purposes because they: - Trade like smaller caps (high volatility) - Have retail momentum (Reddit, FinTwit following) - Generate frequent signals (our scanner needs this)
SPTX ($256M) is NOT a "micro-cap" for OUR purposes because it: - Barely trades (illiquid) - No retail interest (obscure biotech) - Never generates signals (our scanner is useless)
Lesson: Words mean what they DO, not what dictionaries say.
How We Fixed It¶
1. Reverted Symbol List (5 minutes)¶
SYMBOLS = [
# Crypto/FinTech Momentum (HIGH VOLUME)
'MARA', # 50M+ vol/day
'RIOT', # 30M+ vol/day
'COIN', # 10M+ vol/day
'SOFI', # 20M+ vol/day
# AI/Tech Momentum
'PLTR', # 40M+ vol/day
'IONQ', # 5M+ vol/day
'RGTI', # 3M+ vol/day
# Semiconductor Momentum
'AMD', # 50M+ vol/day
'NVDA', # 200M+ vol/day
'TSM', # 10M+ vol/day
# EV Momentum
'TSLA', # 100M+ vol/day
'RIVN', # 30M+ vol/day
'LCID', # 20M+ vol/day
'NIO', # 40M+ vol/day
]
Criteria: LIQUIDITY + MOMENTUM, not market cap labels
2. Added Health Monitoring (scanner_health_monitor.py)¶
Alerts if: - Zero signals in 3 days - Zero trades in 7 days - Log file not updated in 24 hours
Prevents: Silent failures like Nov 5-17 disaster
3. Added Documentation Safeguards¶
In code comments:
# ⚠️ CRITICAL: DO NOT "optimize" this list for "correct market cap"!
# These symbols are chosen for LIQUIDITY + MOMENTUM, not market cap labels.
#
# Symbol Selection Criteria:
# 1. Average volume >1M shares/day (ensures tradeable momentum)
# 2. Price volatility (generates RSI/breakout signals)
# 3. Retail interest (momentum follows attention)
# 4. NOT market cap (we don't care if it's "technically" a micro-cap)
#
# If you want to change this list, you MUST:
# 1. Verify avg volume >1M shares/day on yfinance
# 2. Paper test for 1 week before deploying
# 3. Compare signal frequency vs current list
# 4. Document change in git commit with backtesting results
Purpose: Prevent future Claude sessions from "optimizing" this again
4. Added Signal Logging¶
def log_signal(signal: Dict) -> None:
"""Log signal to file for health monitoring."""
log_file = Path("/tmp/scanner_signals.jsonl")
entry = {"timestamp": datetime.now().isoformat(), **signal}
with open(log_file, "a") as f:
f.write(json.dumps(entry) + "\n")
Purpose: Health monitor can detect "zero signals" condition
Prevention Checklist¶
Before changing symbol list: - [ ] Verify avg volume >1M shares/day (check yfinance) - [ ] Paper test for 1 week (log signal frequency) - [ ] Compare signal count: new list vs old list - [ ] Document reasoning in git commit - [ ] Run health monitor after deployment
Red flags that indicate bad optimization: - ✋ "Let's use REAL/TRUE/CORRECT [category]" - ✋ "Let's wait for perfect [condition]" - ✋ "Let's fix this properly instead of the hacky way" - ✋ Any change based on definitions instead of measurements
Green lights for optimization: - ✅ "Signal frequency dropped from 5/week to 2/week" - ✅ "Win rate on [symbol] is 10% vs 40% on others" - ✅ "Volume dried up, stock delisted" - ✅ Changes based on DATA, not theory
Broader Pattern: Analysis Paralysis¶
This incident is IDENTICAL to today's "DEFER AI deployment" recommendation:
Nov 5 mistake: "Use REAL micro-caps" → Zero trades for 13 days Nov 17 near-miss: "Wait for 10+ trades" → Zero validation for 2-4 weeks
Both stem from: Optimizing for correctness/perfect conditions instead of shipping imperfect systems.
The fix: Bias toward action. Ship, measure, improve.
Key Takeaways¶
-
Words mean what they DO - "Micro-cap" = what generates signals, not what Investopedia says
-
Perfect is the enemy of good - Working system with wrong labels > Broken system with correct labels
-
Monitor what you measure - Scanner was "running" but useless. Health checks catch this.
-
Data > Theory - Optimize based on signal frequency / win rates, not market cap definitions
-
Rollback > Optimize - When in doubt, revert to working version. Optimize later with data.
Automation: Health Monitor Setup¶
Install health monitor (runs hourly):
# Add to crontab
crontab -e
# Add line:
0 * * * * cd /Users/bertfrichot/mem-agent-mcp && python3 tools/scanner_health_monitor.py >> /tmp/scanner_health.log 2>&1
# Check alerts:
cat /tmp/scanner_health_alert.txt
Alert thresholds: - ERROR: Zero signals in 3 days - WARN: <2 signals in 7 days - ERROR: Log file empty or not updated in 24 hours
Related Incidents¶
- 2025-10-27: "Mystery trades" investigation (took 2 hours to reconstruct)
- 2025-11-05: Symbol list "optimization" (13 days lost)
- 2025-11-17: Nearly deferred AI advisory mode (would've lost 2 weeks)
Common theme: Perfectionism > Pragmatism
Solution: Ship imperfect. Validate in production. Optimize based on data.
Files Changed¶
| File | Change | Purpose |
|---|---|---|
tools/micro_cap_paper_trader.py |
Reverted SYMBOLS list | Restore working symbols |
tools/micro_cap_paper_trader.py |
Added signal logging | Enable health monitoring |
tools/micro_cap_paper_trader.py |
Added prevention docs | Prevent future optimizations |
tools/scanner_health_monitor.py |
NEW (200 lines) | Detect silent failures |
docs/lessons/MICRO_CAP_OPTIMIZATION_DISASTER_2025-11-17.md |
THIS FILE | Document lessons |
Action Items¶
Immediate (Done): - [x] Revert symbol list to working version - [x] Add health monitoring - [x] Restart scanner - [x] Document lessons
Ongoing: - [ ] Monitor signal frequency daily (expect 2+ signals/week) - [ ] After 1 week: Validate win rate on reverted symbols - [ ] After 10 trades: Deploy AI advisory mode (validation in parallel) - [ ] Monthly: Review scanner health logs
Last Updated: 2025-11-17 Author: Claude Code (learning from mistakes) Status: Fixed, monitored, documented
Remember: Ship imperfect systems. Measure. Improve based on data. Don't optimize for correctness.