nautechsystems/nautilus_trader · error

Failed to parse `tick_sz` '{}' into Price for {}: {e}

Error message

Failed to parse `tick_sz` '{}' into Price for {}: {e}

What it means

OKX instrument parsing calls `Price::from_str` on the exchange-reported `tick_sz` field, and it failed to parse into the NautilusTrader `Price` type. The library throws this when an instrument definition carries a tick size value that is present but not a valid decimal price string. Parsing fails hard instead of guessing, since a wrong price increment corrupts order pricing downstream.

Source

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

        common: CommonInstrumentData,
        margin_fees: MarginAndFees,
        ts_init: UnixNanos,
    ) -> anyhow::Result<InstrumentAny>;
}

/// Extracts common fields shared across all instrument types.
fn parse_common_instrument_data(
    definition: &OKXInstrument,
) -> anyhow::Result<CommonInstrumentData> {
    let instrument_id = parse_instrument_id(definition.inst_id);
    let raw_symbol = Symbol::from_ustr_unchecked(definition.inst_id);

    if definition.tick_sz.is_empty() {
        anyhow::bail!("`tick_sz` is empty for {}", definition.inst_id);
    }

    let price_increment = Price::from_str(&definition.tick_sz).map_err(|e| {
        anyhow::anyhow!(
            "Failed to parse `tick_sz` '{}' into Price for {}: {e}",
            definition.tick_sz,
            definition.inst_id,
        )
    })?;

    if definition.lot_sz.is_empty() {
        anyhow::bail!("`lot_sz` is empty for {}", definition.inst_id);
    }

    let size_increment = Quantity::from_str(&definition.lot_sz).map_err(|e| {
        anyhow::anyhow!(
            "Failed to parse `lot_sz` '{}' for {}: {e}",
            definition.lot_sz,
            definition.inst_id,
        )
    })?;
    let lot_size = Some(size_increment);

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Log/inspect the raw definition.tick_sz for the failing inst_id and confirm it is a plain decimal string like "0.1".
  2. Verify the value against the live OKX /api/v5/public/instruments response for that instId.
  3. If it comes from a fixture or cache, correct or regenerate the fixture from a fresh OKX response.
  4. If parsing still fails for a valid decimal, check the Price::from_str precision limits and normalize the string (trim whitespace, strip units) before parsing.

Example fix

// before
let price_increment = Price::from_str(&definition.tick_sz).map_err(|e| ...)?;
// after
let tick = definition.tick_sz.trim();
let price_increment = Price::from_str(tick).map_err(|e| ...)?;
Defensive patterns

Strategy: validation

Validate before calling

fn is_decimal(s: &str) -> bool {
    let t = s.trim();
    !t.is_empty() && t.parse::<f64>().is_ok() && !t.contains(['e', 'E'])
}
// guard: assert!(is_decimal(definition.tick_sz), "bad tick_sz: {}", definition.tick_sz);

Type guard

fn valid_price_str(s: &str) -> Option<&str> {
    let t = s.trim();
    if !t.is_empty() && t.parse::<f64>().is_ok() { Some(t) } else { None }
}

Try / catch

match parse_instrument_with_parser(&definition, ts_init) {
    Ok(inst) => inst,
    Err(e) if e.to_string().contains("tick_sz") => {
        tracing::warn!(inst_id = %definition.inst_id, "skipping instrument with bad tick_sz: {e}");
        continue;
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling parse_common_instrument_data (via parse_instrument_with_parser or parse_event_contract_instrument) with an OkxInstrumentDef whose tick_sz is non-empty but not decimal-parseable (e.g. contains scientific notation, units, spaces, or unusual characters from an API schema change).

Common situations: Mocked or hand-crafted instrument JSON in tests; a cached/stale instrument response whose schema changed; OKX introducing a new instrument family with an unexpected tick_sz encoding; manual transcription of tick_sz when building fixtures.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


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