Time Alignment Approximation
Time Alignment Approximation
Summary
Align Polymarket BTC hourly "Up or Down" to the closest-in-time Kalshi BTC hourly strike grid, then build a cross-venue pair with bounded payoff. This is not a 1:1 market match; the edge comes from overlapping payoff ranges when strikes differ.
Opportunity definition
- Instruments: Polymarket hourly Up/Down (binary), Kalshi hourly strike grid (binary per strike).
- Price-to-beat: BTC hourly open (from Binance), used as the Polymarket strike proxy.
- Edge: total cost of the paired legs below $1.00 (100 cents).
Inputs and data sources
- Polymarket event metadata (Gamma API) + CLOB top-of-book asks.
- Kalshi market list for an event ticker (trade API).
- BTCUSDT hourly open (Binance) with fallback to current spot.
Time alignment rules
- Base time: current UTC truncated to the hour.
- Polymarket target: try current hour, then next hour if the current event has already ended.
- Kalshi target: default to Polymarket target + 1 hour; if Polymarket event start/end time exists, derive Kalshi target from those timestamps instead.
- Fallback: if the exact Kalshi event ticker is missing, select the closest market by
close_timewithin the series and use itsevent_ticker.
Market identification
Polymarket slug
Pattern (ET): bitcoin-up-or-down-<month>-<day>-<hour><am|pm>-et
Example: bitcoin-up-or-down-january-26-2pm-et
Kalshi event ticker
Pattern (ET): <KALSHI_SERIES_TICKER>-<YY><MON><DD><HH>
Example: KXBTCD-26JAN2614
Pricing extraction
- Polymarket:
- Read
UpandDownbest asks from CLOB. - Fetch BTC hourly open at event start time; if missing, use current spot and flag as fallback.
- Read
- Kalshi:
- Parse strike from
subtitleusing$numeric capture. - Capture
yes_ask,no_ask,yes_bid,no_bid, and volume for each strike.
- Parse strike from
Candidate construction
- Focus window: take a small set of strikes around the closest strike to the Polymarket price-to-beat (default 5).
- Pairing rules:
- If
poly_strike > kalshi_strike: buy Polymarket Down + Kalshi Yes. - If
poly_strike < kalshi_strike: buy Polymarket Up + Kalshi No. - If equal: choose the cheaper of the two pairs.
- If
- Score:
edge_cents = 100 - (poly_leg + kalshi_leg). Prefer the highest edge.
Output fields (snapshot)
target_time,polymarket.slug,polymarket.price_to_beat,polymarket.up_cost,polymarket.down_costkalshi.event_ticker,kalshi.strike_date,kalshi.markets[]candidate: strike, total_cost, edge_cents, relation, and selected legs
Known caveats
- Polymarket and Kalshi resolve off different reference prices (Binance vs CF Benchmarks).
- Market close/start times can drift; this is why fallback time matching is needed.
- Best-ask pricing ignores slippage, fees, and min-size constraints.
- If
outcomesorclobTokenIdsare malformed, the snapshot may fail.
Implementation references
app/opportunities/time_alignment.py(primary logic)app/data/patterns.pyanddocs/ingestion-plan.md(slug pattern notes)