Skip to main content

ib_flex/types/
common.rs

1//! Common enums used across FLEX statements
2
3use serde::{Deserialize, Serialize};
4
5/// Asset category (security type)
6///
7/// Maps to IB's AssetCategory field. Represents the type of financial instrument.
8#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Deserialize, Serialize)]
9#[serde(rename_all = "UPPERCASE")]
10pub enum AssetCategory {
11    /// Stock
12    #[serde(rename = "STK")]
13    Stock,
14
15    /// Option
16    #[serde(rename = "OPT")]
17    Option,
18
19    /// Future
20    #[serde(rename = "FUT")]
21    Future,
22
23    /// Future Option
24    #[serde(rename = "FOP")]
25    FutureOption,
26
27    /// Cash/Forex
28    #[serde(rename = "CASH")]
29    Cash,
30
31    /// Bond
32    #[serde(rename = "BOND")]
33    Bond,
34
35    /// Treasury Bill (maturity < 1 year)
36    #[serde(rename = "BILL")]
37    Bill,
38
39    /// Commodity
40    #[serde(rename = "CMDTY")]
41    Commodity,
42
43    /// Contract for Difference
44    #[serde(rename = "CFD")]
45    Cfd,
46
47    /// Forex CFD
48    #[serde(rename = "FXCFD")]
49    ForexCfd,
50
51    /// Warrant
52    #[serde(rename = "WAR")]
53    Warrant,
54
55    /// Mutual Fund
56    #[serde(rename = "FUND")]
57    Fund,
58
59    /// Structured Product / Dutch Warrant / Indexed Option
60    #[serde(rename = "IOPT")]
61    StructuredProduct,
62
63    /// Combination / Basket order (spread, combo legs)
64    #[serde(rename = "BAG")]
65    Bag,
66
67    /// Cryptocurrency
68    #[serde(rename = "CRYPTO")]
69    Cryptocurrency,
70
71    /// Physical metals (gold, silver, etc.)
72    #[serde(rename = "METAL")]
73    Metal,
74
75    /// Exchange for Physical
76    #[serde(rename = "EFP")]
77    ExchangeForPhysical,
78
79    /// Event Contract
80    #[serde(rename = "EC")]
81    EventContract,
82
83    /// Index
84    #[serde(rename = "IND")]
85    Index,
86
87    /// Unknown or unrecognized asset category
88    #[serde(other)]
89    Unknown,
90}
91
92/// Buy or Sell side
93#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Deserialize, Serialize)]
94#[serde(rename_all = "UPPERCASE")]
95pub enum BuySell {
96    /// Buy
97    #[serde(rename = "BUY")]
98    Buy,
99
100    /// Sell
101    #[serde(rename = "SELL")]
102    Sell,
103
104    /// Cancelled buy
105    #[serde(rename = "BUY (Ca.)")]
106    CancelBuy,
107
108    /// Cancelled sell
109    #[serde(rename = "SELL (Ca.)")]
110    CancelSell,
111
112    /// Unknown
113    #[serde(other)]
114    Unknown,
115}
116
117/// Open or Close indicator (for options/futures)
118#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Deserialize, Serialize)]
119pub enum OpenClose {
120    /// Opening trade
121    #[serde(rename = "O")]
122    Open,
123
124    /// Closing trade
125    #[serde(rename = "C")]
126    Close,
127
128    /// Close and open (same-day round trip)
129    #[serde(rename = "C;O")]
130    CloseOpen,
131
132    /// Unknown
133    #[serde(other)]
134    Unknown,
135}
136
137/// Order type
138#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Deserialize, Serialize)]
139#[serde(rename_all = "UPPERCASE")]
140pub enum OrderType {
141    /// Market order
142    #[serde(rename = "MKT")]
143    Market,
144
145    /// Limit order
146    #[serde(rename = "LMT")]
147    Limit,
148
149    /// Stop order
150    #[serde(rename = "STP")]
151    Stop,
152
153    /// Stop limit order
154    #[serde(rename = "STP LMT")]
155    StopLimit,
156
157    /// Market on close
158    #[serde(rename = "MOC")]
159    MarketOnClose,
160
161    /// Limit on close
162    #[serde(rename = "LOC")]
163    LimitOnClose,
164
165    /// Market if touched
166    #[serde(rename = "MIT")]
167    MarketIfTouched,
168
169    /// Limit if touched
170    #[serde(rename = "LIT")]
171    LimitIfTouched,
172
173    /// Trailing stop
174    #[serde(rename = "TRAIL")]
175    TrailingStop,
176
177    /// Trailing limit
178    #[serde(rename = "TRAIL LMT")]
179    TrailingLimit,
180
181    /// Mid-price order
182    #[serde(rename = "MIDPX")]
183    MidPrice,
184
185    /// Relative order
186    #[serde(rename = "REL")]
187    Relative,
188
189    /// Multiple order types (complex orders)
190    #[serde(rename = "MULTIPLE")]
191    Multiple,
192
193    /// Unknown or unrecognized order type
194    #[serde(other)]
195    Unknown,
196}
197
198/// Put or Call (for options)
199#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Deserialize, Serialize)]
200pub enum PutCall {
201    /// Put option
202    #[serde(rename = "P")]
203    Put,
204
205    /// Call option
206    #[serde(rename = "C")]
207    Call,
208
209    /// Unknown
210    #[serde(other)]
211    Unknown,
212}
213
214/// Long or Short position side
215#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Deserialize, Serialize)]
216pub enum LongShort {
217    /// Long position
218    Long,
219
220    /// Short position
221    Short,
222
223    /// Unknown
224    #[serde(other)]
225    Unknown,
226}
227
228/// Transaction type for trades
229#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Deserialize, Serialize)]
230pub enum TradeType {
231    /// Exchange trade
232    ExchTrade,
233
234    /// Book trade
235    BookTrade,
236
237    /// Delivery vs Payment trade
238    DvpTrade,
239
240    /// Fractional share trade
241    FracShare,
242
243    /// Fractional share cancellation
244    FracShareCancel,
245
246    /// Manual adjustment
247    Adjustment,
248
249    /// Trade correction
250    TradeCorrect,
251
252    /// Trade cancellation
253    TradeCancel,
254
255    /// IBKR trade
256    IBKRTrade,
257
258    /// Unknown
259    #[serde(other)]
260    Unknown,
261}
262
263/// Cash transaction action type
264#[derive(Debug, Clone, PartialEq, Eq, Hash, Deserialize, Serialize)]
265pub enum CashAction {
266    /// Deposits and withdrawals
267    #[serde(rename = "Deposits & Withdrawals")]
268    DepositsWithdrawals,
269
270    /// Dividend payments
271    Dividends,
272
273    /// Withholding tax
274    WithholdingTax,
275
276    /// Broker interest paid
277    #[serde(rename = "Broker Interest Paid")]
278    BrokerInterestPaid,
279
280    /// Broker interest received
281    #[serde(rename = "Broker Interest Received")]
282    BrokerInterestReceived,
283
284    /// Bond interest received
285    #[serde(rename = "Bond Interest Received")]
286    BondInterestReceived,
287
288    /// Bond interest paid
289    #[serde(rename = "Bond Interest Paid")]
290    BondInterestPaid,
291
292    /// Bond interest (generic)
293    #[serde(rename = "Bond Interest")]
294    BondInterest,
295
296    /// Payment in lieu of dividends
297    #[serde(rename = "Payment In Lieu Of Dividends")]
298    PaymentInLieuOfDividends,
299
300    /// Other fees
301    #[serde(rename = "Other Fees")]
302    OtherFees,
303
304    /// Commission adjustments
305    #[serde(rename = "Commission Adjustments")]
306    CommissionAdjustments,
307
308    /// Advisor fees
309    #[serde(rename = "Advisor Fees")]
310    AdvisorFees,
311
312    /// Cash receipts
313    #[serde(rename = "Cash Receipts")]
314    CashReceipts,
315
316    /// Fees
317    Fees,
318
319    /// Unknown type
320    #[serde(other)]
321    Unknown,
322}
323
324/// Corporate action reorganization type
325#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Deserialize, Serialize)]
326pub enum Reorg {
327    /// Stock split (forward split)
328    #[serde(rename = "Stock Split")]
329    StockSplit,
330
331    /// Forward split (issue)
332    #[serde(rename = "Forward Split (Issue)")]
333    ForwardSplitIssue,
334
335    /// Forward split
336    #[serde(rename = "Forward Split")]
337    ForwardSplit,
338
339    /// Reverse split
340    #[serde(rename = "Reverse Split")]
341    ReverseSplit,
342
343    /// Merger
344    Merger,
345
346    /// Spinoff
347    Spinoff,
348
349    /// Contract spinoff
350    #[serde(rename = "Contract Spinoff")]
351    ContractSpinoff,
352
353    /// Stock dividend
354    #[serde(rename = "Stock Dividend")]
355    StockDividend,
356
357    /// Cash dividend
358    #[serde(rename = "Cash Dividend")]
359    CashDividend,
360
361    /// Choice dividend
362    #[serde(rename = "Choice Dividend")]
363    ChoiceDividend,
364
365    /// Choice dividend (delivery)
366    #[serde(rename = "Choice Dividend (Delivery)")]
367    ChoiceDivDelivery,
368
369    /// Choice dividend (issue)
370    #[serde(rename = "Choice Dividend (Issue)")]
371    ChoiceDivIssue,
372
373    /// Dividend rights issue
374    #[serde(rename = "Dividend Rights Issue")]
375    DivRightsIssue,
376
377    /// Expired dividend right
378    #[serde(rename = "Expired Dividend Right")]
379    ExpiredDivRight,
380
381    /// Delisted
382    Delisted,
383
384    /// Delist (worthless)
385    #[serde(rename = "Delist (Worthless)")]
386    DelistWorthless,
387
388    /// Name change
389    #[serde(rename = "Name Change")]
390    NameChange,
391
392    /// Symbol change
393    #[serde(rename = "Symbol Change")]
394    SymbolChange,
395
396    /// Issue change
397    #[serde(rename = "Issue Change")]
398    IssueChange,
399
400    /// Bond conversion
401    #[serde(rename = "Bond Conversion")]
402    BondConversion,
403
404    /// Bond maturity
405    #[serde(rename = "Bond Maturity")]
406    BondMaturity,
407
408    /// T-Bill maturity
409    #[serde(rename = "T-Bill Maturity")]
410    TBillMaturity,
411
412    /// Convertible issue
413    #[serde(rename = "Convertible Issue")]
414    ConvertibleIssue,
415
416    /// Coupon payment
417    #[serde(rename = "Coupon Payment")]
418    CouponPayment,
419
420    /// Contract consolidation
421    #[serde(rename = "Contract Consolidation")]
422    ContractConsolidation,
423
424    /// Contract split
425    #[serde(rename = "Contract Split")]
426    ContractSplit,
427
428    /// Contract termination
429    #[serde(rename = "CFD Termination")]
430    CfdTermination,
431
432    /// Fee allocation
433    #[serde(rename = "Fee Allocation")]
434    FeeAllocation,
435
436    /// Rights issue
437    #[serde(rename = "Rights Issue")]
438    RightsIssue,
439
440    /// Subscribe rights
441    #[serde(rename = "Subscribe Rights")]
442    SubscribeRights,
443
444    /// Tender
445    Tender,
446
447    /// Tender (issue)
448    #[serde(rename = "Tender (Issue)")]
449    TenderIssue,
450
451    /// Proxy vote
452    #[serde(rename = "Proxy Vote")]
453    ProxyVote,
454
455    /// Generic voluntary
456    #[serde(rename = "Generic Voluntary")]
457    GenericVoluntary,
458
459    /// Asset purchase
460    #[serde(rename = "Asset Purchase")]
461    AssetPurchase,
462
463    /// Purchase (issue)
464    #[serde(rename = "Purchase (Issue)")]
465    PurchaseIssue,
466
467    /// Unknown
468    #[serde(other)]
469    Unknown,
470}
471
472/// Option action type
473#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Deserialize, Serialize)]
474pub enum OptionAction {
475    /// Assignment
476    Assignment,
477
478    /// Exercise
479    Exercise,
480
481    /// Expiration
482    Expiration,
483
484    /// Expire (alternate form)
485    Expire,
486
487    /// Cash settlement
488    #[serde(rename = "Cash Settlement")]
489    CashSettlement,
490
491    /// Buy to open/close
492    Buy,
493
494    /// Sell to open/close
495    Sell,
496
497    /// Unknown
498    #[serde(other)]
499    Unknown,
500}
501
502/// Transfer type
503#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Deserialize, Serialize)]
504pub enum TransferType {
505    /// ACATS transfer
506    ACATS,
507
508    /// ATON transfer
509    ATON,
510
511    /// Free of payment
512    FOP,
513
514    /// Internal transfer
515    INTERNAL,
516
517    /// Delivery vs payment
518    DVP,
519
520    /// Unknown
521    #[serde(other)]
522    Unknown,
523}
524
525/// Transaction code
526///
527/// Comprehensive list of IB transaction classification codes
528#[derive(Debug, Clone, PartialEq, Eq, Hash, Deserialize, Serialize)]
529pub enum Code {
530    /// Assignment
531    A,
532
533    /// Adjustment
534    Adj,
535
536    /// Allocation
537    Al,
538
539    /// Auto exercise
540    Ae,
541
542    /// Auto FX
543    Af,
544
545    /// Away trade
546    Aw,
547
548    /// Buy-in
549    B,
550
551    /// Borrow fee
552    Bo,
553
554    /// Cancellation
555    Ca,
556
557    /// Closing
558    C,
559
560    /// Cash delivery
561    Cd,
562
563    /// Complex position
564    Cp,
565
566    /// Correct
567    Cr,
568
569    /// Crossing
570    Cs,
571
572    /// Dual
573    D,
574
575    /// ETF creation
576    Et,
577
578    /// Expired
579    Ex,
580
581    /// Exercise
582    O,
583
584    /// Guaranteed
585    G,
586
587    /// Highest cost
588    Hc,
589
590    /// HF investment
591    Hi,
592
593    /// HF redemption
594    Hr,
595
596    /// Internal transfer
597    I,
598
599    /// Affiliated account transfer
600    Ia,
601
602    /// Investor
603    Iv,
604
605    /// Margin low
606    L,
607
608    /// LIFO (Last In First Out)
609    Li,
610
611    /// Loan
612    Ln,
613
614    /// Long-term capital gain
615    Lt,
616
617    /// Maximum loss
618    M,
619
620    /// Maximum long-term capital gain
621    Ml,
622
623    /// Minimum long-term capital gain
624    Mn,
625
626    /// Maximum short-term capital gain
627    Ms,
628
629    /// Minimum short-term capital gain
630    Mi,
631
632    /// Manual exercise
633    Mx,
634
635    /// Opening
636    P,
637
638    /// Partial execution
639    Pt,
640
641    /// Fractional risk-less principal
642    Fr,
643
644    /// Fractional principal
645    Fp,
646
647    /// Price improvement
648    Pi,
649
650    /// Post accrual
651    Pa,
652
653    /// Principal
654    Pr,
655
656    /// Reinvestment
657    Re,
658
659    /// Redemption
660    Rd,
661
662    /// Reopen
663    R,
664
665    /// Reverse
666    Rv,
667
668    /// Reimbursement
669    Ri,
670
671    /// Solicited IB
672    Si,
673
674    /// Specific lot
675    Sp,
676
677    /// Solicited other
678    So,
679
680    /// Shortened settlement
681    Ss,
682
683    /// Short-term capital gain
684    St,
685
686    /// Stock yield
687    Sy,
688
689    /// Transfer
690    T,
691
692    /// Wash sale
693    W,
694
695    /// Unknown code
696    #[serde(other)]
697    Unknown,
698}
699
700/// Direction (To/From)
701#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Deserialize, Serialize)]
702pub enum ToFrom {
703    /// To
704    To,
705
706    /// From
707    From,
708
709    /// Unknown
710    #[serde(other)]
711    Unknown,
712}
713
714/// Direction (In/Out)
715#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Deserialize, Serialize)]
716pub enum InOut {
717    /// Incoming
718    IN,
719
720    /// Outgoing
721    OUT,
722
723    /// Unknown
724    #[serde(other)]
725    Unknown,
726}
727
728/// Delivered or Received
729#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Deserialize, Serialize)]
730pub enum DeliveredReceived {
731    /// Delivered
732    Delivered,
733
734    /// Received
735    Received,
736
737    /// Unknown
738    #[serde(other)]
739    Unknown,
740}
741
742#[cfg(test)]
743mod tests {
744    use super::*;
745
746    #[test]
747    fn test_asset_category_basic() {
748        // Test enum construction and comparison
749        let stock = AssetCategory::Stock;
750        assert_eq!(stock, AssetCategory::Stock);
751        assert_ne!(stock, AssetCategory::Option);
752    }
753
754    #[test]
755    fn test_buy_sell_basic() {
756        // Test enum construction and comparison
757        let buy = BuySell::Buy;
758        assert_eq!(buy, BuySell::Buy);
759        assert_ne!(buy, BuySell::Sell);
760    }
761
762    #[test]
763    fn test_open_close_basic() {
764        let open = OpenClose::Open;
765        assert_eq!(open, OpenClose::Open);
766        assert_ne!(open, OpenClose::Close);
767    }
768
769    #[test]
770    fn test_put_call_basic() {
771        let call = PutCall::Call;
772        assert_eq!(call, PutCall::Call);
773        assert_ne!(call, PutCall::Put);
774    }
775}