nautechsystems/nautilus_trader · error · anyhow::Error
Oracle price required for market orders
Error message
Oracle price required for market orders
What it means
Market orders on dYdV v4 are submitted as limit orders at a worst-case price derived from the oracle price plus a slippage buffer. This error is thrown when the builder has no oracle price set, so the worst-case subticks price cannot be computed.
Source
Thrown at crates/adapters/dydx/src/grpc/order.rs:175
result
.to_u64()
.ok_or_else(|| anyhow::anyhow!("Failed to convert quantity to u64"))
}
/// A `round`-like function that quantizes a `value` to the `fraction`.
fn quantize(value: &Decimal, fraction: &Decimal) -> Decimal {
(value / fraction).round() * fraction
}
/// Compute worst-case subticks for a market order using oracle price + slippage.
///
/// # Errors
///
/// Returns an error if oracle price is not available or conversion fails.
pub fn market_order_subticks(&self, side: OrderSide) -> Result<u64, anyhow::Error> {
let oracle = self
.oracle_price
.ok_or_else(|| anyhow::anyhow!("Oracle price required for market orders"))?;
let worst_price = match side {
OrderSide::Buy => oracle * (Decimal::ONE + DEFAULT_MARKET_ORDER_SLIPPAGE),
OrderSide::Sell => oracle * (Decimal::ONE - DEFAULT_MARKET_ORDER_SLIPPAGE),
_ => oracle,
};
self.quantize_price(worst_price)
}
/// Get orderbook pair id.
#[must_use]
pub fn clob_pair_id(&self) -> u32 {
self.clob_pair_id
}
}
/// [`Order`] builder.
///
/// Note that the price input to the `OrderBuilder` is in the "common" units of the perpetual/currency,View on GitHub (pinned to 18893faf8b)
Solutions
- Set the oracle price on the builder (or ensure the adapter populates it from the price cache) before building market orders
- Wait until a price for the instrument exists (check the cache) and retry
- Fall back to a bounded limit order at a manually supplied price if oracle data is unavailable
- Verify the instrument id matches the one the oracle publishes for, so the lookup is not silently empty
Example fix
// before
let order = OrderBuilder::new(params)
.order_type(OrderType::Market)
.side(OrderSide::Buy)
.build()?;
// after
let oracle = price_cache.get(params.clob_pair_id)
.ok_or_else(|| anyhow::anyhow!("no oracle price yet for {}", params.clob_pair_id))?;
let order = OrderBuilder::new(params)
.order_type(OrderType::Market)
.side(OrderSide::Buy)
.oracle_price(oracle)
.build()?; Defensive patterns
Strategy: validation
Validate before calling
let oracle = price_cache.get(instrument_id)
.ok_or_else(|| anyhow::anyhow!("oracle price unavailable for {}", instrument_id))?;
anyhow::ensure!(oracle > Decimal::ZERO, "oracle price must be positive"); Type guard
fn has_oracle_price(b: &OrderBuilder) -> bool {
b.oracle_price.map(|p| p > Decimal::ZERO).unwrap_or(false)
} Try / catch
match builder.build() {
Ok(order) => submit(order).await?,
Err(e) if e.to_string().contains("Oracle price required") => {
// defer order until price feed warms up
}
Err(e) => return Err(e),
} Prevention
- Wait for at least one oracle/price update before allowing market orders
- Check price cache freshness before submitting market orders
- Fall back to a limit order with an explicit price when oracle data is missing
When it happens
Trigger: Calling market_order_subticks (or building a Market / StopMarket / MarketIfTouched order via OrderBuilder::build) when OrderBuilder.oracle_price is None.
Common situations: Submitting a market order before subscribing to or fetching the market's oracle/price data; a race where the price feed has not delivered the first update yet; cache miss in the price provider; building an order in a disconnected or cold-start state.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- Take profit limit order missing limit price
- Invalid order side: {e}
- slots lock poisoned
- missing limit price for order {} (market orders require an e
- partitioned cancel failed: {}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/db049229d9630d72.
Report an issue: GitHub.