Trade Polymarket markets based on valuation divergence. When your probability model differs from Polymarket's price by >threshold, enter using Kelly sizing. Works with any probability model (Simmer AI consensus, user model, external API).
Trade markets where model probability diverges from Polymarket price.
This is a template. The default uses Simmer AI consensus as your probability model. Remix it with your own model, external APIs, or custom forecasting logic. The skill handles market scanning, Kelly sizing, and safe trade execution.
Use this when:
export SIMMER_API_KEY=sk_live_...
Check config:
python valuation_trader.py --config
Dry run (no trades):
python valuation_trader.py
Live trading:
python valuation_trader.py --live
| Setting | Env Var | Default | Description |
|---|---|---|---|
| edge_threshold | SIMMER_VALUATION_EDGE | 0.015 | Min edge to trade (1.5%) |
| kelly_fraction | SIMMER_VALUATION_KELLY | 0.25 | Kelly criterion fraction (cap at 25%) |
| max_position_usd | SIMMER_VALUATION_MAX_POSITION | 5.00 | Max per trade |
| max_trades_per_run | SIMMER_VALUATION_MAX_TRADES | 5 | Max trades per cycle |
| probability_source | SIMMER_VALUATION_SOURCE | simmer_ai | "simmer_ai" or "user_model" |
Update settings:
python valuation_trader.py --set edge_threshold=0.02
Fetches active markets from Simmer. For each:
Default: Simmer AI consensus from /api/sdk/context/{market_id}
To use your own model: Edit get_model_probability() function.
edge = model_probability - market_price
If edge > threshold: trade signal ✓
kelly_fraction = edge / (1 - market_price)
kelly_fraction = min(kelly_fraction, MAX_KELLY)
position_size = kelly_fraction * bankroll
position_size = min(position_size, max_position_usd)
Positions held until market resolves. Check --positions to see current holdings.
🎯 Valuation Trader Scan
Markets scanned: 50
Signals found: 3
Executed: 2
📰 BTC hits $100k by EOY?
Model: 65% | Market: 52% | Edge: +13%
💰 BUY YES $4.50 (Kelly: 2.25 shares)
📰 Will Trump win in 2028?
Model: 58% | Market: 71% | Edge: -13%
💰 BUY NO $3.75 (Kelly: 2.05 shares)
Edit get_model_probability() to use any source:
Option 1: User-provided probabilities (config)
def get_model_probability(market_id, market_question):
# Return fixed probability from config
return USER_PROBABILITIES.get(market_id)
Option 2: External API (e.g., Synth, Metaculus)
def get_model_probability(market_id, market_question):
# Fetch forecast from external API
resp = fetch_json(f"{EXTERNAL_API}/forecast?q={market_question}")
return resp["probability"]
Option 3: Rules-based model
def get_model_probability(market_id, market_question):
if "crypto" in market_question.lower():
return 0.55 # Crypto has historical upside
elif "election" in market_question.lower():
return 0.50 # No strong signal on elections
return None # Skip if no model
# Dry run (simulate trades, no real execution)
python valuation_trader.py
# Live trading
python valuation_trader.py --live
# Show current positions
python valuation_trader.py --positions
# Show config
python valuation_trader.py --config
# Update config
python valuation_trader.py --set edge_threshold=0.02
# Quiet mode (cron-friendly)
python valuation_trader.py --live --quiet
max_position_usd limits each trademax_trades_per_run prevents over-trading"No signals found"
edge_threshold in config if too conservative"Markets scanned: 0"
"Edge is negative but we're buying YES"
"Flip-flop warning: CAUTION"
--no-safeguards.Check your performance:
python valuation_trader.py --positions
Shows: realized P&L, win rate, average edge per trade, largest positions.
Start small. Test with dry-run first. Verify your model against historical outcomes. Then go live with small position sizes.