{"record":{"id":"3af97cddadac98c1","repo":"nautechsystems/nautilus_trader","slug":"position-id-should-be-generated-hedging-oms-type","errorCode":null,"errorMessage":"Position id should be generated. Hedging Oms type order matching engine doesn't exist in cache.","messagePattern":"Position id should be generated\\. Hedging Oms type order matching engine doesn't exist in cache\\.","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/execution/src/matching_engine/ids_generator.rs","lineNumber":167,"sourceCode":"        &mut self,\n        order: &OrderAny,\n        generate: Option<bool>,\n    ) -> Option<PositionId> {\n        let generate = generate.unwrap_or(true);\n\n        if self.oms_type == OmsType::Hedging {\n            {\n                let cache = self.cache.as_ref().borrow();\n                let position_id_result = cache.position_id(&order.client_order_id());\n                if let Some(position_id) = position_id_result {\n                    return Some(position_id.to_owned());\n                }\n            }\n\n            if generate {\n                self.generate_venue_position_id()\n            } else {\n                panic!(\n                    \"Position id should be generated. Hedging Oms type order matching engine doesn't exist in cache.\"\n                )\n            }\n        } else {\n            // Netting OMS (position id will be derived from instrument and strategy)\n            let cache = self.cache.as_ref().borrow();\n            let positions_open = cache.positions_open(\n                None,\n                Some(&order.instrument_id()),\n                Some(&order.strategy_id()),\n                None,\n                None,\n            );\n            positions_open.first().map(|position| position.id)\n        }\n    }\n\n    /// Generates a deterministic trade ID.","sourceCodeStart":149,"sourceCodeEnd":185,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/execution/src/matching_engine/ids_generator.rs#L149-L185","documentation":"The matching engine's position-ID generator could not resolve a position ID for an order under a hedging OMS type. Under hedging mode the position ID normally comes from an existing matching-engine position in the cache; when none exists and generation is not allowed, the engine panics. This means the order reached the matching engine without the preconditions needed for hedging position accounting.","triggerScenarios":"Calling get_position_id (OrderMatchingEngine) for an order whose OMS type is Hedging while the cache holds no position for the instrument/strategy and the `generate` path was not taken (generate=false because a cache lookup was expected).","commonSituations":"Submitting orders to a hedging-mode venue adapter (e.g. Binance Futures/Bybit hedging) before any position exists and with position-ID generation misconfigured; switching an instrument's OMS type between netting and hedging without clearing stale cache state; submitting submits concurrently where the position was just closed.","solutions":["Configure the matching engine/adapter so hedging venues allow venue position-ID generation (check OmsType and position_id generation config for the adapter).","Verify the instrument's OMS type matches the venue reality; use Netting if the venue does not support hedging position IDs for this flow.","Ensure the strategy/instrument cache state is consistent — clear stale cache entries after changing OMS type.","Check adapter-specific config (e.g. `hedge_mode` / `generate_position_id` options) before submitting orders."],"exampleFix":"// before\nlet engine = OrderMatchingEngine::new(..., OmsType::Hedging, ...); // generation disabled\n// after\nlet engine = OrderMatchingEngine::new(..., OmsType::Hedging, ...)\n    .with_generate_venue_position_ids(true); // allow generation when no cached position exists","handlingStrategy":"validation","validationCode":"// before submitting on a hedging venue\nif engine.oms_type() == OmsType::Hedging\n    && cache.position_for(&instrument_id, &strategy_id).is_none()\n    && !venue_supports_position_id_generation\n{\n    return Err(anyhow!(\"hedging venue requires existing position or generation enabled\"));\n}","typeGuard":"fn can_trade_hedging(engine: &OrderMatchingEngine, instrument_id: &InstrumentId) -> bool {\n    engine.oms_type() != OmsType::Hedging || engine.generates_venue_position_ids()\n}","tryCatchPattern":null,"preventionTips":["Match OmsType configuration to the venue's actual position mode (hedge vs one-way).","Enable venue position-ID generation for hedging adapters that support it.","Clear stale cache state after changing OMS type.","Test first order submission on a fresh hedging instrument before going live."],"tags":["rust","matching-engine","hedging","position-id","panic"],"backgroundTag":"invalid-state-transition","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"}