nautechsystems/nautilus_trader · error · anyhow::Error
Unsupported underlying type '{underlying_type}' for TRADIFI_
Error message
Unsupported underlying type '{underlying_type}' for TRADIFI_PERPETUAL symbol '{}' What it means
Binance TRADIFI_PERPETUAL instruments (perpetuals on tokenized traditional-finance underlyings) get their AssetClass from exchangeInfo's underlyingType. Only EQUITY, KR_EQUITY, HK_EQUITY, PREMARKET and COMMODITY are mapped; parse_tradifi_asset_class bails on any other underlyingType string.
Source
Thrown at crates/adapters/binance/src/common/parse.rs:126
Err(e) => {
log::warn!("{e}; using initialization timestamp");
ts_init
}
}
}
fn parse_tradifi_asset_class(symbol: &BinanceFuturesUsdSymbol) -> anyhow::Result<AssetClass> {
let underlying_type = symbol.underlying_type.as_deref().with_context(|| {
format!(
"Missing underlying type for TRADIFI_PERPETUAL symbol '{}'",
symbol.symbol
)
})?;
match underlying_type {
"EQUITY" | "KR_EQUITY" | "HK_EQUITY" | "PREMARKET" => Ok(AssetClass::Equity),
"COMMODITY" => Ok(AssetClass::Commodity),
_ => anyhow::bail!(
"Unsupported underlying type '{underlying_type}' for TRADIFI_PERPETUAL symbol '{}'",
symbol.symbol
),
}
}
/// Returns a currency from the internal map or creates a new crypto currency.
pub fn get_currency(code: &str) -> Currency {
Currency::get_or_create_crypto(code)
}
/// Extracts filter values from Binance symbol filters array.
fn get_filter<'a>(filters: &'a [Value], filter_type: &str) -> Option<&'a Value> {
filters.iter().find(|f| {
f.get("filterType")
.and_then(|v| v.as_str())
.is_some_and(|t| t == filter_type)
})View on GitHub (pinned to a4b06ed870)
Solutions
- Update the Binance adapter to a release that maps the new underlying type
- Until updated, exclude the symbol from instrument loading via the filter config
- Contribute a mapping for the new underlyingType in parse_tradifi_asset_class (crates/adapters/binance/src/common/parse.rs)
Example fix
// before
match underlying_type {
"EQUITY" | "KR_EQUITY" | "HK_EQUITY" | "PREMARKET" => Ok(AssetClass::Equity),
"COMMODITY" => Ok(AssetClass::Commodity),
_ => anyhow::bail!(...),
}
// after: map the newly listed class
"EQUITY" | "KR_EQUITY" | "HK_EQUITY" | "PREMARKET" => Ok(AssetClass::Equity),
"COMMODITY" | "METAL" => Ok(AssetClass::Commodity), Defensive patterns
Strategy: try-catch
Validate before calling
const MAPPED_UNDERLYING: &[&str] = &["EQUITY", "KR_EQUITY", "HK_EQUITY", "PREMARKET", "COMMODITY"];
fn underlying_type_supported(t: &str) -> bool {
MAPPED_UNDERLYING.contains(&t)
} Type guard
fn is_supported_tradifi_underlying(underlying_type: &str) -> bool {
matches!(underlying_type, "EQUITY" | "KR_EQUITY" | "HK_EQUITY" | "PREMARKET" | "COMMODITY")
} Try / catch
for symbol in symbols {
if let Err(e) = parse_symbol(&symbol) {
if e.to_string().contains("Unsupported underlying type") {
log::warn!("skipping unmapped TradFi symbol {}: {e}", symbol.symbol);
continue;
}
return Err(e);
}
} Prevention
- Treat new exchange metadata as expected drift: skip-with-warning on unmapped TradFi underlyings instead of failing instrument loads
- Pin adapter versions and check the exchange's new-listings notes before upgrading trading infrastructure
- Add the known underlying-type allow-list to your monitoring so new values raise an alert
When it happens
Trigger: exchangeInfo returns a TRADIFI_PERPETUAL symbol with an underlyingType outside the mapped set - e.g. Binance launches a new class (FX, rates, metals) after your adapter version was cut.
Common situations: Running an older adapter against a live exchange that has listed new TradFi product types; instrument loading suddenly failing for one new symbol after an exchange rollout.
Related errors
- Invalid price_match value: {s:?}
- Missing field '{field}' in filter
- Failed to parse {field}='{value}': {e}
- callbackRate {rate}% out of Binance range [{min_rate}, {max_
- BinanceFuturesDataClient requires UsdM or CoinM product type
AI-assisted analysis of nautechsystems/nautilus_trader@a4b06ed870 (2026-08-16).
Data as JSON: /api/errors/818b141b0365a4fb.
Report an issue: GitHub.