LIVE
$7.62 min profit is yours / per trade
Get the bot

Expected value Polymarket arbitrage: how to calculate EV correctly

Practical guide to computing expected value for Polymarket arbitrage trades, including taker fees, partial-fill probability, and settlement risks. Step-by-step EV formulas and a working code example.

อัปเดต 2026-04-20· 8 min
arbitrage
expected value
Polymarket
trading

Expected value Polymarket arbitrage: how to calculate EV correctly

This guide shows you how to compute expected value Polymarket arbitrage trades step-by-step, including taker fees, partial-fill probability, and settlement risks. If you run intra-market binary or combinatorial arb on Polymarket, these formulas turn a nominal price gap into an actionable EV estimate.

Key takeaways

  • EV = (payout − cost − fees) × fill probability − downside from partial fills and settlement timing.
  • Always include taker fees and expected partial-fill rates; maker fees are zero on Polymarket so they only matter if you peg to passive liquidity.
  • Use simple probabilistic models (Bernoulli or binomial) for partial fills at small sizes; scale models when execution spans multiple price levels.
  • Never call an arb trade unconditional "risk-free" — list resolution, slippage, fees, UMA disputes, and smart-contract or timing risk.

1. EV fundamentals for prediction-market arbitrage

Start from first principles. A full, successful arbitrage that buys a complete set of outcome tokens costs C (sum of bought best-ask prices plus any taker fees) and ultimately redeems to $1.00 per complete set after resolution. The nominal edge is:

Edge = 1.00 − C

The expected value before fees and execution risk is simply Edge per complete set. For practical trading you must convert that into EV (expected monetary gain) by accounting for fees, the probability your order fills at the quoted prices, and potential partial fills.

EV_basic = Edge × FillProbability − Fees_expected

You will refine FillProbability and Fees_expected in the next sections.

2. Including taker fees and settlement flow

On Polymarket taker fees vary by category and currently sit between 0% and 1.8% depending on market category; maker fees are zero. For arb you typically pay taker fees on executed legs that cross the spread.

When you buy N outcomes (a complete set in a multi-outcome market or both YES and NO in binary), compute gross cost:

C_gross = Σ bestAsk_i

Taker fee per trade is expressed in basis points or percent. If fee_rate is the taker fee (as a decimal), your fees are roughly:

Fees = fee_rate × C_gross

If some legs execute as maker (rare for tight arb) they incur zero fees; model that by splitting C_gross into maker and taker portions.

Net cost C_net = C_gross + Fees

Then nominal profit if fully filled and redeemable is:

Profit_full = 1.00 − C_net

But Profit_full is only realised with probability FillProbability_full, so EV contribution is Profit_full × FillProbability_full.

3. Modelling partial fills and asymmetric execution

Partial fills are the most common source of practical loss. Two examples:

  • Your order buys YES fully but NO only partially. You are left long a residual YES exposure priced above the implied hedge.
  • Fills occur across multiple price levels; the realized C_gross is higher than the sum of first-level best asks.

A simple and useful model for small orders is a Bernoulli fill probability per leg at the displayed best ask. For larger sizes you can model fills as a binomial or as a sum of deterministic volume slices across price levels.

Notation to use in calculations:

  • q_i = quantity intended for leg i (in outcome shares)
  • f_i = probability that q_i fully fills at posted best ask
  • r_i = expected fraction filled for leg i (0 ≤ r_i ≤ 1)

Expected cost when partial fills are possible:

E[C_gross] = Σ (bestAsk_i × q_i × r_i)

Expected fees follow proportionally:

E[Fees] = fee_rate × E[C_gross] for taker-executed portion

But partial fills create an asymmetric residual position. The common conservative approach is to assume any residual single-outcome position must be immediately unwound at the worse mid/ask price, and to include the expected loss from that unwind in EV.

For example, if you expected to buy a complete set but on average only fill 90% of leg NO, you will carry 10% of YES at paid price p_yes. The worst-case residual loss is approximately 0.90 × (p_yes − mid_unwind_price) (adjust for tick sizes and fees). Include expected residual loss term L_residual in the EV.

