Commit Graph

15 Commits

Author SHA1 Message Date
chemavx 0cdb0758c4 feat(strategy): Manifold cross-market signal + per-feature contribution logging
CI/CD / build-and-push (push) Successful in 2m21s
Signal 5: ManifoldClient queries Manifold Markets API for a matching binary
market by keyword overlap (threshold 0.25) and applies a log-odds adjustment
proportional to the divergence from the Polymarket prior.

  manifold_log_adj = (log_odds(manifold_prob) - log_odds(prior)) × 0.6

A 30pp divergence (Manifold 0.75 vs Poly 0.45) produces edge_gross ≈ 0.19,
clearing the politics far-horizon regime_min=0.12 after costs. Confidence
boosted +0.08 when Manifold match found.

Per-feature observability: every SKIP_EDGE_NET and TRADE log line now includes
  fg=±X.XXX  mom=±X.XXX  mfld=±X.XXXX  news=±X.XXXX
so the contribution of each signal to edge is auditable per market.

Files: bot/data/manifold.py (new), bot/strategy/bayesian.py, bot/main.py

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-17 10:07:47 +00:00
chemavx 411d346261 feat(bot): add [CYCLE SUMMARY] diagnostic block at end of each cycle
CI/CD / build-and-push (push) Successful in 2m16s
BayesianStrategy now tracks per-cycle counters (reset each cycle):
  - skip_prior_extreme, skip_family
  - skip_edge_net_nonpositive (edge_net ≤ 0)
  - skip_edge_net_below_regime (0 < edge_net < regime_min)
  - evaluated_edges list for max/pct computations

main.py logs one structured [CYCLE SUMMARY] block per cycle with:
  markets_total, markets_uncertainty_zone, max_edge_gross, max_edge_net,
  pct_edge_gross_gt_002, pct_edge_gross_gt_004, all blocked_by_* counters,
  trades_executed, gnews_queries_used/cap

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-16 15:55:22 +00:00
chemavx 63d9f637ff feat(bot): 5-phase strategy upgrade — edge neto, families, GNews priority, regimes
CI/CD / build-and-push (push) Successful in 2m30s
Phase 1 — Edge neto real (paper.py, bayesian.py, risk/manager.py, db.py):
- Trade records now store edge_gross, edge_net, prior_prob, final_prob,
  mid_price, spread_estimate, commission, family_key
- edge_net = edge_gross - SPREAD_ESTIMATE(0.02) - COMMISSION_RATE(0.02)
  NOTE: both constants are heuristics, not exact Polymarket exchange costs
- Execution gate changed from edge_gross > MIN_EDGE to edge_net > regime_min_edge

Phase 2 — Market families (polymarket.py):
- market_family_key(market) groups related markets:
    texas-republican-2026, fed-april-2026, openai-2026, etc.
- At most 1 trade per family per cycle; occupied_families propagated via main.py
- Family key logged on every TRADE and SKIP line

Phase 3 — GNews priority (news.py, bayesian.py, main.py):
- NewsClient.get_freshness() returns 1.0/0.75/0.40/0.10 by cache age
- gnews_priority(market, news) = uncertainty × volume_score × freshness
- Politics markets sorted by priority DESC before eval so best markets get
  the 5-query/cycle GNews budget first

Phase 4 — Regime min-edge by category/horizon (bayesian.py):
- politics >60d → 0.12, 30-60d → 0.10, <30d → 0.08
- tech / crypto/finance → 0.10
- All thresholds applied to edge_net (not edge_gross)

Phase 5 — Observability (bayesian.py, main.py):
- Structured skip labels: SKIP_UNSUPPORTED, SKIP_NO_SIGNALS,
  SKIP_PRIOR_EXTREME, SKIP_FAMILY, SKIP_GNEWS_PRIORITY, SKIP_EDGE_NET
- TRADE lines now include family_key, edge_gross, edge_net, regime_min, days
- schema.sql: 8 new cols on trades, 7 new cols on signals (via ALTER TABLE IF NOT EXISTS)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-16 15:34:46 +00:00
chemavx a0cbdc0256 fix(polymarket): correct sports/tech/finance categorization + widen 90d window
CI/CD / build-and-push (push) Successful in 2m31s
- Add European football leagues (La Liga, Premier League, Bundesliga, etc.)
  to _SPORTS_EXCLUSIONS so those markets are filtered before category detection
- Reorder _detect_category: check tech before crypto/finance so company-specific
  markets (OpenAI IPO, NVIDIA, Apple) resolve to "tech" instead of "crypto/finance"
- Widen resolution horizon default from 60 to 90 days to surface more
  markets in the 0.08–0.92 uncertainty zone

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-16 14:30:34 +00:00
chemavx 324edbe4c8 feat(polymarket): exclude sports markets before category detection
CI/CD / build-and-push (push) Successful in 1m33s
Add _SPORTS_EXCLUSIONS list checked first in _detect_category so NBA/NFL/
MLB/NHL/tennis/golf/UFC/boxing/wrestling/tournament markets never bleed into
politics or events categories. Also removes 'super bowl' from _EVENTS_KEYWORDS
since it's now covered by the sports exclusion.

