nautechsystems/nautilus_trader · error · anyhow::Error
Invalid peg_offset_value: {s}
Error message
Invalid peg_offset_value: {s} What it means
parse_peg_offset_value reads the optional peg_offset_value string from order command Params and parses it as f64. A present value that is not a valid f64 number produces this error, preventing a malformed peg offset from being sent to BitMEX.
Source
Thrown at crates/adapters/bitmex/src/common/parse.rs:522
Some(s) => BitmexPegPriceType::from_str(s)
.map(Some)
.map_err(|_| anyhow::anyhow!("Invalid peg_price_type: {s}")),
None => Ok(None),
}
}
/// Extracts the peg offset value from order command parameters.
///
/// # Errors
///
/// Returns an error if the value is present but not a valid `f64`.
pub fn parse_peg_offset_value(params: Option<&Params>) -> anyhow::Result<Option<f64>> {
let value = params.and_then(|p| p.get_str("peg_offset_value"));
match value {
Some(s) => s
.parse::<f64>()
.map(Some)
.map_err(|_| anyhow::anyhow!("Invalid peg_offset_value: {s}")),
None => Ok(None),
}
}
/// Derives a deterministic [`TradeId`] for BitMEX trades that arrive without a
/// `trdMatchID` (e.g. certain historical or bucketed rows).
///
/// The hash combines the symbol, timestamp, price, size, and side so replayed
/// data yields the same identifier across runs. FNV-1a is stable across
/// architectures and crate versions; the 0x1f delimiter keeps variable-length
/// fields from colliding.
#[must_use]
pub fn derive_trade_id(
symbol: Ustr,
ts_event_ns: u64,
price: f64,
size: i64,
side: Option<BitmexSide>,View on GitHub (pinned to 18893faf8b)
Solutions
- Pass peg_offset_value as a plain numeric string, e.g. "0.005"
- Convert Decimal/price values with a plain to_string (no thousands separators or suffixes) before inserting into Params
- Validate the value parses as f64 before submitting
Example fix
// before
params.insert("peg_offset_value", format!("{} bps", offset_bps));
// after
params.insert("peg_offset_value", (offset_bps as f64 / 10000.0).to_string()); Defensive patterns
Strategy: validation
Validate before calling
fn peg_offset_ok(s: &str) -> bool { s.trim().parse::<f64>().is_ok() } Type guard
fn is_numeric_string(s: &str) -> bool { s.parse::<f64>().is_ok() } Try / catch
match client.submit_order(order) {
Err(e) if e.to_string().starts_with("Invalid peg_offset_value") => {
log::error!("peg_offset_value must be a plain f64 string: {e}");
}
r => r?,
} Prevention
- Always serialize numeric params with plain to_string() (no units, commas, or suffixes)
- Parse-validate config values once at strategy startup
- Use f64/Decimal types end-to-end instead of formatted strings
When it happens
Trigger: Submitting an order with peg_offset_value in Params set to a non-numeric string (e.g. "10 bps", "1,000", empty string).
Common situations: Strategies formatting the offset with units or locale separators; passing a Decimal-formatted value with commas; wiring a config string directly into Params.
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 peg_price_type: {s}
- Unsupported `OrderSide` for Binance: {value:?}
- Invalid order side: {e}
- Unsupported time in force: {:?}, AX supports GTC, IOC, and D
- AX does not support reduce-only orders
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/84a8ee9c5a0ad722.
Report an issue: GitHub.