futu_qot/
rt.rs

1use futu_core::error::{FutuError, Result};
2use futu_core::proto_id;
3use futu_net::client::FutuClient;
4
5use crate::types::Security;
6
7/// 分时数据点
8#[derive(Debug, Clone)]
9pub struct TimeShare {
10    pub time: String,
11    pub minute: i32,
12    pub is_blank: bool,
13    pub price: f64,
14    pub last_close_price: f64,
15    pub avg_price: f64,
16    pub volume: i64,
17    pub turnover: f64,
18    pub timestamp: f64,
19}
20
21impl TimeShare {
22    pub fn from_proto(t: &futu_proto::qot_common::TimeShare) -> Self {
23        Self {
24            time: t.time.clone(),
25            minute: t.minute,
26            is_blank: t.is_blank,
27            price: t.price.unwrap_or(0.0),
28            last_close_price: t.last_close_price.unwrap_or(0.0),
29            avg_price: t.avg_price.unwrap_or(0.0),
30            volume: t.volume.unwrap_or(0),
31            turnover: t.turnover.unwrap_or(0.0),
32            timestamp: t.timestamp.unwrap_or(0.0),
33        }
34    }
35}
36
37/// 分时查询结果
38#[derive(Debug, Clone)]
39pub struct RTResult {
40    pub security: Security,
41    pub rt_list: Vec<TimeShare>,
42}
43
44/// 获取分时数据
45///
46/// 需要先订阅 SubType::RT。
47pub async fn get_rt(client: &FutuClient, security: &Security) -> Result<RTResult> {
48    let req = futu_proto::qot_get_rt::Request {
49        c2s: futu_proto::qot_get_rt::C2s {
50            security: security.to_proto(),
51        },
52    };
53
54    let body = prost::Message::encode_to_vec(&req);
55    let resp_frame = client.request(proto_id::QOT_GET_RT, body).await?;
56
57    let resp: futu_proto::qot_get_rt::Response =
58        prost::Message::decode(resp_frame.body.as_ref()).map_err(FutuError::Proto)?;
59
60    if resp.ret_type != 0 {
61        return Err(FutuError::ServerError {
62            ret_type: resp.ret_type,
63            msg: resp.ret_msg.unwrap_or_default(),
64        });
65    }
66
67    let s2c = resp
68        .s2c
69        .ok_or(FutuError::Codec("missing s2c in GetRT".into()))?;
70
71    Ok(RTResult {
72        security: Security::from_proto(&s2c.security),
73        rt_list: s2c.rt_list.iter().map(TimeShare::from_proto).collect(),
74    })
75}