Polymarket US Strategy Reference
This section covers every strategy parameter for platform: polymarket_us. Polymarket US is a separate exchange from regular (international) Polymarket. It has its own markets, accounts and API keys. A Polymarket US Bot trades one market on your own Polymarket US account.
The YAML has the same shape as on the other venues: version, platform, strategy, market, risk, loop, then params for a built-in strategy, or rules (and optionally edge) for a custom one. Polymarket US supports only part of the strategy language, though. This page lists every parameter Studio accepts, what it rejects, and how backtesting, paper mode and credentials work. How the Bot picks its market and places orders, how each strategy behaves, and complete examples are on the pages listed under In this section.
In Polymarket US terms, buying YES is going long and buying NO is going short. Every price in the YAML is a dollar price per contract between 0 and 1, and it refers to the YES price unless a section says otherwise.
Note: Turbine is not a financial advisor. The numbers in this section are small, illustrative values that show how parameters behave. They are not recommendations of markets, sizes or thresholds.
In this section
- Polymarket US Markets, Risk and Execution: Choosing the market with
slug,event_slugorquery;max_position, the price floor and ceiling, andloop.interval; the deployment risk limits; and how entries and exits are priced and checked before they're sent. - Polymarket US Strategies and Edge Data: How each built-in strategy behaves on Polymarket US; custom rule fields, actions, validator checks and the decision log; and the edge data providers, including what happens when a feed goes stale.
- Polymarket US Example Strategies: Complete strategies that pass Studio's checks: NWS weather (with a rejected first draft and its fix), Coinbase MACD momentum, the FOMC calendar, a dip buyer with no outside data, and the
spread_capture,mean_reversionandpre_announcement_driftbuilt-ins.
How Polymarket US differs
If you know the Kalshi or Polymarket pages, these are the differences that matter most:
- One fixed market per Bot. You pick it with
market.slug(or, less predictably,event_slugorquery). There is no rolling series: when a dated market closes, the Bot does not move on to the next one. - Fewer risk keys. Only
max_position,price_floorandprice_ceiling. There is nomax_loss,max_notional,max_entries_per_market,active_windowortrading_schedule. - Built-in strategies can't have rules. Use
strategy: customif you want rules. - Exits are
sell_allonly.sell_yesandsell_no, which Kalshi and regular Polymarket accept, are rejected here, and so are the order-book fields (yes_best_bidand friends). - Edge data works, unlike on regular Polymarket: Coinbase, NWS weather and the economic calendar, in custom strategies.
- Entries are resting limit orders at the last trade price, where Kalshi custom entries price at the current ask. Exits are market orders for your whole position, split into orders that each fit the deploy dialog's Max contracts per order. See Order pricing and execution.
- No backtesting, unlike Kalshi and regular Polymarket. You can run a Bot in paper mode, with the gaps described in Paper mode.
- Your own API keys. The Bot trades with the Polymarket US API Key ID and Secret Key you enter when you deploy, not the wallet-based credentials regular Polymarket uses.
What works on Polymarket US compared with Kalshi
| Feature | Polymarket US | Kalshi |
|---|---|---|
| Markets per Bot | One fixed marketslug, event_slug or query; no rollover | One or manyseries_ticker rolls to new markets; selection: all trades every bracket |
| Built-in strategies (all five) | All five | Yes |
Custom rules with buy_yes buy_no sell_all cancel_all skip | Yes | Yes |
sell_yes / sell_no | Nouse sell_all | Yes |
Order-book fields (yes_best_bid and friends) | Nouse price and spread | Yes |
portfolio_position_count field | Norejected when you save | Yes |
| Edge data (Coinbase, NWS, economic calendar) | Yescustom only | Yescustom only |
| Missing or stale edge data cancels resting entry orders | Noorders keep resting | Yesresting exits stay |
derived metrics | No | Yescustom only |
Composite maker orders (orders) | No | Yes |
Entry-relative exits (entry_profit_offset and friends) | No | Yescustom only |
risk.max_loss | Nono loss-based stop | Yescustom only |
risk.max_notional | Nouse deployment risk limits | Yescustom only |
risk.max_entries_per_market | No | Yes |
risk.max_portfolio_positions | No | Yes |
active_window | No | Yescustom only |
trading_schedule | No | Yes |
| Custom exit larger than Max contracts per order | Splitmarket orders of up to 40 | Splitsent in batches |
| Backtesting | Nonot offered | Yes |
| Paper mode | Partialunrealized_pnl reads 0 | Yes |
All Polymarket US parameters
Every key Studio accepts for platform: polymarket_us is listed below. A linked parameter name goes to the sub-page that explains how it behaves on Polymarket US. Keys that Studio rejects are listed under Not available on Polymarket US.
Document keys
| Parameter | Type | Default | Allowed values | What it does |
|---|---|---|---|---|
version | integer | required | 1 | Strategy-language version. |
platform | string | required | polymarket_us | Selects Polymarket US. Case doesn't matter. A Polymarket US Studio session refuses a strategy that names another platform, and that refusal also clears the strategy the session had saved. Start a new session to use another venue. |
strategy | string | required | spread_capture, mean_reversion, panic_fade, observation_momentum, pre_announcement_drift, custom | A built-in strategy or custom rules. |
strategy_name | string | none | any text; Studio trims it to 80 characters | Display name. No effect on trading. |
strategy_name_origin | string | generated | user, generated, curated (anything else, including legacy, is saved as generated) | Where the name came from. Metadata only. |
name | string | none | any | Old key, accepted and ignored. Use strategy_name. |
Market, risk and loop
| Parameter | Type | Default | Allowed values | What it does |
|---|---|---|---|---|
market.slug | string | none | an exact Polymarket US market slug | The market the Bot trades. Set one of slug, event_slug or query. |
market.event_slug | string | none | a Polymarket US event slug | Trades the first open market in that event, chosen once at startup. |
market.query | string | none | free text | Trades the first open market a search returns, chosen once at startup. |
risk.max_position | integer (contracts) | required | whole number, 1 or more | Sizes built-in orders and caps a custom rule's size. |
risk.price_floor | number ($) | 0 | 0 or more, below 1 and below price_ceiling | Lowest price the Bot trades at. Custom entries are clamped up to it. |
risk.price_ceiling | number ($) | none (required in practice) | above 0, at most 1, above price_floor | Highest price the Bot trades at. Custom entries are clamped down to it. |
loop.interval | integer (seconds) | required | 10 or more | Seconds between strategy runs. |
Built-in strategy params
These go under params:. Each one applies only to the strategy named at the start of its description.
| Parameter | Type | Default | Allowed values | What it does |
|---|---|---|---|---|
params.spread_floor | number ($) | required | above 0 | spread_capture: quote only when ask − bid is at least this; also sets quote spacing. |
params.order_count | integer | required | whole number above 0 | spread_capture: quote levels on each side. |
params.post_only | boolean | false | true, false | spread_capture: maker-only quotes. |
params.refresh_on_fill | boolean | false | any | Accepted, no effect on Polymarket US. |
params.entry_low | number (YES $) | required | a number below entry_high | mean_reversion: buy YES at or below this price. |
params.entry_high | number (YES $) | required | a number above entry_low | mean_reversion: buy NO when YES is at or above this price. |
params.exit_target | number (YES $) | 0.5 | a number | mean_reversion: exit when YES is within 2¢ of this. |
params.cooldown | integer (seconds) | 60 | whole number, 0 or more | mean_reversion: minimum time between entry attempts. |
params.panic_threshold | number ($) | required | above 0 | panic_fade: drop from the 5-minute high that triggers a buy. |
params.fade_size | integer (contracts) | required | whole number above 0 | panic_fade: contracts per fade, and per exit. |
params.recovery_exit | number ($) | 0.04 | a number | panic_fade: rise above the fade price that closes it. |
params.max_fades | number | 3 | a number | panic_fade: fades allowed per Bot run. |
params.recovery_target | number | none | any | Accepted, no effect on Polymarket US. Use recovery_exit. |
params.lookback_periods | integer (loops) | required | whole number, 2 or more | observation_momentum: window length, counted in loops. |
params.momentum_threshold | number ($) | required | above 0 | observation_momentum: minimum price move over the window. |
params.position_scale | string | linear | exponential; anything else means linear | observation_momentum: how order size grows. |
params.entry_hours_before | integer (hours) | required | whole number above 0 | pre_announcement_drift: entry window opens this long before close. |
params.blackout_minutes_before | integer (minutes) | required | whole number, 0 or more | pre_announcement_drift: no entries in these final minutes. |
params.drift_direction | string | auto | bullish, bearish; anything else means auto | pre_announcement_drift: which side to buy. bullish buys YES, bearish buys NO, auto buys YES below 0.50 and NO at 0.50 or above. |
params.exit_on_release | boolean | false | true, false | pre_announcement_drift: sell when the blackout starts. |
params.position_size | any | none | any | Not read on Polymarket US. Order size comes from the strategy (see risk.max_position). |
Write params as plain, unquoted values: a quoted number such as entry_low: "0.2" or cooldown: "60" is rejected, and so is a word where a number belongs (exit_target: half) or a quoted boolean such as post_only: "false". See The params block.
Custom rules and edge data
| Parameter | Type | Default | Allowed values | What it does |
|---|---|---|---|---|
rules | list | required for custom | at least 1 rule, including a sell_all or cancel_all rule | Ordered if-then rules. The first match each loop wins. Rejected on built-in strategies. |
rules[].name | string | required | non-empty text | Label in logs and decisions. |
rules[].when.all or rules[].when.any | list of conditions | required (exactly one) | all (every condition true) or any (at least one true) | The rule's trigger. |
rules[].when.*[].field | string | required | price, spread, volume, time_to_expiry, position_size, unrealized_pnl, balance, order_count, edge.<alias>.<field> | The value the condition reads. |
rules[].when.*[].op | string | required | <, >, <=, >=, ==, != | Comparison. Always quote it: op: ">". |
rules[].when.*[].value | number, or duration string | one of value or value_field | a plain number; for time_to_expiry a string like "30m", "6h", "1d" | What to compare against. Numbers must not be quoted. |
rules[].when.*[].value_field | string | one of value or value_field | any numeric field above | Compare against another live value, e.g. MACD against its signal line. |
rules[].action | string | required | buy_yes, buy_no, sell_all, cancel_all, skip | What happens when the rule matches. |
rules[].size | integer (contracts) | 1 | 0 to risk.max_position; decimals are dropped | Contracts per entry. Ignored for other actions. |
edge | map of aliases | none | up to 8 aliases; lowercase names that start with a letter (letters, digits, _; 32 characters max) | Outside data for custom rules. |
edge.<alias>.provider | string | required | coinbase, nws, economic_calendar | The data source. |
edge.<alias>.symbol, .station or .event | string | required (the one that matches the provider) | Coinbase symbol like BTC-USD; NWS station like KLGA; calendar event of FOMC, CPI or FOMC,CPI | What to fetch. |
edge.<alias>.fields | list | required | field names from the provider's catalog | The only fields rules may read from this alias. |
edge.<alias>.refresh | duration | Coinbase 5s, NWS 5m, calendar 15m | at least 1s (Coinbase; 5s with candle fields), 60s (NWS), 5m (calendar) | How often the data is fetched again. |
Deployment risk limits such as Max contracts per order are not YAML keys. Studio pre-fills them in the deploy dialog from your strategy, and you confirm or change them there; see Deployment risk limits.
Not available on Polymarket US
Rejected when you save
Studio refuses a Polymarket US strategy that uses any of these.
| Key or feature | Use this instead on Polymarket US |
|---|---|
risk.max_loss | There is no loss-based stop on Polymarket US. Use price-based sell_all exits and your deployment risk limits. |
risk.max_notional | The deployment risk limits Max dollars per order and Max daily notional traded. |
risk.max_entries_per_market | Guard entries with position_size == 0. For panic_fade, max_fades. |
risk.max_portfolio_positions | Not needed: each Bot trades one market. |
active_window | time_to_expiry conditions, or deploy and stop the Bot at the times you choose. |
trading_schedule (whole strategy or per rule) | time_to_expiry conditions, or economic_calendar edge data for event timing. |
derived (for example distance from strike) | Compare the edge field against a fixed number in the rule. |
rules[].orders and rules[].max_combined_price | buy_yes and buy_no entries. |
entry_profit_offset, entry_stop_loss_offset, entry_profit_targets, entry_profit_min_time_to_expiry | sell_all rules with price conditions. |
Actions sell_yes and sell_no | sell_all, which sells whichever side you hold. |
Fields yes_best_bid, yes_best_ask, no_best_bid, no_best_ask | price and spread. |
Fields paired_best_bid_sum, paired_best_ask_sum | price and spread. |
Fields yes_position_size, no_position_size | position_size (contracts held on either side). |
Field portfolio_position_count | Not needed: each Bot trades one market. |
Kalshi selectors market.ticker, market.event_ticker, market.series_ticker, market.selection | market.slug. |
Polymarket selectors market.series_slug, market.recurring, market.condition_id, market.yes_token_id, market.no_token_id, market.neg_risk, market.tick_size, market.min_order_size | market.slug. |
rules on a built-in strategy | strategy: custom. |
The four risk keys are rejected when set above 0. A value of 0 means off and is accepted, but it does nothing.
Backtesting isn't offered for Polymarket US either; see Backtesting.
Accepted but not supported
These save without an error but don't work on Polymarket US. Avoid them.
params.refresh_on_fill,params.recovery_targetandparams.position_sizeare ignored.- An
edgeblock on a built-in strategy is ignored. Only custom rules read edge data. - Typos inside
paramsor an edge alias. Unknown keys there are silently ignored, soparams.cooldwndoes nothing. Unknown keys insidemarket,riskandloop, such asrisk.max_loss_usdorloop.jitter, are rejected, as are unknown top-level keys and unknown rule keys. - Double quotes or a trailing backslash in
market.slug,event_slug,queryor a rulename. They pass Studio's checks but stop the Bot at startup.
Backtesting, paper mode and credentials
Backtesting
Backtesting isn't available for Polymarket US. Studio refuses backtests for Polymarket US strategies, and Deep Research is not yet supported for Polymarket US. Paper mode is the only way to run a Polymarket US Bot without real orders.
Paper mode
You can deploy a Polymarket US Bot in paper mode. It is the same Bot, reading live Polymarket US market data, but orders, fills, positions and balance are simulated. The simulated balance starts at $1,000 by default.
Your deployment risk limits still apply, and the Bot still needs your API keys, because it signs its market-data requests.
A limit order that crosses the live book fills at once if the visible depth within your limit covers the whole order. Otherwise it rests, and fills in full once the opposite best price moves strictly through your limit.
Post-only orders that would cross are rejected. Simulated fees are 0.
Market orders, which
sell_alland the built-in exits use, fill against the whole visible book at once if its depth covers the order, and are rejected otherwise. They never rest.
Note:
unrealized_pnlreads 0 in paper mode.
Credentials
A Polymarket US Bot trades on your Polymarket US account with the API Key ID and Secret Key you create in the Polymarket US developer portal (polymarket.us/developer). Studio asks for them in the deploy dialog; never paste them into chat. Turbine's own account never trades for you, and buying power comes from your Polymarket US balance.
- These are not regular Polymarket credentials. There is no wallet key.
- Your keys are shared by every Polymarket US Bot, and every Kalshi + Polymarket US arbitrage Bot, on your runner. Entering new keys replaces them for all of those Bots. Other Bots switch to the new keys the next time they restart.
- On a redeploy you can keep the keys already saved.
- A revoked or mistyped key makes every request fail, so the API error breaker trips after 3 errors in 5 minutes (the defaults) and new orders stop; the breaker retries after each 5-minute cooldown and trips again while the key keeps failing.