Turbine — AI Trading Bot Platform
StudioStrategiesResearchCommunityPricingAffiliates
Kalshi TradingPolymarketAI Strategy BuilderBacktesting EngineStudio DocsSandbox RuntimeEdge Data FeedsStrategy LibraryBacktested StrategiesLive Performance
BlogXDiscord
StudioStrategiesResearchCommunityPricingAffiliates
SocialsBlogXDiscord
← Back to Blog
August 17, 2026

By Ryan Bajollari

Turbine Studio

Your next trade is a sentence away.

Describe an idea, review the backtest, and start from the same workspace.

Build a bot

Automating Strike Ladders on Kalshi: Trading Multiple Price Levels at Once

We pulled Kalshi's public API this morning and counted the contracts inside a single Bitcoin event. Not a series. One event, one settlement time, one underlying price.

There were 188 of them.

Every one of those 188 markets settles off the same number: the average of CF Benchmarks' Bitcoin Real-Time Index over the sixty seconds before the hour. They differ only in where the strike sits. And almost every bot we've seen trades exactly one.

That's the mistake this post is about. A strike ladder isn't 188 separate bets. It's one probability distribution, quoted in public, that you can read and trade as a whole.

**Key Takeaways** - A single Kalshi BTC event carried **188 separate strike markets** at $100 spacing on Aug 17, 2026, all settling off one number (our pull of Kalshi's public API) - Strike spacing **scales with time to expiry**. The same series ran $100 spacing at 1 hour out, $250 at 9 hours, and $500 at 105 hours, so ladder bots can't hardcode rung width - Kalshi's `greater`-type ladder is a **cumulative distribution**; differencing adjacent rungs yields the market's implied probability density directly - The cumulative ladder carried **21× to 52× the volume** of the explicit bucket markets on the identical event. Build buckets by differencing, don't trade them - Taker fees cost **0.07 × (1−P) of your stake**, making a 5¢ tail rung 19× more fee-expensive per dollar than a 95¢ rung, while maker fills on Kalshi's BTC series pay **no trading fee**

Trading terminal displaying a vertical ladder of Bitcoin strike prices, each rung glowing with its own bid and ask, forming a bell curve shape in the depth column

One Event, One Settlement, 188 Contracts

Kalshi's data model has three levels, and the middle one is where ladders live.

A series is the recurring template (KXBTCD, "Bitcoin price on [date]"). An event is one instance of it with a fixed settlement time (KXBTCD-26AUG1717, 5 PM EDT on Aug 17). A market is a single binary contract inside that event, identified by its strike (KXBTCD-26AUG1717-T63499.99).

One event holds many markets. That relationship is the whole opportunity.

Across three live BTC events on Aug 17, 2026, pulled from GET /trade-api/v2/events?series_ticker=KXBTCD&with_nested_markets=true:

EventHours to closeRungsStrike spacingRange covered
KXBTCD-26AUG17091.0188$100$18,700
KXBTCD-26AUG17179.080$250$19,750
KXBTCD-26AUG2117105.050$500$24,500

Our pull of Kalshi's public API at 12:00 UTC on Aug 17, 2026. KXBTCD runs hourly, so the front event rolls over every hour: -26AUG1709 is the 9 AM EDT contract, which closes at 13:00 UTC and was therefore exactly one hour out at the time of this pull. The ETH series (KXETHD) showed the same pattern more sharply: 300 rungs at $5 spacing one hour out, versus 40 rungs at $40 spacing nine hours out.

Read the spacing column again. Kalshi tightens the ladder as expiry approaches, because the outcome distribution narrows. Nine hours out, BTC could plausibly land anywhere in a $2,000 band, so $250 rungs resolve it. One hour out, the plausible band is a few hundred dollars, so it takes $100 rungs to say anything useful.

This is the first thing that breaks naive ladder bots. If you hardcode "place orders at $500 intervals," your bot places five orders on the 105-hour event and tries to place non-existent strikes on the 1-hour one. Rung width is a property of the event, discovered at runtime, never a constant in your config.

Treat the strike set as mutable, too. We re-pulled the same event fifteen minutes apart and got an identical ladder, so it's not churning constantly. But Kalshi's market_lifecycle_v2 WebSocket channel exists precisely to emit a metadata_updated message when floor_strike, cap_strike, or strike_type changes (Kalshi changelog). The exchange documents that these values can move. Subscribe to that channel rather than trusting a strike list you cached at startup.

Two related plumbing notes. The /markets endpoint defaults to a limit of 100 with a maximum of 1,000 (Kalshi API docs), so anything that reads a 188-rung event without setting limit or following the cursor is one Kalshi-side default change away from silently seeing a partial ladder. And the markets in an hourly event carry an open_time, before which they aren't quotable, so "the event exists" and "the ladder is tradeable" are different conditions.

The Ladder Is Already a Probability Distribution

A Kalshi greater-type strike ladder is a cumulative distribution function you can read directly off the order book. Each rung quotes P(settlement > that strike), so the rungs together trace the market's entire implied CDF, and subtracting adjacent rungs converts it into a probability density. No model is needed to read it, only arithmetic.

Mechanically, here's why. Kalshi's BTC daily markets use strike_type: "greater" with a single floor_strike and no cap. Each contract asks one question: will the settlement price be above this strike? Stack every rung and you have P(X > k) for each k on the ladder.

Quoted live. For free.

The density then falls out of subtraction. P(price lands between $63,250 and $63,500) is simply P(X > 63,250) − P(X > 63,500).

A descending cumulative curve on the left with discrete nodes marked along it, an arrow with a subtraction symbol pointing right, and a bell-shaped histogram on the right — the transformation from a strike ladder's cumulative prices into an implied probability density

We ran that arithmetic against a live snapshot. Here's the market's implied distribution for BTC at 5 PM EDT, read straight off the mid prices of KXBTCD-26AUG1717 at 12:00:32 UTC:

The Market's Implied Distribution, Read Off the Ladder P(settle in bucket) = P(X > low strike) − P(X > high strike), from mid prices 0% 7% 14% 21% 3.0 8.0 11.0 19.5 20.0 17.0 9.5 5.0 2.0 0.5 0.5 62.5k 63.0k 63.5k 64.0k 64.5k 65.0k Bucket lower bound (BTC settlement price, $250 rungs) These 11 buckets hold 96.0% of probability; four more buckets with any mass, down to $61,250, add 2.5% Our pull of Kalshi's public API: KXBTCD-26AUG1717, snapshot 2026-08-17T12:00:32Z
Derived from our snapshot of Kalshi's public market data for event KXBTCD-26AUG1717 at 12:00:32 UTC on Aug 17, 2026. Bucket probabilities are computed from bid-ask midpoints.

A clean unimodal distribution, peaked at $63,500–$63,750. The eleven buckets shown hold 96.0% of the probability mass; four further buckets carrying any probability at all, running down to $61,250, add another 2.5%, and the remaining 1.5% sits in rungs pinned at the extremes. Nobody published that. It fell out of a column of subtractions.

This matters more than it first appears. When you buy a single binary, say "BTC above $63,500" at 55¢, you're making a one-dimensional claim: the market's 55% is too low. That's it. You've expressed nothing about where you think price lands, only which side of one line.

A ladder lets you express shape. If you think the market is underweighting a move to $64,000, you don't need the market to be wrong about $63,500 at all. You buy the rungs whose implied bucket probability disagrees with your model, and you're trading the distribution rather than a coin flip.

Two Ladders on the Same Event: Trade the Liquid One

Kalshi actually lists both structures for BTC, and this trips people up.

KXBTCD is the cumulative ladder: strike_type: "greater", floor only, "$63,500 or above." KXBTC is the bucket set: strike_type: "between", floor and cap, "$63,500 to $63,599.99." Same underlying, same settlement time, same number of markets.

The bucket markets look like the obvious tool for distribution trading. They aren't.

EventStructureMarketsTotal volumeOpen interest
KXBTCD-26AUG1717greater (cumulative)80849,243381,159
KXBTC-26AUG1717between (buckets)8035,09319,035
KXBTCD-26AUG2117greater (cumulative)50643,791301,834
KXBTC-26AUG2117between (buckets)5030,69718,366
KXBTCD-26AUG1708greater (cumulative)188994,828387,515
KXBTC-26AUG1708between (buckets)18818,9555,539

Our pull of Kalshi's public API on Aug 17, 2026, in the same session as the table above and a few minutes later. The front hourly event here is -26AUG1708, the 8 AM EDT contract, which had just reached its 12:00 UTC close and so carries a full event's accumulated volume. Volume and open interest in contracts.

The cumulative ladder carried 21× to 52× the volume of the bucket markets on identical events. On the just-closed 8 AM event, the bucket set had 5,539 contracts of open interest spread across 188 markets — roughly 29 per market. That's not a market you can size into.

The operational rule: read your distribution off the liquid greater ladder by differencing, then execute on that same ladder. A bucket exposure is synthetically constructible anyway — long the lower strike, short the upper strike, and you own exactly the bucket between them, at the liquid ladder's spreads rather than the bucket market's.

**Citation capsule:** Kalshi lists two parallel contract structures on the same underlying event. The `greater` type (series `KXBTCD` for Bitcoin) carries a `floor_strike` and no cap, so each market resolves Yes if settlement exceeds that strike — collectively forming a cumulative distribution. The `between` type (series `KXBTC`) carries both `floor_strike` and `cap_strike`, resolving Yes only if settlement lands inside that band. In a snapshot of three live events on Aug 17, 2026, the cumulative ladders carried between 21 and 52 times the trading volume of the corresponding bucket markets, despite listing an identical number of contracts at identical settlement times.

Sizing Each Rung Is Not the Same Problem as Sizing One Bet

General position sizing advice, whether Kelly fractions or fixed-fractional risk, assumes independent bets. Ladder rungs are the opposite of independent. They all settle off one number.

Three things change.

First, your rungs are nested, not diversified. On a greater ladder, if the $64,000 rung pays, the $63,500 rung pays too. Buying five adjacent rungs isn't five positions; it's one position with a stepped payoff. Treat total ladder exposure as a single line item against your risk budget, and size the rungs as a split of that one allocation. Our broader framework for this lives in position sizing and risk management for prediction markets.

Second, fees are radically unequal across the ladder. Kalshi's taker fee is 0.07 × C × P × (1−P), where P is price in dollars and C is contract count. It's a formula confirmed against Kalshi's own transaction-level data by Bürgi, Deng & Whelan (2026). Divide it by your stake (C × P) and the P cancels:

fee as a share of stake  =  0.07 × (1 − P)
fee as a share of upside =  0.07 × P

Those two lines are the ladder sizing problem in miniature, and we've not seen them written down anywhere. Cheap out-of-the-money rungs are brutally expensive per dollar staked. Deep in-the-money rungs are cheap per dollar staked but eat most of the thin upside they offer.

Every Rung Pays a Different Effective Fee Kalshi taker fee = 0.07 × C × P × (1−P), expressed two ways % of stake = 0.07(1−P) % of upside = 0.07P 0% 2% 4% 6% both cost 3.5% at 50¢ 5¢ 25¢ 50¢ 75¢ 95¢ Rung price P (contract price in cents) A 5¢ tail rung costs 19× more per dollar staked than a 95¢ rung Our calculation from the taker fee formula 0.07 × C × P × (1−P); maker fills on this series pay no trading fee
Our calculation from Kalshi's taker fee formula, 0.07 × C × P × (1−P), as documented in Bürgi, Deng & Whelan (2026) from Kalshi transaction data. Kalshi's current docs round trade fees up to the nearest $0.0001 rather than the nearest cent (fee rounding), so small per-rung orders cost less than older sources suggest.

The practical consequence is worth working through, because neither obvious sizing scheme is fee-neutral.

Buy the same contract count at every rung and your absolute fee follows P(1−P), peaking at the 50¢ rung and falls toward both ends. Buy the same dollar stake at every rung and the count becomes S/P, so the fee collapses to 0.07 × S × (1−P), and now it's the cheap rungs that cost the most. Equalizing the absolute fee across rungs would require sizing proportional to 1/(P(1−P)), which nobody actually wants, because it dumps size into the tails.

There's no free scheme. What the arithmetic tells you is narrower and more useful: the fee you pay per dollar committed rises linearly as the rung gets cheaper. At 5¢ you're handing over 6.7% of your stake before you've been right about anything; at 95¢ it's 0.35%. So demand proportionally more modeled edge from a wing rung than from a middle one, and never let "it's only a few cents a contract" stand in for that check.

Third, depth is wildly uneven rung to rung. From the same snapshot, resting bid size on adjacent rungs of one ladder:

StrikeMidResting bid size
$63,000 or above0.86010,183
$63,250 or above0.7502,767
$63,500 or above0.5553,715
$63,750 or above0.3555
$64,000 or above0.1854,505

Our pull of Kalshi's public API, KXBTCD-26AUG1717, 12:00:32 UTC, Aug 17, 2026.

One rung had five contracts of resting bid between thousands on either side. A ladder bot that sizes uniformly and sends market orders will get a fine fill on four rungs and walk the book on the fifth. Size each rung against its own observed depth, and cap any single rung at a fraction of the resting size you can actually see.

The Rungs You'll Be Tempted to Buy Are the Worst Ones

The cheap outer rungs of a strike ladder are the worst contracts on the exchange to buy mechanically. Kalshi contracts priced at 10¢ and under have averaged worse than −60% returns, they carry the highest fee burden per dollar staked, and crypto shows the strongest favorite–longshot bias of any Kalshi category. A uniform-size ladder overweights exactly those rungs.

A January 2026 University College Dublin study analyzed transaction-level data on 46,282 Kalshi contracts across 12,403 events, running from the exchange's 2021 launch through April 2025. The average pre-fee return on a Kalshi contract was −20%. Contracts costing 10¢ and under lost more than 60%. Contracts above 70¢ were the only band with statistically significant positive post-fee returns (Bürgi, Deng & Whelan, 2026).

That's the favorite–longshot bias, and it's been documented in betting markets for decades. Cheap contracts are systematically overpriced relative to how often they pay.

The next finding should stop a ladder builder cold. The same paper measured that bias by category, and crypto showed the strongest favorite–longshot bias of any Kalshi category — ψ = 0.058, against 0.034 across all markets (n = 8,150).

Stack that against the fee curve from the last section and a naive ladder looks considerably worse. The cheap wing rungs are simultaneously:

  • the most fee-expensive rungs per dollar staked, at 19× the cost of a 95¢ rung;
  • the worst-performing price band on the exchange, averaging worse than −60%;
  • and they sit in crypto, the category where that same study measured the exchange's strongest longshot bias of all.

A ladder that spreads uniform size across every rung is systematically overweighting exactly those contracts. It feels like buying optionality. It's buying the three worst documented properties on the venue at once.

Execution style is the other half. The same study found takers average −31.46% while makers average −9.64%, and makers buying at 50¢ or above earned +2.6%.

Be careful how you read that 22-point gap. Kalshi charged makers nothing during the study's sample window. The authors ended their sample in April 2025 precisely because maker fees started after that. So a chunk of the difference is the fee, not skill. That's still the point for ladder construction: on a series where fee_type is quadratic, you're in the same fee regime the makers in that study enjoyed.

The maker share of purchases also trends upward with price, rising from 43.5% in the cheapest band to 56.5% in the dearest, with two small reversals along the way:

Cheap Rungs Are Bought by Takers, Expensive Rungs by Makers Share of contracts in each price band purchased by makers (resting orders) 40% 45% 50% 55% 43.5 46.7 48.9 47.8 49.5 50.4 52.2 51.1 53.3 56.5 1–10¢ 11–20 21–30 31–40 41–50 50–59 60–69 70–79 80–89 90–99¢ Takers average −31.46% returns; makers average −9.64% — and takers dominate the cheap rungs Source: Bürgi, Deng & Whelan (2026), Table 10, Kalshi transaction-level data
Source: Bürgi, Deng & Whelan (2026), Table 10. Band labels reproduce the source table's own sequence, which prints both 41¢–50¢ and 50¢–59¢. Note also that the study excludes hourly crypto markets, which it defines out of scope; the pattern is exchange-wide.
**Citation capsule:** Bürgi, Deng and Whelan (University College Dublin, January 2026) analyzed transaction-level data on 46,282 Kalshi contracts from 12,403 events, spanning the exchange's 2021 launch through April 2025. The average pre-fee return on a contract was −20%, with contracts costing 10¢ and under losing more than 60%. Returns differed sharply by execution style: takers, who cross the spread and pay Kalshi's 0.07 × P × (1−P) fee, averaged −31.46%, while makers averaged −9.64% — though makers paid no fees at all during the sample window, so part of that gap is the fee itself. Makers buying contracts at 50¢ or above earned +2.6%. Measuring the favorite–longshot bias by category, crypto showed the strongest coefficient of any category on the exchange (0.058, versus 0.034 across all markets, n = 8,150). The authors excluded markets open less than 24 hours, which removes hourly crypto contracts from the sample entirely.

What this actually implies for ladder design, and it's not "don't build ladders":

  1. Weight toward the middle and the favorite side, not uniformly across rungs. The 50¢-and-above bands are where makers made money.
  2. Rest, don't cross. Given fee_type: "quadratic" on this series, maker fills carry no trading fee, and the maker cohort's measured returns ran 22 points better. Part of that gap simply is the fee you're avoiding.
  3. If your model says a cheap wing rung is mispriced, demand a much larger edge there than in the middle. You're fighting a documented bias and a 19× fee ratio simultaneously.

One honest limitation: this study excluded markets open less than 24 hours, so hourly BTC ladders sit outside its return sample. The bias measurement is exchange-wide, not specific to the ladders we pulled. Treat it as a strong prior, not a measurement of your exact venue.

The Off-By-One That Quietly Breaks Strike Ladder Bots

Kalshi's strike_type values are not interchangeable, and conflating them shifts every inferred bucket boundary by one unit. A ladder that differences a misaligned CDF produces a distribution that looks plausible and is wrong in a way no test will catch. This is the cheapest expensive bug in ladder automation.

Look closely at a Kalshi BTC strike: floor_strike is 63499.99, and the market's own subtitle reads "$63,500 or above." The strikes are deliberately set a cent below the round number so that strike_type: "greater" produces a clean human-readable threshold.

And there's the trap. Kalshi's strike_type field takes several values, and they are not interchangeable. In our own production code we handle them separately:

def bucket_coverage(m):
    st = str(m.get("strike_type") or "").lower()
    floor, cap = m.get("floor_strike"), m.get("cap_strike")
    if st == "between":
        return (floor, cap)
    if st in ("greater", "greater_than"):
        return (floor + 1.0, None)                 # strictly above
    if st in ("greater_or_equal", "greater_than_or_equal_to"):
        return (floor, None)                       # at or above
    if st in ("less", "less_than"):
        return (None, cap - 1.0)
    if st in ("less_or_equal", "less_than_or_equal_to"):
        return (None, cap)
    return None                                    # unknown type — caller must bail

We learned to be this pedantic while building cross-venue bucket matching. If you treat greater and greater_or_equal as the same thing, your inferred bucket boundaries shift by one unit, and a ladder differencing engine that's off by one rung computes a distribution that's subtly, confidently wrong. Every bucket probability gets assigned to its neighbor.

Three defensive rules that cost nothing:

  1. Never parse strikes out of the ticker string. T63499.99 is a display convention, not an API contract. Read floor_strike and cap_strike. Kalshi documents series_ticker and event_ticker as the canonical identifiers for the hierarchy (Kalshi glossary), which is the opposite of what most tutorials show.
  2. Branch on strike_type explicitly, and fail loudly on unknown values rather than falling through to a default.
  3. Assert monotonicity before you difference. On a greater ladder, mid prices must be non-increasing as strikes rise. If they aren't, you have stale quotes or a crossed book, not a trading opportunity. Bail rather than trade.

That third check catches more bugs than the other two combined. We covered the general version of this discipline in how to build a Kalshi trading bot.

Automating a Kalshi Strike Ladder Entry

Automating a strike ladder is six steps: discover the rungs at runtime, filter to what's tradeable, difference the CDF into a density, compare it against your own model, size each rung by edge and available depth, then submit the legs as one batch. Only the fourth step contains any alpha. Every field below comes from Kalshi's public market data.

# 1. Discover the ladder at runtime — never hardcode strikes or spacing
event    = GET /events/{event_ticker}?with_nested_markets=true
rungs    = [m for m in event.markets if m.status == "active"]
rungs.sort(key=floor_strike)

# 2. TWO filters, not one. Read the density on the wide set,
#    place orders only on the narrow one.
quoted    = [r for r in rungs                       # anything with a real quote
             if bid(r) is not None and ask(r) is not None]

tradeable = [r for r in quoted                      # what you'd actually hit
             if 0.02 <= mid(r) <= 0.98              # skip pinned tails
             and (ask(r) - bid(r)) <= MAX_SPREAD    # skip wide books
             and bid_size(r) >= MIN_DEPTH]

# 3. Assert the ladder is sane, then difference the WIDE set into a density
assert all(mid(quoted[i]) >= mid(quoted[i+1])
           for i in range(len(quoted)-1))           # monotone CDF
implied = {(r.floor, nxt.floor): mid(r) - mid(nxt)
           for r, nxt in pairs(quoted)}

# 4. Compare against YOUR distribution — this is the edge, not the plumbing
edge = {bucket: my_model[bucket] - implied[bucket] for bucket in implied}

# 5. Size each rung: conviction × depth cap × fee awareness
#    Only place on buckets whose rungs survived the `tradeable` filter.
for bucket, e in edge.items():
    if e < MIN_EDGE or bucket not in tradeable_buckets: continue
    notional = LADDER_BUDGET * (e / total_positive_edge)
    qty      = min(notional / price(bucket),
                   DEPTH_FRACTION * bid_size(bucket))
    place_limit(bucket, qty, price=bid(bucket))     # maker side, not taker

# 6. Submit as one batch so the legs land together
POST /trade-api/v2/portfolio/events/orders/batched

Four notes on the parts people get wrong.

Step 2 does most of the work, and it's stricter than step 3 needs to be. On the 9-hour event, only 10 of 80 rungs sat between 2¢ and 98¢. The other 70 were pinned at the extremes with no meaningful two-sided market. Your executable ladder is always much shorter than the event's market count.

Worth separating those two filters, because they aren't the same. Reading the distribution wants every rung carrying a quote — the density chart earlier differences twelve rungs, including two priced under 2¢, because the tail rungs still tell you where the distribution ends. Trading it wants the stricter depth-and-spread filter. Compute the density on the wider set; place orders only on the narrower one.

Step 4 is the only step that contains alpha. Steps 1, 2, 3, 5 and 6 are plumbing, the same for everyone. If my_model is just a rescaled version of the market's own prices, you'll trade a lot and earn the spread in reverse. This is the same trap we documented in why backtests lie about prediction market strategies.

Step 5 prefers the maker side deliberately, and on this series it's free. Kalshi's fee_type field on the series object gates maker fees: quadratic means the general fee table with no maker fees, while quadratic_with_maker_fees adds them (Kalshi API docs). We queried the live series object for KXBTCD on Aug 17, 2026 and it returned fee_type: "quadratic", fee_multiplier: 1.

Read that again, because it changes the strategy. On Kalshi's hourly Bitcoin ladder, a resting limit order that gets filled pays no trading fee. The entire fee parabola charted above applies only to the taker side. A passive ladder — post_only, resting across strikes, accepting partial fills — is fee-free on entry, while the identical ladder placed with marketable orders pays 0.07 × P × (1−P) on every rung.

Check fee_type per series before you assume this. It's one API call, and it's the most valuable thing to know before building a ladder.

Step 6 matters more than it looks. A ladder placed leg-by-leg over several seconds can end up half-filled at prices that no longer form a coherent distribution. Batch submission keeps the legs together. Use the current endpoint, POST /trade-api/v2/portfolio/events/orders/batched — the older /portfolio/orders/batched path is deprecated (Kalshi API docs).

Size the batch against your rate limit rather than a guessed constant. Kalshi meters the API with a token bucket in which most requests cost 10 tokens, batch operations bill per item, and the write budget scales by tier — 100 write tokens per second on Basic, rising to several thousand on the higher tiers (Kalshi rate limits).

That arithmetic constrains ladder width directly. A 20-rung ladder costs roughly 200 write tokens, which is about two seconds of Basic-tier write budget. Your maximum practical rung count is partly a function of your API tier, not purely a strategy decision. Check your own tier's published limits before designing around a rung count.

Where Kalshi Strike Ladders Break

Three honest failure modes.

Ladders concentrate risk; they don't spread it. This is the one that gets people. Buying eight rungs feels diversified. It isn't. One settlement number decides all eight. If BTC gaps through your entire ladder, every rung on the wrong side is worth zero simultaneously. Your position sizing must treat the ladder as one bet, because that's what it is.

Fee drag scales with rung count. Each rung pays its own fee. An eight-rung ladder pays eight fees, and if you're wrong you paid them for nothing. A ladder needs meaningfully more edge than a single binary to clear the same hurdle, and per the crossover chart above, the wing rungs are where that drag bites hardest.

Liquidity concentrates near the money, and tightens near expiry. In our snapshots, the top five rungs by volume accounted for 60.6% of event volume nine hours out, and 92.3% on an event about to expire. The wings of your ladder are the rungs least likely to fill and most likely to have stale quotes. Plan for partial construction; a ladder that only builds its middle five rungs is a normal outcome, not an error.

We went looking for published research on how liquidity distributes across strikes within a single prediction-market event and found none. The largest published transaction-level Kalshi dataset we could find explicitly excludes markets open less than 24 hours, which removes hourly crypto ladders entirely. So the concentration figures above are our own measurements from one day's snapshots: directionally useful, not a substitute for measuring your own venue over a longer window.

It also helps to remember what Kalshi's headline volume is made of. Sports accounted for roughly 80% or more of Kalshi's volume through Q2 2026 (CoinDesk, 2026; Sporting Crypto, 2026), which makes crypto a minority category. Exchange-level growth numbers won't tell you whether the specific rung you want to fill has a bid. For when an event is worth skipping entirely, see the prediction market liquidity calendar.

And the standing caveat: everything above describes structure, not edge. Knowing how to read and place a ladder tells you nothing about whether your distribution beats the market's. That's a separate, harder problem.

Build the Ladder Without Writing the Plumbing

Everything in step 4 is where your time should go. Steps 1, 2, 3, 5 and 6 are infrastructure you'd spend a month writing and debugging — pagination, strike-type branching, monotonicity checks, depth-aware sizing, batch submission, reconnects.

Turbine Studio handles that layer. You describe the ladder logic in plain language, backtest it against historical Kalshi order book data, sweep the rung count and edge threshold across a parameter range, and deploy the version that survives out-of-sample.

Start it in paper mode and let it build a few hundred ladders before real capital touches one. The fill behavior on thin wing rungs is the thing you most want to observe before you're paying for it.

Build and backtest a strike ladder on Turbine Studio →

Frequently Asked Questions

What is a strike ladder on Kalshi?

A strike ladder is the full set of binary contracts Kalshi lists on one event at different strike prices. All of them settle off the same underlying number at the same time. Our Aug 17, 2026 API pull found a single BTC event carrying 188 tradeable strikes at $100 spacing.

How is a strike ladder different from a single binary bet?

A single binary expresses one claim: the market's probability for one threshold is wrong. A ladder expresses shape. Because Kalshi's greater-type markets form a cumulative distribution, differencing adjacent rungs gives the market's implied probability density, letting you trade where price lands rather than just which side of one line.

How many strikes does Kalshi list per event?

It varies with time to expiry. On Aug 17, 2026, the same BTC series ran 188 rungs at $100 spacing one hour before close, 80 rungs at $250 nine hours out, and 50 rungs at $500 at 105 hours. Ladder bots must discover spacing at runtime rather than hardcoding it.

Do Kalshi fees make multi-strike ladders uneconomical?

Not inherently, but they're unequal. Taker fees cost 0.07 × (1−P) of your stake, so a 5¢ wing rung costs 19× more per dollar staked than a 95¢ rung. Multi-rung ladders also pay one fee per rung. The mitigation is execution style: Kalshi's BTC series carries fee_type: "quadratic", meaning resting maker fills pay no trading fee.

Does Kalshi charge maker fees on strike ladders?

It depends on the series, and it's checkable in one API call. Kalshi's series object exposes a fee_type field: quadratic means no maker fees, quadratic_with_maker_fees means they apply. The Bitcoin series KXBTCD returned fee_type: "quadratic" on Aug 17, 2026, so resting limit orders that fill pay no trading fee.

Should I trade Kalshi's bucket markets instead of building buckets from the ladder?

Usually not. In our Aug 17, 2026 snapshots, the cumulative greater ladders carried 21× to 52× the volume of the between bucket markets on identical events. Building a bucket synthetically, long the lower strike and short the upper, gets the same exposure at far better spreads.

The Takeaways

  • A ladder is one bet, not eight. Nested payoffs all settle off a single number.
  • Discover the ladder at runtime. Rung count, spacing, and strike range are properties of the event, not constants. Hardcode any of them and your bot breaks silently on the next expiry.
  • Check fee_type before you design anything else. Kalshi's BTC series returns quadratic, so resting maker fills pay no trading fee. On a multi-rung ladder, execution style matters more than ladder shape.
  • The cheap rungs are a documented trap. Contracts at or below 10¢ have averaged worse than −60%, and crypto carries the exchange's strongest measured longshot bias. Demand more edge in the wings, not less.
  • Assert monotonicity before you difference. An off-by-one in your bucket boundaries yields a confidently wrong distribution, which is considerably worse than no distribution at all.

The 188 contracts were always there. The question is whether your bot sees a list of markets or a probability distribution.


This article is for informational and educational purposes only. It is not investment advice, and nothing here is a recommendation to trade any specific contract. Prediction market trading involves risk of loss. Market data cited was captured from Kalshi's public API on August 17, 2026, and reflects that moment only — strike counts, spacing, quotes, and liquidity change continuously. Fee schedules and exchange rules change; verify current terms with Kalshi directly before trading.