Funding and the mark price
Funding here is a rate you set per market, not one the engine derives from an index — what it charges, when it settles, what the 0.75% cap does to the number you typed, and where the mark price that values every position comes from.
Perpetual futures on other venues stay tethered to a spot index by a funding rate: longs pay shorts, or the reverse, every few hours, and that recurring cost is what stops the contract drifting away from the underlying. Those venues calculate the rate, from the premium between their mark and an outside index.
This platform has no index. Your book is the only place the contract trades, so there is no premium to derive a rate from — and so the rate here is one you set, per market, and the platform settles it on a fixed schedule. That is an honest design and a common one for a venue whose book is its own price. What it is not is a premium-driven rate, and nothing in your terms should describe it as one.
The rate you type is multiplied by the value of every open position on that
market, every interval, and the result is debited from and credited to real
wallets by the settleFuturesFunding job. It is a percentage per interval, not
per year. On a market carrying 50x positions a misplaced decimal is an
account-emptying event that looks exactly like a working settlement, which is why
the platform clamps the rate at ±0.75% per interval before it charges
anything.
Funding is off on every market until you set a rate. That is the default, and it is what every market created before the feature shipped has. A market with no rate — or a rate of exactly zero — writes no rows and moves no money.
Setting a rate
Admin panel → Futures → Markets → (market) → Fees, the third step of the market wizard, in the Perpetual Funding card.
- Funding Rate (%) — a percentage of position value per interval. Positive
means longs pay shorts; negative is the reverse. You type a percentage and the
form stores a fraction, so
0.01in the field becomes0.0001in the market'smetadata.fundingRate. - Funding Interval (hours) — 1 to 24, defaulting to 8. A value outside that range is ignored and 8 is used.
Leave the rate field empty to switch funding off for that market. Empty and zero mean the same thing to the settlement: no rows, no wallet movement, and a zero rate published to any bot that asks.
Disabling a market also stops its funding. The settlement only looks at markets whose status is enabled, so a market you have switched off funds nothing while it is off.
The number you type is not always the number charged
The form marks the ±0.75% bounds on the input, but what is stored is what was submitted; the clamp lives in the settlement. A market saved with 2% keeps 2% in its metadata and charges 0.75%.
That gap matters because your surfaces do not all read the same number:
- The Hummingbot funding-rate endpoint (
/api/hb/perpetual/funding-rate/…) publishes the clamped rate — the one that will actually be charged — with the market's own interval and the next settlement time. - The trading ticket and the
fundingRatestream channel publish the raw metadata value. The stream channel also reports its next settlement time on a fixed 8-hour schedule, so a market on any other interval is quoted the wrong one there.
Set a rate above the cap and your own ticket will quote a charge the engine refuses to apply, while the endpoint professional counterparties read quotes a different one. Keep the stored rate inside ±0.75% so every surface agrees, and always state it per interval wherever you publish it.
How a window settles
- Boundaries are anchored to the Unix epoch, in UTC — not to when you set the rate and not to when the server last started. An 8-hour market settles at 00:00, 08:00 and 16:00 UTC. Changing the interval moves the boundaries.
- The job runs every minute and does nothing on almost all of them: a window can only be settled within 30 minutes of its boundary.
- At most three windows settle in one run. If an install was down for longer, the oldest outstanding windows are dropped and logged — but a trader is still charged up to three windows at once when the server comes back.
- A market that has never settled only settles the current window. Switching funding on does not bill anyone for the history of the market.
- The charge is the rate times the position's notional at the mark price, not at its entry price. A position opened at 30,000 and marked at 70,000 is funded on 70,000.
- Collect, then distribute. Payers are debited first, and receivers share only
what was actually collected. A payer whose wallet cannot cover the charge gets a
row marked
UNPAID, and the receivers' share shrinks pro rata. Nothing is minted to cover a payer who came up short — which on a leveraged product is not exotic, it is the normal end state of a losing position. - If nothing can price the market at that moment, the window is deferred, not skipped: charging every position zero and recording the window as done would lose the charge permanently.
- One row is written per position per window, and the
(position, funding time)pair is unique, so a second run over the same window cannot charge twice.
Where the mark price comes from
Everything that values a position — unrealised PnL, stop loss, take profit, liquidation, funding, and the price a manual close settles at — uses one number, and it is not the last print. The mark is the median of three readings of your own market:
- the last traded price from the matching engine's ticker,
- the weighted close of the current 1-minute candle,
(high + low + 2 × close) / 4, - the midpoint of the resting book, counted only when the book has both sides, and taken from order-backed depth rather than the displayed book.
With a two-sided book, the median of the three is the mark. Without one, the last traded price is. With nothing at all to read the mark is zero, and no caller treats that as a price — a zero would read as a 100% adverse move and liquidate everybody. The mark sweep skips the symbol, funding defers the window, a manual close settles at the entry price for zero PnL, and the settlement that runs inside a matching cycle falls back to the price the trade printed at.
There is no external index and no basket of reference exchanges. An ecosystem token pair has no outside price to average in, so three readings of the same book that a single order cannot move together is the strongest honest substitute.
Two operational consequences follow.
A thin market still marks itself. The median only protects you while a two-sided book is standing there to outvote a print. On a market with one side or no resting depth the mark is the last trade, so a single order at an absurd price becomes the mark for every position on that symbol until the next print — with a stop loss, a take profit and a liquidation threshold all reading it. Amount and price limits in the market's metadata are your defence; set them.
A market with no depth cannot liquidate cleanly. Liquidations are placed as real orders against your book. Where nothing is resting, a full liquidation falls back to mark settlement, and any shortfall is cleared against the futures insurance fund. If the fund cannot cover it, the deficit policy decides: the default deleverages the winners at the price the loser could actually fund, and the alternative hands you the bill. See Liquidation.
What traders and bots can see
- The trading ticket shows a Funding Rate row when the market has a rate on its metadata, and nothing when it does not.
- The markets panel has a funding cell, but the futures ticker feed carries no funding rate, so in practice that cell never renders.
- The trader's wallet is where the charge appears: a transaction typed
FUTURES_ORDERwhose description names the market and the rate, for example "Funding paid on BTC/USDT at 0.01%". GET /api/futures/fundingreturns the authenticated trader's own settlements, newest first, with a net total over the settled rows only. No screen calls it yet, and there is no admin funding screen — your own view of a run is the scheduled-task monitor, wheresettleFuturesFundinglogs how many windows settled and how many positions were charged, credited or unpaid. See Scheduled jobs.
The Funding Rate row in the trading ticket is still labelled "Reference only", with a tooltip reading "Funding rate is shown for reference only and is not charged." That label predates the settlement and is now wrong. Until it is corrected, your own interface contradicts your terms on any market you have funded — so say so in your terms, and expect the support ticket.
What to tell traders
Three lines is usually enough, and all three are verifiable from the product:
- Contracts are perpetual: no expiry, no settlement date, no roll.
- Funding is charged and paid at each window, at a rate published per market and capped at 0.75% per interval. It is set by the venue, not derived from an outside index, and a market with no rate set charges nothing.
- Positions are marked against this venue's own market — a median of its last trade, its current minute and its resting book — not an external index.
That third line is the one traders most need, because it changes how they should size a position on a thin market.