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