1use futu_core::error::{FutuError, Result};
2use futu_core::proto_id;
3use futu_net::client::FutuClient;
4
5use crate::types::Security;
6
7#[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#[derive(Debug, Clone)]
39pub struct RTResult {
40 pub security: Security,
41 pub rt_list: Vec<TimeShare>,
42}
43
44pub 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}