In Part 2, we built the "heartbeat" of our engine: PnL Calculation. We ensured that every price tick accurately updates a trader’s equity with decimal precision. But a market cannot survive on price action alone. Without an anchor, the price of a perpetual contract would drift aimlessly away from the actual value of the underlying asset.
That anchor is Funding Rates. It is the regulatory mechanism that ensures the perpetual market remains fair, balanced, and tethered to reality. Here is how I implemented this "incentive engine" in Rust.
1. What are Funding Rates? (The Market’s Anchor)
In perpetual futures, there is no expiration date. To prevent the contract price from deviating too far from the Spot Price, the system uses a peer-to-peer payment exchange.
- When Longs dominate (Bullish): Perpetual Price > Spot Price. Longs pay Shorts.
- When Shorts dominate (Bearish): Perpetual Price < Spot Price. Shorts pay Longs.
This is a zero-sum game. The exchange doesn't keep the money; it simply moves it between traders to incentivize the side that helps bring the price back to equilibrium.
2. The Math: Notional Value & Payments
The funding payment isn't based on your margin; it’s based on your Notional Value (your total market exposure).
The Formulas:
Notional Value = Quantity \times Mark Price
Funding Payment = Notional Value \times Funding Rate
The Reality Check: If you are 10x leveraged, a 0.01% hourly funding rate actually costs you 0.1% of your margin every hour. Over a day, that’s 2.4% of your collateral just to keep the position open.
3. The Implementation: A Periodic Loop
In my Rust engine, funding is a discrete event. While PnL updates with every price tick, funding applies on a scheduled "heartbeat" (typically every hour).
Rust Implementation
pub fn apply_funding(&mut self) -> Result<FundingResult, String> {
let rate = self.funding_rate; // e.g., 0.0001 for 0.01%
let mut total_applied = Decimal::ZERO;
for position in self.positions.values_mut() {
let notional_value = position.quantity * self.mark_price;
let funding_amount = notional_value * rate;
// Longs pay when rate is positive, Shorts receive
if position.position_type == PositionType::Long {
position.pnl -= funding_amount;
total_applied += funding_amount;
} else {
position.pnl += funding_amount;
total_applied -= funding_amount;
}
}
self.last_funding_time = std::time::Instant::now();
Ok(FundingResult { total_applied, rate })
}
4. The "Silent Killer": Funding-Triggered Liquidation
This is the most critical integration point between Part 1 (Liquidations) and Part 3. A position can be liquidated even if the price doesn't move.
If a trader is at max leverage and has very little "maintenance margin" left, a single funding payment can push their PnL into the red, triggering an immediate liquidation.
The Logic Flow:
- Trigger: Timer hits 3600 seconds.
- Apply: Subtract/Add funding from all open positions' PnL.
- Audit: Immediately run the
should_liquidatecheck. - Execute: Close positions that no longer meet margin requirements.
5. Multi-User Scalability with Tokio
In a production-ready engine, you can't block the order book to calculate funding. I used tokio::time::interval to run the funding logic in a background task, ensuring the engine remains responsive.
tokio::spawn(async move {
let mut interval = tokio::time::interval(Duration::from_secs(3600));
loop {
interval.tick().await;
// Acquire write lock and apply funding to all users
engine.apply_funding().await?;
}
});
6. Summary Table
| Concept | What | Why |
|---|---|---|
| Funding Rate | % paid between traders | Keeps Perp price near Spot price. |
| Notional Value | Qty \times Price | Ensures fees scale with total market exposure. |
| Zero-Sum | Longs pay Shorts (or vice versa) | The exchange remains a neutral facilitator. |
| Liquidation Risk | Margin erosion via fees | High leverage can be killed by funding alone. |
Conclusion
Funding rates turn a simple "betting" engine into a sophisticated financial instrument. By implementing this in Rust, we leverage thread safety to ensure that while thousands of trades are happening, the "funding heartbeat" accurately adjusts every balance without a single cent going missing.
Top comments (0)