Install
openclaw skills install polymarket-negrisk-arbClawHub Security found sensitive or high-impact capabilities. Review the scan results before using.
Scan multi-outcome Polymarket markets for mathematical arbitrage. When the sum of all outcome prices falls below $1.00, buy all sides simultaneously via batch trade to lock in risk-free profit. No signals. No AI. Just math.
openclaw skills install polymarket-negrisk-arbThis is a template. The default signal is NegRisk price sum deviation from $1.00 — remix it with tighter thresholds, different min-profit floors, or additional liquidity filters. The skill handles all the plumbing (market discovery, grouping, batch execution, safeguards). Your agent provides the edge by tuning when and how aggressively to enter.
Scan multi-outcome markets for mathematical arbitrage opportunities. When the sum of all outcome prices deviates from $1.00, buy the mispriced side across all buckets simultaneously using Simmer's batch trade endpoint.
No signals. No AI. Just math.
Polymarket NegRisk markets have multiple mutually exclusive outcomes (e.g., election candidates, tweet count ranges). Exactly one outcome resolves YES = $1.00.
The Math:
In an efficient market:
sum(all YES prices) = $1.00
sum(all NO prices) = $1.00
When markets are inefficient:
sum(YES) < $0.95 → Buy ALL YES → guaranteed $1.00 payout, cost < $0.95 → profit
sum(NO) < $0.95 → Buy ALL NO → guaranteed $1.00 payout, cost < $0.95 → profit
Example:
Election market — 4 candidates:
Candidate A: YES = $0.45
Candidate B: YES = $0.22
Candidate C: YES = $0.18
Candidate D: YES = $0.08
Sum = $0.93 (< $0.95 threshold)
→ Buy ALL YES for $0.93 total
→ One candidate wins → collect $1.00
→ Profit: $0.07 (7.5% return, risk-free)
pip install simmer-sdk
export SIMMER_API_KEY="your-key-here"
# Scan for opportunities (dry run, no trades)
python negrisk_arb.py
# Execute real trades
python negrisk_arb.py --live
# Only show YES arbitrage
python negrisk_arb.py --side yes
# Only show NO arbitrage
python negrisk_arb.py --side no
# Set minimum profit threshold
python negrisk_arb.py --min-profit 0.05
# JSON output
python negrisk_arb.py --json
# Quiet mode for cron
python negrisk_arb.py --live --quiet
# Show stats
python negrisk_arb.py --stats
# Show config
python negrisk_arb.py --config
# Update config
python negrisk_arb.py --set max_position_usd=10.00
| Setting | Env Variable | Default | Description |
|---|---|---|---|
| max_yes_sum | SIMMER_NEGRISK_MAX_YES_SUM | 0.95 | Max sum of YES prices to trigger buy |
| max_no_sum | SIMMER_NEGRISK_MAX_NO_SUM | 0.95 | Max sum of NO prices to trigger buy |
| min_profit_pct | SIMMER_NEGRISK_MIN_PROFIT | 0.03 | Min profit % after fees (3%) |
| max_position_usd | SIMMER_NEGRISK_MAX_POSITION | 10.00 | Max USD per outcome bucket |
| max_total_usd | SIMMER_NEGRISK_MAX_TOTAL | 50.00 | Max total USD per event |
| max_trades_per_run | SIMMER_NEGRISK_MAX_TRADES | 2 | Max arbitrage events per cycle |
| daily_budget | SIMMER_NEGRISK_DAILY_BUDGET | 50.00 | Daily spend limit |
| min_outcomes | SIMMER_NEGRISK_MIN_OUTCOMES | 3 | Min outcomes per event (skip binary) |
| max_outcomes | SIMMER_NEGRISK_MAX_OUTCOMES | 15 | Max outcomes (too many = illiquid) |
| slippage_max_pct | SIMMER_NEGRISK_SLIPPAGE | 0.05 | Max slippage tolerance (5%) |
| fee_filter | SIMMER_NEGRISK_FEE_FILTER | true | Skip markets with fees |
| require_simultaneous | SIMMER_NEGRISK_SIMULTANEOUS | true | Use batch trades for simultaneous execution |
Each cycle the script:
yes_cost = sum of all YES prices in cluster
payout = $1.00 (exactly one resolves YES)
fee_cost = sum of (price × fee_rate) for each outcome
net_profit = payout - yes_cost - fee_cost
profit_pct = net_profit / yes_cost
Only trades when profit_pct >= min_profit_pct.
Standard sequential trades are risky:
Buy outcome A → price moves → Buy outcome B → sum now > $1 → no longer profitable
This skill uses Simmer's batch endpoint:
POST /api/sdk/trades/batch
{
"trades": [
{"market_id": "uuid-A", "side": "yes", "amount": 5.0},
{"market_id": "uuid-B", "side": "yes", "amount": 5.0},
{"market_id": "uuid-C", "side": "yes", "amount": 5.0}
],
"venue": "polymarket",
"source": "sdk:negrisk-arb"
}
All trades execute in parallel — minimizes timing risk.
🔢 NegRisk Arbitrage Scanner
==================================================
⚙️ Configuration:
Max YES sum: $0.95
Max NO sum: $0.95
Min profit: 3.0%
Max position: $10.00/bucket
Daily budget: $50.00
🔍 Scanning 847 active markets...
Grouped into 203 multi-outcome events
Evaluating 203 events for arbitrage...
🎯 Opportunities Found: 2
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Event: "Who wins the 2026 German election?"
Side: YES arbitrage
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
CDU/CSU: $0.38
SPD: $0.27
Greens: $0.15
AfD: $0.09
FDP: $0.04
──────────────
Sum: $0.93 (< $0.95 threshold) ✅
Profit calculation:
Cost: $0.93
Payout: $1.00
Net: +$0.07 (7.5%) ✅
Fees: $0.00 (zero-fee market) ✅
Slippage: ~1.2% (within limit) ✅
Executing batch trade...
✅ CDU/CSU YES — 13.2 shares @ $0.38
✅ SPD YES — 18.5 shares @ $0.27
✅ Greens YES — 33.3 shares @ $0.15
✅ AfD YES — 55.6 shares @ $0.09
✅ FDP YES — 125.0 shares @ $0.04
Total spent: $4.65
Expected gain: $0.35 (7.5%)
📊 Summary:
Events scanned: 203
Opportunities: 2
Trades executed: 8 (batch)
Total invested: $9.30
Expected profit: $0.70
The skill tracks every arbitrage in negrisk_ledger.json:
Run --stats after 20+ events to see real performance vs theoretical edge.
"No arbitrage opportunities found"
min_profit_pct to 0.02"All events skipped for fees"
fee_filter=false to override (not recommended)"Batch trade partially filled"
max_position_usd to reduce market impactslippage_max_pct slightly"Sum check passed but trade rejected"
"Event has too many outcomes"
max_outcomes settingGET /api/sdk/markets — Market list with prices and divergenceGET /api/sdk/context/{market_id} — Fee rates and slippage estimatesPOST /api/sdk/trades/batch — Simultaneous multi-outcome executionGET /api/sdk/positions — Current portfolio positionsGET /api/sdk/portfolio — Balance and daily spend tracking"automaton": {
"managed": true,
"entrypoint": "negrisk_arb.py --live --quiet",
"cron": "0 */2 * * *"
}
Runs every 2 hours. Arbitrage windows can be short — more frequent scanning catches more opportunities.
Or via OpenClaw native cron:
openclaw cron add \
--name "NegRisk Arbitrage" \
--cron "0 */2 * * *" \
--session isolated \
--message "Run NegRisk arbitrage scan: cd /path/to/skill && python negrisk_arb.py --live --quiet. Show summary." \
--announce