longbridge/trade/requests/
submit_multileg.rs1use rust_decimal::Decimal;
2use serde::Serialize;
3use time::OffsetDateTime;
4
5use crate::trade::{MultiLegStrategy, OrderSide, OrderType};
6
7#[derive(Debug, Serialize, Clone)]
9pub struct SubmitMultiLegOrderLeg {
10 symbol: String,
12 ratio_quantity: Decimal,
17}
18
19impl SubmitMultiLegOrderLeg {
20 #[inline]
22 pub fn new(symbol: impl Into<String>, ratio_quantity: Decimal) -> Self {
23 Self {
24 symbol: symbol.into(),
25 ratio_quantity,
26 }
27 }
28}
29
30#[derive(Debug, Serialize, Clone)]
32pub struct SubmitMultiLegOrderOptions {
33 side: OrderSide,
34 order_type: OrderType,
35 submitted_quantity: Decimal,
36 strategy: MultiLegStrategy,
37 legs: Vec<SubmitMultiLegOrderLeg>,
38 #[serde(skip_serializing_if = "Option::is_none")]
39 submitted_price: Option<Decimal>,
40 #[serde(skip_serializing_if = "Option::is_none")]
41 remark: Option<String>,
42 #[serde(skip_serializing_if = "Option::is_none")]
43 client_request_id: Option<String>,
44 #[serde(skip_serializing_if = "Option::is_none")]
45 delayed_until: Option<i64>,
46}
47
48impl SubmitMultiLegOrderOptions {
49 #[inline]
51 pub fn new(
52 side: OrderSide,
53 order_type: OrderType,
54 submitted_quantity: Decimal,
55 strategy: MultiLegStrategy,
56 legs: impl IntoIterator<Item = SubmitMultiLegOrderLeg>,
57 ) -> Self {
58 Self {
59 side,
60 order_type,
61 submitted_quantity,
62 strategy,
63 legs: legs.into_iter().collect(),
64 submitted_price: None,
65 remark: None,
66 client_request_id: None,
67 delayed_until: None,
68 }
69 }
70
71 #[inline]
75 #[must_use]
76 pub fn submitted_price(self, submitted_price: Decimal) -> Self {
77 Self {
78 submitted_price: Some(submitted_price),
79 ..self
80 }
81 }
82
83 #[inline]
85 #[must_use]
86 pub fn remark(self, remark: impl Into<String>) -> Self {
87 Self {
88 remark: Some(remark.into()),
89 ..self
90 }
91 }
92
93 #[inline]
99 #[must_use]
100 pub fn client_request_id(self, id: impl Into<String>) -> Self {
101 Self {
102 client_request_id: Some(id.into()),
103 ..self
104 }
105 }
106
107 #[inline]
113 #[must_use]
114 pub fn delayed_until(self, delayed_until: OffsetDateTime) -> Self {
115 Self {
116 delayed_until: Some(super::delayed_until_timestamp(delayed_until)),
117 ..self
118 }
119 }
120}
121
122#[cfg(test)]
123mod tests {
124 use time::macros::datetime;
125
126 use super::*;
127
128 #[test]
129 fn delayed_until() {
130 let opts = SubmitMultiLegOrderOptions::new(
131 OrderSide::Buy,
132 OrderType::MO,
133 Decimal::from(1),
134 MultiLegStrategy::Straddle,
135 [],
136 );
137 assert!(
138 serde_json::to_value(&opts)
139 .unwrap()
140 .get("delayed_until")
141 .is_none()
142 );
143
144 let opts = opts.delayed_until(datetime!(2026-01-01 00:00 UTC));
145 assert_eq!(
146 serde_json::to_value(&opts).unwrap()["delayed_until"],
147 serde_json::json!(1767225600)
148 );
149 }
150}