nautechsystems/nautilus_trader · error

Missing option_type for option instrument

Error message

Missing option_type for option instrument

What it means

When parsing a Deribit option instrument, the option_type field (Call/Put) must be present to construct an OptionKind. If Deribit returns the instrument without option_type populated, parsing cannot proceed and it errors.

Source

Thrown at crates/adapters/deribit/src/common/parse.rs:380

    let instrument_id = InstrumentId::new(Symbol::new(instrument.instrument_name), *DERIBIT_VENUE);
    let underlying = Currency::get_or_create_crypto(instrument.base_currency);
    let quote_currency = Currency::get_or_create_crypto(instrument.quote_currency);
    let settlement = instrument
        .settlement_currency
        .unwrap_or(instrument.base_currency);
    let settlement_currency = Currency::get_or_create_crypto(settlement);

    // Determine if inverse (settled in base currency) or linear (settled in quote/USDC)
    let is_inverse = instrument
        .instrument_type
        .as_ref()
        .is_some_and(|t| t == "reversed");

    // Determine option kind
    let option_kind = match instrument.option_type {
        Some(DeribitOptionType::Call) => OptionKind::Call,
        Some(DeribitOptionType::Put) => OptionKind::Put,
        None => anyhow::bail!("Missing option_type for option instrument"),
    };

    // Parse strike price
    let strike = instrument.strike.context("Missing strike for option")?;
    let strike_price = Price::from_decimal(strike)?;

    // Convert timestamps from milliseconds to nanoseconds
    let activation_ns = (instrument.creation_timestamp as u64) * 1_000_000;
    let expiration_ns = instrument
        .expiration_timestamp
        .context("Missing expiration_timestamp for option")? as u64
        * 1_000_000;

    let price_increment = Price::from_decimal(instrument.tick_size)?;

    let multiplier = deribit_amount_quantity_multiplier();
    let lot_size = Quantity::from_decimal(instrument.min_trade_amount)?;
    let min_trade_amount = Quantity::from_decimal(instrument.min_trade_amount)?;

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Check the instrument is an option (kind field) before calling the option parser
  2. Update the Deribit API client/model if option_type serialization changed
  3. Log and skip instruments missing option_type instead of failing the whole parse

Example fix

// before
None => anyhow::bail!("Missing option_type for option instrument"),
// after
None => {
    log::warn!("Skipping {} with missing option_type", instrument.instrument_name);
    return Ok(None);
}
Defensive patterns

Strategy: type-guard

Validate before calling

assert!(instrument.option_type.is_some(), "instrument {} lacks option_type", instrument.instrument_name);

Type guard

fn is_parseable_option(i: &DeribitInstrument) -> bool {
    i.option_type.is_some() && i.strike.is_some()
}

Try / catch

match parse_deribit_instrument_any(&payload) {
    Err(e) if e.to_string().contains("Missing option_type") => {
        warn!("skipping malformed instrument");
    }
    other => other?,
}

Prevention

When it happens

Trigger: parse_option_instrument receives a DeribitInstrument with option_type == None — e.g. an incomplete or malformed instrument payload from the Deribit API.

Common situations: Deribit API schema changes or partial responses, future-type instruments accidentally routed to the option parser, caching stale instrument definitions.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08). Data as JSON: /api/errors/a75e81c99d970c6f. Report an issue: GitHub.