pre_announcement_drift
This page covers pre_announcement_drift, one of the five built-in strategies, on Kalshi, Polymarket and Polymarket US: its entry window, blackout and release exit, each parameter, venue differences, backtests and examples. Rules all five share, such as order sizes and how to write params, are on the Built-in Strategies page. Every number here is an illustrative example, not a suggested setting.
pre_announcement_drift enters once in a window before the market closes. The market's close time stands in for the announcement; no economic calendar is used. Each loop, for each market:
- It measures the time until the market closes (Kalshi close time, Polymarket end date, Polymarket US end or close time).
- Entry window: hours to close ≤
entry_hours_beforeand minutes to close >blackout_minutes_before. If it hasn't entered yet andprice_floor< price <price_ceiling(on Kalshi, in the series' current market), it buys once, on the sidedrift_directionpicks, for min(max_position, 5). An entry that hasn't filled after two loops is cancelled and placed again while the window is open. Once any of it fills, the market counts as entered. - Blackout: minutes to close ≤
blackout_minutes_before. No entries, and an entry still resting is cancelled. Withexit_on_release: true, it sells what the entry bought.
pre_announcement_drift: the windows before close
- before 08:00Too earlyMore than 6 hours to close. The Bot waits.
- 08:00 → 13:45Entry windowFrom entry_hours_before (6 h) until the blackout. The Bot buys once, on the first loop where price_floor < price < price_ceiling.
- 13:45 → 14:00BlackoutThe final 15 minutes. No entries. If exit_on_release is on and the Bot entered, the release exit fires here.
- 14:00CloseStands in for the announcement. Anything still held settles.
exit_on_release: true exits at the first loop from 13:45 onThe Bot sells what the entry bought, on the side it bought, including a partly filled entry. An entry still resting is cancelled.exit_on_release: false holds to settlementNo pre-close exit. The position settles when the market resolves.entry_hours_before: 6, blackout_minutes_before: 15. Entry size is min(max_position, 5). Keep loop.interval well under 15 minutes so a loop lands inside the blackout.| Parameter | Type | Default | Allowed values | What it does |
|---|---|---|---|---|
entry_hours_before | whole hours | Required | ≥ 1 | When the entry window opens, in hours before close. |
blackout_minutes_before | whole minutes | Required | ≥ 0 | Final minutes before close with no entries. The release exit fires when it starts. 0 means no blackout. |
drift_direction | text | auto | auto, bullish, bearish | bullish buys YES, bearish buys NO. auto (or omitted) buys YES below 0.5 and NO at 0.5 or above. |
exit_on_release | boolean | false | true, false | Exit when the blackout begins. Otherwise the position is held to settlement. |
entry_hours_before
Whole hours only; 1.5 is rejected. The Bot remembers that it entered per market on Kalshi and Polymarket (each window of a rolling series is a new market) and once per Bot on Polymarket US. On Kalshi a restart still sees the position the Bot entered. On Polymarket and Polymarket US the memory resets on restart, so a restart inside the entry window can enter again.
If the market has no close time, Polymarket and Polymarket US Bots never enter, and a Kalshi Bot logs an error on every loop.
# Rejected: entry_hours_before takes whole hours only
# error: pre_announcement_drift requires positive entry_hours_before
version: 1
platform: kalshi
strategy: pre_announcement_drift
market:
series_ticker: "KXFED"
risk:
max_position: 1
price_floor: 0.10
price_ceiling: 0.90
loop:
interval: 60
params:
entry_hours_before: 1.5
blackout_minutes_before: 30The error says "requires positive entry_hours_before" for any value that isn't a positive whole number, including 1.5.
blackout_minutes_before
Keep loop.interval well below blackout_minutes_before × 60 seconds, or a loop may never land inside the blackout before the market closes. The two windows are not cross-checked: if blackout_minutes_before is at least entry_hours_before × 60, the entry window is empty, and the strategy still saves.
exit_on_release
Despite the name, the exit fires at the start of the blackout, before the market closes. It sells what the entry bought, on the side it bought, whether that is YES or NO and whether the entry filled fully or partly:
- Kalshi: reduce-only, immediate-or-cancel sells at that side's best bid, split to fit Max contracts per order.
- Regular Polymarket: a limit sell of that token at its best bid. Shares you held before the entry aren't sold.
- Polymarket US: market sells of that side, split to fit Max contracts per order.
Backtests read this value more strictly than live Bots: an integer 1, or text such as yes, is off in a backtest and on in a live Bot. Write true or false.
pre_announcement_drift by venue
| Kalshi | Polymarket | Polymarket US | |
|---|---|---|---|
| Close time | Market close time | Market end date | End date, else close time |
| No close time | Error on every loop | Never enters | Never enters |
| "Entered" memory | Per market | Per market window | One per Bot |
| Entry order | Limit at the price (NO: 1 − price) | Limit at the bought token's book mid, at least the market minimum | Limit at the price (NO: 1 − price) |
| Release exit | Sells what the entry bought at that side's bid | Limit sell of what the entry bought at its bid | Market sell of what the entry bought |
| Backtest | Yes | Yes | No |
pre_announcement_drift backtests
Backtests use each historical market's close time and the same two windows on bar timestamps. Entry size is min(max_position, 5). With exit_on_release, the backtest sells both sides at the next bar once the blackout starts.
pre_announcement_drift examples
Illustrative only: one YES entry on the most liquid bracket of the next-closing Kalshi Fed event, between 12 hours and 30 minutes before close, sold when the final 30 minutes begin. The release exit sells the YES the entry bought. Studio pre-fills Max contracts per order at 2 and Max dollars per order at $2, which covers the entry at up to the 0.90 price ceiling ($1.80). A 120-second loop is far shorter than the 30-minute blackout.
version: 1
platform: kalshi
strategy: pre_announcement_drift
market:
series_ticker: "KXFED"
risk:
max_position: 2
price_floor: 0.10
price_ceiling: 0.90
loop:
interval: 120
params:
entry_hours_before: 12
blackout_minutes_before: 30
drift_direction: bullish
exit_on_release: trueIllustrative only: one NO entry of 5 shares on a single regular Polymarket yes/no market, between 24 hours and 1 hour before its end date, with everything sold when the final hour begins. The release exit sells the NO the entry bought. The market must be a standalone yes/no market: multi-outcome (negative-risk) markets save but are refused when the Bot starts. The slug is an example.
version: 1
platform: polymarket
strategy: pre_announcement_drift
market:
slug: "will-example-corp-beat-earnings"
risk:
max_position: 5
price_floor: 0.10
price_ceiling: 0.90
loop:
interval: 60
params:
entry_hours_before: 24
blackout_minutes_before: 60
drift_direction: bearish
exit_on_release: true