bybit/models/
order_request.rs

1use crate::prelude::*;
2
3/// Represents a request to place an order on Bybit's trading platform.
4///
5/// The `OrderRequest` struct encapsulates all parameters needed to create an order,
6/// supporting both spot and perpetual futures trading. Perpetual futures on Bybit
7/// allow leveraged trading without expiration, with funding rates balancing long and
8/// short positions. Bots using this struct must handle fields carefully to align with
9/// trading strategies, manage risk (e.g., take-profit/stop-loss), and comply with
10/// Bybit's API constraints (e.g., valid symbol, quantity precision). Incorrect
11/// configurations can lead to order rebing, insufficient margin, or unintended
12/// liquidations.
13#[derive(Clone, Default, Serialize)]
14pub struct OrderRequest<'a> {
15    /// The category of the trading product (e.g., Spot, Linear for perpetual futures).
16    ///
17    /// Bybit organizes trading into categories like Spot (cash trading) and Linear
18    /// (USDT-margined perpetual futures). For perpetual futures, `Linear` is commonly
19    /// used, supporting symbols like BTCUSDT. Bots must set this correctly to target
20    /// the intended market. Misconfiguring the category can result in API errors or
21    /// orders placed in the wrong market, disrupting strategy execution.
22    pub category: Category,
23
24    /// The trading pair symbol, e.g., "BTCUSDT".
25    ///
26    /// The symbol identifies the asset pair being traded, such as BTCUSDT for Bitcoin
27    /// against USDT. In perpetual futures, symbols are typically USDT-margined (Linear).
28    /// Bots must ensure the symbol is valid and supported by Bybit, as invalid symbols
29    /// lead to order rejection. Additionally, each symbol has specific contract details
30    /// (e.g., tick size, quantity precision), which bots should validate to avoid errors.
31    pub symbol: Cow<'a, str>,
32
33    /// Indicates if the order uses leverage (true for margin trading, false otherwise).
34    ///
35    /// Leverage allows traders to amplify positions with borrowed funds, common in
36    /// perpetual futures. For example, 10x leverage means a $1,000 position controls
37    /// $10,000 of assets. Bots must set this field based on the account's margin mode
38    /// (isolated or cross) and risk tolerance. High leverage increases potential returns
39    /// but also liquidation risk if prices move adversely. Bots should monitor margin
40    /// levels to avoid forced liquidations.
41    pub is_leverage: Option<bool>,
42
43    /// The side of the order (Buy or Sell).
44    ///
45    /// Specifies whether the order is to buy (long) or sell (short). In perpetual
46    /// futures, Buy orders open long positions or close short ones, while Sell orders
47    /// open short positions or close long ones. Bots must align the side with their
48    /// market outlook and position management strategy. Incorrect sides can lead to
49    /// unintended exposure, so bots should include validation logic.
50    pub side: Side,
51
52    /// The type of order (Limit or Market).
53    ///
54    /// Determines how the order is executed. Limit orders specify a price, while Market
55    /// orders execute at the best available price. In volatile perpetual futures markets,
56
57    /// Market orders risk slippage, while Limit orders may not execute if the price moves
58    /// away. Bots should choose based on strategy goals (e.g., speed vs. price control)
59    /// and account for Bybit's fee structure (maker vs. taker fees).
60    pub order_type: OrderType,
61
62    /// The quantity of the asset to trade.
63    ///
64    /// Represents the size of the order, typically in the base asset (e.g., BTC for
65    /// BTCUSDT). In perpetual futures, quantity must adhere to Bybit's minimum and
66    /// maximum limits, which vary by symbol. Bots must validate quantity against account
67    /// balance, margin requirements, and symbol constraints to avoid rejections. Overly
68    /// large quantities can trigger liquidations if the market moves against the position.
69    pub qty: f64,
70
71    /// The unit for market orders (optional, used in specific cases).
72    ///
73    /// Some Bybit markets allow specifying quantities in alternative units (e.g., USDT
74    /// for Linear contracts). This field is typically used for market orders in specific
75    /// trading modes. Bots should consult Bybit's API documentation for symbol-specific
76    /// requirements, as incorrect units can cause order failures. Most strategies leave
77    /// this as `None` unless explicitly required.
78    pub market_unit: Option<f64>,
79
80    /// The price at which to place a limit order (optional for market orders).
81    ///
82    /// For Limit orders, this specifies the target price. For Market orders, it’s
83    /// typically `None`. In perpetual futures, price must align with the symbol’s tick
84    /// size (e.g., $0.5 for BTCUSDT). Bots should validate prices against current market
85    /// conditions to ensure orders are realistic. Setting prices too far from the market
86    /// can prevent execution, while tight prices risk being filled at suboptimal levels.
87    pub price: Option<f64>,
88
89    /// The direction of the trigger price (true for rising, false for falling).
90    ///
91    /// Used for conditional orders (e.g., stop or take-profit orders), indicating whether
92    /// the trigger activates when the price rises or falls. For example, a stop-loss
93    /// might trigger when the price falls below a threshold. Bots must set this correctly
94    /// to align with the intended risk management strategy. Incorrect directions can lead
95    /// to premature or missed triggers, impacting profitability.
96    pub trigger_direction: Option<bool>,
97
98    /// A filter to specify the order type (e.g., "tpslOrder" for take-profit/stop-loss).
99    ///
100    /// Bybit uses order filters to categorize special order types, such as take-profit/
101    /// stop-loss (TPSL) orders. For example, setting `order_filter` to "tpslOrder"
102    /// indicates the order is part of a TPSL strategy. Bots must use valid filter values
103    /// as per Bybit’s API to avoid rejections. This field is crucial for automated risk
104    /// management in perpetual futures, where volatility necessitates robust controls.
105    pub order_filter: Option<Cow<'a, str>>,
106
107    /// The price at which a conditional order is triggered.
108    ///
109    /// Specifies the price level that activates a conditional order (e.g., stop-loss or
110    /// take-profit). In perpetual futures, trigger prices are critical for risk management,
111
112    /// as they define exit points for profitable or losing positions. Bots should set
113    /// trigger prices based on technical analysis or risk thresholds, ensuring they align
114    /// with market volatility and symbol tick sizes to avoid invalid orders.
115    pub trigger_price: Option<f64>,
116
117    /// The price type for triggering the order (e.g., "LastPrice", "IndexPrice").
118    ///
119    /// Defines which price metric (e.g., last traded price, index price, or mark price)
120    /// triggers a conditional order. In perpetual futures, Bybit uses different price
121    /// types to account for market manipulation or volatility. For example, "MarkPrice"
122    /// is less susceptible to spoofing than "LastPrice". Bots must choose the appropriate
123    /// trigger type to ensure reliable execution, especially in high-frequency trading.
124    pub trigger_by: Option<Cow<'a, str>>,
125
126    /// The implied volatility for options orders (optional, not used in perpetual futures).
127    ///
128    /// While not typically used in perpetual futures, this field applies to options
129    /// trading on Bybit, representing the expected volatility of the underlying asset.
130    /// Bots trading perpetual futures can ignore this field, but those expanding to
131    /// options must calculate or source accurate volatility data to set this correctly.
132    pub order_iv: Option<f64>,
133
134    /// The time-in-force policy for the order.
135    ///
136    /// Specifies how long the order remains active (e.g., GTC, IOC). In perpetual
137    /// futures, TIF affects execution strategy and fees. For example, PostOnly orders
138    /// optimize for maker fees but may not execute in fast markets. Bots should select
139    /// TIF based on market conditions and strategy goals, ensuring compatibility with
140    /// Bybit’s API requirements.
141    pub time_in_force: Option<Cow<'a, str>>,
142
143    /// The position index for futures (0 for one-way, 1 or 2 for hedge mode).
144    ///
145    /// In Bybit’s perpetual futures, position index distinguishes between one-way mode
146    /// (0) and hedge mode (1 for long, 2 for short). Hedge mode allows simultaneous long
147    /// and short positions on the same symbol. Bots must set this correctly based on the
148    /// account’s position mode to avoid order rejections. Mismanaging position index can
149    /// lead to unintended position netting or increased margin requirements.
150    pub position_idx: Option<u8>,
151
152    /// A user-defined identifier for the order.
153    ///
154    /// Allows bots to tag orders with a custom ID for tracking and management. In
155    /// perpetual futures, where multiple orders may be active, `order_link_id` helps
156    /// bots correlate API responses with specific strategies. Bots should use unique,
157
158    /// descriptive IDs to avoid confusion and ensure robust order tracking.
159    pub order_link_id: Option<Cow<'a, str>>,
160
161    /// The take-profit price for the order.
162    ///
163    /// Sets the price at which a position is automatically closed to lock in profits.
164    /// In perpetual futures, take-profit (TP) is essential for risk management, allowing
165    /// bots to exit positions at predefined profit levels. Bots should calculate TP based
166    /// on market analysis and risk-reward ratios, ensuring the price is realistic given
167    /// volatility and tick size constraints.
168    pub take_profit: Option<f64>,
169
170    /// The stop-loss price for the order.
171    ///
172    /// Sets the price at which a position is closed to limit losses. In perpetual futures,
173
174    /// stop-loss (SL) is critical to prevent significant drawdowns, especially with
175    /// leverage. Bots should set SL based on risk tolerance and market volatility, ensuring
176    /// it’s not too tight (risking premature exit) or too loose (risking large losses).
177    pub stop_loss: Option<f64>,
178
179    /// The price type for triggering take-profit (e.g., "LastPrice", "MarkPrice").
180    ///
181    /// Specifies which price metric triggers the take-profit order. Choosing the right
182    /// trigger type is crucial in perpetual futures to avoid manipulation-driven triggers.
183    /// Bots should prefer stable metrics like "MarkPrice" for reliability, especially in
184    /// volatile markets.
185    pub tp_trigger_by: Option<Cow<'a, str>>,
186
187    /// The price type for triggering stop-loss (e.g., "LastPrice", "MarkPrice").
188    ///
189    /// Specifies which price metric triggers the stop-loss order. Similar to `tp_trigger_by`,
190
191    /// bots should select a reliable trigger type to ensure stop-loss activates as intended,
192
193    /// protecting against adverse price movements in perpetual futures.
194    pub sl_trigger_by: Option<Cow<'a, str>>,
195
196    /// Indicates if the order reduces an existing position (true) or opens a new one (false).
197    ///
198    /// In perpetual futures, `reduce_only` ensures an order only closes an existing
199    /// position, preventing unintended increases in exposure. Bots must set this correctly
200    /// when closing positions to avoid accidentally opening opposing positions, which could
201    /// increase margin requirements or trigger liquidations.
202    pub reduce_only: Option<bool>,
203
204    /// Indicates if the order closes the position when triggered (used for stop orders).
205    ///
206    /// When `true`, the order closes the position upon triggering, typically used for
207    /// stop-loss or take-profit orders. In perpetual futures, this helps bots manage risk
208    /// by ensuring automatic position closure at predefined levels. Bots should enable
209    /// this for risk-limiting orders to prevent unintended position retention.
210    pub close_on_trigger: Option<bool>,
211
212    /// The type of self-match prevention (optional, for institutional traders).
213    ///
214    /// Self-match prevention (SMP) prevents a trader’s own orders from matching against
215    /// each other, which could manipulate market perception. In perpetual futures, this
216    /// is relevant for large or institutional bots to comply with exchange rules. Most
217    /// retail bots can leave this as `None` unless operating at scale.
218    pub smp_type: Option<Cow<'a, str>>,
219
220    /// Indicates if the order uses market maker protection (optional).
221    ///
222    /// Market maker protection (MMP) prevents rapid liquidations for market makers by
223    /// adjusting order execution. In perpetual futures, this is typically used by advanced
224    /// bots providing liquidity. Retail bots can usually ignore this field unless
225    /// participating in Bybit’s market maker program.
226    pub mmp: Option<bool>,
227
228    /// The take-profit/stop-loss mode (e.g., "Full", "Partial").
229    ///
230    /// Specifies whether TP/SL applies to the entire position ("Full") or a portion
231    /// ("Partial"). In perpetual futures, "Full" ensures complete position closure at
232    /// TP/SL levels, while "Partial" allows scaling out. Bots should choose based on
233    /// strategy; "Full" is simpler for risk management, while "Partial" suits complex
234    /// exit strategies.
235    pub tpsl_mode: Option<Cow<'a, str>>,
236
237    /// The limit price for take-profit orders (for limit TP orders).
238    ///
239    /// Specifies the exact price for a limit-based take-profit order. In perpetual futures,
240
241    /// this allows precise profit-taking but risks non-execution if the market doesn’t
242    /// reach the price. Bots should set this based on market depth and volatility to
243    /// balance execution likelihood and profitability.
244    pub tp_limit_price: Option<f64>,
245
246    /// The limit price for stop-loss orders (for limit SL orders).
247    ///
248    /// Specifies the exact price for a limit-based stop-loss order. Similar to
249    /// `tp_limit_price`, bots must balance precision with execution risk, ensuring the
250    /// price is achievable in volatile perpetual futures markets to protect against losses.
251    pub sl_limit_price: Option<f64>,
252
253    /// The order type for take-profit (e.g., "Market", "Limit").
254    ///
255    /// Defines whether the take-profit order executes as a Market or Limit order. Market
256    /// TP ensures execution but risks slippage, while Limit TP offers price control but
257    /// may not fill. Bots should choose based on market conditions and strategy priorities
258    /// in perpetual futures trading.
259    pub tp_order_type: Option<Cow<'a, str>>,
260
261    /// The order type for stop-loss (e.g., "Market", "Limit").
262    ///
263    /// Defines whether the stop-loss order executes as a Market or Limit order. Similar
264    /// to `tp_order_type`, bots must weigh execution speed against price control, as
265    /// Market SL orders ensure loss limitation but may incur slippage in volatile markets.
266    pub sl_order_type: Option<Cow<'a, str>>,
267}
268
269impl<'a> OrderRequest<'a> {
270    /// Creates a default `OrderRequest` with predefined values.
271    ///
272    /// Initializes an order request with common defaults (e.g., Linear category,
273
274    /// BTCUSDT symbol, Market order). Bots can use this as a starting point and modify
275    /// fields as needed. Ensure all required fields are set before submitting to Bybit’s API.
276    pub fn default() -> Self {
277        Self {
278            category: Category::Linear,
279            symbol: Cow::Borrowed("BTCUSDT"),
280            is_leverage: None,
281            side: Side::default(),
282            order_type: OrderType::Market,
283            qty: 0.00,
284            market_unit: None,
285            price: None,
286            trigger_direction: None,
287            order_filter: None,
288            trigger_price: None,
289            trigger_by: None,
290            order_iv: None,
291            time_in_force: None,
292            position_idx: None,
293            order_link_id: None,
294            take_profit: None,
295            stop_loss: None,
296            tp_trigger_by: None,
297            sl_trigger_by: None,
298            reduce_only: None,
299            close_on_trigger: None,
300            smp_type: None,
301            mmp: None,
302            tpsl_mode: None,
303            tp_limit_price: None,
304            sl_limit_price: None,
305            tp_order_type: None,
306            sl_order_type: None,
307        }
308    }
309    /// Creates a custom `OrderRequest` with specified parameters.
310    ///
311    /// Allows bots to construct an order request with full control over all fields.
312    /// Ensure all parameters comply with Bybit’s API constraints (e.g., valid symbol,
313
314    /// quantity precision) to avoid rejections. This method is ideal for tailored
315    /// strategies in perpetual futures trading.
316    pub fn custom(
317        category: Category,
318        symbol: &'a str,
319        leverage: Option<bool>,
320        side: Side,
321        order_type: OrderType,
322        qty: f64,
323        market_unit: Option<f64>,
324        price: Option<f64>,
325        trigger_direction: Option<bool>,
326        order_filter: Option<&'a str>,
327        trigger_price: Option<f64>,
328        trigger_by: Option<&'a str>,
329        order_iv: Option<f64>,
330        time_in_force: Option<&'a str>,
331        position_idx: Option<u8>,
332        order_link_id: Option<&'a str>,
333        take_profit: Option<f64>,
334        stop_loss: Option<f64>,
335        tp_trigger_by: Option<&'a str>,
336        sl_trigger_by: Option<&'a str>,
337        reduce_only: Option<bool>,
338        close_on_trigger: Option<bool>,
339        smp_type: Option<&'a str>,
340        mmp: Option<bool>,
341        tpsl_mode: Option<&'a str>,
342        tp_limit_price: Option<f64>,
343        sl_limit_price: Option<f64>,
344        tp_order_type: Option<&'a str>,
345        sl_order_type: Option<&'a str>,
346    ) -> Self {
347        Self {
348            category,
349            symbol: Cow::Borrowed(symbol),
350            is_leverage: leverage,
351            side,
352            order_type,
353            qty,
354            market_unit,
355            price,
356            trigger_direction,
357            order_filter: order_filter.map(Cow::Borrowed),
358            trigger_price,
359            trigger_by: trigger_by.map(Cow::Borrowed),
360            order_iv,
361            time_in_force: time_in_force.map(Cow::Borrowed),
362            position_idx,
363            order_link_id: order_link_id.map(Cow::Borrowed),
364            take_profit,
365            stop_loss,
366            tp_trigger_by: tp_trigger_by.map(Cow::Borrowed),
367            sl_trigger_by: sl_trigger_by.map(Cow::Borrowed),
368            reduce_only,
369            close_on_trigger,
370            smp_type: smp_type.map(Cow::Borrowed),
371            mmp,
372            tpsl_mode: tpsl_mode.map(Cow::Borrowed),
373            tp_limit_price,
374            sl_limit_price,
375            tp_order_type: tp_order_type.map(Cow::Borrowed),
376            sl_order_type: sl_order_type.map(Cow::Borrowed),
377        }
378    }
379    /// Creates a spot limit order with market-based take-profit and stop-loss.
380    ///
381    /// Constructs a spot limit order with predefined TP/SL executed as market orders.
382    /// Suitable for spot trading strategies aiming for precise entry prices with
383    /// automated exits. Bots should ensure TP/SL prices are set appropriately to balance
384    /// risk and reward.
385    pub fn spot_limit_with_market_tpsl(
386        symbol: &'a str,
387        side: Side,
388        qty: f64,
389        price: f64,
390        tp: f64,
391        sl: f64,
392    ) -> Self {
393        Self {
394            category: Category::Spot,
395            symbol: Cow::Borrowed(symbol),
396            side,
397            order_type: OrderType::Limit,
398            qty,
399            price: Some(price),
400            time_in_force: Some(Cow::Borrowed(TimeInForce::PostOnly.as_str())),
401            take_profit: Some(tp),
402            stop_loss: Some(sl),
403            tp_order_type: Some(Cow::Borrowed("Market")),
404            sl_order_type: Some(Cow::Borrowed("Market")),
405            ..Self::default()
406        }
407    }
408    /// Creates a spot limit order with limit-based take-profit and stop-loss.
409    ///
410    /// Constructs a spot limit order with TP/SL executed as limit orders for precise
411    /// exit prices. Ideal for strategies prioritizing price control over execution
412    /// certainty. Bots must ensure TP/SL prices are achievable given market conditions.
413    pub fn spot_limit_with_limit_tpsl(
414        symbol: &'a str,
415        side: Side,
416        qty: f64,
417        price: f64,
418        tp: f64,
419        sl: f64,
420    ) -> Self {
421        Self {
422            category: Category::Spot,
423            symbol: Cow::Borrowed(symbol),
424            side,
425            order_type: OrderType::Limit,
426            qty,
427            price: Some(price),
428            time_in_force: Some(Cow::Borrowed(TimeInForce::PostOnly.as_str())),
429            take_profit: Some(tp),
430            stop_loss: Some(sl),
431            tp_limit_price: Some(tp),
432            sl_limit_price: Some(sl),
433            tp_order_type: Some(Cow::Borrowed("Limit")),
434            sl_order_type: Some(Cow::Borrowed("Limit")),
435            ..Self::default()
436        }
437    }
438    /// Creates a spot post-only limit order.
439    ///
440    /// Constructs a spot limit order that only adds liquidity (maker order). Useful for
441    /// minimizing fees but risks non-execution if the market moves away. Bots should
442    /// monitor order book depth to ensure the price is competitive.
443    pub fn spot_postonly(symbol: &'a str, side: Side, qty: f64, price: f64) -> Self {
444        Self {
445            category: Category::Spot,
446            symbol: Cow::Borrowed(symbol),
447            side,
448            order_type: OrderType::Limit,
449            qty,
450            price: Some(price),
451            time_in_force: Some(Cow::Borrowed(TimeInForce::PostOnly.as_str())),
452            ..Self::default()
453        }
454    }
455    /// Creates a spot take-profit/stop-loss order.
456    ///
457    /// Constructs a spot order specifically for TP/SL, often used to manage existing
458    /// positions. The `order_filter` is set to "tpslOrder" to indicate this purpose.
459    /// Bots should use this for automated risk management, ensuring the `order_link_id`
460    /// is unique for tracking.
461    pub fn spot_tpsl(
462        symbol: &'a str,
463        side: Side,
464        price: f64,
465        qty: f64,
466        order_link_id: Option<&'a str>,
467    ) -> Self {
468        Self {
469            category: Category::Spot,
470            symbol: Cow::Borrowed(symbol),
471            side,
472            order_type: OrderType::Limit,
473            qty,
474            price: Some(price),
475            time_in_force: Some(Cow::Borrowed(TimeInForce::GTC.as_str())),
476            order_link_id: order_link_id.map(Cow::Borrowed),
477            order_filter: Some(Cow::Borrowed("tpslOrder")),
478            ..Self::default()
479        }
480    }
481    /// Creates a spot margin order with leverage.
482    ///
483    /// Constructs a spot order using margin (borrowed funds). Leverage increases
484    /// potential returns but also liquidation risk. Bots must monitor margin levels
485    /// and ensure sufficient collateral to avoid forced liquidations.
486    pub fn spot_margin(symbol: &'a str, side: Side, qty: f64, price: f64) -> Self {
487        Self {
488            category: Category::Spot,
489            symbol: Cow::Borrowed(symbol),
490            side,
491            order_type: OrderType::Market,
492            qty,
493            price: Some(price),
494            time_in_force: Some(Cow::Borrowed(TimeInForce::PostOnly.as_str())),
495            is_leverage: Some(true),
496            ..Self::default()
497        }
498    }
499    /// Creates a spot market order.
500    ///
501    /// Constructs a spot market order for immediate execution. Ideal for strategies
502    /// prioritizing speed over price control. Bots should account for slippage and
503    /// taker fees, which can impact profitability in volatile markets.
504    pub fn spot_market(symbol: &'a str, side: Side, qty: f64) -> Self {
505        Self {
506            category: Category::Spot,
507            symbol: Cow::Borrowed(symbol),
508            side,
509            order_type: OrderType::Market,
510            qty,
511            time_in_force: Some(Cow::Borrowed(TimeInForce::IOC.as_str())),
512            ..Self::default()
513        }
514    }
515    /// Creates a futures limit order with market-based take-profit and stop-loss.
516    ///
517    /// Constructs a perpetual futures limit order with TP/SL executed as market orders.
518    /// Suitable for strategies balancing precise entry with automated exits. Bots should
519    /// ensure TP/SL levels align with risk management goals and market volatility.
520    pub fn futures_limit_with_market_tpsl(
521        symbol: &'a str,
522        side: Side,
523        qty: f64,
524        price: f64,
525        tp: f64,
526        sl: f64,
527    ) -> Self {
528        Self {
529            category: Category::Linear,
530            symbol: Cow::Borrowed(symbol),
531            side,
532            order_type: OrderType::Limit,
533            qty,
534            price: Some(price),
535            time_in_force: Some(Cow::Borrowed(TimeInForce::PostOnly.as_str())),
536            reduce_only: Some(false),
537            take_profit: Some(tp),
538            stop_loss: Some(sl),
539            tpsl_mode: Some(Cow::Borrowed("Full")),
540            tp_order_type: Some(Cow::Borrowed("Market")),
541            sl_order_type: Some(Cow::Borrowed("Market")),
542            ..Self::default()
543        }
544    }
545    /// Creates a futures limit order with limit-based take-profit and stop-loss.
546    ///
547    /// Constructs a perpetual futures limit order with TP/SL executed as limit orders.
548    /// Ideal for precise exit price control, though execution is not guaranteed. Bots
549    /// must set TP/SL prices realistically to ensure they are filled in volatile markets.
550    pub fn futures_limit_with_limit_tpsl(
551        symbol: &'a str,
552        side: Side,
553        qty: f64,
554        price: f64,
555        tp: f64,
556        sl: f64,
557    ) -> Self {
558        Self {
559            category: Category::Linear,
560            symbol: Cow::Borrowed(symbol),
561            side,
562            order_type: OrderType::Limit,
563            qty,
564            price: Some(price),
565            time_in_force: Some(Cow::Borrowed(TimeInForce::PostOnly.as_str())),
566            reduce_only: Some(false),
567            take_profit: Some(tp),
568            stop_loss: Some(sl),
569            tpsl_mode: Some(Cow::Borrowed("Partial")),
570            tp_order_type: Some(Cow::Borrowed("Limit")),
571            sl_order_type: Some(Cow::Borrowed("Limit")),
572            tp_limit_price: Some(tp),
573            sl_limit_price: Some(sl),
574            ..Self::default()
575        }
576    }
577    /// Creates a futures market order.
578    ///
579    /// Constructs a perpetual futures market order for immediate execution. Suitable
580    /// for strategies needing fast entry or exit. Bots should account for slippage and
581    /// taker fees, which can be significant in perpetual futures due to leverage and
582    /// volatility.
583    pub fn futures_market(symbol: &'a str, side: Side, qty: f64) -> Self {
584        Self {
585            category: Category::Linear,
586            symbol: Cow::Borrowed(symbol),
587            side,
588            order_type: OrderType::Market,
589            qty,
590            time_in_force: Some(Cow::Borrowed(TimeInForce::IOC.as_str())),
591            reduce_only: Some(false),
592            ..Self::default()
593        }
594    }
595    /// Creates a futures limit order to close a position.
596    ///
597    /// Constructs a perpetual futures limit order to close an existing position, with
598    /// `reduce_only` set to `true`. Bots should use this to exit positions at specific
599    /// prices, ensuring the `order_link_id` is unique for tracking. Validate quantity
600    /// against the open position to avoid over-closing.
601    pub fn futures_close_limit(
602        symbol: &'a str,
603        side: Side,
604        qty: f64,
605        price: f64,
606        order_link_id: &'a str,
607    ) -> Self {
608        Self {
609            category: Category::Linear,
610            symbol: Cow::Borrowed(symbol),
611            side,
612            order_type: OrderType::Limit,
613            qty,
614            price: Some(price),
615            time_in_force: Some(Cow::Borrowed(TimeInForce::GTC.as_str())),
616            order_link_id: Some(Cow::Borrowed(order_link_id)),
617            reduce_only: Some(true),
618            ..Self::default()
619        }
620    }
621    /// Creates a futures market order to close a position.
622    ///
623    /// Constructs a perpetual futures market order to immediately close an existing
624    /// position. Ideal for rapid exits in volatile markets. Bots should ensure the
625    /// quantity matches the open position and account for slippage and fees.
626    pub fn futures_market_close(symbol: &'a str, side: Side, qty: f64) -> Self {
627        Self {
628            category: Category::Linear,
629            symbol: Cow::Borrowed(symbol),
630            side,
631            order_type: OrderType::Market,
632            qty,
633            time_in_force: Some(Cow::Borrowed(TimeInForce::IOC.as_str())),
634            reduce_only: Some(true),
635            ..Self::default()
636        }
637    }
638}