Instruments
An instrument represents the specification for a tradable asset, contract, or local
synthetic market. Market data, orders, positions, accounting, portfolio calculations,
and adapter symbology all refer back to an InstrumentId and its instrument definition.
NautilusTrader exposes the same instrument model to Rust and Python users. Rust examples use nautilus_model.
Python examples use nautilus_trader.model.
Instrument types
| Instrument type | InstrumentClass | Description | Typical adapters |
|---|---|---|---|
Equity | SPOT | Listed share or ETF traded on a cash market. | Databento, Interactive Brokers. |
CurrencyPair | SPOT | Fiat FX or crypto spot pair in base/quote form. | Binance, Kraken, OKX, Tardis. |
Commodity | SPOT | Spot commodity such as gold or oil. | Interactive Brokers. |
Cfd | CFD | Contract for difference tracking an underlying. | Interactive Brokers. |
IndexInstrument | SPOT | Reference index, not directly tradable. | Interactive Brokers. |
TokenizedAsset | SPOT | Tokenized asset on a crypto venue. | Kraken. |
FuturesContract | FUTURE | Dated futures contract. | Databento, Interactive Brokers. |
FuturesSpread | FUTURES_SPREAD | Exchange defined futures strategy with several legs. | Databento, Interactive Brokers. |
CryptoFuture | FUTURE | Dated crypto futures contract. | Bybit, Deribit, OKX. |
CryptoFuturesSpread | FUTURES_SPREAD | Exchange defined crypto futures spread. | Deribit, OKX. |
CryptoPerpetual | SWAP | Crypto perpetual futures contract. | Binance, Bybit, dYdX. |
PerpetualContract | SWAP | Perpetual futures contract across asset classes. | Architect AX, Binance. |
OptionContract | OPTION | Exchange traded put or call option. | Databento, Interactive Brokers. |
OptionSpread | OPTION_SPREAD | Exchange defined options strategy with several legs. | Databento, Interactive Brokers. |
CryptoOption | OPTION | Option on a crypto underlying. | Bybit, Deribit, OKX, Tardis. |
CryptoOptionSpread | OPTION_SPREAD | Exchange defined crypto option spread. | Deribit, OKX. |
BinaryOption | BINARY_OPTION | Binary instrument that settles to 0 or 1. | Hyperliquid, OKX, Polymarket. |
BettingInstrument | SPORTS_BETTING | Sports or gaming market selection. | Betfair. |
SyntheticInstrument | n/a | Formula derived local instrument. | Local only. |
Taxonomy
Market structure: NautilusTrader groups instruments by the market structure they represent.
Common fields
Most concrete instruments share the same core shape. Individual type pages list the complete constructor and struct fields for that type.
| Field | Meaning |
|---|---|
id | Nautilus InstrumentId, formed from a symbol and venue. |
raw_symbol | Native venue symbol before Nautilus normalization. |
price_precision | Configured number of decimal places for price values. |
size_precision | Configured number of decimal places for quantity values. |
price_increment | Smallest valid price step. |
size_increment | Smallest valid quantity step. |
multiplier | Contract multiplier used in notional and PnL calculations. |
lot_size | Rounded lot or board size when the venue publishes one. |
margin_init | Initial margin rate as a decimal fraction of notional value. |
margin_maint | Maintenance margin rate as a decimal fraction of notional value. |
max_quantity | Maximum order quantity when known. |
min_quantity | Minimum order quantity when known. |
max_notional | Maximum order notional value when known. |
min_notional | Minimum order notional value when known. |
max_price | Maximum valid quote or order price when known. |
min_price | Minimum valid quote or order price when known. |
tick_scheme | Registered tick scheme name used for price navigation. |
info | Adapter metadata preserved from the venue or data source. |
ts_event | UNIX nanosecond timestamp for when the definition event occurred. |
ts_init | UNIX nanosecond timestamp for when Nautilus initialized the object. |
Tick schemes
A named tick scheme defines the price grid used by an instrument's next_bid_price
and next_ask_price methods. Use FixedTickScheme for a constant increment or
TieredTickScheme when the increment changes across price ranges.
Register a scheme before passing its name as an instrument's tick_scheme constructor argument.
Register custom schemes before loading saved instrument definitions from a catalog. Saved definitions contain the scheme name, and loading validates it against the current process's registry.
Migration from v1:
FixedTickSchemeno longer acceptsmin_tickormax_tickand has nomin_priceormax_priceattributes. Fixed schemes use the representablePricerange, including negative prices. The built-in Forex schemes no longer impose their v1 price bounds.- The
incrementargument requires aPrice. Replace float values withPrice.from_str("0.05").
Fixed tick increments use Price to preserve their exact value. Navigation returns None if the
instrument's price precision cannot represent the increment exactly.
use nautilus_model::{
instruments::{FixedTickScheme, TickScheme, TickSchemeRule, get_tick_scheme, register_tick_scheme},
types::Price,
};
let fixed = FixedTickScheme::new(Price::from("0.05")).unwrap();
register_tick_scheme("FIVE_CENT", TickScheme::Fixed(fixed)).unwrap();
let scheme = get_tick_scheme("five_cent").unwrap();
assert_eq!(scheme.next_bid_price(1.13, 0, 2), Some(Price::from("1.10")));
assert_eq!(scheme.next_ask_price(1.13, 0, 2), Some(Price::from("1.15")));Tier definitions use (start, stop, step) with an inclusive start and exclusive stop. Each tier expands to at
most max_ticks_per_tier prices, including tiers with an infinite stop. The Python default is 100. A finite
tier that exceeds the cap is truncated without an error. Choose a cap large enough to include each required
price.
use nautilus_model::instruments::{TickScheme, TieredTickScheme, register_tick_scheme};
let tiers = [(0.05, 10.00, 0.05), (10.00, f64::INFINITY, 0.25)];
let scheme = TieredTickScheme::new(&tiers, 2, 1000).unwrap();
register_tick_scheme("OPTION_GRID", TickScheme::Tiered(scheme)).unwrap();Registration and lookup
- Names: ASCII, trimmed, and case-insensitive.
- Lifetime: registration lasts for the process lifetime. A registered name cannot be replaced or removed.
- Protected names: built-ins such as
BETFAIRandTOPIX100, and aliases such asFIXED_PRECISION_01forFIXED_PRECISION_1, cannot be replaced or removed. - Listing:
list_tick_schemes()returns canonical built-in and registered names in sorted order.
Failure results: Rust and Python return different results.
| Failure | Rust | Python |
|---|---|---|
| Invalid construction or registration input | TickSchemeError | ValueError |
| Duplicate name on registration | TickSchemeError | ValueError |
| Unknown name on lookup | None | ValueError |
Python registration raises TypeError for an unsupported object. Callers that catch v1's KeyError
for unknown or duplicate names must catch ValueError instead.
Symbology
Each instrument has a unique InstrumentId made from a Nautilus symbol and venue, separated by a period. The
separate raw_symbol field preserves the venue's native symbol.
Binance Futures example: the Ethereum perpetual contract uses this identifier.
ETHUSDT-PERP.BINANCENative symbols should be unique for a venue, but not all exchanges guarantee this. The Nautilus
{symbol}.{venue} pair must be unique inside a system.
The instrument definition must match the market data and venue order semantics. An incorrect instrument can truncate prices or quantities, or calculate notional values with the wrong currency. It can also make a backtest accept prices a live venue would reject.
Rust and Python surfaces
Rust: use the nautilus_model instrument structs and InstrumentAny.
use nautilus_model::instruments::{CurrencyPair, InstrumentAny};Python: normally use instrument classes from nautilus_trader.model.
from nautilus_trader.model import CurrencyPairBoth surfaces represent the same instrument contract: identity, precision, increments, currencies, limits, margins, fees, metadata, and timestamps.
Loading instruments
Test instruments: instantiate generic instruments through the TestInstrumentProvider.
from nautilus_trader.testkit.providers import TestInstrumentProvider
audusd = TestInstrumentProvider.default_fx_ccy("AUD/USD")Live integration adapters expose InstrumentProvider objects that cache instrument
definitions. Use InstrumentProviderConfig(load_all=True) where the integration
supports it, or load_ids to load a known set of instruments. Order submission requires
the matching instrument definition to exist in the central cache.
Finding instruments
Cache lookup: strategies and actors retrieve instruments from the central cache.
use nautilus_model::identifiers::InstrumentId;
let instrument_id = InstrumentId::from("ETHUSDT-PERP.BINANCE");
let instrument = cache.instrument(&instrument_id);Subscriptions: subscribe to one instrument or all instruments for a venue.
self.subscribe_instrument(instrument_id)
self.subscribe_instruments(venue)When the DataEngine receives an instrument update, it passes the object to the
on_instrument() handler.
Precision
For order validation, price_precision and size_precision set the maximum number of
decimal places that the RiskEngine accepts. price_increment and size_increment
record the corresponding minimum steps.
| Field | Constrains | Example |
|---|---|---|
price_precision | Order prices, trigger prices, fills. | 2 -> 50000.01 |
size_precision | Order quantities and fill sizes. | 5 -> 1.00001 |
The price increment precision must match price_precision, and the size increment
precision must match size_precision. For example, price_precision=2 pairs with
price_increment=Price(0.01, 2).
Rounding: use the instrument factory methods to round values to the configured precision.
instrument = self.cache.instrument(instrument_id)
price = instrument.make_price(0.90500)
quantity = instrument.make_qty(150)These methods round to the corresponding increment precision, which instrument
construction requires to match the declared precision. They do not ensure that the
result is a multiple of an increment such as 0.25.
The RiskEngine does not round values automatically. If you create a Price with
5 decimal places for an instrument that supports 2, the order is denied. Use
instrument.make_price() and instrument.make_qty() to round explicitly. The
RiskEngine also does not validate increment multiples, so ensure that prices and
quantities match the venue steps before submission.
Limits, margins, and fees
Optional limits: venue and adapter definitions can include the following limits.
max_quantityandmin_quantity.max_notionalandmin_notional.max_priceandmin_price.
Margin models use margin_init and margin_maint to calculate initial and maintenance margin.
Instruments do not carry maker or taker fee rates. Backtest and sandbox commission uses a fee model. Live commissions come from venue fills.
Fee model rate convention:
- Positive fee rates represent commissions.
- Negative fee rates represent rebates.
For deeper accounting behavior, see Accounting.
Metadata
The info field preserves raw or adapter-specific metadata as a JSON-serializable
dictionary. Use it when the venue publishes useful details that do not belong in the
unified Nautilus instrument API.
Related guides
- Data covers market data types that reference instruments.
- Orders covers order fields that reference instruments.
- Synthetics covers local formula-derived instruments.
- Python API Reference lists Python constructors and members.
Python
NautilusTrader provides a Python control surface over the Rust core through PyO3. This guide explains which runtime owns each part of the system and where...
Equity
Equity represents a listed share, ETF, or similar cash-market security. Nautilus uses this type for instruments that trade in whole units, quote in one...