4. A step-by-step EV formula you can implement

Define:

  • n = number of outcomes in the set (n=2 for binary)
  • ask_i = best ask price for outcome i, in dollars
  • q = target complete-set quantity (shares; e.g., 10 complete sets)
  • fee = taker fee rate as decimal (e.g., 0.006 for 0.6%)
  • r_i = expected fill fraction for leg i (0..1). For full-fill probability use r_i = 1.0.
  • p_unwind_i = expected price you can close any residual position in outcome i (conservative: use current worst ask or mid)

Compute:

  1. E[C_gross] = Σ_i ask_i × q × r_i
  2. E[Fees] = fee × E[C_gross]
  3. E[C_net] = E[C_gross] + E[Fees]
  4. Expected payout when complete sets redeem = q × 1.00 × P_redeem (P_redeem is probability of eventual redeemability; normally 1.0 absent UMA disputes — but include dispute risk below)
  5. Expected residual loss L_residual = Σ_i max(0, q × (1 − r_i) × (paid_price_i − p_unwind_i))

Final EV estimate:

EV = q × P_redeem − E[C_net] − L_residual

If you prefer EV per complete set, divide EV by q.

Notes on P_redeem: UMA disputes can pause or alter settlement. Set P_redeem ≤ 1.0 to reflect non-zero dispute risk; for many markets you can treat P_redeem ≈ 1.0 but you must explicitly account for the possibility of delayed or contested settlement.

5. Worked numerical example (binary) — implementable and conservative

