← Community vipers

Community viper

Late Favorite

In the last minutes of a crypto strike market, buy the side the price clearly favors when the model sees an edge, and hold to settlement.

Version
1.0.0 (published 2026-11-09)
Publisher
mbordash
Markets
crypto · hourly
Venues
All venues (Kalshi, Polymarket US, Polymarket International)
Exposure cap
$5 per market by default
Script API level
1
License
MIT

In the last ten minutes of an hourly crypto strike market ("Will Bitcoin be above $74,400 at 2 PM?"), the price is often far enough from the strike that one side is a clear favorite. Late Favorite estimates how likely that side is to win, and buys it when the market's ask is cheap enough to leave an edge after fees. It holds every position to settlement.

The idea

With t seconds left, the price has to move from where it is to the strike. The script measures that distance in standard deviations of the typical move over the time remaining:

level = oracle - basis
move  = hourly_vol * level * sqrt(t / 3600)
z     = (level - strike) / move
fair  = norm_cdf(z)          (for YES; 1 - that for NO)

It then buys the favored side when:

  • fair is at least min_fair (a real favorite, not a coin flip),
  • the ask is at most max_price,
  • fair - ask - taker fee is at least min_edge.

fair is capped at fair_cap, because crypto has fatter tails than the normal curve: a "99%" favorite loses more often than one time in a hundred.

Parameters to set for your market

  • basis (default 0): how many dollars the price feed (ctx.oracle, Binance) reads above the index the venue settles on. Kalshi settles BTC on CF Benchmarks; on BTC we measured Binance about $20 above it. Polymarket settles each market on the source its rules name. Measure the gap for your venue and coin, and set it here; a wrong basis shifts every estimate.
  • hourly_vol (default 0.003 = 0.3%): the typical one-hour move as a fraction of the price. BTC is usually 0.2–0.5%; ETH and SOL run higher. Too low and the script is overconfident.
  • window_secs (default 600): how close to the close it may enter.

What to expect

This is an idea to try on paper, not a proven strategy. The original ran on paper on Kalshi BTC hourly markets for a few days in November 2026 with a handful of trades. Its one early loss came from a missing-price bug since fixed in DRADIS (the oracle read as zero). Run it on paper for a few weeks before you consider it live, and compare its paper results with what the market priced.

Things to watch:

  • A wrong basis or hourly_vol makes it confident where it should not be.
  • Near the close, books are thin; the default size is 5 contracts.
  • It holds to settlement. There is no stop.

Venues

Written for any venue with crypto strike markets: Kalshi, Polymarket US and Polymarket International. It needs a strike, an oracle price and a close time (ctx.strike, ctx.oracle, ctx.secs_to_close); on a market without them it holds and says why.

Community content, MIT licensed. Not investment advice, and not reviewed for profitability.

Parameters

Every parameter can be changed per squadron in the Control Tower without editing the script.

ParameterDefaultRangeMeaning
basis0-200 to 200Dollars the price feed reads above the settlement index (measure it for your venue and coin)
contracts51 to 100Contracts per entry.
fair_cap0.950.6 to 0.999Highest probability the model may claim
hourly_vol0.0030.0005 to 0.05Typical one-hour move of the underlying, as a fraction of the price (0.005 = 0.5%). Set it from the market you trade.
max_price0.90.01 to 0.99Highest ask to buy.
min_edge0.040 to 0.5Fair minus ask minus fee required.
min_fair0.60.5 to 0.99Only buy a side rated at least this likely
window_secs60060 to 3600Enter only in this many final seconds.

Import into DRADIS

In the Control Tower, open Build a Viper and choose Community, then pick Late Favorite. The engine fetches it from this registry, checks the registry's signature, and shows the readme, parameters and source before anything is saved. It arrives switched off and on paper.

Or download the signed bundle file and use Import a viper file on the same page.

Don't run DRADIS yet? Launch it on AWS Marketplace in your own AWS account.

Source

// Late favorite: in the last minutes of a crypto market, when the price sits
// well clear of the strike, buy the side it favors and hold it to settlement.
//
// The venue settles on its own index (Kalshi uses CF Benchmarks), not on the
// feed in ctx.oracle (Binance), and the two can differ by tens of dollars. The
// `basis` parameter is how far the feed reads ABOVE the settlement index; the
// distance to the strike is measured from the feed minus that. `min_fair`
// keeps it to real favorites rather than near-strike coin flips, and
// `fair_cap` limits how sure it may be (BTC's tails are fat).
fn entry(ctx) {
    if ctx.oracle == () || ctx.strike == () || ctx.secs_to_close == () {
        return #{ hold: "needs an oracle, a strike and a close time" };
    }
    let t = ctx.secs_to_close;
    if t > ctx.params.window_secs || t < 30 { return #{ hold: `outside the last ${ctx.params.window_secs}s` }; }

    // The price in the settlement's terms, and its distance to the strike in
    // standard deviations over the time left. The typical one-hour move is a
    // parameter (a fraction of the price), scaled by the square root of the
    // time left.
    let level = ctx.oracle - ctx.params.basis;
    let move_left = ctx.params.hourly_vol * level * (to_decimal(t) / 3600).sqrt();
    let z = (level - ctx.strike) / move_left;
    let p_yes = norm_cdf(z);
    let side = if p_yes > 0.5 { "yes" } else { "no" };
    let fair = if side == "yes" { p_yes } else { 1 - p_yes };
    // The normal curve's tails are too thin for BTC: cap the claim.
    if fair > ctx.params.fair_cap { fair = ctx.params.fair_cap; }
    if fair < ctx.params.min_fair { return #{ hold: `fair ${fair} below ${ctx.params.min_fair} (z ${z})` }; }

    let book = if side == "yes" { ctx.yes } else { ctx.no };
    if book.ask > ctx.params.max_price { return #{ hold: `ask ${book.ask} above ${ctx.params.max_price}` }; }
    let edge = fair - book.ask - taker_fee(book.ask);
    if edge < ctx.params.min_edge { return #{ hold: `edge ${edge} below ${ctx.params.min_edge}` }; }

    #{ buy: side, price: book.ask, shares: ctx.params.contracts,
       reason: `fair ${fair}, edge ${edge}, level ${level} vs strike ${ctx.strike}, z ${z}` }
}

// Held to the settlement: nothing to decide.
fn exit(ctx, pos) {
    ()
}

sha256 460e5bb7d803b988a09c327ddabd251258688fe87b162b1837f5b48e794bbc99

Versions

  • 1.0.0 2026-11-09

Read before you run

Community content, MIT licensed. Not investment advice, and not reviewed for profitability.