Files
polymarket-bot/bot/data/schema.sql
T
chemavx 63d9f637ff
CI/CD / build-and-push (push) Successful in 2m30s
feat(bot): 5-phase strategy upgrade — edge neto, families, GNews priority, regimes
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

101 lines
5.2 KiB
SQL

-- Polymarket Bot Database Schema
CREATE TABLE IF NOT EXISTS trades (
id TEXT PRIMARY KEY,
market_id TEXT NOT NULL,
question TEXT NOT NULL,
direction TEXT NOT NULL, -- BUY_YES | BUY_NO
size_usdc DOUBLE PRECISION,
entry_price DOUBLE PRECISION,
shares DOUBLE PRECISION,
fee_usdc DOUBLE PRECISION,
net_cost DOUBLE PRECISION,
timestamp TIMESTAMPTZ NOT NULL,
reasoning TEXT,
paper BOOLEAN DEFAULT TRUE
);
CREATE TABLE IF NOT EXISTS metrics_daily (
id SERIAL PRIMARY KEY,
timestamp TIMESTAMPTZ NOT NULL,
total_trades INTEGER,
total_deployed DOUBLE PRECISION,
total_fees DOUBLE PRECISION,
total_pnl DOUBLE PRECISION,
win_rate DOUBLE PRECISION,
avg_edge DOUBLE PRECISION,
sharpe_ratio DOUBLE PRECISION,
calibration_score DOUBLE PRECISION,
paper_mode BOOLEAN DEFAULT TRUE
);
CREATE TABLE IF NOT EXISTS markets (
id TEXT PRIMARY KEY,
condition_id TEXT,
question TEXT NOT NULL,
category TEXT,
end_date TEXT,
active BOOLEAN DEFAULT TRUE,
last_seen TIMESTAMPTZ DEFAULT NOW()
);
CREATE TABLE IF NOT EXISTS signals (
id SERIAL PRIMARY KEY,
market_id TEXT NOT NULL,
timestamp TIMESTAMPTZ NOT NULL,
polymarket_price DOUBLE PRECISION,
estimated_prob DOUBLE PRECISION,
edge DOUBLE PRECISION,
confidence DOUBLE PRECISION,
direction TEXT,
acted_on BOOLEAN DEFAULT FALSE
);
CREATE INDEX IF NOT EXISTS idx_trades_timestamp ON trades(timestamp DESC);
CREATE INDEX IF NOT EXISTS idx_trades_market ON trades(market_id);
CREATE INDEX IF NOT EXISTS idx_metrics_timestamp ON metrics_daily(timestamp DESC);
CREATE INDEX IF NOT EXISTS idx_signals_timestamp ON signals(timestamp DESC);
-- ─────────────────────────────────────────────────────────────────────────────
-- Phase 1 migrations: edge neto real
--
-- spread_estimate and commission are HEURISTICS, not exact Polymarket exchange
-- costs. spread_estimate ≈ estimated half-spread for medium-liquidity markets.
-- commission = COMMISSION_RATE (0.02) * size_usdc — mirrors Polymarket taker fee.
-- edge_net = edge_gross - spread_estimate - commission/size_usdc
-- = edge_gross - 0.02 - 0.02 (always 0.04 deduction at current rates)
--
-- These are stored per-trade so we can audit whether the model's cost assumptions
-- were met in practice once markets resolve.
-- ─────────────────────────────────────────────────────────────────────────────
ALTER TABLE trades ADD COLUMN IF NOT EXISTS edge_gross DOUBLE PRECISION;
ALTER TABLE trades ADD COLUMN IF NOT EXISTS edge_net DOUBLE PRECISION;
ALTER TABLE trades ADD COLUMN IF NOT EXISTS prior_prob DOUBLE PRECISION;
ALTER TABLE trades ADD COLUMN IF NOT EXISTS final_prob DOUBLE PRECISION;
ALTER TABLE trades ADD COLUMN IF NOT EXISTS mid_price DOUBLE PRECISION;
ALTER TABLE trades ADD COLUMN IF NOT EXISTS spread_estimate DOUBLE PRECISION;
ALTER TABLE trades ADD COLUMN IF NOT EXISTS commission DOUBLE PRECISION;
ALTER TABLE trades ADD COLUMN IF NOT EXISTS family_key TEXT;
-- ─────────────────────────────────────────────────────────────────────────────
-- Phase 2 / Phase 5 migrations: market families + observability
--
-- Signals table extended so each evaluated market carries its audit trail:
-- skip_reason — why the market was not traded ("edge_net", "family",
-- "gnews_priority", "regime", "prior_extreme", etc.)
-- passed_gross — True if edge_gross alone met regime_min_edge
-- passed_net — True if edge_net met regime_min_edge (the actual gate)
-- family_key — market family slug (e.g. "texas-republican-2026")
-- regime_min_edge — threshold that applied to this market/category
-- ─────────────────────────────────────────────────────────────────────────────
ALTER TABLE signals ADD COLUMN IF NOT EXISTS edge_gross DOUBLE PRECISION;
ALTER TABLE signals ADD COLUMN IF NOT EXISTS edge_net DOUBLE PRECISION;
ALTER TABLE signals ADD COLUMN IF NOT EXISTS family_key TEXT;
ALTER TABLE signals ADD COLUMN IF NOT EXISTS regime_min_edge DOUBLE PRECISION;
ALTER TABLE signals ADD COLUMN IF NOT EXISTS skip_reason TEXT;
ALTER TABLE signals ADD COLUMN IF NOT EXISTS passed_gross BOOLEAN;
ALTER TABLE signals ADD COLUMN IF NOT EXISTS passed_net BOOLEAN;
CREATE INDEX IF NOT EXISTS idx_signals_market ON signals(market_id);
CREATE INDEX IF NOT EXISTS idx_trades_family ON trades(family_key);