Keywords excluded: nba, nfl, mlb, nhl, basketball, football, baseball, hockey,
soccer, mvp, rookie of the, championship, super bowl, world series, playoffs,
playoff, tournament, tennis, golf, ufc, boxing, wrestler, wrestling,
slam dunk, home run, touchdown.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-14 13:03:49 +00:00
chemavx 7b9c5751ea feat(polymarket): widen market filter for more uncertainty-zone markets
CI/CD / build-and-push (push) Successful in 1m31s
- min_volume: 1000 → 500 USDC (surface lower-liquidity but real markets)
- max_days_to_resolution: 30 → 60 days (more markets with unresolved uncertainty)
- Tech keywords: +tesla, +elon, +nuclear, +quantum, +chip
- Macro keywords: +recession, +gdp, +unemployment, +trade war, +trade deal
  (inflation/tariff already present)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-14 12:53:53 +00:00
chemavx 5a9c6add41 feat(strategy): skip markets with extreme priors (< 0.08 or > 0.92)
CI/CD / build-and-push (push) Successful in 1m33s
Markets where Polymarket consensus is near-certain leave no room for our
signals to generate MIN_EDGE=0.10 — evaluating them wastes GNews quota and
produces noise. Filter them out early with a clear log reason.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-14 12:48:23 +00:00
chemavx 82d6d357eb feat(news): replace keyword sentiment with VADER
CI/CD / build-and-push (push) Successful in 1m27s
vaderSentiment==3.3.2 added to requirements.txt.

_score_headlines now:
- scores each article (title + description) with VADER compound ∈ [-1, +1]
- filters out articles with |compound| ≤ 0.05 (no clear signal)
- weights remaining articles by recency (GNews newest-first, rank 0 → highest weight)
- returns weighted mean clamped to [-1, +1]

Removes the custom keyword sets (_POSITIVE/_NEGATIVE) and the set-based
bag-of-words algorithm that capped scores at ~±0.5 in practice.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-14 12:42:19 +00:00
chemavx 33ad86f352 feat(news): 6h cache, politics-only, max 5/cycle, 2s sleep between calls
CI/CD / build-and-push (push) Successful in 1m32s
- CACHE_TTL: 4h → 6h (≤36 req/day with ≤9 politics markets)
- GNews only called for is_politics markets (BTC/F&G cover crypto/macro)
- MAX_NEWS_QUERIES_PER_CYCLE=5: BayesianStrategy.reset_cycle() called each
  iteration; counter increments only on actual API call (cache hits free)
- 2s asyncio.sleep in news.py finally block after each real HTTP request
- main.py sorts markets: politics first by end_date ascending, so soonest-
  resolving markets consume the 5-query budget before others

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-14 12:33:26 +00:00
chemavx d642dbd9cf fix(news): remove paid-tier 'from' param, add User-Agent, log status+body on error
CI/CD / build-and-push (push) Successful in 1m34s
- Drop the 'from' date filter — it's a paid GNews feature, causes 403 on free tier
- Add User-Agent header to httpx client; urllib default passes, httpx default blocked
- Log actual HTTP status code for every request (INFO) and response body on non-200
- Cache neutral result on 400/401/403/429 to avoid hammering the quota
- Remove unused _iso_days_ago() helper and 'days' param from get_sentiment()

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-14 08:36:46 +00:00
chemavx 4dadd3c2c4 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>
2026-04-14 08:24:11 +00:00
chemavx 98e7f5fe73 feat(logging): log prior/estimate/edge/reason for every evaluated market
CI/CD / build-and-push (push) Successful in 1m35s
Every market now emits an INFO line:
  TRADE/SKIP <question> | cat=... | prior=... | est=... | edge=... | conf=... | dir=... | signals=... [| reason=...]
Unsupported-category and no-external-signals early exits also log at INFO
so the full evaluation funnel is visible without changing log level.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-14 08:15:49 +00:00
chemavx b8d2b733fd feat: expand market coverage to politics, tech, and events categories
CI/CD / build-and-push (push) Successful in 1m31s
- polymarket.py: add keyword lists for politics (election, trump, ukraine…),
  tech (AI, OpenAI, Apple, nvidia…), and events (super bowl, oscar, spacex…);
  introduce _detect_category() so all four categories flow through a single
  code path; filter already-expired markets (end_dt < now) in addition to
  the existing future-cutoff filter; log per-category counts at startup
- bayesian.py: extend is_any_supported to include is_politics / is_tech /
  is_events; use BTC as a risk-sentiment proxy for non-crypto categories
  (halved weight to reflect weaker correlation); cap confidence_cap at 0.65
  for macro/politics/tech/events; MIN_EDGE stays at 0.10

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-14 08:07:17 +00:00
chemavx f8c4f8b78a ci: test pipeline trigger — minor comment update
CI/CD / build-and-push (push) Successful in 1m41s
2026-04-13 20:40:13 +00:00
chemavx 4fda34df3b feat: initial commit — polymarket-bot source + CI/CD pipeline
CI/CD / build-and-push (push) Failing after 30s
2026-04-13 16:05:45 +00:00