Kalshi Active Window and Trading Schedule
A Kalshi event-contract strategy (platform: kalshi) can limit when it trades in two ways. A one-time active_window runs a custom strategy for one fixed period and then stops it. A weekly trading_schedule sets recurring hours for new entries on any strategy type, while exits keep running. The two can't be combined. For every other key, see All Kalshi parameters.
Active window
active_window gives a custom strategy one fixed period to run in. Use it for a single evening's game or to stand down before a scheduled release.
active_window:
start: "2026-10-15T18:30:00-04:00"
end: "2026-10-15T23:30:00-04:00"- Set
start,endor both.active_window: {}fails withrequires at least one of start or end. - Both are RFC3339 timestamps with an offset (
-04:00) orZ. A space instead ofT, a bare date or a missing offset is rejected. Daylight saving is up to you, because the value is an absolute instant. endmust be afterstart. Past times are accepted, so a pastendmakes the Bot idle from the start.- Custom strategies only, and not together with
trading_scheduleor rule-level schedules.
What the Bot does, checked at the start of each cycle:
- Before
start: nothing. No market lookups, no rules, no exits, nomax_losscheck. - Between
startandend: normal trading. - First cycle at or after
end: it cancels this deployment's resting entry orders (its buys), in any market, once. If a cancel fails it retries next cycle, and that cycle's exits still run. Its resting exit orders, your manual orders and other Bots' orders are untouched. - After
end: no new entries. A buy rule whose conditions match is skipped with the reasonactive_window.end reached, and the rules below it still run. The Bot keeps evaluating every market where your account still holds a position or it has a resting order, so sells,cancel_all, stop-losses, take-profits, per-fill exits andmax_losskeep working until you stop the Bot. Withseries_tickerthose are the series' markets; withticker, that market; withevent_ticker, the event's markets; withquery, the market the query finds. With nothing left to manage, it idles.
Note:
active_windownever sells on its own. Afterenda position is only closed by your exit rules ormax_loss; without them, it is held to settlement unless you close it yourself.
What the Bot does before, during and after an active_window
start: 2026-10-15T18:30:00-04:00, end: 2026-10-15T23:30:00-04:00, loop.interval: 15. Boundaries are checked at the start of each cycle, so each can be seen up to one interval plus the cycle time late.With only end, the Bot trades from deploy until that instant:
active_window:
end: "2026-11-12T08:20:00-05:00"Backtest: not supported. A backtest refuses any strategy with active_window, because it targets future wall-clock times. Remove it for a historical test.
Trading schedule
trading_schedule sets recurring weekly hours when the strategy may open positions. It works with every Kalshi strategy type, built-ins included, and can be backtested. It can't be combined with active_window.
trading_schedule:
timezone: America/New_York
trading_hours:
- days: [mon, tue, wed, thu, fri]
start: "09:30"
end: "16:00"
blackouts:
- days: [wed]
start: "13:45"
end: "14:30"A weekly trading schedule with a blackout
- Entries allowed
- Outside trading hours
- Blackout
timezone: America/New_York, trading_hours Mon–Fri 09:30–16:00 and a blackouts window Wed 13:45–14:30, which wins over trading hours. The red block on Wednesday is the blackout. Only new entries are blocked: exits, stop-losses and max_loss run at every hour. When entries become blocked, the Bot cancels its own resting entry orders within a minute. With a schedule present, sells only touch contracts this deployment bought or you adopted at deploy.Only timezone, trading_hours and blackouts are allowed, and each window may only hold days, start and end. A schedule needs between 1 and 32 windows in total, and must leave at least one minute of the week open (trading hours and blackouts leave no time for entries). trading_schedule: null is rejected; remove the key to turn the schedule off.
# Rejected: a one-time active_window and a weekly trading_schedule can't be combined
# error: cannot be combined with active_window
version: 1
platform: kalshi
strategy: custom
market:
ticker: KXMLBGAME-26OCT15NYYBOS-NYY
risk:
max_position: 2
price_ceiling: 0.60
loop:
interval: 30
active_window:
end: "2026-10-15T23:30:00-04:00"
trading_schedule:
timezone: America/New_York
trading_hours:
- days: [thu]
start: "18:30"
end: "23:30"
rules:
- name: take_profit
when:
all:
- {field: yes_position_size, op: ">", value: 0}
- {field: yes_best_bid, op: ">=", value: 0.70}
action: sell_yes
- name: enter_yes
when:
all:
- {field: position_size, op: "==", value: 0}
- {field: yes_best_ask, op: "<=", value: 0.40}
action: buy_yestrading_schedule.timezone
Required. Write UTC or an IANA name with a /, such as America/New_York, America/Chicago or Europe/London. Abbreviations (EST, CST, GMT), Etc/GMT names, wrong capitalization and surrounding spaces are rejected with timezone must be an IANA name such as America/Chicago, or UTC. A correctly formatted name that isn't in Studio's timezone data fails with unknown timezone. The timezone is never guessed from your browser or the server, so choose it on purpose.
trading_hours and blackouts
trading_hours: when present, new entries are allowed only inside these windows. Everything else is outside trading hours. When omitted, the whole week is open except blackouts.blackouts: new entries are never allowed inside these windows. Blackouts are applied last and always win over trading hours.
Leave out a list you don't need. An empty list (trading_hours: []) is rejected with omit unused window lists instead of providing an empty list.
Windows: days, start and end
days: a list of unique lowercase days,monthroughsun.MON,mondayanddays: mon(not a list) are rejected.start: zero-padded 24-hourHH:MM, included.9:00and09:30:00are rejected. Quote it ("09:30").end: excluded.24:00means "until midnight" and is only allowed as an end.startandendmust differ.- Overnight: if
endis earlier thanstart, the window crosses midnight and belongs to the day it starts on.days: [fri],start: "22:00",end: "02:00"covers Friday 22:00 to Saturday 02:00. A Sunday overnight window runs into Monday.
What a schedule blocks and what keeps running
- Blocked: every buy while the current local minute isn't open. On custom strategies, a blocked entry rule is skipped and later rules (such as exits) still run.
- Keeps running: sells,
cancel_all, stop-losses, take-profits andmax_loss. - Resting entries: every minute while entries are blocked, and once at startup, the Bot cancels its own resting entry orders. It leaves exit orders and other Bots' orders alone. Cancellation happens at minute boundaries, so an entry can still fill right at a boundary.
- What you'll see: a blocked entry is logged with the reason
outside_trading_hoursorschedule_blackout. While the Bot is still canceling entry orders after a boundary or a restart, entries wait withschedule_cancellation_pending. If the schedule's timezone data can't be loaded, the Bot blocks every entry (schedule_unavailable) instead of guessing.
With or without a schedule, each sell is reduce-only and capped at what this deployment owns on the side it sells, including positions you explicitly adopt when you deploy. Inventory reserved by pending or unconfirmed exits is unavailable to another exit. A NO position counts as NO whichever way Kalshi reports its fills. If there is nothing to sell, the exit fails with no unreserved Bot-owned inventory for this exit.
Note: After you update or redeploy a Bot, its exit rules can't sell contracts the previous deployment bought unless you adopt them at deploy. Close those positions yourself or adopt them.
Backtest: supported on Kalshi, for custom and built-in strategies.
Daylight saving
The Bot converts every real minute into local time in your timezone and then checks the schedule, so daylight saving is handled for you:
- Spring forward: a local time that is skipped never happens. A Sunday 02:00–03:00 blackout in
America/Chicagoblocks nothing on 8 March 2026, because that hour doesn't exist that day. - Fall back: a repeated local time applies both times. A Sunday 01:00–02:00 blackout in
America/Chicagoblocks two real hours on 1 November 2026.
Rule-level schedules
Custom buy_yes and buy_no rules can carry their own trading_schedule with the same shape. A rule may enter only when both its own schedule and the top-level schedule (if any) are open. When a rule's schedule is closed, the Bot skips it and moves to the next rule, so you can write one entry rule per time of day, each with its own threshold.
Rule schedules aren't allowed on sell, cancel_all or orders rules, with active_window, or in a strategy that uses orders anywhere. When any rule has a schedule, the Bot's resting entry orders also expire at the next schedule change. Details are on Rule-Level Trading Schedules, and a full example is Time-varying EMA-distance entry thresholds.