Skip to main content

longbridge/trade/requests/
submit_multileg.rs

1use rust_decimal::Decimal;
2use serde::Serialize;
3
4use crate::trade::{MultiLegStrategy, OrderSide, OrderType};
5
6/// A leg of a multi-leg combination order to submit
7#[derive(Debug, Serialize, Clone)]
8pub struct SubmitMultiLegOrderLeg {
9    /// Option symbol, in `ticker.region` format (e.g. `QQQ260731C764000.US`)
10    symbol: String,
11    /// Leg ratio quantity — must be a positive number.  The direction of each
12    /// leg is implied by `strategy` together with the order `side`, not by the
13    /// sign of this value; a negative or zero ratio is rejected by the server
14    /// with `602001`.
15    ratio_quantity: Decimal,
16}
17
18impl SubmitMultiLegOrderLeg {
19    /// Create a new `SubmitMultiLegOrderLeg`
20    #[inline]
21    pub fn new(symbol: impl Into<String>, ratio_quantity: Decimal) -> Self {
22        Self {
23            symbol: symbol.into(),
24            ratio_quantity,
25        }
26    }
27}
28
29/// Options for submit multi-leg order request
30#[derive(Debug, Serialize, Clone)]
31pub struct SubmitMultiLegOrderOptions {
32    side: OrderSide,
33    order_type: OrderType,
34    submitted_quantity: Decimal,
35    strategy: MultiLegStrategy,
36    legs: Vec<SubmitMultiLegOrderLeg>,
37    #[serde(skip_serializing_if = "Option::is_none")]
38    submitted_price: Option<Decimal>,
39    #[serde(skip_serializing_if = "Option::is_none")]
40    remark: Option<String>,
41    #[serde(skip_serializing_if = "Option::is_none")]
42    client_request_id: Option<String>,
43}
44
45impl SubmitMultiLegOrderOptions {
46    /// Create a new `SubmitMultiLegOrderOptions`
47    #[inline]
48    pub fn new(
49        side: OrderSide,
50        order_type: OrderType,
51        submitted_quantity: Decimal,
52        strategy: MultiLegStrategy,
53        legs: impl IntoIterator<Item = SubmitMultiLegOrderLeg>,
54    ) -> Self {
55        Self {
56            side,
57            order_type,
58            submitted_quantity,
59            strategy,
60            legs: legs.into_iter().collect(),
61            submitted_price: None,
62            remark: None,
63            client_request_id: None,
64        }
65    }
66
67    /// Set the submitted price
68    ///
69    /// Required for limit order types such as `LO`.
70    #[inline]
71    #[must_use]
72    pub fn submitted_price(self, submitted_price: Decimal) -> Self {
73        Self {
74            submitted_price: Some(submitted_price),
75            ..self
76        }
77    }
78
79    /// Set the remark
80    #[inline]
81    #[must_use]
82    pub fn remark(self, remark: impl Into<String>) -> Self {
83        Self {
84            remark: Some(remark.into()),
85            ..self
86        }
87    }
88
89    /// Set the client request ID for idempotency control.
90    /// If not specified, idempotency control is skipped.
91    /// The server caches this ID for 10 minutes; requests with the same ID
92    /// within that period return the original response without creating a new
93    /// order.
94    #[inline]
95    #[must_use]
96    pub fn client_request_id(self, id: impl Into<String>) -> Self {
97        Self {
98            client_request_id: Some(id.into()),
99            ..self
100        }
101    }
102}