Skip to content

Combos

A combo is one contract that pays only if several markets each resolve the way you name: the Broncos to win the Super Bowl and the Avalanche to win the Stanley Cup and the Rockies to win the World Series. It has no order book to post into. You ask for a price, market makers quote one, you accept a quote, and the trade binds as an ordinary trade on a real market.

The negotiation runs over two WebSocket channels: requesters use rfq:{user_id} and makers use combo_quote:{user_id}. This page covers the model; the combo negotiation channels page covers every command, field and refusal.

The combo negotiation flowThree lanes: the requester, STX, and market makers. The requester sends request_quote with legs and a stake and gets an rfq_id and market_id. Makers quote a price with an expiry and get a quote_id. STX pushes the best live quote to the requester. The requester accepts; STX checks funding on both sides, the maker's sell rests and the requester's buy takes it in full. STX pushes bound to the requester and the winning maker, and negotiation_closed to every other maker who quoted.RequesterSTXMakers1request_quote (legs, stake)rfq_id + market_id2quote (price, expires_in_ms)quote_id3push best_quote4accept (quote_id)Funds checked on both sidesmaker's sell rests,requester's buy takes it all5push boundpush bound (winning maker)push negotiation_closed (other makers)After the bind: an ordinary market. Orders, fills, positions and settlement come through the usual REST endpoints and channels.

Each step is covered in Request, quote, accept, bind below.

A combo is a set of legs. Each leg is an existing market plus the outcome the combo requires of it:

Leg Outcome required
Broncos, Super Bowl won
Avalanche, Stanley Cup won
Rockies, World Series won
  • 2 to 12 legs, each a different market.
  • won or lost per leg. lost is a real requirement, not a prediction: a combo can pay only if the Rockies miss the World Series.
  • Every leg must be open. A leg that is scheduled, not yet trading, closed, cancelled, resulted or voided cannot be part of a new combo, and a leg that stops being open cancels any request on it.
  • Combos do not nest. A leg cannot itself be a combo.

The same legs with the same outcomes are always the same combo, with the same market id, whatever order you send the legs in. A different outcome on any leg is a different combo: won/won/won and won/won/lost over the same three markets never share a market id.

A combo’s market has a max_price of $1 and a tick of 0.0001, so prices run from 0.0001 to 0.9999. The tick is finer than on an ordinary market because a combo’s fair price is the product of its legs and rarely lands on a cent. Three legs each priced at 110/210 (about 0.5238) multiply to about 0.143721; on this grid that quotes at 0.1437, while a cent grid could only offer 0.14.

Requester Maker
Opens the negotiation Yes, naming the legs and a total stake No
Prices it No Yes, a price per contract and how long it stands
Sees other quotes Only the best one Never
Sees the other side’s external_id No Yes, the requester’s, on every quote reply
Accepts or cancels Yes No; a maker can withdraw their own quote
Side of the trade Buys the combo Sells the combo

The requester names money, not a size. The maker names a price, not a size. The size falls out of the two (see Whole contracts and shortfall).

Any account can request or quote; there is no separate maker registration. An account can join both channels, but cannot quote on its own request.

Requesting, quoting, withdrawing a quote, accepting, cancelling and cashing out all need a read_write API key. A read_only key cannot join either channel.

  1. Request. The requester sends the legs and a total stake. The reply is a negotiation id (rfq_id) and the combo’s market_id. The request stays open for 5 minutes; the requester does not choose this.
  2. Quote. Makers send prices against the rfq_id, each with its own expiry in milliseconds. A quote holds no funds. A maker can hold one live quote per request, across many requests; to reprice, withdraw and quote again.
  3. Best quote. The requester is pushed the best live quote as it changes, at most every 250 ms. That is the only price they see.
  4. Accept. The requester accepts the price they were shown. This commits the whole stake.
  5. Bind. Both parties’ funds are checked, the combo becomes a real market if it is not one already, and two orders trade on it: the maker’s sell rests and the requester’s buy takes it in full or not at all. Both parties are pushed bound. Makers whose quotes did not win are pushed negotiation_closed.

Until the bind, the market_id is an identity, not a market. It answers no market lookup, has no order book, and is only held while a negotiation is open on it.

The requester can cancel at any point before accepting, which ends the negotiation and drops every quote on it.

An accept carries the price the requester was shown, and fills at exactly that price or not at all. If the best quote has moved since, higher or lower, nothing trades and the accept is refused with price_moved, carrying the new best. The requester sees it and accepts again. A better price is refused too, so every fill is at a price the requester saw.

