ibkr_cp_api_client/websocket/
requests.rs

1use serde_json::json;
2
3use crate::models::{contract::Contract, tick_types::TickType};
4
5pub enum SubscriptionType {
6    QuoteData((Vec<TickType>, Contract)),
7    HistoricalData,
8    MarketDepth,
9    Orders,
10    Positions,
11    Trades,
12    ProfitLoss,
13}
14
15pub struct Subscription {
16    pub sub_type: SubscriptionType,
17    pub exchange: Option<String>,
18}
19impl Subscription {
20    pub fn new_smart_quote_data(contract: Contract) -> Self {
21        let tick_types = vec![
22            TickType::BidPrice,
23            TickType::AskPrice,
24            TickType::AskSize,
25            TickType::BidSize,
26            TickType::LastPrice,
27        ];
28        Self {
29            sub_type: SubscriptionType::QuoteData((tick_types, contract)),
30            exchange: None,
31        }
32    }
33    pub fn build(&self) -> String {
34        match &self.sub_type {
35            SubscriptionType::QuoteData((tick_types, contract)) => {
36                let field_list = tick_types
37                    .iter()
38                    .map(|t| serde_json::to_string(t).unwrap())
39                    .collect::<Vec<String>>();
40                let contract_rep = match &self.exchange {
41                    Some(exchange) => format!("{}@{exchange}", contract.conid),
42                    None => contract.conid.to_string(),
43                };
44                let arg_json = json!({ "fields": field_list });
45                format!("smd+{contract_rep}+{}", arg_json)
46            }
47            SubscriptionType::HistoricalData => unimplemented!(),
48            SubscriptionType::MarketDepth => unimplemented!(),
49            SubscriptionType::Orders => unimplemented!(),
50            SubscriptionType::Positions => unimplemented!(),
51            SubscriptionType::Trades => String::from("str+{}"),
52            SubscriptionType::ProfitLoss => unimplemented!(),
53        }
54    }
55}