Trader account restrictions
A trader account with any active spline registration cannot place FIFO limit orders or stop-loss orders on any market. Use a separate trader account, such as a dedicated isolated subaccount, for spline activity if you also need regular order-book activity. Other trader accounts owned by the same wallet authority are unaffected. See Accounts for account boundaries.Spline data model
A spline trader controls:
Phoenix separately tracks sequence ordering, expiry, consumed visible and hidden liquidity, and risk-limited bid and ask capacity.
Each region is defined by:
start_offset, inclusiveend_offset, exclusivedensity, in base lots per ticktop_level_hidden_take_size, in base lotslifespan, in slots
start_offset and cannot overlap; adjacent regions and gaps are allowed. A spline can quote only one side, but it must have at least one region in total. If both sides are configured, their first regions cannot both start at offset zero.
Region offsets are tick distances from the spline mid:
- bid offset maps to
- ask offset maps to
- region size is base lots
100, bid region [1, 3), and density 5 exposes:
5lots at995lots at98
[1, 3) on the same spline exposes:
5lots at1015lots at102
Region lifespan
lifespan is measured in slots from the spline’s user_update_slot. A region remains eligible through user_update_slot + lifespan, inclusive.
Every accepted price update resets the lifespan of every configured region by setting the spline’s expiry anchor to that update’s user_update_slot. Each region then receives its full configured lifespan from the new anchor. This happens whether refresh_regions is true or false; that flag controls consumed liquidity, not expiry.
Use GTC_LIFESPAN (u64::MAX) for a region that does not expire. A lifespan of 0 is eligible only at user_update_slot; it does not mean good-til-cancelled.
How spline levels become visible
A spline level is eligible for the book when:- the spline is active
- the spline has a nonzero mid price
- the region has not expired
- the region still has unfilled size
- the spline trader has remaining risk capacity on that side
Updating a spline
Both price and parameter updates accept arefresh_regions flag, but preserving state has different effects for the two update types:
Previously consumed liquidity is replenished only when
refresh_regions=true.
Risk caps
Before matching, Phoenix caps each spline’s available bid and ask size using the spline trader’s current risk state. The cap accounts for:- current margin and position state
leverage_decrease_in_bps- optional max position size limits
- the current risk action
max_position_size has two modes:
Limit { long: 0, short: 0 } is reduce-only: the spline can quote only on the side that moves an existing position toward zero.
When a limit is active, Phoenix clips each side to its remaining capacity:
- bid capacity is capped by the distance from the current position to the maximum long position
- ask capacity is capped by the distance from the current position to the maximum short position
leverage_decrease_in_bps reduces the effective collateral used to calculate spline risk capacity:
The value must be between 0 and 10,000. A value of 0 applies no haircut, 5,000 uses 50% of effective collateral, and 10,000 removes margin-backed capacity for increasing exposure. This setting does not change deposited collateral or the market’s leverage tiers.
Fees
The spline trader pays zero exchange fees on spline fills:- when an incoming order matches a spline, the incoming trader pays its configured taker fee and the spline trader pays zero
- during uncrossing, the resting FIFO trader pays its configured maker fee, or receives its configured maker rebate, while the spline trader pays zero
Uncrossing and slide prices
Spline liquidity from different traders can cross when their mids and regions overlap. Phoenix resolves this before rendering or matching spline-only liquidity. The uncross path:- Matches crossed splines against FIFO liquidity first when the spline crosses the explicit book.
- Computes slide prices for remaining crossed spline-only liquidity.
- Displays and matches more aggressive spline bids at the slide bid.
- Displays and matches more aggressive spline asks at the slide ask.
Pro-rata fills
At a single spline price level, FIFO price-time priority does not apply across spline traders. Phoenix allocates the fill pro-rata by available size: Spline sequence number is still used for deterministic iteration and dust handling. It is not the primary priority rule. When integer rounding leaves unallocated lots, sequence order determines which spline receives the remainder. Important execution consequences:- one spline price level consumes one
match_limitunit, even if multiple splines participate - one FIFO maker order consumes one
match_limitunit - spline liquidity at the same price fills before FIFO liquidity
- worse spline prices do not skip better FIFO prices
Hidden take size
top_level_hidden_take_size is configured per region in base lots. It is separate from the region’s displayed density and total size, and it is not available to incoming takers.
It is available only when the spline itself takes FIFO liquidity during uncrossing. In that path, Phoenix can consume visible size at the region’s current top tick, then up to the remaining hidden take size at that same tick, then visible size through deeper ticks. Phoenix tracks consumed hidden size separately from visible fills, and refresh_regions applies to both.