nautechsystems/nautilus_trader · error · anyhow::Error
invalid open price: {e}
Error message
invalid open price: {e} What it means
When converting a Hyperliquid candle into a Nautilus `Bar`, the open price is parsed with `Price::from_decimal_dp(candle.open, price_precision)`. If the decimal string cannot be parsed or does not fit the instrument's price precision, the error is wrapped as "invalid open price". It indicates malformed or precision-incompatible candle data from the REST/WS feed.
Source
Thrown at crates/adapters/hyperliquid/src/data.rs:2074
let ts = UnixNanos::from(entry.time * 1_000_000);
FundingRateUpdate::new(instrument_id, rate, Some(60), None, ts, ts)
}
pub(crate) fn candle_to_bar(
candle: &HyperliquidCandle,
bar_type: BarType,
price_precision: u8,
size_precision: u8,
) -> anyhow::Result<Bar> {
let ts_event = millis_to_nanos(candle.timestamp)?;
let close_boundary = candle
.end_timestamp
.checked_add(1)
.context("candle close boundary overflow")?;
let ts_init = millis_to_nanos(close_boundary)?;
let open = Price::from_decimal_dp(candle.open, price_precision)
.map_err(|e| anyhow::anyhow!("invalid open price: {e}"))?;
let high = Price::from_decimal_dp(candle.high, price_precision)
.map_err(|e| anyhow::anyhow!("invalid high price: {e}"))?;
let low = Price::from_decimal_dp(candle.low, price_precision)
.map_err(|e| anyhow::anyhow!("invalid low price: {e}"))?;
let close = Price::from_decimal_dp(candle.close, price_precision)
.map_err(|e| anyhow::anyhow!("invalid close price: {e}"))?;
let volume = Quantity::from_decimal_dp(candle.volume, size_precision)
.map_err(|e| anyhow::anyhow!("invalid volume: {e}"))?;
Ok(Bar::new(
bar_type, open, high, low, close, volume, ts_event, ts_init,
))
}
/// Request bars from HTTP API.
async fn request_bars_from_http(
http_client: HyperliquidHttpClient,
bar_type: BarType,View on GitHub (pinned to 18893faf8b)
Solutions
- Verify the instrument's price_precision matches the Hyperliquid market (reload instrument definitions).
- Inspect the raw candle payload for the offending `open` value and fix/clean the data source.
- Re-request the candles; transient bad payloads may be exchange-side glitches.
- If feeding custom data, format prices as plain decimal strings within the instrument's precision.
Example fix
// before
let candle = Candle { open: "1.23456789".to_string(), .. };// precision = 2
// after
let candle = Candle { open: "1.23".to_string(), .. }; // matches price_precision Defensive patterns
Strategy: validation
Validate before calling
fn candle_fits_precision(open: &str, price_precision: u8) -> bool {
rust_decimal::Decimal::from_str(open)
.map(|d| d.scale() <= price_precision as u32)
.unwrap_or(false)
}
// call before requesting/accepting candles:
assert!(candle_fits_precision(&candle.open, price_precision)); Try / catch
match result {
Err(e) if e.to_string().contains("invalid open price") => {
tracing::warn!("skipping candle with bad open: {e:#}");
}
r => r?,
} Prevention
- Keep instrument definitions (price_precision) in sync with the exchange.
- Sanitize decimal strings: plain notation, no whitespace, no empty values.
- Round feed prices to the instrument precision before Bar construction in custom pipelines.
When it happens
Trigger: Requesting historical candles whose `open` field is not a valid decimal (empty, NaN-like, scientific notation out of range) or has more decimal places than the instrument's configured price_precision.
Common situations: Wrong instrument precision in local definitions vs the exchange feed; corrupted/manual candle data; new listings where precision config is stale; test fixtures with fake values.
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
- invalid high price: {e}
- invalid low price: {e}
- invalid close price: {e}
- invalid volume: {e}
- invalid candle volume: {e}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/541ad84717d5e5d1.
Report an issue: GitHub.