nautechsystems/nautilus_trader · error · anyhow::Error
Invalid tickSize of 0 for symbol '{}', cannot create instrum
Error message
Invalid tickSize of 0 for symbol '{}', cannot create instrument What it means
After parsing PRICE_FILTER.tickSize for a USD-M symbol, parse_usdm_instrument_with_fees rejects a tick size of exactly zero: tick size parameterizes the instrument's price increment and precision, so a zero tick cannot produce a valid instrument.
Source
Thrown at crates/adapters/binance/src/common/parse.rs:314
anyhow::bail!(
"Symbol '{}' is not trading (status: {:?})",
symbol.symbol,
symbol.status
);
}
let quote_currency = get_currency(symbol.quote_asset.as_str());
let settlement_currency = get_currency(symbol.margin_asset.as_str());
let instrument_id = format_instrument_id(&symbol.symbol, BinanceProductType::UsdM);
let raw_symbol = Symbol::new(symbol.symbol.as_str());
let price_filter = get_filter(&symbol.filters, "PRICE_FILTER")
.context("Missing PRICE_FILTER in symbol filters")?;
let tick_size = parse_filter_price(price_filter, "tickSize")?;
if tick_size.is_zero() {
anyhow::bail!(
"Invalid tickSize of 0 for symbol '{}', cannot create instrument",
symbol.symbol,
);
}
let max_price = parse_filter_price(price_filter, "maxPrice").ok();
let min_price = parse_filter_price(price_filter, "minPrice").ok();
let lot_filter =
get_filter(&symbol.filters, "LOT_SIZE").context("Missing LOT_SIZE in symbol filters")?;
let step_size = parse_filter_quantity(lot_filter, "stepSize")?;
let max_quantity = parse_filter_quantity(lot_filter, "maxQty").ok();
let min_quantity = parse_filter_quantity(lot_filter, "minQty").ok();
let min_notional = parse_futures_min_notional(&symbol.filters, quote_currency);
// Default margin (0.1 = 10x leverage)
let default_margin = Decimal::new(1, 1);View on GitHub (pinned to a4b06ed870)
Solutions
- Check the live exchangeInfo for the symbol; a zero tickSize usually means it is not tradable yet.
- Skip or defer loading of symbols whose tickSize is 0.
- Clear any exchangeInfo cache and retry with fresh data.
- If a TRADING-status symbol persistently reports tickSize 0, report it to Binance / the adapter maintainers.
Defensive patterns
Strategy: try-catch
Validate before calling
fn usdm_tick_size_is_valid(symbol: &BinanceFuturesUsdSymbol) -> bool {
symbol
.filters
.iter()
.find(|f| f.get("filterType").and_then(|v| v.as_str()) == Some("PRICE_FILTER"))
.and_then(|f| f.get("tickSize").and_then(|v| v.as_str()))
.map(|t| {
rust_decimal::Decimal::from_str(t)
.map(|d| !d.is_zero())
.unwrap_or(false)
})
.unwrap_or(false)
} Try / catch
match parse_usdm_instrument(&symbol, ts_event, ts_init) {
Ok(inst) => instruments.push(inst),
Err(e) if e.to_string().contains("Invalid tickSize of 0") => {
tracing::warn!(symbol = %symbol.symbol, "venue reported zero tickSize, deferring load")
}
Err(e) => return Err(e),
} Prevention
- Pre-check tickSize != 0 when filtering symbols for loading.
- Refresh cached exchangeInfo snapshots rather than serving them indefinitely.
- Re-attempt loading later for pre-listing symbols whose filters are placeholders.
When it happens
Trigger: USD-M exchangeInfo contains a PRICE_FILTER with "tickSize": "0" — typically placeholder data on symbols in pre-listing/settlement states, or corrupted/cached responses.
Common situations: Pre-listing symbols before Binance populates real filters; a stale exchangeInfo cache or replayed fixture with zeroed filters; venue-side data glitch.
Related errors
- Invalid tickSize of 0
- Unsupported USD-M contract type '{}' for symbol '{}'
- Symbol '{}' is not trading (status: {:?})
- invalid {field}='{raw}': {e}
- invalid {field}='{raw}' at precision {precision}: {e}
AI-assisted analysis of nautechsystems/nautilus_trader@a4b06ed870 (2026-08-16).
Data as JSON: /api/errors/84b45dd259cbdbfc.
Report an issue: GitHub.