futu_trd/
query.rs

1use futu_core::error::{FutuError, Result};
2use futu_core::proto_id;
3use futu_net::client::FutuClient;
4
5use crate::types::TrdHeader;
6
7/// 订单信息
8#[derive(Debug, Clone)]
9pub struct Order {
10    pub order_id: u64,
11    pub order_id_ex: String,
12    pub trd_side: i32,
13    pub order_type: i32,
14    pub order_status: i32,
15    pub code: String,
16    pub name: String,
17    pub qty: f64,
18    pub price: f64,
19    pub create_time: String,
20    pub update_time: String,
21    pub fill_qty: f64,
22    pub fill_avg_price: f64,
23    pub last_err_msg: String,
24}
25
26impl Order {
27    pub fn from_proto(o: &futu_proto::trd_common::Order) -> Self {
28        Self {
29            order_id: o.order_id,
30            order_id_ex: o.order_id_ex.clone(),
31            trd_side: o.trd_side,
32            order_type: o.order_type,
33            order_status: o.order_status,
34            code: o.code.clone(),
35            name: o.name.clone(),
36            qty: o.qty,
37            price: o.price.unwrap_or(0.0),
38            create_time: o.create_time.clone(),
39            update_time: o.update_time.clone(),
40            fill_qty: o.fill_qty.unwrap_or(0.0),
41            fill_avg_price: o.fill_avg_price.unwrap_or(0.0),
42            last_err_msg: o.last_err_msg.clone().unwrap_or_default(),
43        }
44    }
45}
46
47/// 成交信息
48#[derive(Debug, Clone)]
49pub struct OrderFill {
50    pub fill_id: u64,
51    pub fill_id_ex: String,
52    pub order_id: u64,
53    pub trd_side: i32,
54    pub code: String,
55    pub name: String,
56    pub qty: f64,
57    pub price: f64,
58    pub create_time: String,
59}
60
61impl OrderFill {
62    pub fn from_proto(f: &futu_proto::trd_common::OrderFill) -> Self {
63        Self {
64            fill_id: f.fill_id,
65            fill_id_ex: f.fill_id_ex.clone(),
66            order_id: f.order_id.unwrap_or(0),
67            trd_side: f.trd_side,
68            code: f.code.clone(),
69            name: f.name.clone(),
70            qty: f.qty,
71            price: f.price,
72            create_time: f.create_time.clone(),
73        }
74    }
75}
76
77/// 查询当日订单列表
78pub async fn get_order_list(client: &FutuClient, header: &TrdHeader) -> Result<Vec<Order>> {
79    let req = futu_proto::trd_get_order_list::Request {
80        c2s: futu_proto::trd_get_order_list::C2s {
81            header: header.to_proto(),
82            filter_conditions: None,
83            filter_status_list: vec![],
84            refresh_cache: None,
85        },
86    };
87
88    let body = prost::Message::encode_to_vec(&req);
89    let resp_frame = client.request(proto_id::TRD_GET_ORDER_LIST, body).await?;
90
91    let resp: futu_proto::trd_get_order_list::Response =
92        prost::Message::decode(resp_frame.body.as_ref()).map_err(FutuError::Proto)?;
93
94    if resp.ret_type != 0 {
95        return Err(FutuError::ServerError {
96            ret_type: resp.ret_type,
97            msg: resp.ret_msg.unwrap_or_default(),
98        });
99    }
100
101    let s2c = resp
102        .s2c
103        .ok_or(FutuError::Codec("missing s2c in GetOrderList".into()))?;
104
105    Ok(s2c.order_list.iter().map(Order::from_proto).collect())
106}
107
108/// 查询当日成交列表
109pub async fn get_order_fill_list(
110    client: &FutuClient,
111    header: &TrdHeader,
112) -> Result<Vec<OrderFill>> {
113    let req = futu_proto::trd_get_order_fill_list::Request {
114        c2s: futu_proto::trd_get_order_fill_list::C2s {
115            header: header.to_proto(),
116            filter_conditions: None,
117            refresh_cache: None,
118        },
119    };
120
121    let body = prost::Message::encode_to_vec(&req);
122    let resp_frame = client
123        .request(proto_id::TRD_GET_ORDER_FILL_LIST, body)
124        .await?;
125
126    let resp: futu_proto::trd_get_order_fill_list::Response =
127        prost::Message::decode(resp_frame.body.as_ref()).map_err(FutuError::Proto)?;
128
129    if resp.ret_type != 0 {
130        return Err(FutuError::ServerError {
131            ret_type: resp.ret_type,
132            msg: resp.ret_msg.unwrap_or_default(),
133        });
134    }
135
136    let s2c = resp
137        .s2c
138        .ok_or(FutuError::Codec("missing s2c in GetOrderFillList".into()))?;
139
140    Ok(s2c
141        .order_fill_list
142        .iter()
143        .map(OrderFill::from_proto)
144        .collect())
145}