{"record":{"id":"b6e7a83497155f79","repo":"nautechsystems/nautilus_trader","slug":"settle-ccy-or-quote-ccy-is-required-for-events","errorCode":null,"errorMessage":"`settle_ccy` or `quote_ccy` is required for EVENTS instrument {}","messagePattern":"`settle_ccy` or `quote_ccy` is required for EVENTS instrument (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/okx/src/common/parse.rs","lineNumber":2631,"sourceCode":"fn okx_inst_category_to_asset_class(category: Option<OKXInstrumentCategory>) -> AssetClass {\n    match category {\n        Some(OKXInstrumentCategory::Crypto) => AssetClass::Cryptocurrency,\n        Some(OKXInstrumentCategory::Equity) => AssetClass::Equity,\n        Some(OKXInstrumentCategory::Commodity) => AssetClass::Commodity,\n        Some(OKXInstrumentCategory::Fx) => AssetClass::FX,\n        Some(OKXInstrumentCategory::Debt) => AssetClass::Debt,\n        Some(OKXInstrumentCategory::Unknown) | None => AssetClass::Alternative,\n    }\n}\n\nfn parse_event_contract_currency(definition: &OKXInstrument) -> anyhow::Result<Currency> {\n    let context = format!(\"EVENTS instrument {}\", definition.inst_id);\n    let currency = if !definition.settle_ccy.is_empty() {\n        definition.settle_ccy\n    } else if !definition.quote_ccy.is_empty() {\n        definition.quote_ccy\n    } else {\n        anyhow::bail!(\n            \"`settle_ccy` or `quote_ccy` is required for EVENTS instrument {}\",\n            definition.inst_id\n        );\n    };\n\n    Ok(Currency::get_or_create_crypto_with_context(\n        currency,\n        Some(&context),\n    ))\n}\n\nfn build_event_contract_info(definition: &OKXInstrument) -> anyhow::Result<Params> {\n    let mut map = serde_json::Map::new();\n\n    if let Some(series_id) = definition.series_id {\n        map.insert(\n            \"series_id\".to_string(),\n            serde_json::Value::String(series_id.to_string()),","sourceCodeStart":2613,"sourceCodeEnd":2649,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/okx/src/common/parse.rs#L2613-L2649","documentation":"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.","triggerScenarios":"parse_event_contract_instrument -> parse_event_contract_currency receives an EVENTS instrument definition where both settle_ccy and quote_ccy are empty strings.","commonSituations":"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.","solutions":["Inspect the raw OKX /api/v5/public/instruments?instType=EVENTS response for the inst_id and check which currency fields OKX returns","Update the parser to read an alternative currency field (e.g. ccy) if OKX moved the settlement currency to a new attribute","Skip EVENTS instruments lacking both fields if they cannot be modeled","Populate settle_ccy in fixtures for EVENTS instruments"],"exampleFix":"// before\nanyhow::bail!(\"`settle_ccy` or `quote_ccy` is required for EVENTS instrument {}\", definition.inst_id);\n// after\nlet currency = definition.settle_ccy.or(definition.quote_ccy).or(definition.ccy)\n    .ok_or_else(|| anyhow::anyhow!(\"no currency field for EVENTS instrument {}\", definition.inst_id))?;","handlingStrategy":"validation","validationCode":"if definition.settle_ccy.is_empty() && definition.quote_ccy.is_empty() { skip EVENTS instrument } // check before parse_event_contract_instrument","typeGuard":"fn events_has_currency(def: &OKXInstrumentDef) -> bool { !def.settle_ccy.is_empty() || !def.quote_ccy.is_empty() }","tryCatchPattern":"match parse_instrument_any(&def) {\n    Err(e) if e.to_string().contains(\"settle_ccy` or `quote_ccy` is required\") => log::warn!(\"skip EVENTS {}: {e}\", def.inst_id),\n    other => other?,\n}","preventionTips":["Populate settle_ccy in all EVENTS fixtures","Monitor OKX EVENTS instrument schema for currency field changes","Skip EVENTS entries lacking both currency fields upstream"],"tags":["okx","event-contracts","instrument-parsing","missing-field"],"backgroundTag":"missing-required-argument","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}