Skip to main content
Version: latest

Instruments

The Instrument base class represents the core specification for any tradable asset/contract. There are currently a number of subclasses representing a range of asset classes and instrument classes which are supported by the platform:

  • Equity (generic Equity)
  • FuturesContract (generic Futures Contract)
  • FuturesSpread (generic Futures Spread)
  • OptionContract (generic Option Contract)
  • OptionSpread (generic Option Spread)
  • BinaryOption (generic Binary Option instrument)
  • Cfd (Contract for Difference instrument)
  • Commodity (commodity instrument in a spot/cash market)
  • CurrencyPair (represents a Fiat FX or Cryptocurrency pair in a spot/cash market)
  • CryptoOption (Crypto Option instrument)
  • CryptoPerpetual (Perpetual Futures Contract a.k.a. Perpetual Swap)
  • CryptoFuture (Deliverable Futures Contract with Crypto assets as underlying, and for price quotes and settlement)
  • IndexInstrument (generic Index instrument)
  • BettingInstrument (Sports, gaming, or other betting)

Symbology

All instruments should have a unique InstrumentId, which is made up of both the native symbol, and venue ID, separated by a period. For example, on the Binance Futures crypto exchange, the Ethereum Perpetual Futures Contract has the instrument ID ETHUSDT-PERP.BINANCE.

All native symbols should be unique for a venue (this is not always the case e.g. Binance share native symbols between spot and futures markets), and the {symbol.venue} combination must be unique for a Nautilus system.

warning

The correct instrument must be matched to a market dataset such as ticks or order book data for logically sound operation. An incorrectly specified instrument may truncate data or otherwise produce surprising results.

Backtesting

Generic test instruments can be instantiated through the TestInstrumentProvider:

from posei_trader.test_kit.providers import TestInstrumentProvider

audusd = TestInstrumentProvider.default_fx_ccy("AUD/USD")

Exchange specific instruments can be discovered from live exchange data using an adapters InstrumentProvider:

from posei_trader.adapters.binance.spot.providers import BinanceSpotInstrumentProvider
from posei_trader.model import InstrumentId

provider = BinanceSpotInstrumentProvider(client=binance_http_client)
await provider.load_all_async()

btcusdt = InstrumentId.from_str("BTCUSDT.BINANCE")
instrument = provider.find(btcusdt)

Or flexibly defined by the user through an Instrument constructor, or one of its more specific subclasses:

from posei_trader.model.instruments import Instrument

instrument = Instrument(...) # <-- provide all necessary parameters

See the full instrument API Reference.

Live trading

Live integration adapters have defined InstrumentProvider classes which work in an automated way to cache the latest instrument definitions for the exchange. Refer to a particular Instrument object by passing the matching InstrumentId to data and execution related methods and classes that require one.

Finding instruments

Since the same actor/strategy classes can be used for both backtest and live trading, you can get instruments in exactly the same way through the central cache:

from posei_trader.model import InstrumentId

instrument_id = InstrumentId.from_str("ETHUSDT-PERP.BINANCE")
instrument = self.cache.instrument(instrument_id)

It's also possible to subscribe to any changes to a particular instrument:

self.subscribe_instrument(instrument_id)

Or subscribe to all instrument changes for an entire venue:

from posei_trader.model import Venue

binance = Venue("BINANCE")
self.subscribe_instruments(binance)

When an update to the instrument(s) is received by the DataEngine, the object(s) will be passed to the actors/strategies on_instrument() method. A user can override this method with actions to take upon receiving an instrument update:

from posei_trader.model.instruments import Instrument

def on_instrument(self, instrument: Instrument) -> None:
# Take some action on an instrument update
pass

Precisions and increments

The instrument objects are a convenient way to organize the specification of an instrument through read-only properties. Correct price and quantity precisions, as well as minimum price and size increments, multipliers and standard lot sizes, are available.

note

Most of these limits are checked by the Nautilus RiskEngine, otherwise invalid values for prices and quantities can result in the exchange rejecting orders.

Limits

Certain value limits are optional for instruments and can be None, these are exchange dependent and can include:

  • max_quantity (maximum quantity for a single order)
  • min_quantity (minimum quantity for a single order)
  • max_notional (maximum value of a single order)
  • min_notional (minimum value of a single order)
  • max_price (maximum valid quote or order price)
  • min_price (minimum valid quote or order price)
note

Most of these limits are checked by the Nautilus RiskEngine, otherwise exceeding published limits can result in the exchange rejecting orders.

Prices and quantities

Instrument objects also offer a convenient way to create correct prices and quantities based on given values.

instrument = self.cache.instrument(instrument_id)

price = instrument.make_price(0.90500)
quantity = instrument.make_qty(150)
tip

The above is the recommended method for creating valid prices and quantities, such as when passing them to the order factory to create an order.

Margins and fees

Margin calculations are handled by the MarginAccount class. This section explains how margins work and introduces key concepts you need to know.

When margins apply?

Each exchange (e.g., CME or Binance) operates with a specific account type that determines whether margin calculations are applicable. When setting up an exchange venue, you'll specify one of these account types:

  • AccountType.MARGIN: Accounts that use margin calculations, which are explained below.
  • AccountType.CASH: Simple accounts where margin calculations do not apply.
  • AccountType.BETTING: Accounts designed for betting, which also do not involve margin calculations.

Vocabulary

To understand trading on margin, let’s start with some key terms:

Notional Value: The total contract value in the quote currency. It represents the full market value of your position. For example, with EUR/USD futures on CME (symbol 6E).

  • Each contract represents 125,000 EUR (EUR is base currency, USD is quote currency).
  • If the current market price is 1.1000, the notional value equals 125,000 EUR × 1.1000 (price of EUR/USD) = 137,500 USD.

Leverage (leverage): The ratio that determines how much market exposure you can control relative to your account deposit. For example, with 10