poll_loop: asyncio.gather parallel fetch of 3 endpoints (portfolio,
news_sentiment, screener_preview) + state update. main.py: FastAPI
lifespan creates StockClient/SignalDedup/shutdown.Event then spawns
poll_loop as background task. GET /health reports status, last poll
times, cache size.
Signal V2 test suite: 19/19 PASS.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>