Skip to main content

futu_mcp/handlers/
plate.rs

1//! 板块 handler
2
3use std::sync::Arc;
4
5use anyhow::Result;
6use futu_net::client::FutuClient;
7use futu_qot::types::QotMarket;
8use futu_surface_spec::input::{parse_plate_market_id, parse_plate_set_id};
9use serde::Serialize;
10
11use crate::qot_sdk_adapter;
12use crate::state::{format_symbol, parse_symbol};
13
14fn parse_market(s: &str) -> Result<QotMarket> {
15    let market = parse_plate_market_id(s)
16        .map_err(|error| anyhow::anyhow!("unknown market {:?}: {error}", error.raw()))?;
17    Ok(qot_sdk_adapter::qot_market_from_id(market))
18}
19
20fn parse_plate_set(s: &str) -> Result<i32> {
21    parse_plate_set_id(s)
22        .map_err(|error| anyhow::anyhow!("unknown plate-set {:?}: {error}", error.raw()))
23}
24
25#[derive(Serialize)]
26struct PlateOut {
27    plate: String,
28    name: String,
29    plate_type: Option<i32>,
30}
31
32pub async fn list_plates(
33    client: &Arc<FutuClient>,
34    market: &str,
35    plate_set: &str,
36) -> Result<String> {
37    let m = parse_market(market)?;
38    let set = parse_plate_set(plate_set)?;
39    let plates = futu_qot::market_misc::get_plate_set(client, m, set).await?;
40    let out: Vec<PlateOut> = plates
41        .iter()
42        .map(|p| PlateOut {
43            plate: format_symbol(&p.security),
44            name: p.name.clone(),
45            plate_type: p.plate_type,
46        })
47        .collect();
48    Ok(serde_json::to_string_pretty(&out)?)
49}
50
51#[derive(Serialize)]
52struct StockOut {
53    symbol: String,
54    id: i64,
55    name: String,
56    sec_type: i32,
57    lot_size: i32,
58    list_time: String,
59    delisting: bool,
60}
61
62pub async fn plate_stocks(client: &Arc<FutuClient>, plate_symbol: &str) -> Result<String> {
63    let plate = parse_symbol(plate_symbol)?;
64    let list = futu_qot::market_misc::get_plate_security(client, &plate).await?;
65    let out: Vec<StockOut> = list
66        .iter()
67        .map(|i| StockOut {
68            symbol: format_symbol(&i.security),
69            id: i.id,
70            name: i.name.clone(),
71            sec_type: i.sec_type,
72            lot_size: i.lot_size,
73            list_time: i.list_time.clone(),
74            delisting: i.delisting,
75        })
76        .collect();
77    Ok(serde_json::to_string_pretty(&out)?)
78}