rustrade_execution/client/ibkr/
contract.rs1use ibapi::contracts::{Contract, Currency, Exchange, OptionRight, SecurityType, Symbol};
4
5#[derive(Debug, Clone, PartialEq, Eq)]
15pub struct InvalidOptionRight(String);
16
17impl InvalidOptionRight {
18 #[must_use]
20 pub fn right(&self) -> &str {
21 &self.0
22 }
23}
24
25impl std::fmt::Display for InvalidOptionRight {
26 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
27 write!(
28 f,
29 "unrecognized option right {:?} (expected one of C/CALL/P/PUT)",
30 self.0
31 )
32 }
33}
34
35impl std::error::Error for InvalidOptionRight {}
36
37fn parse_option_right(right: &str) -> Option<OptionRight> {
42 let right = right.trim();
43 if right.eq_ignore_ascii_case("C") || right.eq_ignore_ascii_case("CALL") {
44 Some(OptionRight::Call)
45 } else if right.eq_ignore_ascii_case("P") || right.eq_ignore_ascii_case("PUT") {
46 Some(OptionRight::Put)
47 } else {
48 None
49 }
50}
51
52pub fn stock_contract(symbol: &str, exchange: &str, currency: &str) -> Contract {
54 Contract::stock(symbol)
55 .on_exchange(exchange)
56 .in_currency(currency)
57 .build()
58}
59
60pub fn futures_contract(
62 symbol: &str,
63 last_trade_date: &str,
64 exchange: &str,
65 currency: &str,
66) -> Contract {
67 Contract {
68 symbol: Symbol::new(symbol),
69 security_type: SecurityType::Future,
70 last_trade_date_or_contract_month: last_trade_date.to_string(),
71 exchange: Exchange::new(exchange),
72 currency: Currency::new(currency),
73 ..Default::default()
74 }
75}
76
77pub fn option_contract(
86 symbol: &str,
87 last_trade_date: &str,
88 strike: f64,
89 right: &str,
90 exchange: &str,
91 currency: &str,
92) -> Result<Contract, InvalidOptionRight> {
93 let right = parse_option_right(right).ok_or_else(|| InvalidOptionRight(right.to_string()))?;
94 Ok(Contract {
95 symbol: Symbol::new(symbol),
96 security_type: SecurityType::Option,
97 last_trade_date_or_contract_month: last_trade_date.to_string(),
98 strike,
99 right: Some(right),
100 exchange: Exchange::new(exchange),
101 currency: Currency::new(currency),
102 ..Default::default()
103 })
104}
105
106pub fn forex_contract(symbol: &str, currency: &str) -> Contract {
108 Contract {
109 symbol: Symbol::new(symbol),
110 security_type: SecurityType::ForexPair,
111 exchange: Exchange::new("IDEALPRO"),
112 currency: Currency::new(currency),
113 ..Default::default()
114 }
115}