{"record":{"id":"e16e53e5a7bceda1","repo":"nautechsystems/nautilus_trader","slug":"take-profit-sell-trigger-price-trigger-price-m","errorCode":null,"errorMessage":"Take profit sell trigger_price ({trigger_price}) must be >= limit price ({price})","messagePattern":"Take profit sell trigger_price \\((.+?)\\) must be >= limit price \\((.+?)\\)","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/adapters/dydx/src/http/parse.rs","lineNumber":271,"sourceCode":"                }\n                OrderSide::Sell if trigger_price > price => {\n                    anyhow::bail!(\n                        \"Stop sell trigger_price ({trigger_price}) must be <= limit price ({price})\"\n                    );\n                }\n                _ => {}\n            }\n        }\n        DydxOrderType::TakeProfitLimit | DydxOrderType::TakeProfitMarket => {\n            // Take profit: trigger when price rises (sell) or falls (buy)\n            match side {\n                OrderSide::Buy if trigger_price > price => {\n                    anyhow::bail!(\n                        \"Take profit buy trigger_price ({trigger_price}) must be <= limit price ({price})\"\n                    );\n                }\n                OrderSide::Sell if trigger_price < price => {\n                    anyhow::bail!(\n                        \"Take profit sell trigger_price ({trigger_price}) must be >= limit price ({price})\"\n                    );\n                }\n                _ => {}\n            }\n        }\n        _ => {}\n    }\n\n    Ok(())\n}\n\n/// Parses a dYdX perpetual market into a Nautilus [`InstrumentAny`].\n///\n/// dYdX v4 only supports perpetual markets, so this function creates a\n/// [`CryptoPerpetual`] instrument with the appropriate fields mapped from\n/// the dYdX market definition.\n///","sourceCodeStart":253,"sourceCodeEnd":289,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/dydx/src/http/parse.rs#L253-L289","documentation":"The dYdX adapter validates conditional (take-profit) orders before submitting them. For a take-profit SELL, the trigger price must be at or above the limit price, otherwise the order could never fill sensibly; validate_conditional_order bails with anyhow when this invariant is violated.","triggerScenarios":"Calling validate_conditional_order (or submitting a TAKE_PROFIT limit order through the dYdX adapter) with OrderSide::Sell and trigger_price < price. Note the buy case has the mirror-image rule (trigger <= limit).","commonSituations":"Computing the trigger from a percentage move but forgetting the limit price uses a different reference; mixing up buy/sell TP rules; hardcoding prices in tests or configs; sign conventions from another venue carried over to dYdX.","solutions":["Ensure trigger_price >= price for sell-side take-profit orders before calling the API.","If you actually want trigger below the limit for a sell, you need a stop-limit (OrderSide::Sell stop) not a take-profit.","Swap prices or fix the side if you accidentally built a sell TP with buy semantics (buy requires trigger <= price)."],"exampleFix":"// before\nlet trigger = price!(100);\nlet limit = price!(110);\nvalidate_conditional_order(OrderSide::Sell, trigger, limit)?;\n// after\nlet trigger = price!(120); // sell TP: trigger must be >= limit\nvalidate_conditional_order(OrderSide::Sell, trigger, limit)?;","handlingStrategy":"validation","validationCode":"fn is_valid_take_profit(side: OrderSide, trigger: Price, limit: Price) -> bool {\n    match side {\n        OrderSide::Buy => trigger <= limit,\n        OrderSide::Sell => trigger >= limit,\n        _ => false,\n    }\n}\nif !is_valid_take_profit(side, trigger_price, price) { return Err(/* fix before submit */); }","typeGuard":null,"tryCatchPattern":"match validate_conditional_order(side, trigger, limit) {\n    Ok(()) => submit(order),\n    Err(e) => log::warn!(\"conditional order rejected: {e}\"), // adjust trigger/limit\n}","preventionTips":["Encode the buy/sell trigger-vs-limit rules in a shared helper used everywhere TPs are built.","Derive trigger and limit from the same reference price.","Add unit tests mirroring the adapter's validation for both sides."],"tags":["order-validation","dydx","rust","conditional-orders"],"backgroundTag":"invalid-argument-value","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"}