1use std::{fmt::Display, str::FromStr};
19
20#[derive(Debug, Clone, Copy, PartialEq, Eq)]
22#[cfg_attr(
23 feature = "python",
24 pyo3::pyclass(
25 module = "nautilus_trader.adapters.interactive_brokers",
26 from_py_object,
27 rename_all = "SCREAMING_SNAKE_CASE"
28 )
29)]
30#[cfg_attr(
31 feature = "python",
32 pyo3_stub_gen::derive::gen_stub_pyclass_enum(
33 module = "nautilus_trader.adapters.interactive_brokers"
34 )
35)]
36pub enum IbHistoricalTickType {
37 Trades,
39 BidAsk,
41}
42
43impl IbHistoricalTickType {
44 #[must_use]
46 pub const fn as_str(self) -> &'static str {
47 match self {
48 Self::Trades => "TRADES",
49 Self::BidAsk => "BID_ASK",
50 }
51 }
52}
53
54impl FromStr for IbHistoricalTickType {
55 type Err = anyhow::Error;
56
57 fn from_str(value: &str) -> Result<Self, Self::Err> {
58 match value.to_ascii_uppercase().as_str() {
59 "TRADES" => Ok(Self::Trades),
60 "BID_ASK" => Ok(Self::BidAsk),
61 _ => anyhow::bail!("Unknown IB historical tick type: {value}"),
62 }
63 }
64}
65
66impl Display for IbHistoricalTickType {
67 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
68 f.write_str(self.as_str())
69 }
70}
71
72#[derive(Debug, Clone, Copy, PartialEq, Eq)]
74#[cfg_attr(
75 feature = "python",
76 pyo3::pyclass(
77 module = "nautilus_trader.adapters.interactive_brokers",
78 from_py_object,
79 rename_all = "SCREAMING_SNAKE_CASE"
80 )
81)]
82#[cfg_attr(
83 feature = "python",
84 pyo3_stub_gen::derive::gen_stub_pyclass_enum(
85 module = "nautilus_trader.adapters.interactive_brokers"
86 )
87)]
88pub enum IbTradingHours {
89 Regular,
91 Extended,
93}
94
95impl IbTradingHours {
96 #[must_use]
98 pub const fn use_rth(self) -> bool {
99 matches!(self, Self::Regular)
100 }
101
102 #[must_use]
104 pub const fn ibapi_trading_hours(self) -> ibapi::market_data::TradingHours {
105 match self {
106 Self::Regular => ibapi::market_data::TradingHours::Regular,
107 Self::Extended => ibapi::market_data::TradingHours::Extended,
108 }
109 }
110}
111
112impl From<bool> for IbTradingHours {
113 fn from(use_rth: bool) -> Self {
114 if use_rth {
115 Self::Regular
116 } else {
117 Self::Extended
118 }
119 }
120}
121
122#[derive(Debug, Clone, Copy, PartialEq, Eq)]
124#[cfg_attr(
125 feature = "python",
126 pyo3::pyclass(
127 module = "nautilus_trader.adapters.interactive_brokers",
128 from_py_object,
129 rename_all = "SCREAMING_SNAKE_CASE"
130 )
131)]
132#[cfg_attr(
133 feature = "python",
134 pyo3_stub_gen::derive::gen_stub_pyclass_enum(
135 module = "nautilus_trader.adapters.interactive_brokers"
136 )
137)]
138pub enum IbHistoricalBarSize {
139 Sec,
140 Sec5,
141 Sec10,
142 Sec15,
143 Sec30,
144 Min,
145 Min2,
146 Min3,
147 Min5,
148 Min10,
149 Min15,
150 Min20,
151 Min30,
152 Hour,
153 Hour2,
154 Hour3,
155 Hour4,
156 Hour8,
157 Day,
158 Week,
159 Month,
160}
161
162impl IbHistoricalBarSize {
163 #[must_use]
165 pub const fn ibapi_bar_size(self) -> ibapi::market_data::historical::BarSize {
166 match self {
167 Self::Sec => ibapi::market_data::historical::BarSize::Sec,
168 Self::Sec5 => ibapi::market_data::historical::BarSize::Sec5,
169 Self::Sec10 => ibapi::market_data::historical::BarSize::Sec10,
170 Self::Sec15 => ibapi::market_data::historical::BarSize::Sec15,
171 Self::Sec30 => ibapi::market_data::historical::BarSize::Sec30,
172 Self::Min => ibapi::market_data::historical::BarSize::Min,
173 Self::Min2 => ibapi::market_data::historical::BarSize::Min2,
174 Self::Min3 => ibapi::market_data::historical::BarSize::Min3,
175 Self::Min5 => ibapi::market_data::historical::BarSize::Min5,
176 Self::Min10 => ibapi::market_data::historical::BarSize::Min10,
177 Self::Min15 => ibapi::market_data::historical::BarSize::Min15,
178 Self::Min20 => ibapi::market_data::historical::BarSize::Min20,
179 Self::Min30 => ibapi::market_data::historical::BarSize::Min30,
180 Self::Hour => ibapi::market_data::historical::BarSize::Hour,
181 Self::Hour2 => ibapi::market_data::historical::BarSize::Hour2,
182 Self::Hour3 => ibapi::market_data::historical::BarSize::Hour3,
183 Self::Hour4 => ibapi::market_data::historical::BarSize::Hour4,
184 Self::Hour8 => ibapi::market_data::historical::BarSize::Hour8,
185 Self::Day => ibapi::market_data::historical::BarSize::Day,
186 Self::Week => ibapi::market_data::historical::BarSize::Week,
187 Self::Month => ibapi::market_data::historical::BarSize::Month,
188 }
189 }
190}
191
192impl Display for IbHistoricalBarSize {
193 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
194 write!(f, "{}", self.ibapi_bar_size())
195 }
196}
197
198#[derive(Debug, Clone, Copy, PartialEq, Eq)]
200#[cfg_attr(
201 feature = "python",
202 pyo3::pyclass(
203 module = "nautilus_trader.adapters.interactive_brokers",
204 from_py_object,
205 rename_all = "SCREAMING_SNAKE_CASE"
206 )
207)]
208#[cfg_attr(
209 feature = "python",
210 pyo3_stub_gen::derive::gen_stub_pyclass_enum(
211 module = "nautilus_trader.adapters.interactive_brokers"
212 )
213)]
214pub enum IbHistoricalWhatToShow {
215 Trades,
216 Midpoint,
217 Bid,
218 Ask,
219 BidAsk,
220 HistoricalVolatility,
221 OptionImpliedVolatility,
222 FeeRate,
223 Schedule,
224 AdjustedLast,
225}
226
227impl IbHistoricalWhatToShow {
228 #[must_use]
230 pub const fn as_str(self) -> &'static str {
231 match self {
232 Self::Trades => "TRADES",
233 Self::Midpoint => "MIDPOINT",
234 Self::Bid => "BID",
235 Self::Ask => "ASK",
236 Self::BidAsk => "BID_ASK",
237 Self::HistoricalVolatility => "HISTORICAL_VOLATILITY",
238 Self::OptionImpliedVolatility => "OPTION_IMPLIED_VOLATILITY",
239 Self::FeeRate => "FEE_RATE",
240 Self::Schedule => "SCHEDULE",
241 Self::AdjustedLast => "ADJUSTED_LAST",
242 }
243 }
244
245 #[must_use]
247 pub const fn ibapi_what_to_show(self) -> ibapi::market_data::historical::WhatToShow {
248 match self {
249 Self::Trades => ibapi::market_data::historical::WhatToShow::Trades,
250 Self::Midpoint => ibapi::market_data::historical::WhatToShow::MidPoint,
251 Self::Bid => ibapi::market_data::historical::WhatToShow::Bid,
252 Self::Ask => ibapi::market_data::historical::WhatToShow::Ask,
253 Self::BidAsk => ibapi::market_data::historical::WhatToShow::BidAsk,
254 Self::HistoricalVolatility => {
255 ibapi::market_data::historical::WhatToShow::HistoricalVolatility
256 }
257 Self::OptionImpliedVolatility => {
258 ibapi::market_data::historical::WhatToShow::OptionImpliedVolatility
259 }
260 Self::FeeRate => ibapi::market_data::historical::WhatToShow::FeeRate,
261 Self::Schedule => ibapi::market_data::historical::WhatToShow::Schedule,
262 Self::AdjustedLast => ibapi::market_data::historical::WhatToShow::AdjustedLast,
263 }
264 }
265}
266
267impl Display for IbHistoricalWhatToShow {
268 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
269 f.write_str(self.as_str())
270 }
271}
272
273#[derive(Debug, Clone, Copy, PartialEq, Eq)]
275#[cfg_attr(
276 feature = "python",
277 pyo3::pyclass(
278 module = "nautilus_trader.adapters.interactive_brokers",
279 from_py_object,
280 rename_all = "SCREAMING_SNAKE_CASE"
281 )
282)]
283#[cfg_attr(
284 feature = "python",
285 pyo3_stub_gen::derive::gen_stub_pyclass_enum(
286 module = "nautilus_trader.adapters.interactive_brokers"
287 )
288)]
289pub enum IbRealtimeBarSize {
290 Sec5,
291}
292
293impl Display for IbRealtimeBarSize {
294 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
295 match self {
296 Self::Sec5 => f.write_str("5 secs"),
297 }
298 }
299}
300
301#[derive(Debug, Clone, Copy, PartialEq, Eq)]
303#[cfg_attr(
304 feature = "python",
305 pyo3::pyclass(
306 module = "nautilus_trader.adapters.interactive_brokers",
307 from_py_object,
308 rename_all = "SCREAMING_SNAKE_CASE"
309 )
310)]
311#[cfg_attr(
312 feature = "python",
313 pyo3_stub_gen::derive::gen_stub_pyclass_enum(
314 module = "nautilus_trader.adapters.interactive_brokers"
315 )
316)]
317pub enum IbRealtimeWhatToShow {
318 Trades,
319 Midpoint,
320 Bid,
321 Ask,
322}
323
324impl IbRealtimeWhatToShow {
325 #[must_use]
327 pub const fn as_str(self) -> &'static str {
328 match self {
329 Self::Trades => "TRADES",
330 Self::Midpoint => "MIDPOINT",
331 Self::Bid => "BID",
332 Self::Ask => "ASK",
333 }
334 }
335
336 #[must_use]
338 pub const fn ibapi_what_to_show(self) -> ibapi::market_data::realtime::WhatToShow {
339 match self {
340 Self::Trades => ibapi::market_data::realtime::WhatToShow::Trades,
341 Self::Midpoint => ibapi::market_data::realtime::WhatToShow::MidPoint,
342 Self::Bid => ibapi::market_data::realtime::WhatToShow::Bid,
343 Self::Ask => ibapi::market_data::realtime::WhatToShow::Ask,
344 }
345 }
346}
347
348impl Display for IbRealtimeWhatToShow {
349 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
350 f.write_str(self.as_str())
351 }
352}
353
354#[derive(Debug, Clone, Copy, PartialEq, Eq)]
356#[cfg_attr(
357 feature = "python",
358 pyo3::pyclass(
359 module = "nautilus_trader.adapters.interactive_brokers",
360 from_py_object,
361 rename_all = "SCREAMING_SNAKE_CASE"
362 )
363)]
364#[cfg_attr(
365 feature = "python",
366 pyo3_stub_gen::derive::gen_stub_pyclass_enum(
367 module = "nautilus_trader.adapters.interactive_brokers"
368 )
369)]
370pub enum IbTickType {
371 Unknown,
372 BidSize,
373 Bid,
374 Ask,
375 AskSize,
376 Last,
377 LastSize,
378 High,
379 Low,
380 Volume,
381 Close,
382 BidOption,
383 AskOption,
384 LastOption,
385 ModelOption,
386 Open,
387 Low13Week,
388 High13Week,
389 Low26Week,
390 High26Week,
391 Low52Week,
392 High52Week,
393 AvgVolume,
394 OpenInterest,
395 OptionHistoricalVol,
396 OptionImpliedVol,
397 OptionBidExch,
398 OptionAskExch,
399 OptionCallOpenInterest,
400 OptionPutOpenInterest,
401 OptionCallVolume,
402 OptionPutVolume,
403 IndexFuturePremium,
404 BidExch,
405 AskExch,
406 AuctionVolume,
407 AuctionPrice,
408 AuctionImbalance,
409 MarkPrice,
410 BidEfpComputation,
411 AskEfpComputation,
412 LastEfpComputation,
413 OpenEfpComputation,
414 HighEfpComputation,
415 LowEfpComputation,
416 CloseEfpComputation,
417 LastTimestamp,
418 Shortable,
419 FundamentalRatios,
420 RtVolume,
421 Halted,
422 BidYield,
423 AskYield,
424 LastYield,
425 CustOptionComputation,
426 TradeCount,
427 TradeRate,
428 VolumeRate,
429 LastRthTrade,
430 RtHistoricalVol,
431 IbDividends,
432 BondFactorMultiplier,
433 RegulatoryImbalance,
434 NewsTick,
435 ShortTermVolume3Min,
436 ShortTermVolume5Min,
437 ShortTermVolume10Min,
438 DelayedBid,
439 DelayedAsk,
440 DelayedLast,
441 DelayedBidSize,
442 DelayedAskSize,
443 DelayedLastSize,
444 DelayedHigh,
445 DelayedLow,
446 DelayedVolume,
447 DelayedClose,
448 DelayedOpen,
449 RtTrdVolume,
450 CreditmanMarkPrice,
451 CreditmanSlowMarkPrice,
452 DelayedBidOption,
453 DelayedAskOption,
454 DelayedLastOption,
455 DelayedModelOption,
456 LastExch,
457 LastRegTime,
458 FuturesOpenInterest,
459 AvgOptVolume,
460 DelayedLastTimestamp,
461 ShortableShares,
462 DelayedHalted,
463 Reuters2MutualFunds,
464 EtfNavClose,
465 EtfNavPriorClose,
466 EtfNavBid,
467 EtfNavAsk,
468 EtfNavLast,
469 EtfFrozenNavLast,
470 EtfNavHigh,
471 EtfNavLow,
472 SocialMarketAnalytics,
473 EstimatedIpoMidpoint,
474 FinalIpoLast,
475 DelayedYieldBid,
476 DelayedYieldAsk,
477}
478
479impl IbTickType {
480 #[must_use]
482 pub const fn as_i32(self) -> i32 {
483 match self {
484 Self::Unknown => -1,
485 Self::BidSize => 0,
486 Self::Bid => 1,
487 Self::Ask => 2,
488 Self::AskSize => 3,
489 Self::Last => 4,
490 Self::LastSize => 5,
491 Self::High => 6,
492 Self::Low => 7,
493 Self::Volume => 8,
494 Self::Close => 9,
495 Self::BidOption => 10,
496 Self::AskOption => 11,
497 Self::LastOption => 12,
498 Self::ModelOption => 13,
499 Self::Open => 14,
500 Self::Low13Week => 15,
501 Self::High13Week => 16,
502 Self::Low26Week => 17,
503 Self::High26Week => 18,
504 Self::Low52Week => 19,
505 Self::High52Week => 20,
506 Self::AvgVolume => 21,
507 Self::OpenInterest => 22,
508 Self::OptionHistoricalVol => 23,
509 Self::OptionImpliedVol => 24,
510 Self::OptionBidExch => 25,
511 Self::OptionAskExch => 26,
512 Self::OptionCallOpenInterest => 27,
513 Self::OptionPutOpenInterest => 28,
514 Self::OptionCallVolume => 29,
515 Self::OptionPutVolume => 30,
516 Self::IndexFuturePremium => 31,
517 Self::BidExch => 32,
518 Self::AskExch => 33,
519 Self::AuctionVolume => 34,
520 Self::AuctionPrice => 35,
521 Self::AuctionImbalance => 36,
522 Self::MarkPrice => 37,
523 Self::BidEfpComputation => 38,
524 Self::AskEfpComputation => 39,
525 Self::LastEfpComputation => 40,
526 Self::OpenEfpComputation => 41,
527 Self::HighEfpComputation => 42,
528 Self::LowEfpComputation => 43,
529 Self::CloseEfpComputation => 44,
530 Self::LastTimestamp => 45,
531 Self::Shortable => 46,
532 Self::FundamentalRatios => 47,
533 Self::RtVolume => 48,
534 Self::Halted => 49,
535 Self::BidYield => 50,
536 Self::AskYield => 51,
537 Self::LastYield => 52,
538 Self::CustOptionComputation => 53,
539 Self::TradeCount => 54,
540 Self::TradeRate => 55,
541 Self::VolumeRate => 56,
542 Self::LastRthTrade => 57,
543 Self::RtHistoricalVol => 58,
544 Self::IbDividends => 59,
545 Self::BondFactorMultiplier => 60,
546 Self::RegulatoryImbalance => 61,
547 Self::NewsTick => 62,
548 Self::ShortTermVolume3Min => 63,
549 Self::ShortTermVolume5Min => 64,
550 Self::ShortTermVolume10Min => 65,
551 Self::DelayedBid => 66,
552 Self::DelayedAsk => 67,
553 Self::DelayedLast => 68,
554 Self::DelayedBidSize => 69,
555 Self::DelayedAskSize => 70,
556 Self::DelayedLastSize => 71,
557 Self::DelayedHigh => 72,
558 Self::DelayedLow => 73,
559 Self::DelayedVolume => 74,
560 Self::DelayedClose => 75,
561 Self::DelayedOpen => 76,
562 Self::RtTrdVolume => 77,
563 Self::CreditmanMarkPrice => 78,
564 Self::CreditmanSlowMarkPrice => 79,
565 Self::DelayedBidOption => 80,
566 Self::DelayedAskOption => 81,
567 Self::DelayedLastOption => 82,
568 Self::DelayedModelOption => 83,
569 Self::LastExch => 84,
570 Self::LastRegTime => 85,
571 Self::FuturesOpenInterest => 86,
572 Self::AvgOptVolume => 87,
573 Self::DelayedLastTimestamp => 88,
574 Self::ShortableShares => 89,
575 Self::DelayedHalted => 90,
576 Self::Reuters2MutualFunds => 91,
577 Self::EtfNavClose => 92,
578 Self::EtfNavPriorClose => 93,
579 Self::EtfNavBid => 94,
580 Self::EtfNavAsk => 95,
581 Self::EtfNavLast => 96,
582 Self::EtfFrozenNavLast => 97,
583 Self::EtfNavHigh => 98,
584 Self::EtfNavLow => 99,
585 Self::SocialMarketAnalytics => 100,
586 Self::EstimatedIpoMidpoint => 101,
587 Self::FinalIpoLast => 102,
588 Self::DelayedYieldBid => 103,
589 Self::DelayedYieldAsk => 104,
590 }
591 }
592
593 #[must_use]
595 pub fn ibapi_tick_type(self) -> ibapi::contracts::tick_types::TickType {
596 ibapi::contracts::tick_types::TickType::from(self.as_i32())
597 }
598}
599
600impl From<i32> for IbTickType {
601 fn from(value: i32) -> Self {
602 match value {
603 0 => Self::BidSize,
604 1 => Self::Bid,
605 2 => Self::Ask,
606 3 => Self::AskSize,
607 4 => Self::Last,
608 5 => Self::LastSize,
609 6 => Self::High,
610 7 => Self::Low,
611 8 => Self::Volume,
612 9 => Self::Close,
613 10 => Self::BidOption,
614 11 => Self::AskOption,
615 12 => Self::LastOption,
616 13 => Self::ModelOption,
617 14 => Self::Open,
618 15 => Self::Low13Week,
619 16 => Self::High13Week,
620 17 => Self::Low26Week,
621 18 => Self::High26Week,
622 19 => Self::Low52Week,
623 20 => Self::High52Week,
624 21 => Self::AvgVolume,
625 22 => Self::OpenInterest,
626 23 => Self::OptionHistoricalVol,
627 24 => Self::OptionImpliedVol,
628 25 => Self::OptionBidExch,
629 26 => Self::OptionAskExch,
630 27 => Self::OptionCallOpenInterest,
631 28 => Self::OptionPutOpenInterest,
632 29 => Self::OptionCallVolume,
633 30 => Self::OptionPutVolume,
634 31 => Self::IndexFuturePremium,
635 32 => Self::BidExch,
636 33 => Self::AskExch,
637 34 => Self::AuctionVolume,
638 35 => Self::AuctionPrice,
639 36 => Self::AuctionImbalance,
640 37 => Self::MarkPrice,
641 38 => Self::BidEfpComputation,
642 39 => Self::AskEfpComputation,
643 40 => Self::LastEfpComputation,
644 41 => Self::OpenEfpComputation,
645 42 => Self::HighEfpComputation,
646 43 => Self::LowEfpComputation,
647 44 => Self::CloseEfpComputation,
648 45 => Self::LastTimestamp,
649 46 => Self::Shortable,
650 47 => Self::FundamentalRatios,
651 48 => Self::RtVolume,
652 49 => Self::Halted,
653 50 => Self::BidYield,
654 51 => Self::AskYield,
655 52 => Self::LastYield,
656 53 => Self::CustOptionComputation,
657 54 => Self::TradeCount,
658 55 => Self::TradeRate,
659 56 => Self::VolumeRate,
660 57 => Self::LastRthTrade,
661 58 => Self::RtHistoricalVol,
662 59 => Self::IbDividends,
663 60 => Self::BondFactorMultiplier,
664 61 => Self::RegulatoryImbalance,
665 62 => Self::NewsTick,
666 63 => Self::ShortTermVolume3Min,
667 64 => Self::ShortTermVolume5Min,
668 65 => Self::ShortTermVolume10Min,
669 66 => Self::DelayedBid,
670 67 => Self::DelayedAsk,
671 68 => Self::DelayedLast,
672 69 => Self::DelayedBidSize,
673 70 => Self::DelayedAskSize,
674 71 => Self::DelayedLastSize,
675 72 => Self::DelayedHigh,
676 73 => Self::DelayedLow,
677 74 => Self::DelayedVolume,
678 75 => Self::DelayedClose,
679 76 => Self::DelayedOpen,
680 77 => Self::RtTrdVolume,
681 78 => Self::CreditmanMarkPrice,
682 79 => Self::CreditmanSlowMarkPrice,
683 80 => Self::DelayedBidOption,
684 81 => Self::DelayedAskOption,
685 82 => Self::DelayedLastOption,
686 83 => Self::DelayedModelOption,
687 84 => Self::LastExch,
688 85 => Self::LastRegTime,
689 86 => Self::FuturesOpenInterest,
690 87 => Self::AvgOptVolume,
691 88 => Self::DelayedLastTimestamp,
692 89 => Self::ShortableShares,
693 90 => Self::DelayedHalted,
694 91 => Self::Reuters2MutualFunds,
695 92 => Self::EtfNavClose,
696 93 => Self::EtfNavPriorClose,
697 94 => Self::EtfNavBid,
698 95 => Self::EtfNavAsk,
699 96 => Self::EtfNavLast,
700 97 => Self::EtfFrozenNavLast,
701 98 => Self::EtfNavHigh,
702 99 => Self::EtfNavLow,
703 100 => Self::SocialMarketAnalytics,
704 101 => Self::EstimatedIpoMidpoint,
705 102 => Self::FinalIpoLast,
706 103 => Self::DelayedYieldBid,
707 104 => Self::DelayedYieldAsk,
708 _ => Self::Unknown,
709 }
710 }
711}
712
713impl Display for IbTickType {
714 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
715 write!(f, "{}", self.as_i32())
716 }
717}