Polymarket and Kalshi vs Pinnacle odds
A Polymarket or Kalshi sports contract pays $1 if its outcome happens, so its price is a probability: 66¢ (or
0.66) means 66 %. To compare it with Pinnacle, take Pinnacle's prices for every outcome of the same
market, remove the margin to get a fair probability, and subtract. If Pinnacle's fair probability is 68.13 %,
a Yes at 66¢ has an edge of +2.13 percentage points, and an expected value of
0.6813 − 0.66 − fee per contract. The calculator below does it, with the fee.
1. Prediction market vs Pinnacle calculator
Pick the platform and the side you are buying, enter the price you would pay (the ask), then Pinnacle's prices for every outcome of the matching market and tick the one the contract's Yes stands for. It runs in your browser; nothing is sent anywhere.
The defaults are a Premier League moneyline (home −238, away +655, draw +318) and a Yes on the home side at 0.66 with no fee. Set the fee rate to 0.05 and the EV falls from +$0.0213 to +$0.0101 per contract. Read the fair column: section 2 says why.
2. A contract price is a probability
A Yes contract pays $1 if the outcome happens and nothing if not, so a price of p is a bet at
decimal odds 1 / p: 0.66 is 1.5152, and 25¢ is 4.00. The price is the market's probability, and
your expected value per contract before fees is simply q − p, where q is the true
probability. A No contract is the other side: it pays $1 if the outcome does not happen, so its fair value is
1 − q.
Pinnacle's prices include a margin: the implied probabilities of −238, +655 and +318 add up to 107.58 %, not 100 %. Take it out before you compare. The multiplicative method (no-vig) divides each implied probability by the sum; the power method (fair) raises each to the power that makes them add up to 1, and takes more margin off the long shots, the way bookmakers charge it. On this market they give 65.45 % and 68.13 % for the favourite, and that gap decides the trade: at 0.66 the no-vig column shows −0.55 pp, the fair column +2.13 pp. Both methods, with worked examples, are in Pinnacle no-vig odds.
| Yes on the home side at 0.66 | Value |
|---|---|
| Pinnacle's fair probability (power) | 68.13 % |
| Contract price (implied probability) | 66.00 % |
| Edge | +2.13 pp |
| Fee at a 0.05 rate: 0.05 × 0.66 × 0.34 | $0.0112 |
| EV per contract: 0.6813 − 0.66 − 0.0112 | +$0.0101 |
| Highest price with EV ≥ 0 | 0.6703 |
Pinnacle's fair price is an estimate, not the truth. It is a good one because Pinnacle runs low margins and takes large bets from sharp bettors, which is why its closing line is the usual benchmark (closing line value). A gap of a point or two can also be noise, a stale quote or a difference in the rules.
3. Map the outcome exactly
Most false edges come from comparing two things that settle differently. Read the contract's rules and find the Pinnacle market that settles the same way.
-
Draws. A soccer contract "Arsenal wins" is usually decided on the result in regulation, so
a draw makes it resolve No. Its match on Pinnacle is the three-way moneyline (
s;0;m, home, away and draw), and you need all three prices. Leave the draw out and the home side's fair probability on the default market jumps from 68.13 % to 77.31 %: an edge of +11.31 pp that does not exist. Buying No on "Arsenal wins" is a bet on draw or away, worth1 − 0.6813 = 31.87 %. - Regulation time or overtime. In hockey, basketball and American football, check whether the contract counts overtime. A moneyline that includes overtime and a regulation-time market settle differently: a contract that resolves on regulation needs a three-way regulation market, with the tie. If Pinnacle has none for that match, there is nothing to compare it with.
- Voids and retirements. If a match is postponed, abandoned or a tennis player retires, the platform's rules and the bookmaker's may settle it differently: void, resolved on the official result, or something else. A small edge is not worth that uncertainty on a match likely to be disrupted.
-
Period and line. A "first half" or "over 2.5 goals" contract maps to the market with the same
period and the same points. Market keys say both:
s;0;ou;2.5is the full-match 2.5 total.
4. Fees
Both platforms charge trading fees, and on Polymarket the fee depends on the price: in dollars it is largest at 50¢ and shrinks towards 0¢ and $1. Fee rules change and vary by market, so take the current rate from the platform's own page:
-
Polymarket. Its
fee docs give
fee = C × feeRate × p × (1 − p)forCshares at pricep, paid only by takers (orders that fill against the book; makers are not charged), in USDC and rounded to five decimal places. When we checked, on November 10, 2026, the table listed a sports taker rate of 0.05. - Kalshi. Its fees are set in the fee schedule (linked from its help centre); trading fees are charged when an order executes, and orders that rest on the book may carry a maker fee. Read the formula, the rate and the rounding for the market you trade there.
The calculator uses the rate × p × (1 − p) shape per contract, without rounding. If your
platform's fee has another shape, set the rate to 0 and subtract the fee per contract from the EV yourself; a
platform that rounds each order's fee up charges slightly more on small orders. Deposits, withdrawals and network
costs are not in it. The output row "highest price with EV ≥ 0" is where the fee and the edge cancel: above
it, skip.
5. Bid, ask and depth
- Buy at the ask, sell at the bid. The last traded price and the midpoint are not prices you can get. Enter the ask of the side you buy; if you plan to exit before settlement, the bid is what you get back.
- Yes and No are one book. Buying No at 35¢ is the same trade as selling Yes at 65¢. Compare both routes and take the cheaper one.
- Depth. The ask is only good for the size shown at it. A large order walks the book, and its average price is what goes into the calculator.
- Posting instead of taking. A resting order at your own price can avoid the taker fee, but it fills mostly when the price moves against you. Check the edge again at the moment it fills.
6. Timing and in-play
The comparison holds only if both prices are from the same moment. Before kick-off, Pinnacle's pre-match prices move slowly and an hour-old quote can still be close; in play, a goal, a break of serve or a red card moves Pinnacle's price at once, and a contract whose ask has not caught up shows an edge that is really a stale order someone may already be taking. For in-play comparisons you need Pinnacle's prices as they change, not a poll every minute.
The pre-match match and the in-play match are separate events on Pinnacle, with the same market keys: the
in-play one's parentId is the pre-match id. See
Pinnacle pre-match odds and
the WebSocket guide.
7. Pinnacle fair odds by API
OddsPush pushes Pinnacle's prices for all 13 sports, live and pre-match, about 30 ms after Pinnacle publishes them (bots hosted in Europe), with the no-vig and fair probability of the open markets, computed exactly as in the calculator. On the stream, turn it on once:
{"type": "subscribe", "fair": true}
After each odds update with open markets you receive a fair message for the same
markets (reference):
{
"type": "fair",
"data": {
"event_id": 1638780974,
"sport_id": 1,
"channel": "ld",
"ts": 1793458714075,
"markets": [
{
"key": "s;0;m",
"version": 3772905262,
"margin": 0.075827,
"prices": [
{
"designation": "home",
"price": -238,
"no_vig": 0.654512,
"fair": 0.681313,
"no_vig_decimal": 1.5279,
"fair_decimal": 1.4678
},
{
"designation": "away",
"price": 655,
"no_vig": 0.123115,
"fair": 0.109537,
"no_vig_decimal": 8.1225,
"fair_decimal": 9.1293
},
{
"designation": "draw",
"price": 318,
"no_vig": 0.222373,
"fair": 0.20915,
"no_vig_decimal": 4.497,
"fair_decimal": 4.7813
}
]
},
{
"key": "s;0;ou;2.5",
"version": 3772905263,
"margin": 0.039746,
"prices": [
{
"designation": "over",
"price": 104,
"points": 2.5,
"no_vig": 0.471458,
"fair": 0.469757,
"no_vig_decimal": 2.1211,
"fair_decimal": 2.1288
},
{
"designation": "under",
"price": -122,
"points": 2.5,
"no_vig": 0.528542,
"fair": 0.530243,
"no_vig_decimal": 1.892,
"fair_decimal": 1.8859
}
]
}
]
}
}
Over REST, /v1/events/{id}?fair=true returns the fair prices of one event; add
channel=pre for a match that has not started (reference). REST
allows bursts of 120 requests and 300 a minute. This script compares one contract with Pinnacle's fair price:
// Node 18 or newer. Save as edge.mjs and run, for example:
// node edge.mjs 1638780960 "s;0;m" home 0.66 0.05
// event id, market key, Pinnacle outcome, your price (0-1; Kalshi cents / 100), fee rate
const BASE = 'https://feed.oddspush.com/v1';
const [eventId, key, outcome, price, feeRate = '0'] = process.argv.slice(2);
// channel=pre: a match that has not kicked off has its prices on the pre-match channel.
const r = await fetch(`${BASE}/events/${eventId}?channel=pre&fair=true`, {
headers: { 'x-token': process.env.ODDSPUSH_KEY },
});
if (!r.ok) throw new Error(`${r.status} ${r.url}`); // a 429 carries retry-after
const { fair } = await r.json();
const leg = fair[key]?.prices.find((x) => x.designation === outcome);
if (!leg) throw new Error('no fair price for that market and outcome');
const p = Number(price);
const fee = Number(feeRate) * p * (1 - p); // Polymarket's fee shape; check your platform's
console.log({
fair: leg.fair, // Pinnacle's probability, power method
edge_pp: Number(((leg.fair - p) * 100).toFixed(2)),
ev_per_contract: Number((leg.fair - p - fee).toFixed(4)),
});
{ fair: 0.681313, edge_pp: 2.13, ev_per_contract: 0.0101 }
To find value across many contracts at once, see the value betting calculator; to convert between American, decimal and cents, the odds converter. Full clients are in Python and Node.js.
Pinnacle's fair price next to every contract
The free trial gives you REST and the live stream, with no-vig, fair and closing odds, all 13 sports, for 7 days. No card.
OddsPush is not affiliated with, endorsed by or sponsored by Pinnacle. OddsPush is not affiliated with Polymarket or Kalshi. This page explains a calculation; it is not betting or investment advice.