Skip to main content

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    /// Slippage tolerance type for market orders (TickSize or Percent).
269    ///
270    /// Specifies how slippage tolerance is calculated for market orders.
271    /// - `TickSize`: slippage tolerance is measured in tick size units
272    /// - `Percent`: slippage tolerance is measured as a percentage
273    /// Not supported for take profit, stop loss, or conditional orders.
274    pub slippage_tolerance_type: Option<Cow<'a, str>>,
275
276    /// Slippage tolerance value for market orders.
277    ///
278    /// The value depends on `slippage_tolerance_type`:
279    /// - For `TickSize`: range is [1, 10000], integer only
280    /// - For `Percent`: range is [0.01, 10], up to 2 decimals
281    pub slippage_tolerance: Option<f64>,
282
283    /// BBO (Best Bid/Offer) side type for linear & inverse orders.
284    ///
285    /// Determines which side of the order book to use for pricing:
286    /// - `Queue`: use order price on the same side as the order
287    /// - `Counterparty`: use order price on the opposite side
288    /// Valid for `linear` & `inverse` categories only.
289    pub bbo_side_type: Option<Cow<'a, str>>,
290
291    /// BBO (Best Bid/Offer) level for linear & inverse orders.
292    ///
293    /// Specifies which level of the order book to use (1-5).
294    /// Valid for `linear` & `inverse` categories only.
295    pub bbo_level: Option<u8>,
296}
297
298impl<'a> OrderRequest<'a> {
299    /// Creates a default `OrderRequest` with predefined values.
300    ///
301    /// Initializes an order request with common defaults (e.g., Linear category,
302
303    /// BTCUSDT symbol, Market order). Bots can use this as a starting point and modify
304    /// fields as needed. Ensure all required fields are set before submitting to Bybit’s API.
305    pub fn default() -> Self {
306        Self {
307            category: Category::Linear,
308            symbol: Cow::Borrowed("BTCUSDT"),
309            is_leverage: None,
310            side: Side::default(),
311            order_type: OrderType::Market,
312            qty: 0.00,
313            market_unit: None,
314            price: None,
315            trigger_direction: None,
316            order_filter: None,
317            trigger_price: None,
318            trigger_by: None,
319            order_iv: None,
320            time_in_force: None,
321            position_idx: None,
322            order_link_id: None,
323            take_profit: None,
324            stop_loss: None,
325            tp_trigger_by: None,
326            sl_trigger_by: None,
327            reduce_only: None,
328            close_on_trigger: None,
329            smp_type: None,
330            mmp: None,
331            tpsl_mode: None,
332            tp_limit_price: None,
333            sl_limit_price: None,
334            tp_order_type: None,
335            sl_order_type: None,
336            slippage_tolerance_type: None,
337            slippage_tolerance: None,
338            bbo_side_type: None,
339            bbo_level: None,
340        }
341    }
342    /// Creates a custom `OrderRequest` with specified parameters.
343    ///
344    /// Allows bots to construct an order request with full control over all fields.
345    /// Ensure all parameters comply with Bybit’s API constraints (e.g., valid symbol,
346
347    /// quantity precision) to avoid rejections. This method is ideal for tailored
348    /// strategies in perpetual futures trading.
349    pub fn custom(
350        category: Category,
351        symbol: &'a str,
352        leverage: Option<bool>,
353        side: Side,
354        order_type: OrderType,
355        qty: f64,
356        market_unit: Option<f64>,
357        price: Option<f64>,
358        trigger_direction: Option<bool>,
359        order_filter: Option<&'a str>,
360        trigger_price: Option<f64>,
361        trigger_by: Option<&'a str>,
362        order_iv: Option<f64>,
363        time_in_force: Option<&'a str>,
364        position_idx: Option<u8>,
365        order_link_id: Option<&'a str>,
366        take_profit: Option<f64>,
367        stop_loss: Option<f64>,
368        tp_trigger_by: Option<&'a str>,
369        sl_trigger_by: Option<&'a str>,
370        reduce_only: Option<bool>,
371        close_on_trigger: Option<bool>,
372        smp_type: Option<&'a str>,
373        mmp: Option<bool>,
374        tpsl_mode: Option<&'a str>,
375        tp_limit_price: Option<f64>,
376        sl_limit_price: Option<f64>,
377        tp_order_type: Option<&'a str>,
378        sl_order_type: Option<&'a str>,
379        slippage_tolerance_type: Option<&'a str>,
380        slippage_tolerance: Option<f64>,
381        bbo_side_type: Option<&'a str>,
382        bbo_level: Option<u8>,
383    ) -> Self {
384        Self {
385            category,
386            symbol: Cow::Borrowed(symbol),
387            is_leverage: leverage,
388            side,
389            order_type,
390            qty,
391            market_unit,
392            price,
393            trigger_direction,
394            order_filter: order_filter.map(Cow::Borrowed),
395            trigger_price,
396            trigger_by: trigger_by.map(Cow::Borrowed),
397            order_iv,
398            time_in_force: time_in_force.map(Cow::Borrowed),
399            position_idx,
400            order_link_id: order_link_id.map(Cow::Borrowed),
401            take_profit,
402            stop_loss,
403            tp_trigger_by: tp_trigger_by.map(Cow::Borrowed),
404            sl_trigger_by: sl_trigger_by.map(Cow::Borrowed),
405            reduce_only,
406            close_on_trigger,
407            smp_type: smp_type.map(Cow::Borrowed),
408            mmp,
409            tpsl_mode: tpsl_mode.map(Cow::Borrowed),
410            tp_limit_price,
411            sl_limit_price,
412            tp_order_type: tp_order_type.map(Cow::Borrowed),
413            sl_order_type: sl_order_type.map(Cow::Borrowed),
414            slippage_tolerance_type: slippage_tolerance_type.map(Cow::Borrowed),
415            slippage_tolerance,
416            bbo_side_type: bbo_side_type.map(Cow::Borrowed),
417            bbo_level,
418        }
419    }
420    /// Creates a spot limit order with market-based take-profit and stop-loss.
421    ///
422    /// Constructs a spot limit order with predefined TP/SL executed as market orders.
423    /// Suitable for spot trading strategies aiming for precise entry prices with
424    /// automated exits. Bots should ensure TP/SL prices are set appropriately to balance
425    /// risk and reward.
426    pub fn spot_limit_with_market_tpsl(
427        symbol: &'a str,
428        side: Side,
429        qty: f64,
430        price: f64,
431        tp: f64,
432        sl: f64,
433    ) -> Self {
434        Self {
435            category: Category::Spot,
436            symbol: Cow::Borrowed(symbol),
437            side,
438            order_type: OrderType::Limit,
439            qty,
440            price: Some(price),
441            time_in_force: Some(Cow::Borrowed(TimeInForce::PostOnly.as_str())),
442            take_profit: Some(tp),
443            stop_loss: Some(sl),
444            tp_order_type: Some(Cow::Borrowed("Market")),
445            sl_order_type: Some(Cow::Borrowed("Market")),
446            ..Self::default()
447        }
448    }
449    /// Creates a spot limit order with limit-based take-profit and stop-loss.
450    ///
451    /// Constructs a spot limit order with TP/SL executed as limit orders for precise
452    /// exit prices. Ideal for strategies prioritizing price control over execution
453    /// certainty. Bots must ensure TP/SL prices are achievable given market conditions.
454    pub fn spot_limit_with_limit_tpsl(
455        symbol: &'a str,
456        side: Side,
457        qty: f64,
458        price: f64,
459        tp: f64,
460        sl: f64,
461    ) -> Self {
462        Self {
463            category: Category::Spot,
464            symbol: Cow::Borrowed(symbol),
465            side,
466            order_type: OrderType::Limit,
467            qty,
468            price: Some(price),
469            time_in_force: Some(Cow::Borrowed(TimeInForce::PostOnly.as_str())),
470            take_profit: Some(tp),
471            stop_loss: Some(sl),
472            tp_limit_price: Some(tp),
473            sl_limit_price: Some(sl),
474            tp_order_type: Some(Cow::Borrowed("Limit")),
475            sl_order_type: Some(Cow::Borrowed("Limit")),
476            ..Self::default()
477        }
478    }
479    /// Creates a spot post-only limit order.
480    ///
481    /// Constructs a spot limit order that only adds liquidity (maker order). Useful for
482    /// minimizing fees but risks non-execution if the market moves away. Bots should
483    /// monitor order book depth to ensure the price is competitive.
484    pub fn spot_postonly(symbol: &'a str, side: Side, qty: f64, price: f64) -> Self {
485        Self {
486            category: Category::Spot,
487            symbol: Cow::Borrowed(symbol),
488            side,
489            order_type: OrderType::Limit,
490            qty,
491            price: Some(price),
492            time_in_force: Some(Cow::Borrowed(TimeInForce::PostOnly.as_str())),
493            ..Self::default()
494        }
495    }
496    /// Creates a spot take-profit/stop-loss order.
497    ///
498    /// Constructs a spot order specifically for TP/SL, often used to manage existing
499    /// positions. The `order_filter` is set to "tpslOrder" to indicate this purpose.
500    /// Bots should use this for automated risk management, ensuring the `order_link_id`
501    /// is unique for tracking.
502    pub fn spot_tpsl(
503        symbol: &'a str,
504        side: Side,
505        price: f64,
506        qty: f64,
507        order_link_id: Option<&'a str>,
508    ) -> Self {
509        Self {
510            category: Category::Spot,
511            symbol: Cow::Borrowed(symbol),
512            side,
513            order_type: OrderType::Limit,
514            qty,
515            price: Some(price),
516            time_in_force: Some(Cow::Borrowed(TimeInForce::GTC.as_str())),
517            order_link_id: order_link_id.map(Cow::Borrowed),
518            order_filter: Some(Cow::Borrowed("tpslOrder")),
519            ..Self::default()
520        }
521    }
522    /// Creates a spot margin order with leverage.
523    ///
524    /// Constructs a spot order using margin (borrowed funds). Leverage increases
525    /// potential returns but also liquidation risk. Bots must monitor margin levels
526    /// and ensure sufficient collateral to avoid forced liquidations.
527    pub fn spot_margin(symbol: &'a str, side: Side, qty: f64, price: f64) -> Self {
528        Self {
529            category: Category::Spot,
530            symbol: Cow::Borrowed(symbol),
531            side,
532            order_type: OrderType::Market,
533            qty,
534            price: Some(price),
535            time_in_force: Some(Cow::Borrowed(TimeInForce::PostOnly.as_str())),
536            is_leverage: Some(true),
537            ..Self::default()
538        }
539    }
540    /// Creates a spot market order.
541    ///
542    /// Constructs a spot market order for immediate execution. Ideal for strategies
543    /// prioritizing speed over price control. Bots should account for slippage and
544    /// taker fees, which can impact profitability in volatile markets.
545    pub fn spot_market(symbol: &'a str, side: Side, qty: f64) -> Self {
546        Self {
547            category: Category::Spot,
548            symbol: Cow::Borrowed(symbol),
549            side,
550            order_type: OrderType::Market,
551            qty,
552            time_in_force: Some(Cow::Borrowed(TimeInForce::IOC.as_str())),
553            ..Self::default()
554        }
555    }
556    /// Creates a futures limit order with market-based take-profit and stop-loss.
557    ///
558    /// Constructs a perpetual futures limit order with TP/SL executed as market orders.
559    /// Suitable for strategies balancing precise entry with automated exits. Bots should
560    /// ensure TP/SL levels align with risk management goals and market volatility.
561    pub fn futures_limit_with_market_tpsl(
562        symbol: &'a str,
563        side: Side,
564        qty: f64,
565        price: f64,
566        tp: f64,
567        sl: f64,
568    ) -> Self {
569        Self {
570            category: Category::Linear,
571            symbol: Cow::Borrowed(symbol),
572            side,
573            order_type: OrderType::Limit,
574            qty,
575            price: Some(price),
576            time_in_force: Some(Cow::Borrowed(TimeInForce::PostOnly.as_str())),
577            reduce_only: Some(false),
578            take_profit: Some(tp),
579            stop_loss: Some(sl),
580            tpsl_mode: Some(Cow::Borrowed("Full")),
581            tp_order_type: Some(Cow::Borrowed("Market")),
582            sl_order_type: Some(Cow::Borrowed("Market")),
583            ..Self::default()
584        }
585    }
586    /// Creates a futures limit order with limit-based take-profit and stop-loss.
587    ///
588    /// Constructs a perpetual futures limit order with TP/SL executed as limit orders.
589    /// Ideal for precise exit price control, though execution is not guaranteed. Bots
590    /// must set TP/SL prices realistically to ensure they are filled in volatile markets.
591    pub fn futures_limit_with_limit_tpsl(
592        symbol: &'a str,
593        side: Side,
594        qty: f64,
595        price: f64,
596        tp: f64,
597        sl: f64,
598    ) -> Self {
599        Self {
600            category: Category::Linear,
601            symbol: Cow::Borrowed(symbol),
602            side,
603            order_type: OrderType::Limit,
604            qty,
605            price: Some(price),
606            time_in_force: Some(Cow::Borrowed(TimeInForce::PostOnly.as_str())),
607            reduce_only: Some(false),
608            take_profit: Some(tp),
609            stop_loss: Some(sl),
610            tpsl_mode: Some(Cow::Borrowed("Partial")),
611            tp_order_type: Some(Cow::Borrowed("Limit")),
612            sl_order_type: Some(Cow::Borrowed("Limit")),
613            tp_limit_price: Some(tp),
614            sl_limit_price: Some(sl),
615            ..Self::default()
616        }
617    }
618    /// Creates a futures market order.
619    ///
620    /// Constructs a perpetual futures market order for immediate execution. Suitable
621    /// for strategies needing fast entry or exit. Bots should account for slippage and
622    /// taker fees, which can be significant in perpetual futures due to leverage and
623    /// volatility.
624    pub fn futures_market(symbol: &'a str, side: Side, qty: f64) -> Self {
625        Self {
626            category: Category::Linear,
627            symbol: Cow::Borrowed(symbol),
628            side,
629            order_type: OrderType::Market,
630            qty,
631            time_in_force: Some(Cow::Borrowed(TimeInForce::IOC.as_str())),
632            reduce_only: Some(false),
633            ..Self::default()
634        }
635    }
636    /// Creates a futures limit order to close a position.
637    ///
638    /// Constructs a perpetual futures limit order to close an existing position, with
639    /// `reduce_only` set to `true`. Bots should use this to exit positions at specific
640    /// prices, ensuring the `order_link_id` is unique for tracking. Validate quantity
641    /// against the open position to avoid over-closing.
642    pub fn futures_close_limit(
643        symbol: &'a str,
644        side: Side,
645        qty: f64,
646        price: f64,
647        order_link_id: &'a str,
648    ) -> Self {
649        Self {
650            category: Category::Linear,
651            symbol: Cow::Borrowed(symbol),
652            side,
653            order_type: OrderType::Limit,
654            qty,
655            price: Some(price),
656            time_in_force: Some(Cow::Borrowed(TimeInForce::GTC.as_str())),
657            order_link_id: Some(Cow::Borrowed(order_link_id)),
658            reduce_only: Some(true),
659            ..Self::default()
660        }
661    }
662    /// Creates a futures market order to close a position.
663    ///
664    /// Constructs a perpetual futures market order to immediately close an existing
665    /// position. Ideal for rapid exits in volatile markets. Bots should ensure the
666    /// quantity matches the open position and account for slippage and fees.
667    pub fn futures_market_close(symbol: &'a str, side: Side, qty: f64) -> Self {
668        Self {
669            category: Category::Linear,
670            symbol: Cow::Borrowed(symbol),
671            side,
672            order_type: OrderType::Market,
673            qty,
674            time_in_force: Some(Cow::Borrowed(TimeInForce::IOC.as_str())),
675            reduce_only: Some(true),
676            ..Self::default()
677        }
678    }
679}