Strategy Overview

PolySpread is a pure spread-capture bot for Polymarket's BTC Up/Down prediction markets. It simultaneously buys one Up share and one Down share whenever their combined price is below $0.90, locks in the difference, and holds both to settlement. At settlement, exactly one side pays $1.00, yielding a guaranteed profit of $1.00 - (up_price + down_price) per pair.

This is not a directional trading strategy. The bot does not predict whether BTC will go up or down. It simply exploits temporary pricing inefficiencies in the order book.

Entry Condition

The only condition for entering a trade is that the combined price of Up and Down is below $0.90:

if up_price + down_price < 0.90:
    # Enter trade — at least 10¢ guaranteed profit
    enter_pair()

There is no per-side price cap. A pair at 55¢ + 30¢ = 85¢ is just as valid as 48¢ + 40¢ = 88¢. Only the combined sum matters because profit = $1.00 - (up + down) regardless of per-side allocation.

Why combined only?

Profit at settlement is always $1.00 per winning share. If you paid 55¢ + 30¢ = 85¢ total, your profit is 15¢ regardless of which side wins. Per-side caps would exclude profitable pairs like 55¢ + 30¢.

Share Calculation

Polymarket's CLOB enforces a $1 minimum per order. To stay close to the $1 target while meeting this requirement, the bot uses ceiling division:

shares = math.ceil(1.0 / price)

At 48¢: ceil(1.0 / 0.48) = 3 shares → costs $1.44 (above $1 min)
At 5¢: ceil(1.0 / 0.05) = 20 shares → costs $1.00 (at $1 min)
At 50¢: ceil(1.0 / 0.50) = 2 shares → costs $1.00 (at $1 min)

Why not floor?

int(1.0 / 0.55) = 1 share at 55¢ = $0.55 order — CLOB rejects this as below minimum. Ceiling ensures every order meets the $1 requirement.

Execution Order

Execution order matters for preventing orphaned positions:

1. Buy Up (FAK limit)  # Harder to fill (pricier)
2. if Up filled:
        Buy Down (FAK limit)  # Easier to fill (cheaper)
    else:
        Skip pair entirely

Up is typically more expensive (68¢-94¢ range) and harder to fill. By buying it first, we ensure we never hold a Down position without its Up pair. If Up doesn't fill, the entire pair is abandoned.

Up-first prevents orphaned Downs

Down fills easily at 5-11¢. If we bought Down first and Up failed to fill, we'd hold a useless Down share. Up-first execution eliminates this risk entirely.

Order Type: FAK Limit

All orders use Fill-or-Kill (FAK) limit orders:

Risk Controls

ControlValueWhy
Deadline protection90s before window endNo trades in final 90 seconds — too close to resolution
Per-side max spend$5 per side per windowLimits exposure to $10 total per window
Hard price floor$0.05Ignore shares priced below 5¢ — no edge
Cooldown between trades2 secondsPrevents rapid-fire entries

Hold to Settlement

The bot never sells. Every purchased share is held until the window resolves. At settlement, the winning side automatically pays $1.00 per share. No exit management needed.

How settlement works

Polymarket resolves each window against Chainlink's BTC/USD data stream. If BTC ends higher than at window start, Up shares pay $1.00 and Down pays $0.00 — and vice versa. The bot always holds both, so it always receives exactly $1.00 per pair.

Example: Simulated Window Run

Here's what one 5-minute window looked like in simulation mode (no real money):

MetricValue
Total trades12
Complete pairs6
Total spend$9.93
Theoretical profit$1.07 (~11%)
Settlement value$11.00 (if Down won)

Key Design Decisions

DecisionWhy
Combined < 0.90, no per-side capPer-side 50¢ cap made combined < 0.90 impossible. Only combined price matters for profit.
Up-first executionDown fills at 5-11¢ (easy). Without Up pair it's orphaned. Up-first avoids this.
FAK over GTC limit ordersFAK = immediate fill-or-kill. GTC needs order management and cancellation on window end.
ceil(1.0/price) over int(1.0/price)CLOB enforces $1 minimum. int gives $0.50-$0.90 → rejected. ceil ensures ≥$1.00.
No SELLsHold to settlement. Platform pays $1 for winning shares automatically.