Crypto perpetuals - sbOogway/sbt2 GitHub Wiki
Crypto perpetuals
The first asset class. First data source: Source Bybit (linear perps, L2 and trades).
Definition
| Concern | Choice |
|---|---|
| Key | nautilus AssetClass.CRYPTOCURRENCY + InstrumentClass.SWAP |
| Instrument | CryptoPerpetual, from the exchange's real spec |
| Calendar | 24/7, no sessions |
| Annualization | 365 days |
| Account | margin account in the settlement currency (USDT for linear perps), netting (one-way mode), leverage |
| Liquidation | off by default; venue config liquidation_enabled, liquidation_trigger_ratio, liquidation_cancel_open_orders, or the spec's liquidation key. Only works on runs that stream quotes (below) |
| Carry | funding, settled natively by nautilus's simulated venue (below) |
| Reference prices | mark price |
| Valuation price | mark price, for mark-to-market equity: PortfolioConfig(use_mark_prices=True), fed by MarkPriceUpdate from the catalog |
| Buy-and-hold convention | the perp's own mark-price series held with no funding, paying only the entry fee at the taker_rate of the run's venue fee model (v2 instruments carry no fees); a fee model without a taker rate fails. Behaves like spot without needing spot data. |
Funding
Nautilus v2's simulated venue settles funding itself; sbt2 has no funding code. (Nautilus 1.231 delivered funding rates to strategies but never charged the account, which is why an earlier design had a custom module.)
- At each funding boundary the venue charges or credits
position notional at mark price × funding rateto every open position. A positive rate debits longs and credits shorts. With no mark price it falls back to top of book. - Each payment is a
PositionAdjustedevent of typeFunding: it changes the position's realized PnL and the account balance together, so funding is in equity, PnL and every metric. - The carry ledger is read from those adjustments after the run (see Results).
- The boundary is
next_funding_nswhen the update has one, otherwise the update's ownts_event, and only when thatts_eventis an exact multiple ofintervalsince the Unix epoch (for 8h: 00:00, 08:00 and 16:00 UTC). A record off that grid, even by 1 ns, is silently never charged. Bybit's funding history gives settlement times with the interval (usually 8h, 4h for some instruments such as XAUT), so each record settles at its own time. The source's parser fills in a missingintervalfrom the instrument spec (for Bybit, the snapshot'sfundingInterval); a record without one would never settle. - A 1 BTC long at a 50,000 mark and a +0.01% rate is debited exactly 5.00 USDT at the boundary. A position opened at the funding timestamp pays it. These rules are pinned by the nautilus characterization tests (see Quality).
Funding rates and mark prices are downloaded by the source and ingested into the catalog as FundingRateUpdate / MarkPriceUpdate, and stream with the run.
Liquidation
Nautilus's simulated venue checks maintenance margin on every data event, but it prices open positions only at the top-of-book quote (bid for longs, ask for shorts), not at mark price. A run that streams trades and mark prices but no quotes, which is every bar strategy, on trades or on candles, can therefore never liquidate. Instead nautilus logs a warning for every trade while a position is open. Pinned by the characterization test test_liquidation.py (see Quality).
- The crypto-perp default is liquidation off. A run can turn it on with
liquidation = truein its spec (see Spec), and pre-flight refuses that unless the run streams quotes (see Run). - With liquidation off, a position whose equity falls below maintenance margin stays open, and equity can go negative. Treat a run that gets near zero equity as blown.
- The check is costly as well as noisy: on a month of BTCUSDT (76M trades) the run took 2 min 27 s with liquidation on and 54 s with it off.
Decisions
| Decision | Why |
|---|---|
| Funding settled by nautilus's venue, no custom module | v2 does it at mark price and records it on the position; the earlier SimulationModule plan existed only because 1.231 didn't. |
| Funding uses mark price | That's what perp exchanges charge on. |
| 365-day annualization | Crypto trades every day. v1 used 252. |
| Benchmark = perp price, no funding, entry fee only | A perp benchmark that pays funding blurs the comparison; spot data isn't downloaded, and the perp price tracks spot closely. |
| Mark-to-market at mark price | The exchange values positions at mark price for margin and liquidation too. |
| Liquidation off by default; on only for runs that stream quotes | Nautilus liquidates only on quotes, so with trades alone it was silently never applied, while logging a warning per trade and slowing the run 2.7×. |
Open items
- Delisted symbols aren't served by the first source, so cross-sectional runs carry a survivorship warning.
- How does nautilus's liquidation compare with the exchange's rules?