ibkr_cp_api_client/models/
contract.rs

1use super::definitions::{AssetClass, OptionRight};
2use rust_decimal::Decimal;
3use serde::{Deserialize, Serialize};
4use serde_json::Value;
5#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
6#[serde(rename_all = "camelCase")]
7pub struct SecurityDefinitions {
8    pub secdef: Vec<Contract>,
9}
10
11#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)]
12#[serde(rename_all = "camelCase")]
13#[serde(default)]
14pub struct Contract {
15    #[serde(with = "unpack_exchanges", alias = "exchange")]
16    pub all_exchanges: Vec<String>,
17    pub asset_class: AssetClass,
18    pub chinese_name: String,
19    pub conid: i64,
20    pub country_code: String,
21    pub currency: String,
22    pub display_rule: DisplayRule,
23    pub expiry: Option<String>,
24    pub full_name: String,
25    pub group: Option<String>,
26    pub has_options: bool,
27    pub increment_rules: Vec<IncrementRule>,
28    pub is_event_contract: bool,
29    #[serde(rename = "isUS")]
30    pub is_us: Option<bool>,
31    pub last_trading_day: Option<String>,
32    pub listing_exchange: String,
33    pub multiplier: Decimal,
34    pub name: Option<String>,
35    pub page_size: Option<i64>,
36    pub put_or_call: Option<OptionRight>,
37    pub sector: Option<String>,
38    pub sector_group: Option<String>,
39    pub strike: String,
40    pub ticker: String,
41    pub time: i64,
42    #[serde(rename = "type")]
43    pub type_field: String,
44    pub und_conid: i64,
45    pub cross_currency: Option<bool>,
46    pub und_comp: Option<Value>,
47    pub und_sym: Option<String>,
48}
49impl Contract {
50    pub fn from_con_id(con_id: i64) -> Self {
51        Self {
52            conid: con_id,
53            ..Default::default()
54        }
55    }
56}
57#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
58#[serde(rename_all = "camelCase")]
59pub struct DisplayRule {
60    pub display_rule_step: Vec<DisplayRuleStep>,
61    pub magnification: i64,
62}
63
64#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
65#[serde(rename_all = "camelCase")]
66pub struct DisplayRuleStep {
67    pub decimal_digits: i64,
68    #[serde(with = "rust_decimal::serde::float")]
69    pub lower_edge: Decimal,
70    pub whole_digits: i64,
71}
72
73#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
74#[serde(rename_all = "camelCase")]
75pub struct IncrementRule {
76    #[serde(with = "rust_decimal::serde::float")]
77    pub increment: Decimal,
78    #[serde(with = "rust_decimal::serde::float")]
79    pub lower_edge: Decimal,
80}
81
82pub mod unpack_exchanges {
83    use serde::{self, Deserialize, Deserializer, Serializer};
84
85    pub fn serialize<S>(exchanges: &[String], serializer: S) -> Result<S::Ok, S::Error>
86    where
87        S: Serializer,
88    {
89        let s = exchanges
90            .iter()
91            .map(|e| e.to_string())
92            .collect::<Vec<String>>()
93            .join(",");
94        serializer.serialize_str(&s)
95    }
96
97    pub fn deserialize<'de, D>(deserializer: D) -> Result<Vec<String>, D::Error>
98    where
99        D: Deserializer<'de>,
100    {
101        let s = String::deserialize(deserializer)?;
102        let exchanges: Vec<String> = s.split(',').map(|e| e.trim().to_string()).collect();
103
104        Ok(exchanges)
105    }
106}