Two fixes to universe snapshot build:
1. SEC EDGAR exchange case mismatch: company_tickers_exchange.json uses
"Nasdaq" (mixed case) but filter expected "NASDAQ". All NASDAQ-listed
stocks (AAPL, MSFT, GOOGL, etc.) were silently excluded from registry.
Fixed with case-insensitive _US_EXCHANGE_MAP lookup + canonical normalization.
2. OOM during large builds: SEC EDGAR companyfacts JSONs accumulate in
_json_cache without eviction, causing OOM after ~1500-1800 tickers.
Fixed by clearing _json_cache + _text_cache + gc.collect() every 20
batches. Memory remains stable throughout full 9,376-ticker build.
Result: 529,328 snapshot rows, 5,570 tickers (NASDAQ:2515, NYSE:2084, OTC:971)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>