Polymarket Strategy Parameters
This page covers platform: polymarket: regular (international) Polymarket. If you trade on the US exchange, see Polymarket US instead. The two venues use different selectors and support different features.
A Polymarket strategy has the same shape as a Kalshi one: version, platform, strategy, market, risk and loop, then params for a built-in strategy or rules for your own. The runtime underneath is different, so the same keys can behave differently.
This page gives you the overview: how Polymarket differs from Kalshi, a table of every key Polymarket accepts and the keys that are not available here. The details are split across the pages listed under In this section, and the linked rows in the parameter table take you straight to the right one. See the Strategy Reference overview for how the venue references fit together.
Note: Examples on this page and its sub-pages are illustrative shapes, not recommendations. Values are small on purpose. Choose your own markets, sizes and thresholds, and remember that automated strategies can lose money. See Risk & Limits.
In this section
- Polymarket Market Selection: Every
marketselector (slug,condition_id, a YES/NO token pair,series_slugandrecurring), which markets a Bot can trade, the discovery-onlyevent_slugandquery, the fallbacktick_sizeandmin_order_size, and what carries over when a series rolls to its next market. - Polymarket Units, Rounding and Risk: The units for prices, sizes, money and time, how buys are clamped and orders rounded onto the tick, the market's minimum order size, each
riskkey, and a note that Polymarket Bots don't enforce deployment risk limits. - Polymarket Built-in Strategies and Custom Rules: How each built-in strategy enters, prices, sizes and exits on Polymarket, and what is specific to custom rules here: the 12 fields, the actions, how a custom buy is priced and sized, and what the validator checks.
- Polymarket Active Window, Backtests, Fees and Location: The one-time
active_window, what can be backtested and where backtests differ from live Bots, how fees are charged, and where live Polymarket trading is not available. - Polymarket Example Strategies: Seven complete strategies that pass validation: custom rules on rolling crypto series and pinned markets (dollar P&L exits, NO-book fields, a
skipguard and acancel_allfor stale bids), plus the built-inpanic_fadeon a token-pinned market,mean_reversionandpre_announcement_drift.
Polymarket at a glance
| Topic | Kalshi | Polymarket |
|---|---|---|
| Markets per Bot | One market, or several with a Kalshi series selector | Exactly one binary market at a time. A series rolls to the next market. |
| Choosing the market | ticker, event_ticker, series_ticker, query | slug, condition_id, a YES/NO token pair, series_slug or recurring |
| Order books | One YES/NO book | Two separate books: one for the YES token, one for the NO token |
| Units | Whole contracts at 1-cent prices | Shares, a per-market price tick (0.1 down to 0.0001), a minimum order size (usually 5 shares), fractional sizes possible |
| Custom buy price | Best ask | The side's midpoint, so buys can rest unfilled |
External data (edge), derived | Supported | Not available |
| Time controls | trading_schedule, active_window | active_window only |
| Loss and portfolio caps | max_loss, max_portfolio_positions | Not available |
| Backtests | Order-book history with a candle fallback | YES order-book history only |
| Deployment risk limits | Enforced by the Bot | Not read, and not shown when you deploy. Your risk block is the limit. |
For Up/Down crypto markets, Up is YES and Down is NO everywhere on this page and its sub-pages: in token IDs, actions and fields.
All Polymarket parameters
Every key Polymarket accepts. Rows that link go to the section of a sub-page that covers the key in more detail.
| Parameter | Type | Default | Allowed values | What it does |
|---|---|---|---|---|
version | integer | required | 1 | DSL version. |
platform | string | required | polymarket | Selects regular Polymarket. Must match the venue of your Studio session. |
strategy | string | required | custom, spread_capture, mean_reversion, panic_fade, observation_momentum, pre_announcement_drift | Your own rules, or a built-in strategy. |
strategy_name | string | none | free text, stored up to 80 characters | Display name. |
strategy_name_origin | string | generated | user, generated, curated; anything else, including legacy, is treated as generated | Where the name came from. Metadata only. |
name | any | none | any | Legacy key, accepted and ignored. Use strategy_name. |
market | mapping | required | one concrete selector | The market the Bot trades. See Market selection. |
market.slug | string | none | a Polymarket market slug | Pins one market by its URL slug. |
market.condition_id | string | none | a 0x… condition ID | Pins one market by its condition ID. |
market.yes_token_id | string | none | a token ID | The YES (Up) token. Needs no_token_id. |
market.no_token_id | string | none | a token ID | The NO (Down) token. Needs yes_token_id. |
market.series_slug | string | none | a Polymarket series slug | Follows a rolling series, one market at a time. |
market.recurring | mapping | none | kind, asset, interval | Shorthand for the crypto Up/Down series. |
market.recurring.kind | string | updown | updown | The only kind on regular Polymarket. |
market.recurring.asset | string | required in recurring | btc, eth, sol, xrp, doge, hype, bnb | Which asset's series to follow. |
market.recurring.interval | string | required in recurring | 5m, 15m, 1h, 4h, 1d | Length of each market in the series. |
market.recurring.event_slug_prefix | string | none | any | Accepted and ignored here. Used only by arbitrage. |
market.event_slug | string | none | an event slug | Discovery only. Cannot be deployed. |
market.query | string | none | free text | Discovery only. Cannot be deployed. |
market.neg_risk | boolean | false | false | true is rejected: multi-outcome markets are not supported. |
market.tick_size | string or number | 0.01 | 0.1, 0.01, 0.001, 0.0001 | Fallback price tick for token-pinned markets. |
market.min_order_size | string or number | 5 | a positive number | Fallback minimum order size, in shares, for token-pinned markets. |
risk | mapping | required | max_position, price_floor, price_ceiling, max_entries_per_market, max_notional | Position and price limits. See Risk keys on Polymarket. |
risk.max_position | whole number (shares) | required | greater than 0 | Most YES + NO shares held in the current market. |
risk.price_floor | number ($ per share) | 0 | 0 or more, below 1 and below the ceiling | Lowest price the Bot buys at. Clamps every live buy. |
risk.price_ceiling | number ($ per share) | required | above 0, up to 1, above the floor | Highest price the Bot buys at. Clamps every live buy. |
risk.max_entries_per_market | whole number | off | 0 or more; custom only | Caps buy orders per market. |
risk.max_notional | number ($) | off | 0 or more; custom only | Dollar budget for buys in the current market. |
loop | mapping | required | interval | How often the Bot runs. |
loop.interval | whole number (seconds) | required | 10 or more | How often the Bot checks the market and runs its logic. |
active_window | mapping | always active | start, end (at least one); custom only | One-time trading window. |
active_window.start | timestamp | none | RFC 3339 with offset, e.g. 2026-10-04T09:00:00-04:00 | The Bot does nothing before this time. |
active_window.end | timestamp | none | RFC 3339, after start | The Bot cancels its own resting buys and stops entering; exits keep running. |
params | mapping | none | depends on the strategy | Built-in strategy settings. See Built-in strategies on Polymarket. |
params.spread_floor | number ($) | required for spread_capture | greater than 0 | Minimum YES spread before quoting; also sets quote distance. |
params.order_count | whole number | required for spread_capture | greater than 0 | Price levels quoted on each side. |
params.post_only | boolean | false | unquoted true or false only | spread_capture quotes are maker-only. |
params.refresh_on_fill | boolean | false | true, false | Accepted; no effect on Polymarket. |
params.entry_low | number (YES price) | required for mean_reversion | below entry_high | Buy YES at or below this price. |
params.entry_high | number (YES price) | required for mean_reversion | above entry_low | Buy NO when YES is at or above this price. |
params.exit_target | number (YES price) | 0.5 | a number | Sell everything when YES is within ±0.02 of this. |
params.cooldown | whole number (seconds) | 60 | 0 or more | Minimum time between entry attempts. |
params.panic_threshold | number ($) | required for panic_fade | greater than 0 | Drop from the 5-minute high that triggers a buy. |
params.fade_size | whole number (shares) | required for panic_fade | greater than 0 | Shares bought per fade. |
params.recovery_exit | number ($) | 0.04 | a number | Rise above the entry price that triggers the exit. |
params.recovery_target | number ($) | none | a number | Legacy key read only by backtests. Use recovery_exit. |
params.max_fades | whole number | 3 | a whole number | Most fades per Bot run. |
params.lookback_periods | whole number (loops) | required for observation_momentum | 2 or more | How many recent loop samples of the YES price to compare (newest minus oldest); it can fire once 2 samples exist. |
params.momentum_threshold | number ($) | required for observation_momentum | greater than 0 | Minimum move that triggers a buy. |
params.position_scale | string | linear | linear, exponential | How order size grows on repeated signals. |
params.entry_hours_before | whole number (hours) | required for pre_announcement_drift | greater than 0 | When the entry window opens before the end date. |
params.blackout_minutes_before | whole number (minutes) | required for pre_announcement_drift | 0 or more | Final minutes with no entries. |
params.drift_direction | string | auto | bullish, bearish | Which side to buy. Anything else means auto. |
params.exit_on_release | boolean | false | unquoted true or false only | Sell everything when the blackout starts. Never fires with blackout_minutes_before: 0. |
rules | list | required for custom | 1 or more rules, at least one exit | Your if/then rules. See Custom rules on Polymarket. |
rules[].name | string | required | non-empty text | Label shown in logs and decisions. |
rules[].when | mapping | required | exactly one of all, any | The rule's conditions. |
rules[].when.all[].field (or any[]) | string | required | one of the 12 Polymarket fields | The live value to compare. |
rules[].when.all[].op | string | required | <, >, <=, >=, ==, != | Comparison operator. Quote it in YAML. |
rules[].when.all[].value | number or duration | none | an unquoted number; for time_to_expiry a whole-number duration such as "90s", "5m", "6h", "1d" ("1.5h" is rejected; write "90m") | Fixed value to compare against. |
rules[].when.all[].value_field | string | none | another field | Compare against another live field instead. |
rules[].action | string | required | buy_yes, buy_no, sell_yes, sell_no, sell_all, cancel_all, skip | What happens when the rule matches. See Actions. |
rules[].size | whole number (shares) | buys: 1; sells: all held | 0 or more; buys up to max_position | Shares per order. |
Unknown keys inside market, risk, loop and active_window are rejected, so conditon_id, max_notinal or active_window.timezone fails with an unknown … field error, as do unknown top-level keys and unknown rule keys. Unknown keys inside params are still ignored without an error, so check their spelling.
Not available on Polymarket
These keys are rejected when platform is polymarket:
market.ticker,market.event_ticker,market.series_tickerare Kalshi selectors. Useslug,condition_id, a token pair,series_slugorrecurring.market.selectionis Kalshi's multi-market mode. A Polymarket Bot trades one market at a time; useseries_slugorrecurringto follow a series.risk.max_lossis Kalshi custom only. The closest option is asell_allrule onunrealized_pnl, which can match only while the Bot can value your position (see Fields).risk.max_portfolio_positionsis Kalshi only. There is no equivalent, because a Polymarket Bot holds one market.trading_schedule, at the top level or on a rule, is Kalshi only. Useactive_windowfor a one-time window, ortime_to_expiryconditions.edge(external data such as Coinbase prices and indicators) is not available on regular Polymarket. Kalshi and Polymarket US support it. See Edge Data.derivedmetrics are Kalshi custom only.rules[].ordersandrules[].max_combined_price(composite orders) are Kalshi only. Usebuy_yesorbuy_no.entry_profit_offset,entry_stop_loss_offset,entry_profit_targets,entry_profit_min_time_to_expiryare Kalshi only. Writesell_yesorsell_norules onprice, the book fields orunrealized_pnlinstead. See Advanced Kalshi Rules.- Fields
yes_position_sizeandno_position_sizeare Kalshi only. On Polymarket,position_sizeis YES and NO shares combined. - Fields
paired_best_bid_sumandpaired_best_ask_sumare Kalshi only. You can compareyes_best_askwithno_best_askusingvalue_field. - Field
portfolio_position_countis Kalshi only: Polymarket never supplies it. risk.max_entries_per_market,risk.max_notionalandactive_windoware rejected on built-in strategies. They work withstrategy: custom.
# Rejected: max_loss needs run-level loss tracking that only Kalshi custom strategies have
# error: currently supported only for Kalshi custom strategies
version: 1
platform: polymarket
strategy: custom
market:
slug: "will-example-event-happen-by-2026-12-31"
risk:
max_position: 10
price_floor: 0.05
price_ceiling: 0.95
max_loss: 5
loop:
interval: 30
rules:
- name: take_profit
when:
all:
- {field: position_size, op: ">", value: 0}
- {field: price, op: ">=", value: 0.60}
action: sell_yes
- name: buy_yes_low
when:
all:
- {field: position_size, op: "==", value: 0}
- {field: price, op: "<=", value: 0.40}
action: buy_yes
size: 5# Rejected: regular Polymarket has no external data feeds
# error: regular Polymarket strategies do not support edge aliases
version: 1
platform: polymarket
strategy: custom
market:
slug: "will-example-event-happen-by-2026-12-31"
edge:
btc:
provider: coinbase
symbol: BTC-USD
fields: [price]
risk:
max_position: 10
price_floor: 0.05
price_ceiling: 0.95
loop:
interval: 30
rules:
- name: take_profit
when:
all:
- {field: position_size, op: ">", value: 0}
- {field: price, op: ">=", value: 0.60}
action: sell_yes
- name: buy_yes_low
when:
all:
- {field: position_size, op: "==", value: 0}
- {field: price, op: "<=", value: 0.40}
- {field: edge.btc.price, op: ">", value: 0}
action: buy_yes
size: 5