Skip to main content

futu_qot/
order_book.rs

1use futu_core::error::{FutuError, Result};
2use futu_core::proto_id;
3use futu_net::client::FutuClient;
4
5use crate::types::{OrderBookData, OrderBookEntry, Security};
6
7/// 获取摆盘数据
8///
9/// 查询指定股票的买卖盘口数据。需要先订阅 SubType::OrderBook。
10///
11/// - `num`: 请求的摆盘档数 (1~10)
12pub async fn get_order_book(
13    client: &FutuClient,
14    security: &Security,
15    num: i32,
16) -> Result<OrderBookData> {
17    let req = futu_proto::qot_get_order_book::Request {
18        c2s: futu_proto::qot_get_order_book::C2s {
19            security: security.to_proto(),
20            num,
21            header: None,
22        },
23    };
24
25    let body = prost::Message::encode_to_vec(&req);
26    let resp_frame = client.request(proto_id::QOT_GET_ORDER_BOOK, body).await?;
27
28    let resp: futu_proto::qot_get_order_book::Response =
29        prost::Message::decode(resp_frame.body.as_ref()).map_err(FutuError::Proto)?;
30
31    if resp.ret_type != 0 {
32        return Err(FutuError::ServerError {
33            ret_type: resp.ret_type,
34            msg: resp.ret_msg.unwrap_or_default(),
35        });
36    }
37
38    let s2c = resp
39        .s2c
40        .ok_or(FutuError::Codec("missing s2c in GetOrderBook".into()))?;
41
42    Ok(OrderBookData {
43        security: Security::from_proto(&s2c.security),
44        ask_list: s2c
45            .order_book_ask_list
46            .iter()
47            .map(OrderBookEntry::from_proto)
48            .collect(),
49        bid_list: s2c
50            .order_book_bid_list
51            .iter()
52            .map(OrderBookEntry::from_proto)
53            .collect(),
54    })
55}