panic_fade
This page covers panic_fade, one of the five built-in strategies, on Kalshi, Polymarket and Polymarket US: how it fades sharp drops, each parameter, one fade at a time, 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.
panic_fade buys YES after a sharp drop and sells on a small recovery. It only fades drops; it never sells into spikes. Each loop, for each market:
- It records the YES price and keeps the last 5 minutes of its own samples.
- It computes the drop: the highest price in the window minus the current price.
- It buys
fade_sizeYES at the current price when all of these hold:- the drop is at least
panic_threshold; - fewer than
max_fadesfades have been used; price_floor< price <price_ceiling;- no fade is open or waiting to fill (on Kalshi, in this market), and on Kalshi this is the series' current market;
- on Polymarket and Polymarket US, no order is resting.
- the drop is at least
- The fade opens once its buy fills, even partly. A buy that hasn't filled after two loops is cancelled, and it doesn't count toward
max_fades. - While a fade is open, it sells the YES the fade bought when the price is
recovery_exitabove the fade's price, or when the price falls belowprice_floor.
panic_fade: one fade, from drop to recovery
- YES price, one sample per loop
- 5-minute high
- Trigger: high − panic_threshold
- Exit: fade price + recovery_exit
loop.interval: 30, panic_threshold: 0.08, fade_size: 1, recovery_exit: 0.04, max_fades: 3. The window holds the Bot's own samples from the last 5 minutes, about 10 at this interval. At an interval of 300 seconds or more it would hold one sample and never fire. A price that lands exactly on a threshold can miss it because of decimal rounding (0.57 − 0.53 computes as just under 0.04), so this example clears each threshold by a cent.| Parameter | Type | Default | Allowed values | What it does |
|---|---|---|---|---|
panic_threshold | number (YES dollars) | Required | > 0 | Drop from the 5-minute high that triggers a buy. |
fade_size | whole number | Required | ≥ 1 | YES contracts bought per fade. The exit sells what the fade bought. |
recovery_exit | number (YES dollars) | 0.04 | 0 to 1 | Take-profit distance above the fade's entry price. Set it explicitly: backtests use a different default. |
max_fades | whole number | 3 | ≥ 0; 0 disables entries | Most fades that fill. |
recovery_target | number | — | — | Ignored by live Bots. Backtests use it (default 0.50) only when recovery_exit is missing or 0. |
panic_threshold
The window is built from the Bot's own loop samples, so loop.interval must be well under 300 seconds. At 30 seconds the window holds about 10 samples. At 300 seconds or more it holds one, and the strategy never fires. The window starts empty after a restart.
On a rolling Polymarket series the window starts empty in each new market, so one market's closing price is never compared with the next one's.
fade_size
fade_size alone sets the size of each fade. On Kalshi and Polymarket US, Studio pre-fills Max contracts per order from fade_size, but a fade is refused once held plus resting contracts would pass the lower of max_position and Max open contracts (see Deployment risk limits), so keep fade_size at or below max_position. On regular Polymarket a fade_size below the market's minimum order size (often 5 shares) is raised to the minimum, as long as max_position is at least the minimum; otherwise the fade is skipped.
If a fade's buy only partly fills, the exit sells the part that filled and cancels the rest.
max_fades
- Kalshi: counted per market when the fade's buy fills, so each new market in a series starts at 0.
- Polymarket: counted when a fade fills, per market, so each window of a rolling series starts at 0 (see Markets and memory).
- Polymarket US: one counter for the Bot's whole life, counted when a fade fills.
Every counter resets when the Bot restarts.
One fade at a time
On every venue a fade must be sold, or its unfilled buy cancelled, before the next one can start. The 5-minute high stays in the window, so a new fade can follow soon after an exit if the price is still down.
On Kalshi a restart doesn't lose an open fade: the Bot still holds its YES, and measures the recovery from the first price it sees after the restart. On Polymarket and Polymarket US a restart forgets the fade, so the Bot won't exit YES it bought before the restart.
panic_fade by venue
| Kalshi | Polymarket | Polymarket US | |
|---|---|---|---|
| Fades open at once | 1 per market | 1 | 1 |
max_fades counter | Per market | Per market window | One per Bot |
| Exit order | Reduce-only, immediate-or-cancel sell of the fade's YES at the YES bid | Limit sell of the fade's YES at the YES bid | Market sell of the fade's YES |
Stop below price_floor | Sells at the YES bid | Sells at the YES bid | Market sell |
| Minimum order size | None | fade_size raised to the market minimum (often 5 shares) | None |
| Deployment risk limits | Enforced | Not applied | Enforced |
| Backtest | Yes | Yes | No |
panic_fade backtests
The backtest uses a 5-minute window of historical bar prices and buys at the next bar's ask. Like the live Bot it opens one fade at a time and counts a fade only when it fills. Unlike the live Bot it caps holdings at max_position and sells the whole position on exit.
When recovery_exit is omitted, the backtest exits at the hidden recovery_target distance (0.50 by default) while the live Bot exits at 0.04. The backtest also treats recovery_exit: 0 as omitted, while a live Bot with 0 exits as soon as the price is back at the fade price. Always set recovery_exit to a number above 0.
panic_fade examples
Illustrative only: 1-contract fades on the most liquid strike of the current Kalshi BTC daily event. It buys after a 12-cent drop, sells at +6 cents or below 0.15, makes at most 2 fades per market, and places no new entries on weekdays from 08:25 to 08:45 New York time. A fade's buy that hasn't filled after two loops is cancelled, and so is one still resting when a blackout starts.
version: 1
platform: kalshi
strategy: panic_fade
market:
series_ticker: "KXBTCD"
selection: most_liquid
risk:
max_position: 2
price_floor: 0.15
price_ceiling: 0.85
loop:
interval: 30
trading_schedule:
timezone: America/New_York
blackouts:
- days: [mon, tue, wed, thu, fri]
start: "08:25"
end: "08:45"
params:
panic_threshold: 0.12
fade_size: 1
recovery_exit: 0.06
max_fades: 2Illustrative only: a single 1-contract fade on one Polymarket US market. max_fades: 1 means one fade for the life of the Bot. The slug is an example.
version: 1
platform: polymarket_us
strategy: panic_fade
market:
slug: "nba-lal-bos-2026-11-04"
risk:
max_position: 1
price_floor: 0.10
price_ceiling: 0.90
loop:
interval: 20
params:
panic_threshold: 0.10
fade_size: 1
recovery_exit: 0.05
max_fades: 1