Skip to main content

truefix_twsapi_client/
types.rs

1use rust_decimal::Decimal;
2
3use crate::constants::{UNSET_DOUBLE, UNSET_INTEGER};
4use crate::enums::{OptionExerciseType, TriggerMethod};
5
6/// Market data ticker id.
7pub type TickerId = i32;
8/// TWS order id.
9pub type OrderId = i32;
10/// Financial-advisor data type.
11pub type FaDataType = i32;
12
13/// A generic tag/value pair.
14#[derive(Debug, Clone, Default, PartialEq, Eq)]
15pub struct TagValue {
16    /// Tag name.
17    pub tag: String,
18    /// Tag value.
19    pub value: String,
20}
21
22/// Soft-dollar tier metadata.
23#[derive(Debug, Clone, Default, PartialEq, Eq)]
24pub struct SoftDollarTier {
25    /// Tier name.
26    pub name: String,
27    /// Tier value.
28    pub value: String,
29    /// Display name.
30    pub display_name: String,
31}
32
33/// A reason why a contract cannot be traded.
34#[derive(Debug, Clone, Default, PartialEq, Eq)]
35pub struct IneligibilityReason {
36    pub id: String,
37    pub description: String,
38}
39
40/// A market-depth exchange description.
41#[derive(Debug, Clone, Default, PartialEq, Eq)]
42pub struct DepthMarketDataDescription {
43    pub exchange: String,
44    pub security_type: String,
45    pub listing_exchange: String,
46    pub service_data_type: String,
47    pub aggregate_group: i32,
48}
49
50/// Price increment for a market rule.
51#[derive(Debug, Clone, Copy, Default, PartialEq)]
52pub struct PriceIncrement {
53    pub low_edge: f64,
54    pub increment: f64,
55}
56
57/// A price/size bucket returned by `reqHistogramData`.
58#[derive(Debug, Clone, Default, PartialEq)]
59pub struct HistogramEntry {
60    pub price: f64,
61    pub size: Decimal,
62}
63
64/// Account family-code mapping.
65#[derive(Debug, Clone, Default, PartialEq, Eq)]
66pub struct FamilyCode {
67    pub account_id: String,
68    pub family_code: String,
69}
70
71/// News provider metadata.
72#[derive(Debug, Clone, Default, PartialEq, Eq)]
73pub struct NewsProvider {
74    pub code: String,
75    pub name: String,
76}
77
78/// Structured WSH event payload. The original JSON is retained for fields added by IB later.
79#[derive(Debug, Clone, Default, PartialEq, Eq)]
80pub struct WshEventData {
81    pub req_id: i32,
82    pub con_id: i32,
83    pub filter: String,
84    pub fill_watchlist: bool,
85    pub fill_portfolio: bool,
86    pub fill_position: bool,
87    pub fill_account: bool,
88    pub data_json: String,
89}
90
91impl WshEventData {
92    /// Parses the standard WSH JSON fields while retaining the original payload.
93    pub fn from_json(req_id: i32, data_json: impl Into<String>) -> Self {
94        let data_json = data_json.into();
95        #[derive(serde::Deserialize, Default)]
96        struct Raw {
97            #[serde(rename = "conId", default)]
98            con_id: i32,
99            #[serde(default)]
100            filter: String,
101            #[serde(rename = "fillWatchlist", default)]
102            fill_watchlist: bool,
103            #[serde(rename = "fillPortfolio", default)]
104            fill_portfolio: bool,
105            #[serde(rename = "fillPosition", default)]
106            fill_position: bool,
107            #[serde(rename = "fillAccount", default)]
108            fill_account: bool,
109        }
110        let raw = serde_json::from_str::<Raw>(&data_json).unwrap_or_default();
111        Self {
112            req_id,
113            con_id: raw.con_id,
114            filter: raw.filter,
115            fill_watchlist: raw.fill_watchlist,
116            fill_portfolio: raw.fill_portfolio,
117            fill_position: raw.fill_position,
118            fill_account: raw.fill_account,
119            data_json,
120        }
121    }
122}
123
124/// Combo leg open/close value.
125#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
126#[repr(i32)]
127pub enum LegOpenClose {
128    /// Same as combo.
129    #[default]
130    SamePosition = 0,
131    /// Open position.
132    OpenPosition = 1,
133    /// Close position.
134    ClosePosition = 2,
135    /// Unknown.
136    Unknown = 3,
137}
138
139/// Contract combo leg.
140#[derive(Debug, Clone, PartialEq, Eq)]
141pub struct ComboLeg {
142    /// Contract id.
143    pub con_id: i32,
144    /// Leg ratio.
145    pub ratio: i32,
146    /// BUY/SELL/SHORT.
147    pub action: String,
148    /// Exchange.
149    pub exchange: String,
150    /// Open/close marker.
151    pub open_close: LegOpenClose,
152    /// Short-sale slot.
153    pub short_sale_slot: i32,
154    /// Designated location.
155    pub designated_location: String,
156    /// Exempt code.
157    pub exempt_code: i32,
158}
159
160impl Default for ComboLeg {
161    fn default() -> Self {
162        Self {
163            con_id: 0,
164            ratio: 0,
165            action: String::new(),
166            exchange: String::new(),
167            open_close: LegOpenClose::SamePosition,
168            short_sale_slot: 0,
169            designated_location: String::new(),
170            exempt_code: -1,
171        }
172    }
173}
174
175/// Delta-neutral contract.
176#[derive(Debug, Clone, Default, PartialEq)]
177pub struct DeltaNeutralContract {
178    /// Contract id.
179    pub con_id: i32,
180    /// Delta.
181    pub delta: f64,
182    /// Price.
183    pub price: f64,
184}
185
186/// TWS contract.
187#[derive(Debug, Clone, PartialEq)]
188pub struct Contract {
189    /// Contract id.
190    pub con_id: i32,
191    /// Symbol.
192    pub symbol: String,
193    /// Security type.
194    pub sec_type: String,
195    /// Last trade date or contract month.
196    pub last_trade_date_or_contract_month: String,
197    /// Last trade date.
198    pub last_trade_date: String,
199    /// Strike.
200    pub strike: f64,
201    /// Right.
202    pub right: String,
203    /// Multiplier.
204    pub multiplier: String,
205    /// Exchange.
206    pub exchange: String,
207    /// Primary exchange.
208    pub primary_exchange: String,
209    /// Currency.
210    pub currency: String,
211    /// Local symbol.
212    pub local_symbol: String,
213    /// Trading class.
214    pub trading_class: String,
215    /// Include expired contracts.
216    pub include_expired: bool,
217    /// Security id type.
218    pub sec_id_type: String,
219    /// Security id.
220    pub sec_id: String,
221    /// Description.
222    pub description: String,
223    /// Issuer id.
224    pub issuer_id: String,
225    /// Combo legs description.
226    pub combo_legs_description: String,
227    /// Combo legs.
228    pub combo_legs: Vec<ComboLeg>,
229    /// Optional delta-neutral contract.
230    pub delta_neutral_contract: Option<DeltaNeutralContract>,
231}
232
233impl Default for Contract {
234    fn default() -> Self {
235        Self {
236            con_id: 0,
237            symbol: String::new(),
238            sec_type: String::new(),
239            last_trade_date_or_contract_month: String::new(),
240            last_trade_date: String::new(),
241            strike: UNSET_DOUBLE,
242            right: String::new(),
243            multiplier: String::new(),
244            exchange: String::new(),
245            primary_exchange: String::new(),
246            currency: String::new(),
247            local_symbol: String::new(),
248            trading_class: String::new(),
249            include_expired: false,
250            sec_id_type: String::new(),
251            sec_id: String::new(),
252            description: String::new(),
253            issuer_id: String::new(),
254            combo_legs_description: String::new(),
255            combo_legs: Vec::new(),
256            delta_neutral_contract: None,
257        }
258    }
259}
260
261/// Contract details returned by TWS.
262#[derive(Debug, Clone, Default, PartialEq)]
263pub struct ContractDetails {
264    /// Contract.
265    pub contract: Contract,
266    /// Market name.
267    pub market_name: String,
268    /// Minimum tick.
269    pub min_tick: f64,
270    /// Supported order types.
271    pub order_types: String,
272    /// Valid exchanges.
273    pub valid_exchanges: String,
274    /// Price magnifier.
275    pub price_magnifier: i32,
276    /// Underlying conId.
277    pub under_con_id: i32,
278    /// Long name.
279    pub long_name: String,
280    /// Contract month.
281    pub contract_month: String,
282    /// Industry.
283    pub industry: String,
284    /// Category.
285    pub category: String,
286    /// Subcategory.
287    pub subcategory: String,
288    /// Time zone id.
289    pub time_zone_id: String,
290    /// Trading hours.
291    pub trading_hours: String,
292    /// Liquid hours.
293    pub liquid_hours: String,
294    /// Economic value rule.
295    pub ev_rule: String,
296    /// Economic value multiplier.
297    pub ev_multiplier: f64,
298    /// Security identifiers returned by TWS.
299    pub sec_id_list: Vec<TagValue>,
300    /// Market-data aggregation group.
301    pub aggregate_group: i32,
302    /// Underlying symbol.
303    pub under_symbol: String,
304    /// Underlying security type.
305    pub under_sec_type: String,
306    /// Market rule ids.
307    pub market_rule_ids: String,
308    /// CUSIP.
309    pub cusip: String,
310    /// Issue date.
311    pub issue_date: String,
312    /// Ratings.
313    pub ratings: String,
314    /// Bond type.
315    pub bond_type: String,
316    /// Coupon.
317    pub coupon: f64,
318    /// Coupon type.
319    pub coupon_type: String,
320    /// Convertible flag.
321    pub convertible: bool,
322    /// Callable flag.
323    pub callable: bool,
324    /// Puttable flag.
325    pub puttable: bool,
326    /// Description append.
327    pub desc_append: String,
328    /// Next option date.
329    pub next_option_date: String,
330    /// Next option type.
331    pub next_option_type: String,
332    /// Next option partial flag.
333    pub next_option_partial: bool,
334    /// Bond notes.
335    pub bond_notes: String,
336    /// Real expiration date.
337    pub real_expiration_date: String,
338    /// Stock type.
339    pub stock_type: String,
340    /// Minimum order size.
341    pub min_size: Decimal,
342    /// Order-size increment.
343    pub size_increment: Decimal,
344    /// Suggested order-size increment.
345    pub suggested_size_increment: Decimal,
346    /// Fund name.
347    pub fund_name: String,
348    /// Fund family.
349    pub fund_family: String,
350    /// Fund type code.
351    pub fund_type: String,
352    /// Fund front load.
353    pub fund_front_load: String,
354    /// Fund back load.
355    pub fund_back_load: String,
356    /// Fund back-load interval.
357    pub fund_back_load_time_interval: String,
358    /// Fund management fee.
359    pub fund_management_fee: String,
360    /// Whether the fund is closed.
361    pub fund_closed: bool,
362    /// Whether the fund is closed to new investors.
363    pub fund_closed_for_new_investors: bool,
364    /// Whether the fund is closed to new money.
365    pub fund_closed_for_new_money: bool,
366    /// Fund notification amount.
367    pub fund_notify_amount: String,
368    /// Minimum initial purchase.
369    pub fund_minimum_initial_purchase: String,
370    /// Minimum subsequent purchase.
371    pub fund_minimum_subsequent_purchase: String,
372    /// Blue-sky states.
373    pub fund_blue_sky_states: String,
374    /// Blue-sky territories.
375    pub fund_blue_sky_territories: String,
376    /// Distribution policy indicator.
377    pub fund_distribution_policy_indicator: String,
378    /// Asset type.
379    pub fund_asset_type: String,
380    /// Ineligibility reasons.
381    pub ineligibility_reason_list: Vec<IneligibilityReason>,
382    /// First event contract.
383    pub event_contract1: String,
384    /// First event contract description.
385    pub event_contract_description1: String,
386    /// Second event contract description.
387    pub event_contract_description2: String,
388    /// Minimum algorithmic order size.
389    pub min_algo_size: Decimal,
390    /// Last-price precision.
391    pub last_price_precision: Decimal,
392    /// Last-size precision.
393    pub last_size_precision: Decimal,
394}
395
396/// Order combo leg.
397#[derive(Debug, Clone, PartialEq)]
398pub struct OrderComboLeg {
399    /// Leg price.
400    pub price: f64,
401}
402
403impl Default for OrderComboLeg {
404    fn default() -> Self {
405        Self {
406            price: UNSET_DOUBLE,
407        }
408    }
409}
410
411/// Order origin.
412#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
413#[repr(i32)]
414pub enum Origin {
415    /// Customer order.
416    #[default]
417    Customer = 0,
418    /// Firm order.
419    Firm = 1,
420    /// Unknown origin.
421    Unknown = 2,
422}
423
424/// Auction strategy.
425#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
426#[repr(i32)]
427pub enum AuctionStrategy {
428    /// Unset.
429    #[default]
430    Unset = 0,
431    /// Match.
432    Match = 1,
433    /// Improvement.
434    Improvement = 2,
435    /// Transparent.
436    Transparent = 3,
437}
438
439/// TWS order.
440#[derive(Debug, Clone, PartialEq)]
441pub struct Order {
442    /// Soft-dollar tier.
443    pub soft_dollar_tier: SoftDollarTier,
444    /// Order id.
445    pub order_id: i32,
446    /// Client id.
447    pub client_id: i32,
448    /// Permanent id.
449    pub perm_id: i64,
450    /// BUY/SELL.
451    pub action: String,
452    /// Total quantity.
453    pub total_quantity: Decimal,
454    /// Order type.
455    pub order_type: String,
456    /// Limit price.
457    pub limit_price: f64,
458    /// Auxiliary price.
459    pub aux_price: f64,
460    /// Time in force.
461    pub tif: String,
462    /// Active start time.
463    pub active_start_time: String,
464    /// Active stop time.
465    pub active_stop_time: String,
466    /// OCA group.
467    pub oca_group: String,
468    /// OCA type.
469    pub oca_type: i32,
470    /// Order ref.
471    pub order_ref: String,
472    /// Transmit flag.
473    pub transmit: bool,
474    /// Parent order id.
475    pub parent_id: i32,
476    /// Block order.
477    pub block_order: bool,
478    /// Sweep to fill.
479    pub sweep_to_fill: bool,
480    /// Display size.
481    pub display_size: i32,
482    /// Trigger method.
483    pub trigger_method: i32,
484    /// Outside regular trading hours.
485    pub outside_rth: bool,
486    /// Hidden order.
487    pub hidden: bool,
488    /// Good-after time.
489    pub good_after_time: String,
490    /// Good-till date.
491    pub good_till_date: String,
492    /// Rule 80A.
493    pub rule80a: String,
494    /// All-or-none flag.
495    pub all_or_none: bool,
496    /// Minimum quantity.
497    pub min_qty: i32,
498    /// Percent offset.
499    pub percent_offset: f64,
500    /// Override percentage constraints.
501    pub override_percentage_constraints: bool,
502    /// Trail stop price.
503    pub trail_stop_price: f64,
504    /// Trailing percent.
505    pub trailing_percent: f64,
506    /// Financial-advisor group.
507    pub fa_group: String,
508    /// Financial-advisor method.
509    pub fa_method: String,
510    /// Financial-advisor percentage.
511    pub fa_percentage: String,
512    /// Short-sale designated location.
513    pub designated_location: String,
514    /// Open/close marker.
515    pub open_close: String,
516    /// Order origin.
517    pub origin: Origin,
518    /// Short-sale slot.
519    pub short_sale_slot: i32,
520    /// Exempt code.
521    pub exempt_code: i32,
522    /// Discretionary amount.
523    pub discretionary_amount: f64,
524    /// Opt out of SMART routing.
525    pub opt_out_smart_routing: bool,
526    /// Auction strategy.
527    pub auction_strategy: AuctionStrategy,
528    /// Starting price.
529    pub starting_price: f64,
530    /// Stock reference price.
531    pub stock_ref_price: f64,
532    /// Delta.
533    pub delta: f64,
534    /// Stock range lower.
535    pub stock_range_lower: f64,
536    /// Stock range upper.
537    pub stock_range_upper: f64,
538    /// Randomize price.
539    pub randomize_price: bool,
540    /// Randomize size.
541    pub randomize_size: bool,
542    /// Volatility.
543    pub volatility: f64,
544    /// Volatility type.
545    pub volatility_type: i32,
546    /// Delta-neutral order type.
547    pub delta_neutral_order_type: String,
548    /// Delta-neutral auxiliary price.
549    pub delta_neutral_aux_price: f64,
550    /// Delta-neutral contract id.
551    pub delta_neutral_con_id: i32,
552    /// Delta-neutral settling firm.
553    pub delta_neutral_settling_firm: String,
554    /// Delta-neutral clearing account.
555    pub delta_neutral_clearing_account: String,
556    /// Delta-neutral clearing intent.
557    pub delta_neutral_clearing_intent: String,
558    /// Delta-neutral open/close marker.
559    pub delta_neutral_open_close: String,
560    /// Delta-neutral short sale flag.
561    pub delta_neutral_short_sale: bool,
562    /// Delta-neutral short-sale slot.
563    pub delta_neutral_short_sale_slot: i32,
564    /// Delta-neutral designated location.
565    pub delta_neutral_designated_location: String,
566    /// Continuous update flag.
567    pub continuous_update: bool,
568    /// Reference price type.
569    pub reference_price_type: i32,
570    /// Combo basis points.
571    pub basis_points: f64,
572    /// Combo basis-points type.
573    pub basis_points_type: i32,
574    /// Initial scale level size.
575    pub scale_init_level_size: i32,
576    /// Subsequent scale level size.
577    pub scale_subs_level_size: i32,
578    /// Scale price increment.
579    pub scale_price_increment: f64,
580    /// Scale price adjust value.
581    pub scale_price_adjust_value: f64,
582    /// Scale price adjust interval.
583    pub scale_price_adjust_interval: i32,
584    /// Scale profit offset.
585    pub scale_profit_offset: f64,
586    /// Scale auto-reset flag.
587    pub scale_auto_reset: bool,
588    /// Scale initial position.
589    pub scale_init_position: i32,
590    /// Scale initial fill quantity.
591    pub scale_init_fill_qty: i32,
592    /// Scale random percent flag.
593    pub scale_random_percent: bool,
594    /// Scale table.
595    pub scale_table: String,
596    /// Hedge type.
597    pub hedge_type: String,
598    /// Hedge parameter.
599    pub hedge_param: String,
600    /// Hedge maximum size.
601    pub hedge_max_size: i32,
602    /// Account.
603    pub account: String,
604    /// Settling firm.
605    pub settling_firm: String,
606    /// Clearing account.
607    pub clearing_account: String,
608    /// Clearing intent.
609    pub clearing_intent: String,
610    /// Model code.
611    pub model_code: String,
612    /// Algo strategy.
613    pub algo_strategy: String,
614    /// Algo parameters.
615    pub algo_params: Vec<TagValue>,
616    /// Smart combo routing parameters.
617    pub smart_combo_routing_params: Vec<TagValue>,
618    /// Algo id.
619    pub algo_id: String,
620    /// What-if flag.
621    pub what_if: bool,
622    /// Not-held flag.
623    pub not_held: bool,
624    /// Solicited flag.
625    pub solicited: bool,
626    /// Order combo legs.
627    pub order_combo_legs: Vec<OrderComboLeg>,
628    /// Misc options.
629    pub order_misc_options: Vec<TagValue>,
630    /// Reference contract id.
631    pub reference_contract_id: i32,
632    /// Pegged change amount.
633    pub pegged_change_amount: f64,
634    /// Pegged change amount decrease flag.
635    pub is_pegged_change_amount_decrease: bool,
636    /// Reference change amount.
637    pub reference_change_amount: f64,
638    /// Reference exchange id.
639    pub reference_exchange_id: String,
640    /// Adjusted order type.
641    pub adjusted_order_type: String,
642    /// Trigger price.
643    pub trigger_price: f64,
644    /// Adjusted stop price.
645    pub adjusted_stop_price: f64,
646    /// Adjusted stop limit price.
647    pub adjusted_stop_limit_price: f64,
648    /// Adjusted trailing amount.
649    pub adjusted_trailing_amount: f64,
650    /// Adjustable trailing unit.
651    pub adjustable_trailing_unit: i32,
652    /// Limit price offset.
653    pub limit_price_offset: f64,
654    /// Conditions.
655    pub conditions: Vec<OrderCondition>,
656    /// Cancel if conditions match.
657    pub conditions_cancel_order: bool,
658    /// Ignore RTH for conditions.
659    pub conditions_ignore_rth: bool,
660    /// External operator.
661    pub ext_operator: String,
662    /// Native cash quantity.
663    pub cash_qty: f64,
664    /// MiFID II decision maker.
665    pub mifid2_decision_maker: String,
666    /// MiFID II decision algo.
667    pub mifid2_decision_algo: String,
668    /// MiFID II execution trader.
669    pub mifid2_execution_trader: String,
670    /// MiFID II execution algo.
671    pub mifid2_execution_algo: String,
672    /// Do not use auto price for hedge.
673    pub dont_use_auto_price_for_hedge: bool,
674    /// OMS container flag.
675    pub is_oms_container: bool,
676    /// Discretionary up-to-limit price flag.
677    pub discretionary_up_to_limit_price: bool,
678    /// Auto-cancel date.
679    pub auto_cancel_date: String,
680    /// Filled quantity.
681    pub filled_quantity: Decimal,
682    /// Reference futures contract id.
683    pub ref_futures_con_id: i32,
684    /// Auto-cancel parent flag.
685    pub auto_cancel_parent: bool,
686    /// Shareholder.
687    pub shareholder: String,
688    /// Imbalance only flag.
689    pub imbalance_only: bool,
690    /// Route marketable order to BBO.
691    pub route_marketable_to_bbo: i32,
692    /// Parent permanent id.
693    pub parent_perm_id: i64,
694    /// Use price-management algo.
695    pub use_price_mgmt_algo: i32,
696    /// Duration.
697    pub duration: i32,
698    /// Post to ATS.
699    pub post_to_ats: i32,
700    /// Advanced error override.
701    pub advanced_error_override: String,
702    /// Manual order time.
703    pub manual_order_time: String,
704    /// Minimum trade quantity.
705    pub min_trade_qty: i32,
706    /// Minimum compete size.
707    pub min_compete_size: i32,
708    /// Compete against best offset.
709    pub compete_against_best_offset: f64,
710    /// Mid offset at whole.
711    pub mid_offset_at_whole: f64,
712    /// Mid offset at half.
713    pub mid_offset_at_half: f64,
714    /// Customer account.
715    pub customer_account: String,
716    /// Professional customer flag.
717    pub professional_customer: bool,
718    /// Bond accrued interest.
719    pub bond_accrued_interest: String,
720    /// Include overnight flag.
721    pub include_overnight: bool,
722    /// Manual order indicator.
723    pub manual_order_indicator: i32,
724    /// Submitter.
725    pub submitter: String,
726    /// Post-only flag.
727    pub post_only: bool,
728    /// Allow pre-open flag.
729    pub allow_pre_open: bool,
730    /// Ignore open auction flag.
731    pub ignore_open_auction: bool,
732    /// Deactivate flag.
733    pub deactivate: bool,
734    /// Seek price improvement.
735    pub seek_price_improvement: i32,
736    /// What-if type.
737    pub what_if_type: i32,
738    /// Stop-loss attached order id.
739    pub stop_loss_order_id: i32,
740    /// Stop-loss attached order type.
741    pub stop_loss_order_type: String,
742    /// Profit-taker attached order id.
743    pub profit_taker_order_id: i32,
744    /// Profit-taker attached order type.
745    pub profit_taker_order_type: String,
746}
747
748impl Default for Order {
749    fn default() -> Self {
750        Self {
751            soft_dollar_tier: SoftDollarTier::default(),
752            order_id: 0,
753            client_id: 0,
754            perm_id: 0,
755            action: String::new(),
756            total_quantity: Decimal::from_i128_with_scale(0, 0),
757            order_type: String::new(),
758            limit_price: UNSET_DOUBLE,
759            aux_price: UNSET_DOUBLE,
760            tif: String::new(),
761            active_start_time: String::new(),
762            active_stop_time: String::new(),
763            oca_group: String::new(),
764            oca_type: 0,
765            order_ref: String::new(),
766            transmit: true,
767            parent_id: 0,
768            block_order: false,
769            sweep_to_fill: false,
770            display_size: 0,
771            trigger_method: 0,
772            outside_rth: false,
773            hidden: false,
774            good_after_time: String::new(),
775            good_till_date: String::new(),
776            rule80a: String::new(),
777            all_or_none: false,
778            min_qty: UNSET_INTEGER,
779            percent_offset: UNSET_DOUBLE,
780            override_percentage_constraints: false,
781            trail_stop_price: UNSET_DOUBLE,
782            trailing_percent: UNSET_DOUBLE,
783            fa_group: String::new(),
784            fa_method: String::new(),
785            fa_percentage: String::new(),
786            designated_location: String::new(),
787            open_close: String::new(),
788            origin: Origin::Customer,
789            short_sale_slot: 0,
790            exempt_code: -1,
791            discretionary_amount: 0.0,
792            opt_out_smart_routing: false,
793            auction_strategy: AuctionStrategy::Unset,
794            starting_price: UNSET_DOUBLE,
795            stock_ref_price: UNSET_DOUBLE,
796            delta: UNSET_DOUBLE,
797            stock_range_lower: UNSET_DOUBLE,
798            stock_range_upper: UNSET_DOUBLE,
799            randomize_price: false,
800            randomize_size: false,
801            volatility: UNSET_DOUBLE,
802            volatility_type: UNSET_INTEGER,
803            delta_neutral_order_type: String::new(),
804            delta_neutral_aux_price: UNSET_DOUBLE,
805            delta_neutral_con_id: 0,
806            delta_neutral_settling_firm: String::new(),
807            delta_neutral_clearing_account: String::new(),
808            delta_neutral_clearing_intent: String::new(),
809            delta_neutral_open_close: String::new(),
810            delta_neutral_short_sale: false,
811            delta_neutral_short_sale_slot: 0,
812            delta_neutral_designated_location: String::new(),
813            continuous_update: false,
814            reference_price_type: UNSET_INTEGER,
815            basis_points: UNSET_DOUBLE,
816            basis_points_type: UNSET_INTEGER,
817            scale_init_level_size: UNSET_INTEGER,
818            scale_subs_level_size: UNSET_INTEGER,
819            scale_price_increment: UNSET_DOUBLE,
820            scale_price_adjust_value: UNSET_DOUBLE,
821            scale_price_adjust_interval: UNSET_INTEGER,
822            scale_profit_offset: UNSET_DOUBLE,
823            scale_auto_reset: false,
824            scale_init_position: UNSET_INTEGER,
825            scale_init_fill_qty: UNSET_INTEGER,
826            scale_random_percent: false,
827            scale_table: String::new(),
828            hedge_type: String::new(),
829            hedge_param: String::new(),
830            hedge_max_size: UNSET_INTEGER,
831            account: String::new(),
832            settling_firm: String::new(),
833            clearing_account: String::new(),
834            clearing_intent: String::new(),
835            model_code: String::new(),
836            algo_strategy: String::new(),
837            algo_params: Vec::new(),
838            smart_combo_routing_params: Vec::new(),
839            algo_id: String::new(),
840            what_if: false,
841            not_held: false,
842            solicited: false,
843            order_combo_legs: Vec::new(),
844            order_misc_options: Vec::new(),
845            reference_contract_id: 0,
846            pegged_change_amount: 0.0,
847            is_pegged_change_amount_decrease: false,
848            reference_change_amount: 0.0,
849            reference_exchange_id: String::new(),
850            adjusted_order_type: String::new(),
851            trigger_price: UNSET_DOUBLE,
852            adjusted_stop_price: UNSET_DOUBLE,
853            adjusted_stop_limit_price: UNSET_DOUBLE,
854            adjusted_trailing_amount: UNSET_DOUBLE,
855            adjustable_trailing_unit: 0,
856            limit_price_offset: UNSET_DOUBLE,
857            conditions: Vec::new(),
858            conditions_cancel_order: false,
859            conditions_ignore_rth: false,
860            ext_operator: String::new(),
861            cash_qty: UNSET_DOUBLE,
862            mifid2_decision_maker: String::new(),
863            mifid2_decision_algo: String::new(),
864            mifid2_execution_trader: String::new(),
865            mifid2_execution_algo: String::new(),
866            dont_use_auto_price_for_hedge: false,
867            is_oms_container: false,
868            discretionary_up_to_limit_price: false,
869            auto_cancel_date: String::new(),
870            filled_quantity: Decimal::from_i128_with_scale(0, 0),
871            ref_futures_con_id: 0,
872            auto_cancel_parent: false,
873            shareholder: String::new(),
874            imbalance_only: false,
875            route_marketable_to_bbo: UNSET_INTEGER,
876            parent_perm_id: 0,
877            use_price_mgmt_algo: UNSET_INTEGER,
878            duration: UNSET_INTEGER,
879            post_to_ats: UNSET_INTEGER,
880            advanced_error_override: String::new(),
881            manual_order_time: String::new(),
882            min_trade_qty: UNSET_INTEGER,
883            min_compete_size: UNSET_INTEGER,
884            compete_against_best_offset: UNSET_DOUBLE,
885            mid_offset_at_whole: UNSET_DOUBLE,
886            mid_offset_at_half: UNSET_DOUBLE,
887            customer_account: String::new(),
888            professional_customer: false,
889            bond_accrued_interest: String::new(),
890            include_overnight: false,
891            manual_order_indicator: UNSET_INTEGER,
892            submitter: String::new(),
893            post_only: false,
894            allow_pre_open: false,
895            ignore_open_auction: false,
896            deactivate: false,
897            seek_price_improvement: UNSET_INTEGER,
898            what_if_type: UNSET_INTEGER,
899            stop_loss_order_id: UNSET_INTEGER,
900            stop_loss_order_type: String::new(),
901            profit_taker_order_id: UNSET_INTEGER,
902            profit_taker_order_type: String::new(),
903        }
904    }
905}
906
907/// Order cancellation metadata.
908#[derive(Debug, Clone, Default, PartialEq, Eq)]
909pub struct OrderCancel {
910    /// Manual order cancel time.
911    pub manual_order_cancel_time: String,
912    /// Ext operator.
913    pub ext_operator: String,
914    /// Manual order indicator.
915    pub manual_order_indicator: i32,
916}
917
918/// Execution filter.
919#[derive(Debug, Clone, PartialEq, Eq)]
920pub struct ExecutionFilter {
921    /// Client id.
922    pub client_id: i32,
923    /// Account code.
924    pub acct_code: String,
925    /// Time.
926    pub time: String,
927    /// Symbol.
928    pub symbol: String,
929    /// Security type.
930    pub sec_type: String,
931    /// Exchange.
932    pub exchange: String,
933    /// Side.
934    pub side: String,
935    /// Number of prior days to include. `UNSET_INTEGER` leaves it unspecified.
936    pub last_n_days: i32,
937    /// Specific execution dates, encoded when the server supports parametrized execution days.
938    pub specific_dates: Vec<i32>,
939}
940
941impl Default for ExecutionFilter {
942    fn default() -> Self {
943        Self {
944            client_id: 0,
945            acct_code: String::new(),
946            time: String::new(),
947            symbol: String::new(),
948            sec_type: String::new(),
949            exchange: String::new(),
950            side: String::new(),
951            last_n_days: UNSET_INTEGER,
952            specific_dates: Vec::new(),
953        }
954    }
955}
956
957/// Execution details returned by TWS.
958#[derive(Debug, Clone, Default, PartialEq)]
959pub struct Execution {
960    /// Order id.
961    pub order_id: i32,
962    /// Execution id.
963    pub exec_id: String,
964    /// Execution time.
965    pub time: String,
966    /// Account number.
967    pub acct_number: String,
968    /// Exchange.
969    pub exchange: String,
970    /// Side.
971    pub side: String,
972    /// Executed quantity.
973    pub shares: Decimal,
974    /// Execution price.
975    pub price: f64,
976    /// Permanent id.
977    pub perm_id: i64,
978    /// Client id.
979    pub client_id: i32,
980    /// Liquidation marker.
981    pub liquidation: i32,
982    /// Cumulative quantity.
983    pub cum_qty: Decimal,
984    /// Average price.
985    pub avg_price: f64,
986    /// Order reference.
987    pub order_ref: String,
988    /// Economic value rule.
989    pub ev_rule: String,
990    /// Economic value multiplier.
991    pub ev_multiplier: f64,
992    /// Model code.
993    pub model_code: String,
994    /// Last liquidity marker.
995    pub last_liquidity: i32,
996    /// Price revision pending marker.
997    pub pending_price_revision: bool,
998    /// Submitter.
999    pub submitter: String,
1000    /// Option exercise or lapse type.
1001    pub opt_exercise_or_lapse_type: i32,
1002}
1003
1004/// Account allocation details for an order state.
1005#[derive(Debug, Clone, Default, PartialEq)]
1006pub struct OrderAllocation {
1007    /// Account.
1008    pub account: String,
1009    /// Current position.
1010    pub position: Decimal,
1011    /// Desired position.
1012    pub position_desired: Decimal,
1013    /// Position after allocation.
1014    pub position_after: Decimal,
1015    /// Desired allocation quantity.
1016    pub desired_alloc_qty: Decimal,
1017    /// Allowed allocation quantity.
1018    pub allowed_alloc_qty: Decimal,
1019    /// Monetary allocation flag.
1020    pub is_monetary: bool,
1021}
1022
1023/// Order state returned by TWS.
1024#[derive(Debug, Clone, Default, PartialEq)]
1025pub struct OrderState {
1026    /// Status.
1027    pub status: String,
1028    /// Initial margin before the order.
1029    pub init_margin_before: f64,
1030    /// Maintenance margin before the order.
1031    pub maint_margin_before: f64,
1032    /// Equity with loan before the order.
1033    pub equity_with_loan_before: f64,
1034    /// Initial margin change.
1035    pub init_margin_change: f64,
1036    /// Maintenance margin change.
1037    pub maint_margin_change: f64,
1038    /// Equity with loan change.
1039    pub equity_with_loan_change: f64,
1040    /// Initial margin after the order.
1041    pub init_margin_after: f64,
1042    /// Maintenance margin after the order.
1043    pub maint_margin_after: f64,
1044    /// Equity with loan after the order.
1045    pub equity_with_loan_after: f64,
1046    /// Commission and fees.
1047    pub commission_and_fees: f64,
1048    /// Minimum commission and fees.
1049    pub min_commission_and_fees: f64,
1050    /// Maximum commission and fees.
1051    pub max_commission_and_fees: f64,
1052    /// Commission and fees currency.
1053    pub commission_and_fees_currency: String,
1054    /// Margin currency.
1055    pub margin_currency: String,
1056    /// Initial margin before the order outside RTH.
1057    pub init_margin_before_outside_rth: f64,
1058    /// Maintenance margin before the order outside RTH.
1059    pub maint_margin_before_outside_rth: f64,
1060    /// Equity with loan before the order outside RTH.
1061    pub equity_with_loan_before_outside_rth: f64,
1062    /// Initial margin change outside RTH.
1063    pub init_margin_change_outside_rth: f64,
1064    /// Maintenance margin change outside RTH.
1065    pub maint_margin_change_outside_rth: f64,
1066    /// Equity with loan change outside RTH.
1067    pub equity_with_loan_change_outside_rth: f64,
1068    /// Initial margin after the order outside RTH.
1069    pub init_margin_after_outside_rth: f64,
1070    /// Maintenance margin after the order outside RTH.
1071    pub maint_margin_after_outside_rth: f64,
1072    /// Equity with loan after the order outside RTH.
1073    pub equity_with_loan_after_outside_rth: f64,
1074    /// Suggested size.
1075    pub suggested_size: String,
1076    /// Reject reason.
1077    pub reject_reason: String,
1078    /// Allocation details.
1079    pub order_allocations: Vec<OrderAllocation>,
1080    /// Warning text.
1081    pub warning_text: String,
1082    /// Completed time.
1083    pub completed_time: String,
1084    /// Completed status.
1085    pub completed_status: String,
1086}
1087
1088/// Commission and fees report.
1089#[derive(Debug, Clone, Default, PartialEq)]
1090pub struct CommissionAndFeesReport {
1091    /// Execution id.
1092    pub exec_id: String,
1093    /// Commission and fees.
1094    pub commission_and_fees: f64,
1095    /// Currency.
1096    pub currency: String,
1097    /// Realized profit and loss.
1098    pub realized_pnl: f64,
1099    /// Bond yield.
1100    pub bond_yield: f64,
1101    /// Yield redemption date.
1102    pub yield_redemption_date: String,
1103}
1104
1105/// Contract description returned by matching symbol queries.
1106#[derive(Debug, Clone, Default, PartialEq)]
1107pub struct ContractDescription {
1108    /// Contract.
1109    pub contract: Contract,
1110    /// Derivative security types.
1111    pub derivative_sec_types: Vec<String>,
1112}
1113
1114/// Smart routing component.
1115#[derive(Debug, Clone, Default, PartialEq, Eq)]
1116pub struct SmartComponent {
1117    /// Bit number.
1118    pub bit_number: i32,
1119    /// Exchange.
1120    pub exchange: String,
1121    /// Exchange letter.
1122    pub exchange_letter: String,
1123}
1124
1125/// Historical trading session.
1126#[derive(Debug, Clone, Default, PartialEq, Eq)]
1127pub struct HistoricalSession {
1128    /// Session start.
1129    pub start_date_time: String,
1130    /// Session end.
1131    pub end_date_time: String,
1132    /// Reference date.
1133    pub ref_date: String,
1134}
1135
1136/// Historical midpoint/trade tick.
1137#[derive(Debug, Clone, Default, PartialEq)]
1138pub struct HistoricalTick {
1139    /// Unix timestamp seconds.
1140    pub time: i64,
1141    /// Price.
1142    pub price: f64,
1143    /// Size.
1144    pub size: Decimal,
1145}
1146
1147/// Bid/ask historical tick attributes.
1148#[derive(Debug, Clone, Default, PartialEq, Eq)]
1149pub struct TickAttribBidAsk {
1150    /// Bid past low marker.
1151    pub bid_past_low: bool,
1152    /// Ask past high marker.
1153    pub ask_past_high: bool,
1154}
1155
1156/// Last trade historical tick attributes.
1157#[derive(Debug, Clone, Default, PartialEq, Eq)]
1158pub struct TickAttribLast {
1159    /// Past limit marker.
1160    pub past_limit: bool,
1161    /// Unreported marker.
1162    pub unreported: bool,
1163}
1164
1165/// Historical bid/ask tick.
1166#[derive(Debug, Clone, Default, PartialEq)]
1167pub struct HistoricalTickBidAsk {
1168    /// Unix timestamp seconds.
1169    pub time: i64,
1170    /// Attributes.
1171    pub tick_attrib_bid_ask: TickAttribBidAsk,
1172    /// Bid price.
1173    pub price_bid: f64,
1174    /// Ask price.
1175    pub price_ask: f64,
1176    /// Bid size.
1177    pub size_bid: Decimal,
1178    /// Ask size.
1179    pub size_ask: Decimal,
1180}
1181
1182/// Historical last trade tick.
1183#[derive(Debug, Clone, Default, PartialEq)]
1184pub struct HistoricalTickLast {
1185    /// Unix timestamp seconds.
1186    pub time: i64,
1187    /// Attributes.
1188    pub tick_attrib_last: TickAttribLast,
1189    /// Price.
1190    pub price: f64,
1191    /// Size.
1192    pub size: Decimal,
1193    /// Exchange.
1194    pub exchange: String,
1195    /// Special conditions.
1196    pub special_conditions: String,
1197}
1198
1199/// Tick-by-tick payload.
1200#[derive(Debug, Clone, PartialEq)]
1201pub enum TickByTick {
1202    /// Last trade tick.
1203    Last(HistoricalTickLast),
1204    /// Bid/ask tick.
1205    BidAsk(HistoricalTickBidAsk),
1206    /// Midpoint tick.
1207    MidPoint(HistoricalTick),
1208}
1209
1210/// Scanner subscription.
1211#[derive(Debug, Clone, Default, PartialEq)]
1212pub struct ScannerSubscription {
1213    /// Number of rows.
1214    pub number_of_rows: i32,
1215    /// Instrument.
1216    pub instrument: String,
1217    /// Location code.
1218    pub location_code: String,
1219    /// Scan code.
1220    pub scan_code: String,
1221    /// Above price.
1222    pub above_price: f64,
1223    /// Below price.
1224    pub below_price: f64,
1225    /// Above volume.
1226    pub above_volume: i32,
1227    /// Market cap above.
1228    pub market_cap_above: f64,
1229    /// Market cap below.
1230    pub market_cap_below: f64,
1231    /// Moody rating above.
1232    pub moody_rating_above: String,
1233    /// Moody rating below.
1234    pub moody_rating_below: String,
1235    /// SP rating above.
1236    pub sp_rating_above: String,
1237    /// SP rating below.
1238    pub sp_rating_below: String,
1239    /// Maturity date above.
1240    pub maturity_date_above: String,
1241    /// Maturity date below.
1242    pub maturity_date_below: String,
1243    /// Coupon rate above.
1244    pub coupon_rate_above: f64,
1245    /// Coupon rate below.
1246    pub coupon_rate_below: f64,
1247    /// Exclude convertible.
1248    pub exclude_convertible: bool,
1249    /// Average option volume above.
1250    pub average_option_volume_above: i32,
1251    /// Scanner setting pairs.
1252    pub scanner_setting_pairs: String,
1253    /// Stock type filter.
1254    pub stock_type_filter: String,
1255}
1256
1257/// Order condition.
1258#[derive(Debug, Clone, PartialEq)]
1259pub enum OrderCondition {
1260    /// Price condition.
1261    Price {
1262        /// AND if true, OR if false.
1263        is_conjunction_connection: bool,
1264        /// Trigger method.
1265        trigger_method: i32,
1266        /// Contract id.
1267        con_id: i32,
1268        /// Exchange.
1269        exchange: String,
1270        /// More-than comparison.
1271        is_more: bool,
1272        /// Price.
1273        price: f64,
1274    },
1275    /// Time condition.
1276    Time {
1277        /// AND if true, OR if false.
1278        is_conjunction_connection: bool,
1279        /// More-than comparison.
1280        is_more: bool,
1281        /// Time string.
1282        time: String,
1283    },
1284    /// Margin condition.
1285    Margin {
1286        /// AND if true, OR if false.
1287        is_conjunction_connection: bool,
1288        /// More-than comparison.
1289        is_more: bool,
1290        /// Percent.
1291        percent: f64,
1292    },
1293    /// Execution condition.
1294    Execution {
1295        /// AND if true, OR if false.
1296        is_conjunction_connection: bool,
1297        /// Security type.
1298        sec_type: String,
1299        /// Exchange.
1300        exchange: String,
1301        /// Symbol.
1302        symbol: String,
1303    },
1304    /// Volume condition.
1305    Volume {
1306        /// AND if true, OR if false.
1307        is_conjunction_connection: bool,
1308        /// Contract id.
1309        con_id: i32,
1310        /// Exchange.
1311        exchange: String,
1312        /// More-than comparison.
1313        is_more: bool,
1314        /// Volume.
1315        volume: i32,
1316    },
1317    /// Percent-change condition.
1318    PercentChange {
1319        /// AND if true, OR if false.
1320        is_conjunction_connection: bool,
1321        /// Contract id.
1322        con_id: i32,
1323        /// Exchange.
1324        exchange: String,
1325        /// More-than comparison.
1326        is_more: bool,
1327        /// Change percent.
1328        change_percent: f64,
1329    },
1330}
1331
1332impl OrderCondition {
1333    /// Returns the typed trigger method for a price condition.
1334    pub fn trigger_method(&self) -> Option<TriggerMethod> {
1335        match self {
1336            Self::Price { trigger_method, .. } => Some(TriggerMethod::from_i32(*trigger_method)),
1337            _ => None,
1338        }
1339    }
1340}
1341
1342impl Execution {
1343    /// Returns the typed option exercise/lapse result.
1344    pub const fn option_exercise_type(&self) -> OptionExerciseType {
1345        OptionExerciseType::from_i32(self.opt_exercise_or_lapse_type)
1346    }
1347
1348    /// Returns the typed liquidity classification.
1349    pub const fn liquidity(&self) -> crate::enums::Liquidities {
1350        crate::enums::Liquidities::from_i32(self.last_liquidity)
1351    }
1352}
1353
1354/// Historical bar data.
1355#[derive(Debug, Clone, Default, PartialEq)]
1356pub struct BarData {
1357    /// Date.
1358    pub date: String,
1359    /// Open.
1360    pub open: f64,
1361    /// High.
1362    pub high: f64,
1363    /// Low.
1364    pub low: f64,
1365    /// Close.
1366    pub close: f64,
1367    /// Volume.
1368    pub volume: Decimal,
1369    /// WAP.
1370    pub wap: Decimal,
1371    /// Bar count.
1372    pub bar_count: i32,
1373}
1374
1375/// Real-time five-second bar. This is intentionally distinct from historical bars because its
1376/// timestamp and end time have different semantics in the TWS API.
1377#[derive(Debug, Clone, Default, PartialEq)]
1378pub struct RealTimeBar {
1379    pub time: i64,
1380    pub end_time: i64,
1381    pub open: f64,
1382    pub high: f64,
1383    pub low: f64,
1384    pub close: f64,
1385    pub volume: Decimal,
1386    pub wap: Decimal,
1387    pub count: i32,
1388}