1#[derive(Debug, Clone, PartialEq, Eq, Hash)]
6pub struct Security {
7 pub market: QotMarket,
9 pub code: String,
11}
12
13impl Security {
14 pub fn new(market: QotMarket, code: impl Into<String>) -> Self {
16 Self {
17 market,
18 code: code.into(),
19 }
20 }
21
22 pub fn from_proto(s: &futu_proto::qot_common::Security) -> Self {
24 Self {
25 market: QotMarket::from_i32(s.market),
26 code: s.code.clone(),
27 }
28 }
29
30 pub fn to_proto(&self) -> futu_proto::qot_common::Security {
32 futu_proto::qot_common::Security {
33 market: self.market as i32,
34 code: self.code.clone(),
35 }
36 }
37}
38
39#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
41#[repr(i32)]
42#[non_exhaustive]
43pub enum QotMarket {
44 Unknown = 0,
45 HkSecurity = 1,
46 HkFuture = 2,
47 UsSecurity = 11,
48 CnshSecurity = 21,
49 CnszSecurity = 22,
50 SgSecurity = 31,
51 JpSecurity = 41,
52 AuSecurity = 51,
53 MySecurity = 61,
54 CaSecurity = 71,
55 FxSecurity = 81,
56 Crypto = 91,
60}
61
62impl QotMarket {
63 pub fn from_i32(v: i32) -> Self {
65 match v {
66 1 => Self::HkSecurity,
67 2 => Self::HkFuture,
68 11 => Self::UsSecurity,
69 21 => Self::CnshSecurity,
70 22 => Self::CnszSecurity,
71 31 => Self::SgSecurity,
72 41 => Self::JpSecurity,
73 51 => Self::AuSecurity,
74 61 => Self::MySecurity,
75 71 => Self::CaSecurity,
76 81 => Self::FxSecurity,
77 91 => Self::Crypto,
78 _ => Self::Unknown,
79 }
80 }
81}
82
83#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
85#[repr(i32)]
86#[non_exhaustive]
87pub enum SubType {
88 None = 0,
89 Basic = 1,
90 OrderBook = 2,
91 Ticker = 4,
92 RT = 5,
93 KLDay = 6,
94 KL5Min = 7,
95 KL15Min = 8,
96 KL30Min = 9,
97 KL60Min = 10,
98 KL1Min = 11,
99 KLWeek = 12,
100 KLMonth = 13,
101 Broker = 14,
102 KLQuarter = 15,
103 KLYear = 16,
104 KL3Min = 17,
105 OrderDetail = 18,
106}
107
108#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
110#[repr(i32)]
111#[non_exhaustive]
112pub enum KLType {
113 Unknown = 0,
114 Min1 = 1,
115 Day = 2,
116 Week = 3,
117 Month = 4,
118 Year = 5,
119 Min5 = 6,
120 Min15 = 7,
121 Min30 = 8,
122 Min60 = 9,
123 Min3 = 10,
124 Quarter = 11,
125}
126
127#[derive(Debug, Clone, Copy, PartialEq, Eq)]
129#[repr(i32)]
130#[non_exhaustive]
131pub enum RehabType {
132 None = 0,
133 Forward = 1,
134 Backward = 2,
135}
136
137#[derive(Debug, Clone)]
139pub struct KLine {
140 pub time: String,
142 pub is_blank: bool,
144 pub high_price: f64,
146 pub open_price: f64,
148 pub low_price: f64,
150 pub close_price: f64,
152 pub last_close_price: f64,
154 pub volume: i64,
156 pub turnover: f64,
158 pub turnover_rate: f64,
160 pub pe: f64,
162 pub change_rate: f64,
164 pub timestamp: f64,
166}
167
168impl KLine {
169 pub fn from_proto(k: &futu_proto::qot_common::KLine) -> Self {
170 Self {
171 time: k.time.clone(),
172 is_blank: k.is_blank,
173 high_price: k.high_price.unwrap_or(0.0),
174 open_price: k.open_price.unwrap_or(0.0),
175 low_price: k.low_price.unwrap_or(0.0),
176 close_price: k.close_price.unwrap_or(0.0),
177 last_close_price: k.last_close_price.unwrap_or(0.0),
178 volume: k.volume.unwrap_or(0),
179 turnover: k.turnover.unwrap_or(0.0),
180 turnover_rate: k.turnover_rate.unwrap_or(0.0),
181 pe: k.pe.unwrap_or(0.0),
182 change_rate: k.change_rate.unwrap_or(0.0),
183 timestamp: k.timestamp.unwrap_or(0.0),
184 }
185 }
186}
187
188#[derive(Debug, Clone)]
190pub struct BasicQot {
191 pub security: Security,
193 pub is_suspended: bool,
195 pub list_time: String,
197 pub price_spread: f64,
199 pub update_time: String,
201 pub high_price: f64,
203 pub open_price: f64,
205 pub low_price: f64,
207 pub cur_price: f64,
209 pub last_close_price: f64,
211 pub volume: i64,
213 pub turnover: f64,
215 pub turnover_rate: f64,
217 pub amplitude: f64,
219}
220
221impl BasicQot {
222 pub fn from_proto(q: &futu_proto::qot_common::BasicQot) -> Self {
223 Self {
224 security: Security::from_proto(&q.security),
225 is_suspended: q.is_suspended,
226 list_time: q.list_time.clone(),
227 price_spread: q.price_spread,
228 update_time: q.update_time.clone(),
229 high_price: q.high_price,
230 open_price: q.open_price,
231 low_price: q.low_price,
232 cur_price: q.cur_price,
233 last_close_price: q.last_close_price,
234 volume: q.volume,
235 turnover: q.turnover,
236 turnover_rate: q.turnover_rate,
237 amplitude: q.amplitude,
238 }
239 }
240}
241
242#[derive(Debug, Clone)]
244pub struct OrderBookEntry {
245 pub price: f64,
247 pub volume: i64,
249 pub order_count: i32,
251}
252
253impl OrderBookEntry {
254 pub fn from_proto(ob: &futu_proto::qot_common::OrderBook) -> Self {
255 Self {
256 price: ob.price,
257 volume: ob.volume,
258 order_count: ob.oreder_count, }
260 }
261}
262
263#[derive(Debug, Clone)]
265pub struct OrderBookData {
266 pub security: Security,
268 pub ask_list: Vec<OrderBookEntry>,
270 pub bid_list: Vec<OrderBookEntry>,
272}
273
274pub fn market_state_label(s: i32) -> &'static str {
283 match s {
284 0 => "None", 1 => "Auction", 2 => "WaitingOpen", 3 => "Morning", 4 => "Rest", 5 => "Afternoon", 6 => "Closed", 8 => "PreMarketBegin", 9 => "PreMarketEnd", 10 => "AfterHoursBegin", 11 => "AfterHoursEnd", 12 => "FutuSwitchDate", 13 => "NightOpen", 14 => "NightEnd", 15 => "FutureDayOpen", 16 => "FutureDayBreak", 17 => "FutureDayClose", 18 => "FutureDayWaitForOpen", 19 => "HkCas", 20 => "FutureNightWait", 21 => "FutureAfternoon", 22 => "FutureSwitchDate", 23 => "FutureOpen", 24 => "FutureBreak", 25 => "FutureBreakOver", 26 => "FutureClose", 27 => "StibAfterHoursWait", 28 => "StibAfterHoursBegin", 29 => "StibAfterHoursEnd", 30 => "CloseAuction", 31 => "AfternoonEnd", 32 => "Night", 33 => "OvernightBegin", 34 => "OvernightEnd", 35 => "TradeAtLast", 36 => "TradeAuction", 37 => "Overnight", _ => "Unknown",
322 }
323}
324
325#[cfg(test)]
326mod tests;