Position Fees
Overview
Position fees are periodic charges applied to all open positions on an instrument, proportional to the absolute size of each position. Unlike funding charges, position fees are not a transfer between long and short holders. Instead, the collected fees are deposited into a designated beneficiary account (such as the insurance fund).
Position fees may also be configured as rebates (a negative fee), in which case the beneficiary account pays out to position holders rather than collecting from them.
The administrator triggers each position fee round via the control gateway API, supplying a rate and reference price for each instrument. The engine then charges (or credits) every open position on those instruments.
Calculation
The rate and reference price mechanism is identical to funding. The engine accumulates a cumulative total rate from inception to prevent rounding errors from building up over successive rounds.
Simple Rate
The fee for a position in a given round is:
\text{Fee} = |\text{Position}| \times P_k \times R_kwhere P_k is the reference price and R_k is the rate for round k.
To prevent rounding errors, the engine tracks the total position fee rate since inception:
F(n) = \sum_{k=1}^n R_k P_kAt round n+1, the charge applied to a position C is:
F_T = F(n+1) \times |C| - F(n) \times |C|
Example
Two accounts hold positions on a linear BTC future with an inverse step size of 1,000,000 (each contract represents 0.000001 BTC). The administrator applies a position fee with R = 0.01\% and P = 50{,}000.
Instrument: Linear BTC future, inverse step size 1,000,000
Long account: +2,000,000 contracts = 2 BTC notional
Short account: −800,000 contracts = 0.8 BTC notional
Fee for long account = (2,000,000 / 1,000,000) × 50,000 × 0.0001 = 2 × 5 = 10.00
Fee for short account = (800,000 / 1,000,000) × 50,000 × 0.0001 = 0.8 × 5 = 4.00
Total deposited to beneficiary account = 14.00
Both positions are charged based on the absolute size.
Cost per Contract
As with funding, an alternative mode allows the administrator to specify a fixed cost per number of contracts rather than a rate applied to a reference price. The engine uses the same cumulative approach to avoid rounding error accumulation.
Fee Payment
Position fees are collected from the following sources, in order.
Account Balance
The fee is deducted first from the account's available balance.
Unrealized PnL
If an account does not have sufficient balance to cover the position fee, but holds unrealized profits on the charged instrument, the engine will draw on those unrealized gains to cover the shortfall. This is achieved by adjusting the position entry price to a slightly less favorable value, reducing the unrealized PnL by the required amount. Two executions of equal and opposite size, marked as PaymentByUnrealizedPnl, record this adjustment.
Example
Instrument: Linear BTC future, inverse step size 1,000,000
Position: Long 2,000,000 contracts (= 2 BTC notional)
Entry price: 49,800
Mark price: 50,000
Balance: 6.00
Fee owed: 10.00
Unrealized PnL = (50,000 − 49,800) × 2 = 400.00
Paid from balance: 6.00
Remaining from unrealized PnL: 4.00
New Unrealized PnL = 400.00 − 4.00 = 396.00
New Entry Price = 50,000 − (396.00 / 2) = 49,802.00
Unrealized PnL on Other Instruments
Adjusting the entry price of the charged instrument to collect unrealized PnL may not always be possible: the required adjustment could push the entry price above the instrument's maximum price or below its minimum price. In that case, the engine caps the entry price at the relevant bound and, if the account holds positions on other instruments, applies the remaining shortfall using the same PaymentByUnrealizedPnl mechanism on one of those other positions.
Liquidation
If the position fee exceeds what can be covered by the account's balance and unrealized PnL, the account is liquidated. The insurance fund covers any remaining shortfall via a balance reset, and the normal liquidation workflow follows.
Rebates
When the fee rate is negative, the beneficiary account pays a rebate to each position holder in proportion to the absolute size of their position.
Beneficiary Account Margin Check
Before applying a rebate round, the engine performs an initial margin check on the beneficiary account. If the beneficiary account does not have sufficient margin to cover all rebates to be paid, the entire position fee round is rejected. No rebates are applied to any position.
Error Cases
State and History
The timestamp of the most recent position fee event is tracked per instrument and is included in the instrument's state-of-the-world output. This allows clients to determine when position fees were last applied for any futures instrument.
Each position fee round also generates a transaction record for every position that was charged, and a response message summarizing the fees collected across all positions.