nautechsystems/nautilus_trader · error

`settle_ccy` or `quote_ccy` is required for EVENTS instrumen

Error message

`settle_ccy` or `quote_ccy` is required for EVENTS instrument {}

What it means

EVENTS (event contract) instruments on OKX do not carry a conventional settle currency, so parse_event_contract_currency falls back to settle_ccy first, then quote_ccy. This error fires when both fields are empty, leaving no currency to create the event contract's settlement currency from.

Source

Thrown at crates/adapters/okx/src/common/parse.rs:2631

fn okx_inst_category_to_asset_class(category: Option<OKXInstrumentCategory>) -> AssetClass {
    match category {
        Some(OKXInstrumentCategory::Crypto) => AssetClass::Cryptocurrency,
        Some(OKXInstrumentCategory::Equity) => AssetClass::Equity,
        Some(OKXInstrumentCategory::Commodity) => AssetClass::Commodity,
        Some(OKXInstrumentCategory::Fx) => AssetClass::FX,
        Some(OKXInstrumentCategory::Debt) => AssetClass::Debt,
        Some(OKXInstrumentCategory::Unknown) | None => AssetClass::Alternative,
    }
}

fn parse_event_contract_currency(definition: &OKXInstrument) -> anyhow::Result<Currency> {
    let context = format!("EVENTS instrument {}", definition.inst_id);
    let currency = if !definition.settle_ccy.is_empty() {
        definition.settle_ccy
    } else if !definition.quote_ccy.is_empty() {
        definition.quote_ccy
    } else {
        anyhow::bail!(
            "`settle_ccy` or `quote_ccy` is required for EVENTS instrument {}",
            definition.inst_id
        );
    };

    Ok(Currency::get_or_create_crypto_with_context(
        currency,
        Some(&context),
    ))
}

fn build_event_contract_info(definition: &OKXInstrument) -> anyhow::Result<Params> {
    let mut map = serde_json::Map::new();

    if let Some(series_id) = definition.series_id {
        map.insert(
            "series_id".to_string(),
            serde_json::Value::String(series_id.to_string()),

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Inspect the raw OKX /api/v5/public/instruments?instType=EVENTS response for the inst_id and check which currency fields OKX returns
  2. Update the parser to read an alternative currency field (e.g. ccy) if OKX moved the settlement currency to a new attribute
  3. Skip EVENTS instruments lacking both fields if they cannot be modeled
  4. Populate settle_ccy in fixtures for EVENTS instruments

Example fix

// before
anyhow::bail!("`settle_ccy` or `quote_ccy` is required for EVENTS instrument {}", definition.inst_id);
// after
let currency = definition.settle_ccy.or(definition.quote_ccy).or(definition.ccy)
    .ok_or_else(|| anyhow::anyhow!("no currency field for EVENTS instrument {}", definition.inst_id))?;
Defensive patterns

Strategy: validation

Validate before calling

if definition.settle_ccy.is_empty() && definition.quote_ccy.is_empty() { skip EVENTS instrument } // check before parse_event_contract_instrument

Type guard

fn events_has_currency(def: &OKXInstrumentDef) -> bool { !def.settle_ccy.is_empty() || !def.quote_ccy.is_empty() }

Try / catch

match parse_instrument_any(&def) {
    Err(e) if e.to_string().contains("settle_ccy` or `quote_ccy` is required") => log::warn!("skip EVENTS {}: {e}", def.inst_id),
    other => other?,
}

Prevention

When it happens

Trigger: parse_event_contract_instrument -> parse_event_contract_currency receives an EVENTS instrument definition where both settle_ccy and quote_ccy are empty strings.

Common situations: OKX response schema drift on the EVENTS instrument type; new event-contract listings missing both fields; hand-built fixtures for EVENTS instruments that omit currency fields.

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/b6e7a83497155f79. Report an issue: GitHub.