feat: add GNews sentiment signal for politics/tech/events markets
CI/CD / build-and-push (push) Successful in 1m28s

bot/data/news.py (new):
- NewsClient with in-memory cache (TTL=4h) to stay within 100 req/day limit
- _build_query(): strips dates, punctuation and stopwords from market question
- _score_headlines(): keyword-based pos/neg vote per article, averaged ∈ [-1, +1]
- Degrades to 0.0 on missing key, 403 quota, or network error

bot/strategy/bayesian.py:
- BayesianStrategy(news=NewsClient) — optional, backwards compatible
- Signal 4: GNews sentiment applied as direct log-odds shift (weight=1.5)
  so a ±1.0 sentiment score moves a 50% prior to 82%/18%
- +0.10 confidence boost when news signal is present
- NEWS_LOGODDS_WEIGHT constant documented at module level

bot/main.py:
- Instantiate NewsClient, pass to BayesianStrategy, close in finally block

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
chemavx
2026-04-14 08:24:11 +00:00
parent 98e7f5fe73
commit 4dadd3c2c4
3 changed files with 223 additions and 4 deletions
+4 -1
View File
@@ -9,6 +9,7 @@ from contextlib import asynccontextmanager
from bot.data.polymarket import PolymarketClient
from bot.data.external import ExternalDataClient
from bot.data.news import NewsClient
from bot.strategy.bayesian import BayesianStrategy
from bot.risk.manager import RiskManager
from bot.executor.paper import PaperExecutor
@@ -98,7 +99,8 @@ async def main() -> None:
poly = PolymarketClient()
external = ExternalDataClient()
strategy = BayesianStrategy()
news = NewsClient()
strategy = BayesianStrategy(news=news)
risk = RiskManager(max_position_pct=0.05, max_exposure_pct=0.30)
executor = PaperExecutor(db=db, bankroll=PAPER_BANKROLL) if PAPER_MODE else None
metrics = MetricsTracker(db=db)
@@ -115,6 +117,7 @@ async def main() -> None:
await run_trading_loop(poly, external, strategy, risk, executor, metrics)
finally:
await db.disconnect()
await news.close()
if __name__ == "__main__":