{"record":{"id":"2fd093e2c54d32f4","repo":"nautechsystems/nautilus_trader","slug":"trailingstopmarket-requires-trailing-offset-type","errorCode":null,"errorMessage":"TrailingStopMarket requires trailing_offset_type","messagePattern":"TrailingStopMarket requires trailing_offset_type","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/okx/src/execution.rs","lineNumber":893,"sourceCode":"        let price = context.price;\n        let is_reduce_only = context.is_reduce_only;\n\n        let trailing_offset = order.trailing_offset();\n        let trailing_offset_type = order.trailing_offset_type();\n        let activation_price = order.activation_price();\n\n        let close_fraction = get_param_as_string(&cmd.params, \"close_fraction\");\n        let reduce_only = if close_fraction.is_some() {\n            Some(true)\n        } else {\n            Some(is_reduce_only)\n        };\n\n        let (callback_ratio, callback_spread) = if order_type == OrderType::TrailingStopMarket {\n            let offset = trailing_offset\n                .ok_or_else(|| anyhow::anyhow!(\"TrailingStopMarket requires trailing_offset\"))?;\n            let offset_type = trailing_offset_type.ok_or_else(|| {\n                anyhow::anyhow!(\"TrailingStopMarket requires trailing_offset_type\")\n            })?;\n\n            match offset_type {\n                TrailingOffsetType::BasisPoints => {\n                    // Convert basis points to ratio (e.g., 100 bps = 0.01)\n                    let ratio = offset / Decimal::from(10000);\n                    (Some(ratio.to_string()), None)\n                }\n                TrailingOffsetType::Price => (None, Some(offset.to_string())),\n                _ => {\n                    anyhow::bail!(\"Unsupported trailing_offset_type for OKX: {offset_type:?}\");\n                }\n            }\n        } else {\n            (None, None)\n        };\n\n        self.ws_dispatch_state.track_order_context(context);","sourceCodeStart":875,"sourceCodeEnd":911,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/okx/src/execution.rs#L875-L911","documentation":"Along with trailing_offset, a TrailingStopMarket order on OKX requires trailing_offset_type, which tells the adapter how to interpret the offset (BasisPoints -> callback_ratio, price/other units -> callback_spread). Missing it means the adapter cannot choose the OKX parameter encoding, so submission fails.","triggerScenarios":"submit_order -> submit_conditional_order with order_type == TrailingStopMarket and trailing_offset_type == None, even when trailing_offset is provided.","commonSituations":"Strategy sets the numeric offset but forgets the unit; porting from venues where the offset type is implicit; factory helpers that only set one of the two fields.","solutions":["Set trailing_offset_type (e.g. TrailingOffsetType::BasisPoints or Price) whenever trailing_offset is set for TrailingStopMarket.","Use the order factory's trailing_stop_market constructor which takes both parameters.","Add a pre-submit validation in strategy code for trailing orders.","If the desired unit is percent/bps, remember the adapter converts (100 bps = 0.01 ratio)."],"exampleFix":"// before\nlet cmd = ...TrailingStopMarket..., trailing_offset: Some(Decimal::from(50)), trailing_offset_type: None...\n// after\nlet cmd = ...trailing_offset: Some(Decimal::from(50)), trailing_offset_type: Some(TrailingOffsetType::BasisPoints)...","handlingStrategy":"validation","validationCode":"if order_type == OrderType::TrailingStopMarket && trailing_offset_type.is_none() {\n    return Err(anyhow::anyhow!(\n        \"TrailingStopMarket requires trailing_offset_type\"\n    ));\n}","typeGuard":"fn has_offset_type(t: &TrailingOffsetType) -> bool { true } // prefer Option::is_some check","tryCatchPattern":null,"preventionTips":["Pair trailing_offset with trailing_offset_type at the strategy layer, never separately.","Use the order factory constructor that accepts both parameters.","Document the unit semantics (bps -> ratio, price -> spread) in strategy config."],"tags":["okx","order-submission","trailing-stop","missing-parameter"],"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"}