Skip to main content

twsapi/core/
common.rs

1//! Common types
2use std::fmt::Display;
3use std::fmt::{self, Error, Formatter};
4
5use num_derive::FromPrimitive;
6
7use serde::{Deserialize, Serialize};
8
9pub const NO_VALID_ID: i32 = -1;
10pub const MAX_MSG_LEN: i64 = 0xFFFFFF; //16Mb - 1byte
11
12pub const UNSET_INTEGER: i32 = std::i32::MAX;
13pub const UNSET_DOUBLE: f64 = 1.7976931348623157E308_f64;
14pub const UNSET_LONG: i64 = std::i64::MAX;
15
16//==================================================================================================
17/// Tick types
18#[repr(i32)]
19#[derive(Serialize, Deserialize, Clone, Debug, FromPrimitive, Copy)]
20pub enum TickType {
21    BidSize = 0,
22    Bid = 1,
23    Ask = 2,
24    AskSize = 3,
25    Last = 4,
26    LastSize = 5,
27    High = 6,
28    Low = 7,
29    Volume = 8,
30    Close = 9,
31    BidOptionComputation = 10,
32    AskOptionComputation = 11,
33    LastOptionComputation = 12,
34    ModelOption = 13,
35    Open = 14,
36    Low13Week = 15,
37    High13Week = 16,
38    Low26Week = 17,
39    High26Week = 18,
40    Low52Week = 19,
41    High52Week = 20,
42    AvgVolume = 21,
43    OpenInterest = 22,
44    OptionHistoricalVol = 23,
45    OptionImpliedVol = 24,
46    OptionBidExch = 25,
47    OptionAskExch = 26,
48    OptionCallOpenInterest = 27,
49    OptionPutOpenInterest = 28,
50    OptionCallVolume = 29,
51    OptionPutVolume = 30,
52    IndexFuturePremium = 31,
53    BidExch = 32,
54    AskExch = 33,
55    AuctionVolume = 34,
56    AuctionPrice = 35,
57    AuctionImbalance = 36,
58    MarkPrice = 37,
59    BidEfpComputation = 38,
60    AskEfpComputation = 39,
61    LastEfpComputation = 40,
62    OpenEfpComputation = 41,
63    HighEfpComputation = 42,
64    LowEfpComputation = 43,
65    CloseEfpComputation = 44,
66    LastTimestamp = 45,
67    Shortable = 46,
68    FundamentalRatios = 47,
69    RtVolume = 48,
70    Halted = 49,
71    BidYield = 50,
72    AskYield = 51,
73    LastYield = 52,
74    CustOptionComputation = 53,
75    TradeCount = 54,
76    TradeRate = 55,
77    VolumeRate = 56,
78    LastRthTrade = 57,
79    RtHistoricalVol = 58,
80    IbDividends = 59,
81    BondFactorMultiplier = 60,
82    RegulatoryImbalance = 61,
83    NewsTick = 62,
84    ShortTermVolume3Min = 63,
85    ShortTermVolume5Min = 64,
86    ShortTermVolume10Min = 65,
87    DelayedBid = 66,
88    DelayedAsk = 67,
89    DelayedLast = 68,
90    DelayedBidSize = 69,
91    DelayedAskSize = 70,
92    DelayedLastSize = 71,
93    DelayedHigh = 72,
94    DelayedLow = 73,
95    DelayedVolume = 74,
96    DelayedClose = 75,
97    DelayedOpen = 76,
98    RtTrdVolume = 77,
99    CreditmanMarkPrice = 78,
100    CreditmanSlowMarkPrice = 79,
101    DelayedBidOption = 80,
102    DelayedAskOption = 81,
103    DelayedLastOption = 82,
104    DelayedModelOption = 83,
105    LastExch = 84,
106    LastRegTime = 85,
107    FuturesOpenInterest = 86,
108    AvgOptVolume = 87,
109    DelayedLastTimestamp = 88,
110    ShortableShares = 89,
111    NotSet = UNSET_INTEGER,
112}
113
114impl fmt::Display for TickType {
115    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
116        match *self {
117            TickType::BidSize => write!(fmt, "bidSize"),
118            TickType::Bid => write!(fmt, "bidPrice"),
119            TickType::Ask => write!(fmt, "askPrice"),
120            TickType::AskSize => write!(fmt, "askSize"),
121            TickType::Last => write!(fmt, "lastPrice"),
122            TickType::LastSize => write!(fmt, "lastSize"),
123            TickType::High => write!(fmt, "high"),
124            TickType::Low => write!(fmt, "low"),
125            TickType::Volume => write!(fmt, "volume"),
126            TickType::Close => write!(fmt, "close"),
127            TickType::BidOptionComputation => write!(fmt, "bidOptComp"),
128            TickType::AskOptionComputation => write!(fmt, "askOptComp"),
129            TickType::LastOptionComputation => write!(fmt, "lastOptComp"),
130            TickType::ModelOption => write!(fmt, "modelOptComp"),
131            TickType::Open => write!(fmt, "open"),
132            TickType::Low13Week => write!(fmt, "13WeekLow"),
133            TickType::High13Week => write!(fmt, "13WeekHigh"),
134            TickType::Low26Week => write!(fmt, "26WeekLow"),
135            TickType::High26Week => write!(fmt, "26WeekHigh"),
136            TickType::Low52Week => write!(fmt, "52WeekLow"),
137            TickType::High52Week => write!(fmt, "52WeekHigh"),
138            TickType::AvgVolume => write!(fmt, "AvgVolume"),
139            TickType::OpenInterest => write!(fmt, "OpenInterest"),
140            TickType::OptionHistoricalVol => write!(fmt, "OptionHistoricalVolatility"),
141            TickType::OptionImpliedVol => write!(fmt, "OptionImpliedVolatility"),
142            TickType::OptionBidExch => write!(fmt, "OptionBidExch"),
143            TickType::OptionAskExch => write!(fmt, "OptionAskExch"),
144            TickType::OptionCallOpenInterest => write!(fmt, "OptionCallOpenInterest"),
145            TickType::OptionPutOpenInterest => write!(fmt, "OptionPutOpenInterest"),
146            TickType::OptionCallVolume => write!(fmt, "OptionCallVolume"),
147            TickType::OptionPutVolume => write!(fmt, "OptionPutVolume"),
148            TickType::IndexFuturePremium => write!(fmt, "IndexFuturePremium"),
149            TickType::BidExch => write!(fmt, "bidExch"),
150            TickType::AskExch => write!(fmt, "askExch"),
151            TickType::AuctionVolume => write!(fmt, "auctionVolume"),
152            TickType::AuctionPrice => write!(fmt, "auctionPrice"),
153            TickType::AuctionImbalance => write!(fmt, "auctionImbalance"),
154            TickType::MarkPrice => write!(fmt, "markPrice"),
155            TickType::BidEfpComputation => write!(fmt, "bidEFP"),
156            TickType::AskEfpComputation => write!(fmt, "askEFP"),
157            TickType::LastEfpComputation => write!(fmt, "lastEFP"),
158            TickType::OpenEfpComputation => write!(fmt, "openEFP"),
159            TickType::HighEfpComputation => write!(fmt, "highEFP"),
160            TickType::LowEfpComputation => write!(fmt, "lowEFP"),
161            TickType::CloseEfpComputation => write!(fmt, "closeEFP"),
162            TickType::LastTimestamp => write!(fmt, "lastTimestamp"),
163            TickType::Shortable => write!(fmt, "shortable"),
164            TickType::FundamentalRatios => write!(fmt, "fundamentals"),
165            TickType::RtVolume => write!(fmt, "RTVolume"),
166            TickType::Halted => write!(fmt, "halted"),
167            TickType::BidYield => write!(fmt, "bidYield"),
168            TickType::AskYield => write!(fmt, "askYield"),
169            TickType::LastYield => write!(fmt, "lastYield"),
170            TickType::CustOptionComputation => write!(fmt, "custOptComp"),
171            TickType::TradeCount => write!(fmt, "tradeCount"),
172            TickType::TradeRate => write!(fmt, "tradeRate"),
173            TickType::VolumeRate => write!(fmt, "volumeRate"),
174            TickType::LastRthTrade => write!(fmt, "lastRTHTrade"),
175            TickType::RtHistoricalVol => write!(fmt, "RTHistoricalVol"),
176            TickType::IbDividends => write!(fmt, "IBDividends"),
177            TickType::BondFactorMultiplier => write!(fmt, "bondFactorMultiplier"),
178            TickType::RegulatoryImbalance => write!(fmt, "regulatoryImbalance"),
179            TickType::NewsTick => write!(fmt, "newsTick"),
180            TickType::ShortTermVolume3Min => write!(fmt, "shortTermVolume3Min"),
181            TickType::ShortTermVolume5Min => write!(fmt, "shortTermVolume5Min"),
182            TickType::ShortTermVolume10Min => write!(fmt, "shortTermVolume10Min"),
183            TickType::DelayedBid => write!(fmt, "delayedBid"),
184            TickType::DelayedAsk => write!(fmt, "delayedAsk"),
185            TickType::DelayedLast => write!(fmt, "delayedLast"),
186            TickType::DelayedBidSize => write!(fmt, "delayedBidSize"),
187            TickType::DelayedAskSize => write!(fmt, "delayedAskSize"),
188            TickType::DelayedLastSize => write!(fmt, "delayedLastSize"),
189            TickType::DelayedHigh => write!(fmt, "delayedHigh"),
190            TickType::DelayedLow => write!(fmt, "delayedLow"),
191            TickType::DelayedVolume => write!(fmt, "delayedVolume"),
192            TickType::DelayedClose => write!(fmt, "delayedClose"),
193            TickType::DelayedOpen => write!(fmt, "delayedOpen"),
194            TickType::RtTrdVolume => write!(fmt, "rtTrdVolume"),
195            TickType::CreditmanMarkPrice => write!(fmt, "creditmanMarkPrice"),
196            TickType::CreditmanSlowMarkPrice => write!(fmt, "creditmanSlowMarkPrice"),
197            TickType::DelayedBidOption => write!(fmt, "delayedBidOptComp"),
198            TickType::DelayedAskOption => write!(fmt, "delayedAskOptComp"),
199            TickType::DelayedLastOption => write!(fmt, "delayedLastOptComp"),
200            TickType::DelayedModelOption => write!(fmt, "delayedModelOptComp"),
201            TickType::LastExch => write!(fmt, "lastExchange"),
202            TickType::LastRegTime => write!(fmt, "lastRegTime"),
203            TickType::FuturesOpenInterest => write!(fmt, "futuresOpenInterest"),
204            TickType::AvgOptVolume => write!(fmt, "avgOptVolume"),
205            TickType::DelayedLastTimestamp => write!(fmt, "delayedLastTimestamp"),
206            TickType::ShortableShares => write!(fmt, "shortableShares"),
207            TickType::NotSet => write!(fmt, "unknown"),
208        }
209    }
210}
211
212//==================================================================================================
213/// Financial advisor data types
214#[repr(i32)]
215#[derive(Serialize, Deserialize, Clone, FromPrimitive, Debug)]
216pub enum FaDataType {
217    NA = 0,
218    GROUPS = 1,
219    PROFILES = 2,
220    ALIASES = 3,
221}
222
223impl fmt::Display for FaDataType {
224    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
225        write!(f, "Type: {}", self)
226    }
227}
228
229//==================================================================================================
230/// Tick by tick types
231#[repr(i32)]
232#[derive(Serialize, Deserialize, Clone, FromPrimitive, Debug)]
233pub enum TickByTickType {
234    NA = 0,
235    Last = 1,
236    AllLast = 2,
237    BidAsk = 3,
238    MidPoint = 4,
239}
240
241impl fmt::Display for TickByTickType {
242    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
243        match self {
244            TickByTickType::NA => write!(f, "N/A"),
245            TickByTickType::Last => write!(f, "Last"),
246            TickByTickType::AllLast => write!(f, "AllLast"),
247            TickByTickType::BidAsk => write!(f, "BidAsk"),
248            TickByTickType::MidPoint => write!(f, "MidPoint"),
249        }
250    }
251}
252
253//==================================================================================================
254/// date - the bar's date and time (either as a yyyymmss hh:mm:ssformatted
255///        string or as system time according to the request)
256/// open  - the bar's open point
257/// high  - the bar's high point
258/// low   - the bar's low point
259/// close - the bar's closing point
260/// volume - the bar's traded volume if available
261/// count - the number of trades during the bar's timespan (only available
262///         for TRADES).
263/// bar_count - running count of the bars received for this request
264/// average - average price of the bar
265#[derive(Serialize, Deserialize, Clone, Debug, Default)]
266pub struct BarData {
267    pub date: String,
268    pub open: f64,
269    pub high: f64,
270    pub low: f64,
271    pub close: f64,
272    pub volume: i64,
273    pub bar_count: i32,
274    pub average: f64,
275}
276
277impl BarData {
278    pub fn new(
279        date: String,
280        open: f64,
281        high: f64,
282        low: f64,
283        close: f64,
284        volume: i64,
285        bar_count: i32,
286        average: f64,
287    ) -> Self {
288        BarData {
289            date,
290            open,
291            high,
292            low,
293            close,
294            volume,
295            bar_count,
296            average,
297        }
298    }
299}
300
301impl fmt::Display for BarData {
302    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
303        write!(f, "date: {}, open: {}, high: {}, low: {}, close: {}, volume: {}, average: {}, barcount: {}", self.date, self.open, self.high,
304               self.low, self.close, self.volume, self.average, self.bar_count)
305    }
306}
307
308//==================================================================================================
309/// date_time - the bar's date and time (either as a yyyymmss hh:mm:ssformatted
310///        string or as system time according to the request)
311/// open  - the bar's open point
312/// high  - the bar's high point
313/// low   - the bar's low point
314/// close - the bar's closing point
315/// volume - the bar's traded volume if available
316/// count - the number of trades during the bar's timespan (only available
317///         for TRADES).
318/// wap -   the bar's Weighted Average Price
319/// count - running count of the bars for this request
320#[derive(Serialize, Deserialize, Clone, Debug, Default)]
321pub struct RealTimeBar {
322    pub date_time: String,
323    pub open: f64,
324    pub high: f64,
325    pub low: f64,
326    pub close: f64,
327    pub volume: i64,
328    pub wap: f64,
329    pub count: i32,
330}
331
332impl RealTimeBar {
333    pub fn new(
334        date_time: String,
335        open: f64,
336        high: f64,
337        low: f64,
338        close: f64,
339        volume: i64,
340        wap: f64,
341        count: i32,
342    ) -> Self {
343        RealTimeBar {
344            date_time,
345            open,
346            high,
347            low,
348            close,
349            volume,
350            wap,
351            count,
352        }
353    }
354}
355
356impl fmt::Display for RealTimeBar {
357    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
358        write!(
359            f,
360            "date_time: {},open: {}, high: {}, low: {}, close: {}, volume: {}, wap: {}, count: {}",
361            self.date_time,
362            self.open,
363            self.high,
364            self.low,
365            self.close,
366            self.volume,
367            self.wap,
368            self.count
369        )
370    }
371}
372
373//==================================================================================================
374#[derive(Serialize, Deserialize, Clone, Debug, Default)]
375pub struct HistogramData {
376    pub price: f64,
377    pub count: i32,
378}
379
380impl HistogramData {
381    pub fn new(price: f64, count: i32) -> Self {
382        HistogramData { price, count }
383    }
384}
385
386impl fmt::Display for HistogramData {
387    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
388        write!(f, "price: {}, count: {}", self.price, self.count)
389    }
390}
391
392//==================================================================================================
393#[derive(Serialize, Deserialize, Clone, Debug, Default)]
394pub struct DepthMktDataDescription {
395    pub exchange: String,
396    pub sec_type: String,
397    pub listing_exch: String,
398    pub service_data_type: String,
399    pub agg_group: i32,
400}
401
402impl DepthMktDataDescription {
403    pub fn new(
404        exchange: String,
405        sec_type: String,
406        listing_exch: String,
407        service_data_type: String,
408        agg_group: i32,
409    ) -> Self {
410        DepthMktDataDescription {
411            exchange,
412            sec_type,
413            listing_exch,
414            service_data_type,
415            agg_group,
416        }
417    }
418}
419
420impl fmt::Display for DepthMktDataDescription {
421    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
422        write!(
423            f,
424            "exchange: {}, sectype: {}, listing_exchange: {}, service_data_type: {}, agggroup: {}, ",
425            self.exchange,
426            self.sec_type,
427            self.listing_exch,
428            self.service_data_type,
429            if self.agg_group != UNSET_INTEGER {
430                format!("{}", self.agg_group)
431            } else {
432                "".to_string()
433            }
434        )
435    }
436}
437
438//==================================================================================================
439#[derive(Serialize, Deserialize, Clone, Debug, Default)]
440pub struct SmartComponent {
441    pub bit_number: i32,
442    pub exchange: String,
443    pub exchange_letter: String,
444}
445
446impl SmartComponent {
447    pub fn new(bit_number: i32, exchange: String, exchange_letter: String) -> Self {
448        SmartComponent {
449            bit_number,
450            exchange,
451            exchange_letter,
452        }
453    }
454}
455
456impl fmt::Display for SmartComponent {
457    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
458        write!(
459            f,
460            "bit_number: {}, exchange: {}, exchange_letter: {}",
461            self.bit_number, self.exchange, self.exchange_letter
462        )
463    }
464}
465
466//==================================================================================================
467#[derive(Serialize, Deserialize, Clone, Debug, Default)]
468pub struct TickAttrib {
469    pub can_auto_execute: bool,
470    pub past_limit: bool,
471    pub pre_open: bool,
472}
473
474impl TickAttrib {
475    pub fn new(can_auto_execute: bool, past_limit: bool, pre_open: bool) -> Self {
476        TickAttrib {
477            can_auto_execute,
478            past_limit,
479            pre_open,
480        }
481    }
482}
483
484impl fmt::Display for TickAttrib {
485    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
486        write!(
487            f,
488            "can_auto_execute: {}, past_limit: {}, pre_open: {}",
489            self.can_auto_execute, self.past_limit, self.pre_open
490        )
491    }
492}
493
494//==================================================================================================
495#[derive(Serialize, Deserialize, Clone, Debug, Default)]
496pub struct TickAttribBidAsk {
497    pub bid_past_low: bool,
498    pub ask_past_high: bool,
499}
500
501impl TickAttribBidAsk {
502    pub fn new(bid_past_low: bool, ask_past_high: bool) -> Self {
503        TickAttribBidAsk {
504            bid_past_low,
505            ask_past_high,
506        }
507    }
508}
509
510impl fmt::Display for TickAttribBidAsk {
511    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
512        write!(
513            f,
514            "bid_past_low: {}, ask_past_high: {}",
515            self.bid_past_low, self.ask_past_high
516        )
517    }
518}
519
520//==================================================================================================
521#[derive(Serialize, Deserialize, Clone, Debug, Default)]
522pub struct TickAttribLast {
523    pub past_limit: bool,
524    pub unreported: bool,
525}
526
527impl TickAttribLast {
528    pub fn new(past_limit: bool, unreported: bool) -> Self {
529        TickAttribLast {
530            past_limit,
531            unreported,
532        }
533    }
534}
535
536impl fmt::Display for TickAttribLast {
537    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
538        write!(
539            f,
540            "past_limit: {}, unreported: {}",
541            self.past_limit, self.unreported
542        )
543    }
544}
545
546//==================================================================================================
547#[derive(Serialize, Deserialize, Clone, Debug, Default)]
548pub struct FamilyCode {
549    pub account_id: String,
550    pub family_code_str: String,
551}
552
553impl FamilyCode {
554    pub fn new(account_id: String, family_code_str: String) -> Self {
555        FamilyCode {
556            account_id,
557            family_code_str,
558        }
559    }
560}
561
562impl fmt::Display for FamilyCode {
563    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
564        write!(
565            f,
566            "account_id: {}, family_code_str: {}",
567            self.account_id, self.family_code_str
568        )
569    }
570}
571
572//==================================================================================================
573#[derive(Serialize, Deserialize, Clone, Debug, Default)]
574pub struct PriceIncrement {
575    pub low_edge: f64,
576    pub increment: f64,
577}
578
579impl PriceIncrement {
580    pub fn new(low_edge: f64, increment: f64) -> Self {
581        PriceIncrement {
582            low_edge,
583            increment,
584        }
585    }
586}
587
588impl fmt::Display for PriceIncrement {
589    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
590        write!(
591            f,
592            "low_edge: {}, increment: {}",
593            self.low_edge, self.increment
594        )
595    }
596}
597
598//==================================================================================================
599#[derive(Serialize, Deserialize, Clone, Debug, Default)]
600pub struct HistoricalTick {
601    pub time: i32,
602    pub price: f64,
603    pub size: i32,
604}
605
606impl HistoricalTick {
607    pub fn new(time: i32, price: f64, size: i32) -> Self {
608        HistoricalTick { time, price, size }
609    }
610}
611
612impl fmt::Display for HistoricalTick {
613    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
614        write!(
615            f,
616            "time: {}, price: {}, size: {}",
617            self.time, self.price, self.size
618        )
619    }
620}
621
622//==================================================================================================
623#[derive(Serialize, Deserialize, Clone, Debug, Default)]
624pub struct HistoricalTickBidAsk {
625    pub time: i32,
626    pub tick_attrib_bid_ask: TickAttribBidAsk,
627    pub price_bid: f64,
628    pub price_ask: f64,
629    pub size_bid: i32,
630    pub size_ask: i32,
631}
632
633impl HistoricalTickBidAsk {
634    pub fn new(
635        time: i32,
636        tick_attrib_bid_ask: TickAttribBidAsk,
637        price_bid: f64,
638        price_ask: f64,
639        size_bid: i32,
640        size_ask: i32,
641    ) -> Self {
642        HistoricalTickBidAsk {
643            time,
644            tick_attrib_bid_ask,
645            price_bid,
646            price_ask,
647            size_bid,
648            size_ask,
649        }
650    }
651}
652
653impl fmt::Display for HistoricalTickBidAsk {
654    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
655        write!(
656            f,
657            "time: {}, tick_attrib_bid_ask: {}, price_bid: {}, price_ask: {}, size_bid: {}, size_ask: {}",
658            self.time,
659            self.tick_attrib_bid_ask,
660            self.price_bid,
661            self.price_ask,
662            self.size_bid,
663            self.size_ask
664        )
665    }
666}
667
668//==================================================================================================
669#[derive(Serialize, Deserialize, Clone, Debug, Default)]
670pub struct HistoricalTickLast {
671    pub time: i32,
672    pub tick_attrib_last: TickAttribLast,
673    pub price: f64,
674    pub size: i32,
675    pub exchange: String,
676    pub special_conditions: String,
677}
678
679impl HistoricalTickLast {
680    pub fn new(
681        time: i32,
682        tick_attrib_last: TickAttribLast,
683        price: f64,
684        size: i32,
685        exchange: String,
686        special_conditions: String,
687    ) -> Self {
688        HistoricalTickLast {
689            time,
690            tick_attrib_last,
691            price,
692            size,
693            exchange,
694            special_conditions,
695        }
696    }
697}
698
699impl fmt::Display for HistoricalTickLast {
700    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
701        write!(f, "time: {}, tick_attrib_last: {}, price: {}, size: {}, exchange: {}, special_conditions: {}",
702               self.time,
703               self.tick_attrib_last,
704               self.price,
705               self.size,
706               self.exchange,
707               self.special_conditions)
708    }
709}
710
711//==================================================================================================
712#[derive(Serialize, Deserialize, Clone, Debug, Default)]
713pub struct CommissionReport {
714    pub exec_id: String,
715    pub commission: f64,
716    pub currency: String,
717    pub realized_pnl: f64,
718    pub yield_: f64,
719    pub yield_redemption_date: String, //YYYYMMDD format
720}
721
722impl CommissionReport {
723    pub fn new(
724        exec_id: String,
725        commission: f64,
726        currency: String,
727        realized_pnl: f64,
728        yield_: f64,
729        yield_redemption_date: String,
730    ) -> Self {
731        CommissionReport {
732            exec_id,
733            commission,
734            currency,
735            realized_pnl,
736            yield_,
737            yield_redemption_date,
738        }
739    }
740}
741
742impl fmt::Display for CommissionReport {
743    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
744        write!(f, "exec_id: {}, commission: {}, currency: {}, realized_pnl: {}, yield_: {}, yield_redemption_date: {}",
745               self.exec_id,
746               self.commission,
747               self.currency,
748               if self.realized_pnl != UNSET_DOUBLE { format!("{}", self.realized_pnl) } else { "".to_string() },
749               if self.yield_ != UNSET_DOUBLE { format!("{}", self.yield_) } else { "".to_string() },
750               self.yield_redemption_date)
751    }
752}
753
754//==================================================================================================
755#[derive(Serialize, Deserialize, Clone, Debug, Default)]
756pub struct NewsProvider {
757    pub code: String,
758    pub name: String,
759}
760
761impl NewsProvider {
762    pub fn new(code: String, name: String) -> Self {
763        NewsProvider { code, name }
764    }
765}
766
767impl fmt::Display for NewsProvider {
768    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
769        write!(f, "code: {}, name: {}", self.code, self.name,)
770    }
771}
772
773//==================================================================================================
774#[derive(Serialize, Deserialize, Clone, Debug, Default)]
775pub struct TagValue {
776    pub tag: String,
777    pub value: String,
778}
779
780impl TagValue {
781    pub fn new(tag: String, value: String) -> Self {
782        TagValue { tag, value }
783    }
784}
785
786impl fmt::Display for TagValue {
787    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
788        write!(f, "{}={};", self.tag, self.value,)
789    }
790}
791
792//==================================================================================================
793#[repr(i32)]
794#[derive(Serialize, Deserialize, Clone, FromPrimitive, Debug)]
795pub enum ComboParam {
796    NonGuaranteed,
797    PriceCondConid,
798    CondPriceMax,
799    CondPriceMin,
800    ChangeToMktTime1,
801    ChangeToMktTime2,
802    DiscretionaryPct,
803    DontLeginNext,
804    LeginPrio,
805    MaxSegSize,
806}
807
808impl Display for ComboParam {
809    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
810        match *self {
811            ComboParam::NonGuaranteed => write!(f, "NonGuaranteed"),
812            ComboParam::PriceCondConid => write!(f, "PriceCondConid"),
813            ComboParam::CondPriceMax => write!(f, "CondPriceMax"),
814            ComboParam::CondPriceMin => write!(f, "CondPriceMin"),
815            ComboParam::ChangeToMktTime1 => write!(f, "ChangeToMktTime1"),
816            ComboParam::ChangeToMktTime2 => write!(f, "ChangeToMktTime2"),
817            ComboParam::DiscretionaryPct => write!(f, "DiscretionaryPct"),
818            ComboParam::DontLeginNext => write!(f, "DontLeginNext"),
819            ComboParam::LeginPrio => write!(f, "LeginPrio"),
820            ComboParam::MaxSegSize => write!(f, "MaxSegSize"),
821        }
822    }
823}
824
825//==================================================================================================
826#[repr(i32)]
827#[derive(Serialize, Deserialize, Clone, FromPrimitive, Debug)]
828pub enum HedgeType {
829    None,
830    Delta,
831    Beta,
832    Fx,
833    Pair,
834}
835
836impl Display for HedgeType {
837    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
838        match *self {
839            HedgeType::None => write!(f, ""),
840            HedgeType::Delta => write!(f, "Delta"),
841            HedgeType::Beta => write!(f, "Beta"),
842            HedgeType::Fx => write!(f, "Fx"),
843            HedgeType::Pair => write!(f, "Pair"),
844        }
845    }
846}
847
848//==================================================================================================
849#[repr(i32)]
850#[derive(Serialize, Deserialize, Clone, FromPrimitive, Debug)]
851pub enum Right {
852    None,
853    Put,
854    Call,
855}
856
857impl Display for Right {
858    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
859        match *self {
860            Right::None => write!(f, ""),
861            Right::Put => write!(f, "P"),
862            Right::Call => write!(f, "C"),
863        }
864    }
865}
866
867//==================================================================================================
868#[repr(i32)]
869#[derive(Serialize, Deserialize, Clone, FromPrimitive, Debug)]
870pub enum VolatilityType {
871    None,
872    Daily,
873    Annual,
874}
875
876impl Display for VolatilityType {
877    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
878        match *self {
879            VolatilityType::None => write!(f, "None"),
880            VolatilityType::Daily => write!(f, "Daily"),
881            VolatilityType::Annual => write!(f, "Annual"),
882        }
883    }
884}
885
886//==================================================================================================
887#[repr(i32)]
888#[derive(Serialize, Deserialize, Clone, FromPrimitive, Debug)]
889pub enum ReferencePriceType {
890    None,
891    Midpoint,
892    BidOrAsk,
893}
894
895impl Display for ReferencePriceType {
896    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
897        match *self {
898            ReferencePriceType::None => write!(f, "None"),
899            ReferencePriceType::Midpoint => write!(f, "Midpoint"),
900            ReferencePriceType::BidOrAsk => write!(f, "BidOrAsk"),
901        }
902    }
903}
904
905//==================================================================================================
906#[repr(i32)]
907#[derive(Serialize, Deserialize, Clone, FromPrimitive, Debug)]
908pub enum TriggerMethod {
909    Default,
910    DoubleBidAsk,
911    Last,
912    DoubleLast,
913    BidAsk,
914    LastOrBidAsk,
915    Midpoint,
916}
917
918impl Display for TriggerMethod {
919    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
920        match *self {
921            TriggerMethod::Default => write!(f, "Default"),
922            TriggerMethod::DoubleBidAsk => write!(f, "DoubleBidAsk"),
923            TriggerMethod::Last => write!(f, "Last"),
924            TriggerMethod::DoubleLast => write!(f, "DoubleLast"),
925            TriggerMethod::BidAsk => write!(f, "BidAsk"),
926            TriggerMethod::LastOrBidAsk => write!(f, "LastOrBidAsk"),
927            TriggerMethod::Midpoint => write!(f, "Midpoint"),
928        }
929    }
930}
931
932//==================================================================================================
933#[repr(i32)]
934#[derive(Serialize, Deserialize, Clone, FromPrimitive, Debug)]
935pub enum Action {
936    BUY,
937    SELL,
938    SSHORT,
939}
940
941impl Display for Action {
942    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
943        match *self {
944            Action::BUY => write!(f, "BUY"),
945            Action::SELL => write!(f, "SELL"),
946            Action::SSHORT => write!(f, "SSHORT"),
947        }
948    }
949}
950
951//==================================================================================================
952#[repr(i32)]
953#[derive(Serialize, Deserialize, Clone, FromPrimitive, Debug)]
954pub enum Rule80A {
955    None,
956    Individual,
957    Agency,
958    AgentOtherMember,
959    IndividualPTIA,
960    AgencyPTIA,
961    AgentOtherMemberPTIA,
962    IndividualPT,
963    AgencyPT,
964    AgentOtherMemberPT,
965}
966
967impl Display for Rule80A {
968    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
969        match self {
970            Rule80A::None => write!(f, ""),
971            Rule80A::Individual => write!(f, "I"),
972            Rule80A::Agency => write!(f, "A"),
973            Rule80A::AgentOtherMember => write!(f, "W"),
974            Rule80A::IndividualPTIA => write!(f, "J"),
975            Rule80A::AgencyPTIA => write!(f, "U"),
976            Rule80A::AgentOtherMemberPTIA => write!(f, "M"),
977            Rule80A::IndividualPT => write!(f, "K"),
978            Rule80A::AgencyPT => write!(f, "Y"),
979            Rule80A::AgentOtherMemberPT => write!(f, "N"),
980        }
981    }
982}
983
984//==================================================================================================
985#[repr(i32)]
986#[derive(Serialize, Deserialize, Clone, FromPrimitive, Debug)]
987pub enum OcaType {
988    None,
989    CancelWithBlocking,
990    ReduceWithBlocking,
991    ReduceWithoutBlocking,
992}
993
994impl Display for OcaType {
995    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
996        match *self {
997            OcaType::None => write!(f, "None"),
998            OcaType::CancelWithBlocking => write!(f, "CancelWithBlocking"),
999            OcaType::ReduceWithBlocking => write!(f, "ReduceWithBlocking"),
1000            OcaType::ReduceWithoutBlocking => write!(f, "ReduceWithoutBlocking"),
1001        }
1002    }
1003}
1004
1005//==================================================================================================
1006#[repr(i32)]
1007#[derive(Serialize, Deserialize, Clone, FromPrimitive, Debug)]
1008pub enum TimeInForce {
1009    DAY,
1010    GTC,
1011    OPG,
1012    IOC,
1013    GTD,
1014    GTT,
1015    AUC,
1016    FOK,
1017    GTX,
1018    DTC,
1019}
1020
1021impl Display for TimeInForce {
1022    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
1023        match *self {
1024            TimeInForce::DAY => write!(f, "DAY"),
1025            TimeInForce::GTC => write!(f, "GTC"),
1026            TimeInForce::OPG => write!(f, "OPG"),
1027            TimeInForce::IOC => write!(f, "IOC"),
1028            TimeInForce::GTD => write!(f, "GTD"),
1029            TimeInForce::GTT => write!(f, "GTT"),
1030            TimeInForce::AUC => write!(f, "AUC"),
1031            TimeInForce::FOK => write!(f, "FOK"),
1032            TimeInForce::GTX => write!(f, "GTX"),
1033            TimeInForce::DTC => write!(f, "DTC"),
1034        }
1035    }
1036}
1037
1038//==================================================================================================
1039#[repr(i32)]
1040#[derive(Serialize, Deserialize, Clone, FromPrimitive, Debug)]
1041pub enum ExerciseType {
1042    None,
1043    Exercise,
1044    Lapse,
1045}
1046
1047impl Display for ExerciseType {
1048    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
1049        match *self {
1050            ExerciseType::None => write!(f, ""),
1051            ExerciseType::Exercise => write!(f, "Exercise"),
1052            ExerciseType::Lapse => write!(f, "Lapse"),
1053        }
1054    }
1055}
1056
1057//==================================================================================================
1058#[repr(i32)]
1059#[derive(Serialize, Deserialize, Clone, FromPrimitive, Debug)]
1060pub enum FundamentalType {
1061    ReportSnapshot,
1062    ReportsFinSummary,
1063    ReportRatios,
1064    ReportsFinStatements,
1065    RESC,
1066    CalendarReport,
1067    ReportsOwnership,
1068}
1069
1070impl Display for FundamentalType {
1071    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
1072        match *self {
1073            FundamentalType::ReportSnapshot => write!(f, "Company overview"),
1074            FundamentalType::ReportsFinSummary => write!(f, "Financial summary"),
1075            FundamentalType::ReportRatios => write!(f, "Financial ratios"),
1076            FundamentalType::ReportsFinStatements => write!(f, "Financial statements"),
1077            FundamentalType::RESC => write!(f, "Analyst estimates"),
1078            FundamentalType::CalendarReport => write!(f, "Company calendar"),
1079            FundamentalType::ReportsOwnership => write!(f, "Company ownership"),
1080        }
1081    }
1082}
1083
1084//==================================================================================================
1085#[repr(i32)]
1086#[derive(Serialize, Deserialize, Clone, FromPrimitive, Debug)]
1087pub enum WhatToShow {
1088    Trades,
1089    Midpoint,
1090    Bid,
1091    Ask,
1092    // << only these are valid for real-time bars
1093    BidAsk,
1094    HistoricalVolatility,
1095    OptionImpliedVolatility,
1096    YieldAsk,
1097    YieldBid,
1098    YieldBidAsk,
1099    YieldLast,
1100    AdjustedLast,
1101}
1102
1103impl Display for WhatToShow {
1104    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
1105        match *self {
1106            WhatToShow::Trades => write!(f, "TRADES"),
1107            WhatToShow::Midpoint => write!(f, "MIDPOINT"),
1108            WhatToShow::Bid => write!(f, "BID"),
1109            WhatToShow::Ask => write!(f, "ASK"),
1110            WhatToShow::BidAsk => write!(f, "BID_ASK"),
1111            WhatToShow::HistoricalVolatility => write!(f, "HISTORICAL_VOLATILITY"),
1112            WhatToShow::OptionImpliedVolatility => write!(f, "OPTION_IMPLIED_VOLATILITY"),
1113            WhatToShow::YieldAsk => write!(f, "YIELD_ASK"),
1114            WhatToShow::YieldBid => write!(f, "YIELD_ASK"),
1115            WhatToShow::YieldBidAsk => write!(f, "YIELD_BID_ASK"),
1116            WhatToShow::YieldLast => write!(f, "YIELD_LAST"),
1117            WhatToShow::AdjustedLast => write!(f, "ADJUSTED_LAST"),
1118        }
1119    }
1120}
1121
1122//==================================================================================================
1123#[repr(i32)]
1124#[derive(Serialize, Deserialize, Clone, FromPrimitive, Debug)]
1125pub enum BarSize {
1126    _1Secs,
1127    _5Secs,
1128    _10Secs,
1129    _15Secs,
1130    _30Secs,
1131    _1Min,
1132    _2Mins,
1133    _3Mins,
1134    _5Mins,
1135    _10Mins,
1136    _15Mins,
1137    _20Mins,
1138    _30Mins,
1139    _1Hour,
1140    _4Hours,
1141    _1Day,
1142    _1Week,
1143    _1Month,
1144}
1145
1146impl Display for BarSize {
1147    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
1148        match *self {
1149            BarSize::_1Secs => write!(f, "1 secs"),
1150            BarSize::_5Secs => write!(f, "5 secs"),
1151            BarSize::_10Secs => write!(f, "10 secs"),
1152            BarSize::_15Secs => write!(f, "15 secs"),
1153            BarSize::_30Secs => write!(f, "30 secs"),
1154            BarSize::_1Min => write!(f, "1 min"),
1155            BarSize::_2Mins => write!(f, "2 mins"),
1156            BarSize::_3Mins => write!(f, "3 mins"),
1157            BarSize::_5Mins => write!(f, "5 mins"),
1158            BarSize::_10Mins => write!(f, "10 mins"),
1159            BarSize::_15Mins => write!(f, "15 mins"),
1160            BarSize::_20Mins => write!(f, "20 mins"),
1161            BarSize::_30Mins => write!(f, "30 mins"),
1162            BarSize::_1Hour => write!(f, "1 hour"),
1163            BarSize::_4Hours => write!(f, "4 hours"),
1164            BarSize::_1Day => write!(f, "1 day"),
1165            BarSize::_1Week => write!(f, "1 week"),
1166            BarSize::_1Month => write!(f, "1 month"),
1167        }
1168    }
1169}
1170
1171//==================================================================================================
1172#[repr(i32)]
1173#[derive(Serialize, Deserialize, Clone, FromPrimitive, Debug)]
1174pub enum DurationUnit {
1175    SECOND,
1176    DAY,
1177    WEEK,
1178    MONTH,
1179    YEAR,
1180}
1181
1182impl Display for DurationUnit {
1183    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
1184        match *self {
1185            DurationUnit::SECOND => write!(f, "SECOND"),
1186            DurationUnit::DAY => write!(f, "DAY"),
1187            DurationUnit::WEEK => write!(f, "WEEK"),
1188            DurationUnit::MONTH => write!(f, "MONTH"),
1189            DurationUnit::YEAR => write!(f, "YEAR"),
1190        }
1191    }
1192}
1193
1194//==================================================================================================
1195#[repr(i32)]
1196#[derive(Serialize, Deserialize, Clone, FromPrimitive, Debug)]
1197pub enum DeepType {
1198    INSERT,
1199    UPDATE,
1200    DELETE,
1201}
1202
1203impl Display for DeepType {
1204    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
1205        match *self {
1206            DeepType::INSERT => write!(f, "INSERT"),
1207            DeepType::UPDATE => write!(f, "UPDATE"),
1208            DeepType::DELETE => write!(f, "DELETE"),
1209        }
1210    }
1211}
1212
1213#[repr(i32)]
1214#[derive(Serialize, Deserialize, Clone, FromPrimitive, Debug)]
1215pub enum DeepSide {
1216    Sell,
1217    Buy,
1218}
1219
1220impl Display for DeepSide {
1221    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
1222        match *self {
1223            DeepSide::Buy => write!(f, "BUY"),
1224            DeepSide::Sell => write!(f, "SELL"),
1225        }
1226    }
1227}
1228
1229//==================================================================================================
1230#[repr(i32)]
1231#[derive(Serialize, Deserialize, Clone, FromPrimitive, Debug)]
1232pub enum NewsType {
1233    Unknown,
1234    BBS,
1235    LiveExch,
1236    DeadExch,
1237    HTML,
1238    PopupText,
1239    PopupHtml,
1240}
1241
1242impl Display for NewsType {
1243    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
1244        match *self {
1245            NewsType::Unknown => write!(f, "UNKNOWN"),
1246            NewsType::BBS => write!(f, "BBS"),
1247            NewsType::LiveExch => write!(f, "LIVE_EXCH"),
1248            NewsType::DeadExch => write!(f, "DEAD_EXCH"),
1249            NewsType::HTML => write!(f, "HTML"),
1250            NewsType::PopupText => write!(f, "POPUP_TEXT"),
1251            NewsType::PopupHtml => write!(f, "POPUP_HTML"),
1252        }
1253    }
1254}
1255
1256//==================================================================================================
1257#[repr(i32)]
1258#[derive(Serialize, Deserialize, Clone, FromPrimitive, Debug)]
1259pub enum SecIdType {
1260    None,
1261    CUSIP,
1262    SEDOL,
1263    ISIN,
1264    RIC,
1265}
1266
1267impl Display for SecIdType {
1268    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
1269        match *self {
1270            SecIdType::None => write!(f, ""),
1271            SecIdType::CUSIP => write!(f, "CUSIP"),
1272            SecIdType::SEDOL => write!(f, "SEDOL"),
1273            SecIdType::ISIN => write!(f, "ISIN"),
1274            SecIdType::RIC => write!(f, "RIC"),
1275        }
1276    }
1277}
1278
1279//==================================================================================================
1280#[repr(i32)]
1281#[derive(Serialize, Deserialize, Clone, FromPrimitive, Debug)]
1282pub enum SecType {
1283    None,
1284    STK,
1285    OPT,
1286    FUT,
1287    CONTFUT,
1288    CASH,
1289    BOND,
1290    CFD,
1291    FOP,
1292    WAR,
1293    IOPT,
1294    FWD,
1295    BAG,
1296    IND,
1297    BILL,
1298    FUND,
1299    FIXED,
1300    SLB,
1301    NEWS,
1302    CMDTY,
1303    BSK,
1304    ICU,
1305    ICS,
1306}
1307
1308impl Display for SecType {
1309    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
1310        match *self {
1311            SecType::None => write!(f, ""),
1312            SecType::STK => write!(f, "STK"),
1313            SecType::OPT => write!(f, "OPT"),
1314            SecType::FUT => write!(f, "FUT"),
1315            SecType::CONTFUT => write!(f, "CONTFUT"),
1316            SecType::CASH => write!(f, "CASH"),
1317            SecType::BOND => write!(f, "BOND"),
1318            SecType::CFD => write!(f, "CFD"),
1319            SecType::FOP => write!(f, "FOP"),
1320            SecType::WAR => write!(f, "WAR"),
1321            SecType::IOPT => write!(f, "IOPT"),
1322            SecType::FWD => write!(f, "FWD"),
1323            SecType::BAG => write!(f, "BAG"),
1324            SecType::IND => write!(f, "IND"),
1325            SecType::BILL => write!(f, "BILL"),
1326            SecType::FUND => write!(f, "FUND"),
1327            SecType::FIXED => write!(f, "FIXED"),
1328            SecType::SLB => write!(f, "SLB"),
1329            SecType::NEWS => write!(f, "NEWS"),
1330            SecType::CMDTY => write!(f, "CMDTY"),
1331            SecType::BSK => write!(f, "BSK"),
1332            SecType::ICU => write!(f, "ICU"),
1333            SecType::ICS => write!(f, "ICS"),
1334        }
1335    }
1336}
1337
1338//==================================================================================================
1339#[repr(i32)]
1340#[derive(Serialize, Deserialize, Clone, FromPrimitive, Debug)]
1341pub enum MarketDataTypeEnum {
1342    Unknown,
1343    Realtime,
1344    Frozen,
1345    Delayed,
1346    DelayedFrozen, //public static MktDataType get( int ordinal) {
1347                   //return getEnum( ordinal, values() );
1348                   //}
1349}
1350
1351impl Display for MarketDataTypeEnum {
1352    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
1353        match self {
1354            MarketDataTypeEnum::Unknown => write!(f, "N/A"),
1355            MarketDataTypeEnum::Realtime => write!(f, "REALTIME"),
1356            MarketDataTypeEnum::Frozen => write!(f, "FROZEN"),
1357            MarketDataTypeEnum::Delayed => write!(f, "DELAYED"),
1358            MarketDataTypeEnum::DelayedFrozen => write!(f, "DELAYED_FROZEN"),
1359        }
1360    }
1361}
1362
1363//==================================================================================================
1364#[repr(i32)]
1365#[derive(Serialize, Deserialize, Clone, FromPrimitive, Debug)]
1366pub enum Method {
1367    None,
1368    EqualQuantity,
1369    AvailableEquity,
1370    NetLiq,
1371    PctChange,
1372}
1373
1374impl Display for Method {
1375    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
1376        match self {
1377            Method::None => write!(f, ""),
1378            Method::EqualQuantity => write!(f, "EqualQuantity"),
1379            Method::AvailableEquity => write!(f, "AvailableEquity"),
1380            Method::NetLiq => write!(f, "NetLiq"),
1381            Method::PctChange => write!(f, "PctChange"),
1382        }
1383    }
1384}
1385
1386//==================================================================================================
1387#[repr(i32)]
1388#[derive(Serialize, Deserialize, Clone, FromPrimitive, Debug)]
1389pub enum UsePriceMgmtAlgo {
1390    Default,
1391    NotUse,
1392    Use,
1393}
1394
1395impl UsePriceMgmtAlgo {
1396    pub fn value(&self) -> Option<bool> {
1397        match *self {
1398            UsePriceMgmtAlgo::Default => None,
1399            UsePriceMgmtAlgo::NotUse => Some(false),
1400            UsePriceMgmtAlgo::Use => Some(true),
1401        }
1402    }
1403}