How to Handle Margin Modeling for Futures and Options in Nautilus Trader
Nautilus Trader handles margin modeling for futures and options through interchangeable margin models—StandardMarginModel for fixed-percentage broker-style margin or LeveragedMarginModel for crypto-style leverage-adjusted margin—that calculate initial and maintenance requirements based on instrument definitions.
Nautilus Trader separates margin calculation from the core trading engine through a dedicated margin modeling system. This architecture allows you to handle margin modeling for futures and options using either built-in or custom implementations that respect venue-specific risk rules. The system supports both traditional brokerage margin calculations and crypto-exchange style leveraged accounts through configurable models in nautilus_trader/accounting/margin_models.pyx.
Understanding Margin Models in Nautilus Trader
Margin models in Nautilus Trader are pluggable components that determine how much collateral is required to open and maintain positions. The base class MarginModel defines the interface, while concrete implementations handle specific calculation methodologies. When calculating requirements, the model receives the instrument definition, quantity, price, and account leverage, then returns a Money object representing the required margin in the appropriate currency.
Built-in Margin Models
Nautilus Trader provides two primary margin models that cover most traditional and crypto trading scenarios.
StandardMarginModel (Fixed Percentage)
The StandardMarginModel calculates margin as a fixed percentage of the notional value, ignoring account leverage entirely. This behavior matches traditional brokerages like Interactive Brokers, where margin requirements are determined solely by the instrument's risk settings.
According to the source code in nautilus_trader/accounting/margin_models.pyx, the calculation follows:
# StandardMarginModel implementation
# https://github.com/nautechsystems/nautilus_trader/blob/develop/nautilus_trader/accounting/margin_models.pyx#L101-L112
LeveragedMarginModel (Leverage-Adjusted)
The LeveragedMarginModel divides the notional value by the account leverage before applying the margin percentage. This approach decreases margin requirements as leverage increases, matching the behavior of crypto exchanges like Binance or Bybit. This is the default model used by Nautilus Trader for crypto-style accounts.
The implementation in nautilus_trader/accounting/margin_models.pyx shows:
# LeveragedMarginModel implementation
# https://github.com/nautechsystems/nautilus_trader/blob/develop/nautilus_trader/accounting/margin_models.pyx#L171-L182
Configuring Margin for Futures and Options
Proper margin handling requires configuring both the instrument definitions and the account settings.
Instrument Definitions
Each Instrument in Nautilus Trader—whether FuturesContract or OptionContract—exposes specific margin parameters:
margin_init: The fixed percentage of notional required for initial marginmargin_maint: The percentage required for maintenance marginis_inverse: Boolean flag for inverse futures where margin is quoted in the base currency
These definitions reside in nautilus_trader/model/instruments/futures_contract.py and nautilus_trader/model/instruments/option_contract.py.
Account Configuration
The MarginAccount class in nautilus_trader/accounting/accounts/margin.pyx stores per-instrument leverage settings and forwards calculation requests to the active margin model. You can set leverage for specific instruments using:
account.set_leverage(instrument.id, Decimal(20))
Practical Code Examples
Standard Model with Inverse Futures
This example demonstrates using StandardMarginModel with an inverse futures contract where margin is calculated in the base currency (BTC):
from decimal import Decimal
from nautilus_trader.test_kit.providers import TestInstrumentProvider
from nautilus_trader.backtest.models import StandardMarginModel
from nautilus_trader.accounting.accounts.margin import MarginAccount
from nautilus_trader.model.objects import Quantity, Price
# Create an inverse futures instrument (e.g., BTC/USD perpetual)
future = TestInstrumentProvider.default_inverse_future("BTC/USD")
# Create margin account with Standard model
account = MarginAccount(state=None)
account.set_margin_model(StandardMarginModel())
# Set leverage (ignored by Standard model)
account.set_leverage(future.id, Decimal(50))
# Calculate initial margin
margin = account.calculate_margin_init(
instrument=future,
quantity=Quantity.from_int(10),
price=Price.from_str("30000"),
)
print(margin) # Money(900, BTC) - calculated as notional * margin_init percentage
Leveraged Model with Options
This example shows LeveragedMarginModel applied to an option contract:
from decimal import Decimal
from nautilus_trader.test_kit.providers import TestInstrumentProvider
from nautilus_trader.backtest.models import LeveragedMarginModel
from nautilus_trader.accounting.accounts.margin import MarginAccount
from nautilus_trader.model.objects import Quantity, Price
# Create a call option (e.g., AAPL 150 CALL)
option = TestInstrumentProvider.aapl_option()
# Margin account with Leveraged model
account = MarginAccount(state=None)
account.set_margin_model(LeveragedMarginModel())
# Set 10x leverage (reduces margin requirement)
account.set_leverage(option.id, Decimal(10))
# Calculate initial margin
margin = account.calculate_margin_init(
instrument=option,
quantity=Quantity.from_int(100),
price=Price.from_str("2.50"),
)
print(margin) # ((notional / 10) * option.margin_init)
Configuration-Based Model Selection
For backtests or live trading, select the margin model via configuration:
from nautilus_trader.backtest.config import MarginModelConfig, MarginModelFactory
# Configure standard model
cfg = MarginModelConfig(model_type="standard")
model = MarginModelFactory.create(cfg) # Returns StandardMarginModel instance
Or via YAML configuration:
margin_model:
model_type: "leveraged" # Options: "standard", "leveraged", or "<module>:<Class>"
config: {}
Summary
- Nautilus Trader separates margin calculation from the trading engine through pluggable margin models defined in
nautilus_trader/accounting/margin_models.pyx - StandardMarginModel calculates margin as a fixed percentage of notional value, ignoring leverage, matching traditional broker behavior
- LeveragedMarginModel divides notional by account leverage before applying the percentage, matching crypto-exchange behavior
- Instrument definitions in
futures_contract.pyandoption_contract.pyspecifymargin_init,margin_maint, andis_inverseflags - MarginAccount stores per-instrument leverage and delegates calculations to the active model via
calculate_margin_init() - Configure models via
MarginModelConfigandMarginModelFactoryfor backtests or live trading
Frequently Asked Questions
What is the difference between StandardMarginModel and LeveragedMarginModel?
StandardMarginModel calculates margin requirements as a fixed percentage of the notional contract value, completely ignoring any account leverage settings. This matches traditional brokerage behavior where margin is determined solely by regulatory and exchange requirements. LeveragedMarginModel divides the notional value by the account leverage before applying the margin percentage, meaning higher leverage results in lower margin requirements, which matches crypto-exchange behavior.
How do I configure margin for inverse futures in Nautilus Trader?
Inverse futures require special handling because margin is typically quoted in the base currency (e.g., BTC) rather than the quote currency (e.g., USD). Set the is_inverse=True flag on the FuturesContract definition, and ensure use_quote_for_inverse=False in your account settings. The margin model will then return Money objects denominated in the base currency when calculating requirements for these instruments.
Can I use custom margin models for proprietary risk calculations?
Yes, Nautilus Trader supports custom margin models through its pluggable architecture. You can implement the MarginModel abstract base class defined in nautilus_trader/accounting/margin_models.pyx and provide your own calculate_margin_init() and calculate_margin_maint() implementations. Reference your custom class in the configuration using the "<module>:<Class>" syntax in the model_type field of MarginModelConfig.
Where does Nautilus Trader store per-instrument leverage settings?
Per-instrument leverage is stored within the MarginAccount class in nautilus_trader/accounting/accounts/margin.pyx. The account maintains a mapping of instrument IDs to leverage values, which you can modify using the set_leverage(instrument_id, leverage) method. When using LeveragedMarginModel, these values directly affect margin calculations; when using StandardMarginModel, they are ignored but still stored for potential use by custom models or future calculations.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →