Polyester market orders use immediate-or-cancel execution with a price boundary. They can fill immediately at available prices within that boundary, while any unfilled quantity is canceled.
The boundary is calculated from a reference price and a slippage tolerance. A request can provide its own tolerance, or it can omit the tolerance and use the Pair's configured default.
How the execution boundary is calculated
Choose the reference price
The server reference is an admission-time estimate derived from current order-book or recent-trade data. It can include a safety margin and is not guaranteed to equal the best bid or ask displayed by a market-data feed at the same instant.
Choose the slippage tolerance
0 selects the
platform fallback rather than zero tolerance.Calculate the protected price
Execute immediately or cancel
For basis-point protection:
| Side | Protected boundary |
|---|---|
| Buy | reference price * (1 + max slippage bps / 10,000) |
| Sell | reference price * (1 - max slippage bps / 10,000) |
Fractional-tick adjustments round outward so the boundary never grants less tolerance than requested. A buy boundary rounds upward and a sell boundary rounds downward, making the effective boundary up to one price tick more permissive than the exact percentage.
Example: explicit 6% slippage
600 basis points equals 6%. With a reference price of 100:
| Side | Result |
|---|---|
| Buy | May fill up to a protected price of 106 |
| Sell | May fill down to a protected price of 94 |
The 600 bps value is used unchanged even if the Pair default is lower.
Explicit values, defaults, and limits
| Request | Behavior |
|---|---|
Positive maxSlippageBps | Uses the request value instead of the Pair default |
Positive maxSlippageTicks | Uses the absolute tick delta instead of basis points |
| Neither field supplied | Uses the side-specific Pair default, or the platform fallback when that value is 0 |
| Both fields supplied | Rejected because they are alternatives in the same choice |
maxSlippageBps accepts values from 1 through 10,000:
1 bp = 0.01%
600 bps = 6%
10,000 bps = 100%Values outside that range are rejected as MAX_SLIPPAGE_INVALID. Values inside the range are not
silently resized.
maxSlippageBps = 10000 is valid. For a buy, the protected boundary is twice the
reference price. For a sell, the boundary is clamped to the minimum positive price of one price
tick. Integrations should apply their own stricter policy when 100% tolerance is not acceptable.Read the current Pair policy
Pair policy is returned by MarketDataService.GetSpotConfig. Read these fields for the selected
Pair instead of hardcoding current defaults:
| Pair field | Meaning |
|---|---|
defaultMarketSlippageBpsBuy | Default basis-point tolerance when a buy omits slippage |
defaultMarketSlippageBpsSell | Default basis-point tolerance when a sell omits slippage |
maxClientRefDriftBps | Maximum accepted drift between a supplied client reference and Polyester's server reference |
The default slippage fields are fallback values, not ceilings on client overrides.
0, Polyester does not apply zero tolerance. It uses the
corresponding platform fallback. Treat 0 as "not explicitly configured for this Pair," not as the
effective tolerance.The TypeScript SDK catalog exposes these values as percentages: defaultMarketSlippagePctBuy, defaultMarketSlippagePctSell, and maxClientRefDriftPct. Use the
raw GetSpotConfig response when an integration needs the basis-point field names shown above.
Client reference drift
A client reference price records the price the client used for a preview or trading decision. When both client and server references are available, Polyester calculates:
drift bps = absolute(client reference - server reference) * 10,000 / server referenceFor example, client reference 105 and server reference 100 produce 500 bps, or 5%, of
drift. If drift exceeds maxClientRefDriftBps, the order is rejected as STALE_QUOTE.
STALE_QUOTE as the only safeguard when current
server-side pricing may be unavailable.maxClientRefDriftBps does not:
- cap the request's slippage value
- replace
maxSlippageBps - apply when the request omits a client reference price
The compounded bounds in that example are:
buy: 1.05 * 1.06 = 1.113
sell: 0.95 * 0.94 = 0.893If an integration intends to enforce a total distance from current market data, it must account for both the permitted reference drift and the requested slippage. The server reference itself may differ from a simultaneously observed best bid or ask, so it should not be treated as an interchangeable top-of-book price.
Request fields by interface
Send either basis-point slippage or tick slippage, not both.
Send the REST body to POST /v1/orders. REST accepts decimal strings for quantity and the optional
client reference:
{
"order": {
"symbol": "BTC-USDT",
"side": "BUY",
"baseQty": "0.25",
"clientOrderId": "market-buy-001",
"marketIoc": {
"maxSlippageBps": 600,
"clientRefPrice": "100.000000"
}
}
}Send the ProtoJSON body to POST /orders.v1.OrdersService/CreateOrder. ConnectRPC uses scaled
integer values. This example assumes an 8-decimal base-quantity scale:
{
"order": {
"symbol": "BTC-USDT",
"side": "BUY",
"baseQtyScaled": "25000000",
"clientOrderId": "market-buy-001",
"marketIoc": {
"maxSlippageBps": 600,
"clientRefPriceTicks": "100000000"
}
}
}order {
symbol: "BTC-USDT"
side: BUY
base_qty_scaled: 25000000
client_order_id: "market-buy-001"
market_ioc {
max_slippage_bps: 600
client_ref_price_ticks: 100000000
}
}For tick-based protection, replace maxSlippageBps with maxSlippageTicks, or max_slippage_bps with max_slippage_ticks in protobuf source fields. Price ticks use a fixed
1e-6 quote-unit scale. baseQtyScaled uses the Pair's base-quantity scale from GetSpotConfig. See Scaled Integers.
For a BUY market IOC, clients can send maxQuoteDebit in REST or max_quote_debit_scaled in protobuf instead of a base quantity. This value is a hard, all-in quote
debit limit. Polyester resolves and returns the gross base quantity before execution. A quote fee
counts toward the limit, while a base fee reduces the base amount received. See Order Sizing.
OrdersService.PreviewOrder accepts the same nested OrderIntent as create and returns the
resolved quantity and price boundary without creating an order or reservation. It also checks
current available balance and returns a typed admission result. Preview does not inspect future
order-book depth or guarantee execution. See Preview Order.
Official SDKs expose the same controls through language-specific order inputs. See the applicable SDK Orders reference for its field names and types.
Error behavior
| Condition | Stable code | ConnectRPC code | Meaning |
|---|---|---|---|
maxSlippageBps is outside 1 to 10,000, or maxSlippageTicks is not positive | MAX_SLIPPAGE_INVALID | InvalidArgument | The requested tolerance is invalid |
| REST supplies both slippage alternatives | VALIDATION_ERROR | InvalidArgument | Send either basis points or ticks; protobuf clients cannot encode both because the fields are a oneof |
| Client reference drift exceeds Pair policy | STALE_QUOTE | FailedPrecondition | The supplied reference is stale relative to current server market data |
| No client reference or usable server reference is available | MARKET_PRICE_UNAVAILABLE | FailedPrecondition | Polyester cannot establish a price from which to calculate the boundary |
STALE_QUOTE is returned to the caller with the message:
Client reference price is stale relative to server market data.The rejection can also appear as the order's terminal reason in order-state and realtime updates.
Integration guidance
- Fetch and refresh Pair policy rather than treating current defaults as permanent constants.
- Send the same client reference used to show the user an execution preview.
- Choose an application-level maximum below 100% when the integration requires a stricter risk policy.
- Treat
STALE_QUOTEas a signal to refresh market data and obtain a new trading decision. Do not blindly retry the unchanged order. - Do not retry
MAX_SLIPPAGE_INVALIDor request-validation errors unchanged. Correct the request before sending it again.