{"record":{"id":"7dcd513d126ecfc2","repo":"nautechsystems/nautilus_trader","slug":"ask-required-7dcd51","errorCode":null,"errorMessage":"Ask required","messagePattern":"Ask required","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/execution/src/trailing.rs","lineNumber":137,"sourceCode":"\n    match trigger_type {\n        TriggerType::LastPrice | TriggerType::MarkPrice => {\n            let last = last.ok_or(OrderError::InvalidStateTransition)?;\n            let cand_trigger = compute(trailing_offset, last)?;\n            new_trigger_price = maybe_move(&mut trigger_price, cand_trigger, better_trigger);\n\n            if order_type == OrderType::TrailingStopLimit {\n                let limit_offset = order.limit_offset().ok_or_else(|| {\n                    anyhow::anyhow!(\"Missing `limit_offset` for trailing stop limit calculation\")\n                })?;\n                let cand_limit = compute(limit_offset, last)?;\n                new_limit_price = maybe_move(&mut limit_price, cand_limit, better_limit);\n            }\n        }\n        TriggerType::Default | TriggerType::BidAsk | TriggerType::LastOrBidAsk => {\n            let (bid, ask) = (\n                bid.ok_or_else(|| anyhow::anyhow!(\"Bid required\"))?,\n                ask.ok_or_else(|| anyhow::anyhow!(\"Ask required\"))?,\n            );\n            let basis = match order_side {\n                OrderSide::Buy => ask,\n                OrderSide::Sell => bid,\n            };\n            let cand_trigger = compute(trailing_offset, basis)?;\n            new_trigger_price = maybe_move(&mut trigger_price, cand_trigger, better_trigger);\n\n            if order_type == OrderType::TrailingStopLimit {\n                let limit_offset = order.limit_offset().ok_or_else(|| {\n                    anyhow::anyhow!(\"Missing `limit_offset` for trailing stop limit calculation\")\n                })?;\n                let cand_limit = compute(limit_offset, basis)?;\n                new_limit_price = maybe_move(&mut limit_price, cand_limit, better_limit);\n            }\n\n            if trigger_type == TriggerType::LastOrBidAsk {\n                let last = last.ok_or_else(|| anyhow::anyhow!(\"Last required\"))?;","sourceCodeStart":119,"sourceCodeEnd":155,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/execution/src/trailing.rs#L119-L155","documentation":"Same quote-dependency as the 'Bid required' error: for `TriggerType::Default`, `BidAsk`, or `LastOrBidAsk` the trailing basis is the ask (for Buy side) or bid (for Sell side), and both quotes must be supplied. Here `ask: Option<Price>` was `None`, so the calculation cannot proceed and returns this anyhow error.","triggerScenarios":"Calling `trailing_stop_calculate`/`update_trailing_stop_order` with `trigger_type` in {Default, BidAsk, LastOrBidAsk} and `ask: None` — typical when only the bid side of the book is populated or no ask quote has been received yet.","commonSituations":"Fresh instrument subscription where the ask hasn't arrived; one-sided/illiquid book; feed disruption dropping ask updates; strategy passing only trade data while the order expects quotes.","solutions":["Pass the current `ask` (and `bid`) from the quote cache when invoking the calculator.","Defer the update until both bid and ask are present: check `ask.is_some() && bid.is_some()` before calling.","Use a `LastPrice`/`MarkPrice` trigger type instead if only last-trade data is reliably available.","Verify the market-data subscription is configured for quotes on the instrument."],"exampleFix":"// before\nlet result = trailing_stop_calculate(increment, None, &order, bid, None, last)?;\n// after\nif let (Some(bid), Some(ask)) = (bid, ask) {\n    let result = trailing_stop_calculate(increment, None, &order, Some(bid), Some(ask), last)?;\n} else {\n    // defer update until quotes available\n}","handlingStrategy":"validation","validationCode":"fn ask_available(ask: Option<Price>, trigger_type: TriggerType) -> Result<(), String> {\n    if matches!(trigger_type, TriggerType::Default | TriggerType::BidAsk | TriggerType::LastOrBidAsk)\n        && ask.is_none()\n    {\n        return Err(\"ask quote not yet available; defer trailing update\".into());\n    }\n    Ok(())\n}","typeGuard":null,"tryCatchPattern":"if let Err(e) = update_trailing_stop_order(&mut order, bid, ask, last) {\n    if e.to_string().contains(\"Ask required\") {\n        // retry on next quote tick\n        return Ok(());\n    }\n    return Err(e.into());\n}","preventionTips":["Guard with `bid.is_some() && ask.is_some()` before invoking the trailing calculation.","Ensure quote subscriptions are established and warmed up before arming trailing stop orders.","Monitor feed health: a persistent missing ask usually indicates a subscription or venue connectivity issue."],"tags":["rust","trailing-stop","missing-quote","market-data"],"backgroundTag":"missing-required-argument","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}