{"record":{"id":"8dced1978007903e","repo":"nautechsystems/nautilus_trader","slug":"missing-trailing-offset-for-trailing-stop-calcul","errorCode":null,"errorMessage":"Missing `trailing_offset` for trailing stop calculation","messagePattern":"Missing `trailing_offset` for trailing stop calculation","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/execution/src/trailing.rs","lineNumber":72,"sourceCode":"        anyhow::bail!(\"Invalid `OrderType` {order_type} for trailing stop calculation\");\n    }\n\n    // Seed from the current trigger only (never the activation price): when the trigger has\n    // not yet materialized it stays `None` here so the offset candidate below becomes the\n    // initial trigger on the first update (matches v1 `TrailingStopCalculator`).\n    let mut trigger_price = trigger_px.or(order.trigger_price());\n\n    let mut limit_price = if order_type == OrderType::TrailingStopLimit {\n        order.price()\n    } else {\n        None\n    };\n\n    let trigger_type = order\n        .trigger_type()\n        .ok_or_else(|| anyhow::anyhow!(\"Missing `TriggerType` for trailing stop calculation\"))?;\n    let trailing_offset = order.trailing_offset().ok_or_else(|| {\n        anyhow::anyhow!(\"Missing `trailing_offset` for trailing stop calculation\")\n    })?;\n    let trailing_offset_type = order.trailing_offset_type().ok_or_else(|| {\n        anyhow::anyhow!(\"Missing `TrailingOffsetType` for trailing stop calculation\")\n    })?;\n    let mut new_trigger_price: Option<Price>;\n    let mut new_limit_price: Option<Price> = None;\n\n    let maybe_move = |current: &mut Option<Price>,\n                      candidate: Price,\n                      better: fn(Price, Price) -> bool|\n     -> Option<Price> {\n        match current {\n            Some(p) if better(candidate, *p) => {\n                *current = Some(candidate);\n                Some(candidate)\n            }\n            None => {\n                *current = Some(candidate);","sourceCodeStart":54,"sourceCodeEnd":90,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/execution/src/trailing.rs#L54-L90","documentation":"trailing_stop_calculate requires a numeric trailing_offset, but `order.trailing_offset()` returned None. Without the offset there is no distance definition for recalculating the trailing stop's trigger price.","triggerScenarios":"Calling trailing_stop_calculate (or update_trailing_stop_order) with an order whose trailing_offset() is None — the order was created without trailing_offset or constructed/deserialized incompletely.","commonSituations":"Omitting trailing_offset in order templates or strategy config; older serialized orders lacking the field; test fixtures building invalid trailing stop orders.","solutions":["Specify trailing_offset (price or percentage per trailing_offset_type) when creating the trailing stop order","Fix the order factory/config so trailing_offset is always set for TrailingStop* orders","Migrate deserialized order payloads to include trailing_offset","In tests, build orders with a valid trailing_offset fixture value"],"exampleFix":"// before\norder = order_factory.trailing_stop_limit(\n    side=OrderSide.BUY, trigger_type=TriggerType.LAST_PRICE,\n)\n// after\norder = order_factory.trailing_stop_limit(\n    side=OrderSide.BUY, trigger_type=TriggerType.LAST_PRICE,\n    trailing_offset=Decimal(\"0.005\"),\n    trailing_offset_type=TrailingOffsetType.BASIS_POINTS,\n)","handlingStrategy":"validation","validationCode":"if order.trailing_offset() is None:\n    raise ValueError(\"Trailing stop order requires trailing_offset\")","typeGuard":"fn has_trailing_offset(order: &OrderAny) -> bool {\n    order.trailing_offset().is_some() && order.trailing_offset_type().is_some()\n}","tryCatchPattern":"match trailing_stop_calculate(order_type, trigger_px, &order, bid, ask, last) {\n    Ok(prices) => apply(prices),\n    Err(e) => { log::error!(\"trailing calc failed: {e}\"); leave_trigger_unchanged() }\n}","preventionTips":["Always provide trailing_offset (and trailing_offset_type) for trailing stop orders","Centralize order construction in a factory that validates trailing-stop fields","Validate order fixtures in tests before invoking the calculator"],"tags":["trailing-stop","missing-field","orders"],"backgroundTag":"missing-required-config-field","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}