An accept names a price, not a counterparty. Any maker quoting that same price can fill it. If the first maker cannot fund their side at the bind, the next maker at the same price is tried. If none can, the accept is refused with no_fundable_quote, the request stays open, and the next best price arrives as a new best quote to accept or not.

The best-quote push is paced, at most one every 250 ms, so the price on screen can briefly trail the book. Expect an occasional price_moved in normal use and handle it by showing the new price.

Contracts do not divide, so the stake is the inexact side. The fill is the largest whole number of contracts the stake covers at the filled price, and what is left over is reported as shortfall, not spent.

Value
Stake 250.00
Filled price 0.1200
Contracts floor(250 / 0.12) = 2083
Charged 2083 × 0.12 = 249.9600
Shortfall 250.00 − 249.96 = 0.0400

A stake is money you spend, so it is accepted to the cent and no finer. The charge lands on the price tick, which is finer than a cent, so a whole-cent stake does not always give a whole-cent charge: a 125.22 stake at 0.0501 buys 2499 contracts for 125.1999 and reports 0.0201 as shortfall.

The maker’s risk is not the requester’s premium. A maker selling quantity contracts at price on a combo with max_price of $1 owes, if the combo settles at its ceiling:

(max_price − price) × quantity

In the example above the requester pays 249.9600 and the maker is exposed to (1 − 0.12) × 2083 = 1833.0400. That is the amount the maker’s available balance is checked against, both when the quote is placed and again at the bind, and it is what the maker’s account carries once the trade binds. A maker whose balance drops below what a quote needs loses that quote without notice.

A holder can sell a combo position back through the same negotiation in the other direction. The holder sends cash_out naming only the combo’s market; makers quote to buy it; the holder accepts one.

What changes when you are leaving rather than entering:

Entering Cashing out
Requester’s side Buy Sell
Maker’s side Sell Buy
Requester names A stake Nothing: the whole position is sold
Best quote is the Lowest price Highest price
Accepted price is Exact Exact
charged in the reply What the requester pays What the seller receives
shortfall The stake’s remainder Always 0.0000
Maker’s exposure (max_price − price) × quantity price × quantity

There is no partial exit, and an account can have one exit open per combo at a time. Every leg must still be open to cash out, so once the first leg results the position runs to settlement.

A combo settles at the product of its legs, scaled to its own max_price and floored to its tick:

price = max_price × ∏ (leg factor)

Each leg’s factor is a fraction of that leg’s own ceiling:

  • A leg the combo needs to win contributes result_price / leg max_price.
  • A leg the combo needs to lose contributes (leg max_price − result_price) / leg max_price.

So a leg that lands as required contributes 1, a leg that misses contributes 0, and a push settles at half its ceiling and contributes exactly 0.5.

Leg Required Result result_price max_price Factor
Broncos, Super Bowl won won 1.0000 1.0000 1
Avalanche, Stanley Cup won push 0.5000 1.0000 0.5
Rockies, World Series won won 1.0000 1.0000 1

The combo settles at 1 × 1 × 0.5 × 1 = 0.5000. For the trade above, the requester’s gross profit is (0.5000 − 0.1200) × 2083 = 791.5400 and the maker’s is −791.5400, before settlement fees.

The other outcomes of the same trade:

Legs Combo price Requester (gross) Maker (gross)
All three land as required 1.0000 +1833.0400 −1833.0400
Avalanche pushes, the others land 0.5000 +791.5400 −791.5400
Any leg misses 0.0000 −249.9600 +249.9600
Any leg is voided or cancelled void stake returned exposure released
  • A void on any leg voids the whole combo, whatever the other legs did, and it unwinds as soon as that leg is voided.
  • A combo settles once every leg has resolved. A leg that misses fixes the price at zero, but the combo still waits for its remaining legs before it settles.
  • A leg that has not resolved, or resolved without a settlement price, leaves the combo unsettled. A missing factor is never treated as 1.

A bound combo is a real market with real orders, and everything downstream works the way it does for any other market:

You want REST WebSocket
The two orders List orders Orders channel
The fill List fills Fills channel
Your position List open positions Positions channel
The settlement List settlements Settlements channel
Your balance and exposure Get account balance Balances channel

Two differences from a listed market:

  • A combo does not appear in market listings or on the market catalogue channels. Track it by the market_id the negotiation gave you.
  • Enter and leave a combo through negotiation. request_quote opens a position and cash_out closes one. Orders sent to a combo’s market through the order endpoints are refused.

Fees follow the fee schedule as for any trade.

The channel reference lists what the negotiation does not yet do, including how a maker learns of a request and how to confirm a position after a bind.

v1.5.9Changelogllms.txtllms-full.txt