Assume a small binary arbitrage where you intend to buy 100 complete-sets by buying YES and NO at their respective best asks. Use numbers only for illustration; keep fee within documented ranges.

  • ask_YES = $0.49
  • ask_NO = $0.50
  • q = 100 sets
  • fee = 0.006 (0.6% taker fee)
  • r_YES = 1.0, r_NO = 0.95 (NO may partially fill at first level)
  • p_unwind_NO = $0.52 (price you'd expect to sell residual NO)
  • P_redeem = 1.0 (assume eventual redeemability)

Compute E[C_gross] = (0.49 + 0.50) × 100 × average_r

More precisely:

E[C_gross] = (0.49 × 100 × 1.0) + (0.50 × 100 × 0.95) = 49.00 + 47.50 = 96.50

E[Fees] = 0.006 × 96.50 = 0.579

E[C_net] = 96.50 + 0.579 = 97.079

Payout = 100 × 1.00 = 100.00

L_residual: you expected 100 NO but only got 95, so you have a shortfall of 5 NO if your intention was to hold complete sets. The typical residual is the extra exposure on the other leg (YES). In this example the partial fill leaves 5 YES unpaired — if you paid 0.49 for those YES and must unwind at p_unwind_YES (conservative), compute accordingly. For symmetry a conservative residual loss estimate for misfilled leg is:

L_residual = (q × (1 − r_NO)) × (paid_price_NO_unpaired − p_unwind_NO)

If unpaired leg is the more expensive side, include that loss. Plug in numbers conservatively to avoid overstatement of EV.

Final EV = 100 − 97.079 − L_residual

If L_residual is small the trade remains positive EV; if L_residual exceeds the nominal Edge, the trade is negative. Run this math programmatically before sending orders.

6. A short, usable JavaScript snippet

This snippet computes EV per complete set, given inputs above. It is valid JavaScript and ready to drop into your risk framework.

function computeEVPerSet(asks, r, fee, p_unwind, P_redeem = 1.0) {
  // asks: array of best asks for each outcome, e.g. [0.49, 0.50]
  // r: array of expected fill fractions for each outcome, e.g. [1.0, 0.95]
  const n = asks.length;
  const q = 1; // per-set basis

  const E_C_gross = asks.reduce((s, a, i) => s + a * q * r[i], 0);
  const E_Fees = fee * E_C_gross;
  const E_C_net = E_C_gross + E_Fees;

  // Residual loss: assume unfilled fraction must be closed at p_unwind
  const L_residual = asks.reduce((s, a, i) => {
    const unfilled = q * (1 - r[i]);
    const paid_price = a; // price you paid for filled portion of this outcome
    const unwind_price = p_unwind[i];
    return s + Math.max(0, unfilled * (paid_price - unwind_price));
  }, 0);

  const EV = q * P_redeem - E_C_net - L_residual;
  return { EV_per_set: EV, E_C_gross, E_Fees, L_residual };
}

// Example
const asks = [0.49, 0.50];
const r = [1.0, 0.95];
const fee = 0.006; // 0.6%
const p_unwind = [0.48, 0.52];
console.log(computeEVPerSet(asks, r, fee, p_unwind));

Adjust the p_unwind values conservatively (use the worse ask or mid) and set r based on historical fill rates at your size.

7. Practical tips for live trading

  • Measure empirical fill rates per instrument and per size. Use short, frequent instrumentation windows; microstructure varies by market.
  • Break large intended quantities into smaller slices to reduce partial-fill risk and to stay within builder or relayer limits if applicable.
  • Account for tick-size behaviour: when prices approach extremes the tick size tightens to $0.001, which can change unwind slippage.
  • Include UMA dispute and settlement timing risk in P_redeem. Disputes can pause settlement and affect opportunity cost.
  • Respect geographic restrictions: markets are geo-blocked by IP; never recommend VPN bypass.

How this affects your trading

Compute EV per set before sending orders and compare it to your internal minimum-acceptable EV that already includes capital costs, opportunity cost of locked pUSD, and the costs of potential dispute delays. Use the EV formula programmatically in your pre-trade checks. For small, frequent arb you will typically require a modest positive EV per set after fees and expected residual loss to justify operational overhead.

Close with the primary keyword: expected value Polymarket arbitrage should always be computed conservatively, with taker fees and partial-fill probability modelled explicitly.

Frequently asked questions

How do I model partial-fill probability for larger orders?

Start with empirical fill rates at the size you trade. For small increments use Bernoulli per-slice assumptions; for larger sizes model fills as a binomial sum across price levels or use historical depth-of-book to deterministically slice your order. Always err on the conservative side when estimating r_i.

Which fees should I include in the EV calculation?

Include taker fees for executed legs — Polymarket's taker fees currently vary between 0% and 1.8% depending on category; maker fees are zero. Model fees as fee_rate × executed_cost and split executed_cost into maker/taker portions if applicable.

Do I need to account for UMA disputes in EV?

Yes. UMA disputes can pause settlement or change timing. Include a P_redeem factor ≤ 1.0 to reflect dispute probability and the expected time value/cost of delayed settlement.

Can I ignore residual unwind loss if I expect to re-balance later?

No. Residual positions carry market and directional risk. Include a conservative unwind price (p_unwind) in your EV model unless you have a documented, statistically justified plan to re-balance with known costs.

Is the nominal edge the same as EV?

No. Nominal edge = 1.00 − Σ bestAsk_i. EV adjusts that edge for taker fees, partial-fill probability, residual unwind loss, and settlement/dispute risk. Use EV for decision-making.

คำศัพท์อ้างอิง

คู่มือที่เกี่ยวข้อง

เพื่อการศึกษาเท่านั้น ไม่ใช่คำแนะนำด้านการเงิน กฎหมาย หรือภาษี Polymarket อาจไม่สามารถใช้งานได้ในเขตอำนาจของคุณ

PolyArb

PolyArb เป็นบอท arbitrage บน Polymarket ที่สแกนตลาด binary และ multi-outcome ทุกตลาดเพื่อ YES/NO < $1 และ mispricing แบบ combinatorial จากนั้นล็อคสเปรดด้วย latency 40ms — เทียบกับประมาณ 800ms ของคู่แข่ง — และมี edge ขั้นต่ำที่รับประกัน $7.62 ต่อการเทรด.

Product
Resources
Legal
© 2026 PolyArb. All rights reserved.
PolyArb เป็นเครื่องมืออิสระ ไม่เกี่ยวข้องกับ Polymarket ไม่ให้คำแนะนำด้านการเงิน.