NautilusTrader
ConceptsInstruments

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 typeInstrumentClassDescriptionTypical adapters
EquitySPOTListed share or ETF traded on a cash market.Databento, Interactive Brokers.
CurrencyPairSPOTFiat FX or crypto spot pair in base/quote form.Binance, Kraken, OKX, Tardis.
CommoditySPOTSpot commodity such as gold or oil.Interactive Brokers.
CfdCFDContract for difference tracking an underlying.Interactive Brokers.
IndexInstrumentSPOTReference index, not directly tradable.Interactive Brokers.
TokenizedAssetSPOTTokenized asset on a crypto venue.Kraken.
FuturesContractFUTUREDated futures contract.Databento, Interactive Brokers.
FuturesSpreadFUTURES_SPREADExchange defined futures strategy with several legs.Databento, Interactive Brokers.
CryptoFutureFUTUREDated crypto futures contract.Bybit, Deribit, OKX.
CryptoFuturesSpreadFUTURES_SPREADExchange defined crypto futures spread.Deribit, OKX.
CryptoPerpetualSWAPCrypto perpetual futures contract.Binance, Bybit, dYdX.
PerpetualContractSWAPPerpetual futures contract across asset classes.Architect AX, Binance.
OptionContractOPTIONExchange traded put or call option.Databento, Interactive Brokers.
OptionSpreadOPTION_SPREADExchange defined options strategy with several legs.Databento, Interactive Brokers.
CryptoOptionOPTIONOption on a crypto underlying.Bybit, Deribit, OKX, Tardis.
CryptoOptionSpreadOPTION_SPREADExchange defined crypto option spread.Deribit, OKX.
BinaryOptionBINARY_OPTIONBinary instrument that settles to 0 or 1.Hyperliquid, OKX, Polymarket.
BettingInstrumentSPORTS_BETTINGSports or gaming market selection.Betfair.
SyntheticInstrumentn/aFormula 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.

FieldMeaning
idNautilus InstrumentId, formed from a symbol and venue.
raw_symbolNative venue symbol before Nautilus normalization.
price_precisionConfigured number of decimal places for price values.
size_precisionConfigured number of decimal places for quantity values.
price_incrementSmallest valid price step.
size_incrementSmallest valid quantity step.
multiplierContract multiplier used in notional and PnL calculations.
lot_sizeRounded lot or board size when the venue publishes one.
margin_initInitial margin rate as a decimal fraction of notional value.
margin_maintMaintenance margin rate as a decimal fraction of notional value.
max_quantityMaximum order quantity when known.
min_quantityMinimum order quantity when known.
max_notionalMaximum order notional value when known.
min_notionalMinimum order notional value when known.
max_priceMaximum valid quote or order price when known.
min_priceMinimum valid quote or order price when known.
tick_schemeRegistered tick scheme name used for price navigation.
infoAdapter metadata preserved from the venue or data source.
ts_eventUNIX nanosecond timestamp for when the definition event occurred.
ts_initUNIX 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:

  • FixedTickScheme no longer accepts min_tick or max_tick and has no min_price or max_price attributes. Fixed schemes use the representable Price range, including negative prices. The built-in Forex schemes no longer impose their v1 price bounds.
  • The increment argument requires a Price. Replace float values with Price.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 BETFAIR and TOPIX100, and aliases such as FIXED_PRECISION_01 for FIXED_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.

FailureRustPython
Invalid construction or registration inputTickSchemeErrorValueError
Duplicate name on registrationTickSchemeErrorValueError
Unknown name on lookupNoneValueError

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.BINANCE

Native 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 CurrencyPair

Both 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.

FieldConstrainsExample
price_precisionOrder prices, trigger prices, fills.2 -> 50000.01
size_precisionOrder 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_quantity and min_quantity.
  • max_notional and min_notional.
  • max_price and min_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.

  • 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.

On this page