futu_qot/
types.rs

1// 行情域通用类型
2// 从 proto 结构体转换为 Rust 友好的类型。
3
4/// 股票标识
5#[derive(Debug, Clone, PartialEq, Eq, Hash)]
6pub struct Security {
7    pub market: QotMarket,
8    pub code: String,
9}
10
11impl Security {
12    pub fn new(market: QotMarket, code: impl Into<String>) -> Self {
13        Self {
14            market,
15            code: code.into(),
16        }
17    }
18
19    /// 从 proto Security 转换
20    pub fn from_proto(s: &futu_proto::qot_common::Security) -> Self {
21        Self {
22            market: QotMarket::from_i32(s.market),
23            code: s.code.clone(),
24        }
25    }
26
27    /// 转换为 proto Security
28    pub fn to_proto(&self) -> futu_proto::qot_common::Security {
29        futu_proto::qot_common::Security {
30            market: self.market as i32,
31            code: self.code.clone(),
32        }
33    }
34}
35
36/// 市场类型
37#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
38#[repr(i32)]
39pub enum QotMarket {
40    Unknown = 0,
41    HkSecurity = 1,
42    HkFuture = 2,
43    UsSecurity = 11,
44    CnshSecurity = 21,
45    CnszSecurity = 22,
46}
47
48impl QotMarket {
49    pub fn from_i32(v: i32) -> Self {
50        match v {
51            1 => Self::HkSecurity,
52            2 => Self::HkFuture,
53            11 => Self::UsSecurity,
54            21 => Self::CnshSecurity,
55            22 => Self::CnszSecurity,
56            _ => Self::Unknown,
57        }
58    }
59}
60
61/// 订阅类型
62#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
63#[repr(i32)]
64pub enum SubType {
65    None = 0,
66    Basic = 1,
67    OrderBook = 2,
68    Ticker = 4,
69    RT = 5,
70    KLDay = 6,
71    KL5Min = 7,
72    KL15Min = 8,
73    KL30Min = 9,
74    KL60Min = 10,
75    KL1Min = 11,
76    KLWeek = 12,
77    KLMonth = 13,
78    Broker = 14,
79    KLQuarter = 15,
80    KLYear = 16,
81    KL3Min = 17,
82    OrderDetail = 18,
83}
84
85/// K 线类型
86#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
87#[repr(i32)]
88pub enum KLType {
89    Unknown = 0,
90    Min1 = 1,
91    Day = 2,
92    Week = 3,
93    Month = 4,
94    Year = 5,
95    Min5 = 6,
96    Min15 = 7,
97    Min30 = 8,
98    Min60 = 9,
99    Min3 = 10,
100    Quarter = 11,
101}
102
103/// 复权类型
104#[derive(Debug, Clone, Copy, PartialEq, Eq)]
105#[repr(i32)]
106pub enum RehabType {
107    None = 0,
108    Forward = 1,
109    Backward = 2,
110}
111
112/// K 线数据点
113#[derive(Debug, Clone)]
114pub struct KLine {
115    pub time: String,
116    pub is_blank: bool,
117    pub high_price: f64,
118    pub open_price: f64,
119    pub low_price: f64,
120    pub close_price: f64,
121    pub last_close_price: f64,
122    pub volume: i64,
123    pub turnover: f64,
124    pub turnover_rate: f64,
125    pub pe: f64,
126    pub change_rate: f64,
127    pub timestamp: f64,
128}
129
130impl KLine {
131    pub fn from_proto(k: &futu_proto::qot_common::KLine) -> Self {
132        Self {
133            time: k.time.clone(),
134            is_blank: k.is_blank,
135            high_price: k.high_price.unwrap_or(0.0),
136            open_price: k.open_price.unwrap_or(0.0),
137            low_price: k.low_price.unwrap_or(0.0),
138            close_price: k.close_price.unwrap_or(0.0),
139            last_close_price: k.last_close_price.unwrap_or(0.0),
140            volume: k.volume.unwrap_or(0),
141            turnover: k.turnover.unwrap_or(0.0),
142            turnover_rate: k.turnover_rate.unwrap_or(0.0),
143            pe: k.pe.unwrap_or(0.0),
144            change_rate: k.change_rate.unwrap_or(0.0),
145            timestamp: k.timestamp.unwrap_or(0.0),
146        }
147    }
148}
149
150/// 基本行情数据
151#[derive(Debug, Clone)]
152pub struct BasicQot {
153    pub security: Security,
154    pub is_suspended: bool,
155    pub list_time: String,
156    pub price_spread: f64,
157    pub update_time: String,
158    pub high_price: f64,
159    pub open_price: f64,
160    pub low_price: f64,
161    pub cur_price: f64,
162    pub last_close_price: f64,
163    pub volume: i64,
164    pub turnover: f64,
165    pub turnover_rate: f64,
166    pub amplitude: f64,
167}
168
169impl BasicQot {
170    pub fn from_proto(q: &futu_proto::qot_common::BasicQot) -> Self {
171        Self {
172            security: Security::from_proto(&q.security),
173            is_suspended: q.is_suspended,
174            list_time: q.list_time.clone(),
175            price_spread: q.price_spread,
176            update_time: q.update_time.clone(),
177            high_price: q.high_price,
178            open_price: q.open_price,
179            low_price: q.low_price,
180            cur_price: q.cur_price,
181            last_close_price: q.last_close_price,
182            volume: q.volume,
183            turnover: q.turnover,
184            turnover_rate: q.turnover_rate,
185            amplitude: q.amplitude,
186        }
187    }
188}
189
190/// 摆盘数据项
191#[derive(Debug, Clone)]
192pub struct OrderBookEntry {
193    pub price: f64,
194    pub volume: i64,
195    pub order_count: i32,
196}
197
198impl OrderBookEntry {
199    pub fn from_proto(ob: &futu_proto::qot_common::OrderBook) -> Self {
200        Self {
201            price: ob.price,
202            volume: ob.volume,
203            order_count: ob.oreder_count, // proto 中拼写为 oreder_count
204        }
205    }
206}
207
208/// 摆盘数据
209#[derive(Debug, Clone)]
210pub struct OrderBookData {
211    pub security: Security,
212    pub ask_list: Vec<OrderBookEntry>,
213    pub bid_list: Vec<OrderBookEntry>,
214}