A Python implementation of the "gabagool strategy" for guaranteed-profit arbitrage on Polymarket's binary prediction markets.
In binary markets (YES/NO outcomes), the two sides always settle to $1.00 combined:
- If YES wins → YES pays $1.00, NO pays $0.00
- If NO wins → NO pays $1.00, YES pays $0.00
The insight: If you can acquire YES + NO shares for less than $1.00 combined, you lock in profit regardless of outcome.
Buy 100 YES @ $0.45 = $45.00
Buy 100 NO @ $0.48 = $48.00
Total cost: $93.00
At settlement:
- If YES wins: 100 × $1.00 = $100.00 → Profit: $7.00
- If NO wins: 100 × $1.00 = $100.00 → Profit: $7.00
Guaranteed profit: $7.00 (7.5% return)
Short-term markets (especially 15-minute crypto predictions) have wild price swings due to emotions. When people panic-sell one side, prices get mispriced. You don't predict direction—you just buy whichever side is cheap.
cd polymarket_arb
pip install -r requirements.txtTest trades and see how they affect your pair cost:
python cli.py calculatorSee the strategy in action with synthetic data:
python cli.py simulatepython cli.py markets --limit 20
python cli.py markets --crypto-15m # 15-minute marketspython cli.py scan --min-margin 0.02 # 2% minimum marginpython cli.py monitor --duration 900 --interval 2.0| Metric | Description | Target |
|---|---|---|
| Pair Cost | avg(YES price) + avg(NO price) | < $1.00 |
| Paired Shares | min(YES shares, NO shares) | Balanced |
| Guaranteed Profit | Paired shares × (1.00 - Pair Cost) | Positive |
| Exposure | YES shares - NO shares | Near zero |
polymarket_arb/
├── cli.py # Command-line interface
├── bot.py # Main arbitrage bot
├── core/
│ └── position_tracker.py # Position & P&L tracking
├── api/
│ └── client.py # Polymarket API client
└── data/ # Saved positions (auto-created)
Edit BotConfig in bot.py:
BotConfig(
max_capital_per_market=1000, # Max $ per market
max_pair_cost=0.98, # Target 2% margin
min_arbitrage_margin=0.02, # Min spread to trade
poll_interval=2.0, # Seconds between checks
dry_run=True, # Simulate only
)- Scan markets for YES + NO < $1.00
- Identify which side is cheaper
- Simulate trade impact on pair cost
- Execute if it improves position
- Balance to minimize directional exposure
- Repeat until market closes
- Start with
dry_run=Trueto simulate - Use small position sizes initially
- Monitor for API rate limits
- Be aware of liquidity constraints
- 15-minute markets may require specific API endpoints
- Some markets have minimum order sizes
- Fees can compress margins
- Live trading requires wallet setup and API keys
- This is a proof-of-concept, not production-ready
- Past performance doesn't guarantee future results
from core.position_tracker import Position
pos = Position(market_id="btc-up-down", market_name="BTC 15m")
pos.add_trade('YES', quantity=100, price=0.45)
pos.add_trade('NO', quantity=100, price=0.48)
print(pos.pair_cost) # 0.93
print(pos.guaranteed_profit) # 7.00# Check impact before executing
sim = pos.simulate_trade('YES', 50, 0.40)
print(sim['should_execute']) # True/False
print(sim['profit_change']) # Expected profit changefrom api.client import PolymarketClient
client = PolymarketClient()
markets = client.get_markets(active=True, tag_slug='crypto')
price = client.get_market_price(market)
print(price.arbitrage_margin)Implement execute_trade() in bot.py using the Polymarket CLOB client:
pip install py-clob-clientFor real-time price feeds instead of polling.
Replace JSON state files with SQLite for better history tracking.
This software is for educational purposes. Trading involves risk of loss. Do your own research and never trade more than you can afford to lose.