two-way-arbitrage draft

Identifying a guaranteed-profit opportunity by combining one side at one venue with the opposite side at another, when their fair-cost implied probabilities sum to less than 1

Tags
arbitrage arb cross-book kalshi hedging implied-probability
Vocabulary
two_way_arb
Buying one side of a binary market at one venue and the opposite side at another, where the combined fee-adjusted implied probabilities sum to less than 1.0. Profit is guaranteed regardless of outcome, modulo execution risk.
arb_pct
Headline guaranteed-profit margin on a one-dollar combined position. Kairos computes it as (1 − p_side − p_opp) × 100 where p_side and p_opp are fee-adjusted implied probabilities of the two legs.
fee_adjusted_implied_prob
Implied probability computed from the price the operator actually pays, including venue fees. For Kalshi, Kairos uses the half-maker fee (0.875% net of rebate) baked into the AM column.
cross_book_arb
Two-leg arb where both legs are at sportsbooks (no Kalshi leg involved). Same math; different friction profile.
hedge
A second bet placed to offset the directional risk of a first bet. In an arb, the two legs are mutual hedges — whichever side wins, the other loses, and the combined position pays a fixed amount.
binary_market
A market with exactly two outcomes (e.g. Team A wins vs. Team B wins). The two-way arb formula assumes binary; three-way markets need a different formula.

A two-way arbitrage is the simplest form of locked-in profit in a binary market: you buy Side A at one venue and Side B at another, and if the combined fee-adjusted implied probabilities sum to less than 1.0, the position pays the same dollar amount no matter which side wins, and that dollar amount exceeds your total stake. The arbitrage exists because the two venues disagree about the line by more than their combined vig — one venue's price for A and the other venue's price for B together imply a market that is sub-1.0 probability, which is impossible if both prices were "fair."

A single vigged book never offers an arb against itself: by construction, its A and B implied probabilities sum to more than 1.0 (that's the overround, see book-vig-overround). Arbs only show up when you cross venues — different sportsbooks, or a sportsbook against an exchange like Kalshi where the cost structure differs.

Kairos's implementation

Kairos's arb-detection logic lives in kairos/core/arb_calc.py. It is identification-only, not sizing — the file produces an arb_pct per opportunity and (for Kalshi-vs-book) a book_key indicating the best counterparty. Stake-sizing per leg is left to the operator (or to UI code that consumes the arb result).

Three exported entry points:

The core formula in all three is:

arb_pct = (1.0 − p_side − p_opp) × 100

where p_side is the fee-adjusted implied probability of the leg you'd buy at venue 1, and p_opp is the fee-adjusted implied probability of the opposite leg at venue 2. Kalshi prices route through kalshi_half_maker to absorb the 0.875% half-maker trading fee (net of Kairos's 50% rebate); American sportsbook prices go straight through implied_prob_from_american. The formula is the textbook arb-margin formula: subtract the combined no-arb probability from 1.0.

This arb_pct quantifies the cross-venue version of the same arithmetic that defines the MBA reference price (vf-and-mba-targets): a quote strictly better than the cross-side flip is arb-positive. MBA tests this within a single book (almost never triggers because of vig); arb_pct tests it across venues.

The math, step by step

A binary market has exactly two outcomes. If venue 1 quotes Side A at decimal odds d_A and venue 2 quotes Side B at decimal odds d_B, an arb exists when:

1/d_A + 1/d_B  <  1.0

The left-hand side is the combined cost-per-dollar-of-payout: pay 1/d_A at venue 1 to receive $1 if A wins; pay 1/d_B at venue 2 to receive $1 if B wins. If the sum is less than $1, you've locked in $1 − (1/d_A + 1/d_B) per dollar of guaranteed payout. The arb margin is exactly:

arb_margin = 1 − (1/d_A + 1/d_B)

To realize this margin from a fixed total stake S, split it so that both legs return the same dollar amount on a win. The standard sizing is:

stake_A = S × (1/d_A) / (1/d_A + 1/d_B)
stake_B = S × (1/d_B) / (1/d_A + 1/d_B)

Then stake_A × d_A = stake_B × d_B = S / (1/d_A + 1/d_B). Both outcomes pay the same total return, and that return divided by S is 1 / (1/d_A + 1/d_B), which is > 1 exactly when the inequality at the top of this section holds.

Kairos's arb_pct reports (1 − sum_of_implied_probs) × 100. To convert from arb_pct to a return-on-stake percentage, the operator divides by the cost: a 2.0% arb_pct against an implied-prob sum of 0.98 means the per-dollar-of-stake return is 1/0.98 ≈ 1.0204, i.e. ~2.04% return-on-stake. Headline arb_pct and return-on-stake are nearly identical at small margins, but they diverge slightly at larger margins.

Worked example

Suppose Kalshi has Side A YES trading at 47¢, and a sportsbook quotes Side B at +120.

Sizing a $100 total stake (use the fee-adjusted Kalshi probability for the Kalshi-side 1/d, just like you did when computing arb_pct — mixing fee-adjusted and raw probabilities here would re-introduce the bug the fee adjustment was meant to fix):

Unit-arithmetic check at a larger margin

To verify the formulas at larger margins, take an unrealistic example: Kalshi A YES at 38¢ (p_A ≈ 0.386), sportsbook B at +180 (p_B ≈ 0.357). This combination would only show up on a market that's badly mispriced or stale on one side, but it makes the arithmetic easy to read:

The 25.7% headline is the gross arb percentage; the return-on-stake is ~34.5% because the cost (0.743) is well under $1. At small margins the two are close; at large margins they diverge — this is the cleanest place to see that.

Real-world frictions

The math above assumes both legs fill at the quoted prices, simultaneously, with no execution friction. None of those assumptions hold in practice. The gross arb percentage Kairos reports is always more generous than the net arb that survives:

The right mental model: Kairos's arb_pct is the gross arb under perfect execution. The operator's expected-value calculation against a real-world execution model — accounting for fill probabilities, line-move risk, and account longevity — produces the net number, which is always smaller and sometimes negative.

Gotchas

Open questions

Cross-references