1use std::ops::{Deref, DerefMut};
2use derive_setters::Setters;
3use rust_decimal::Decimal;
4use serde::{Deserialize, Serialize};
5use crate::schema::enums::{ImpactLevel, MarginMode, ProfitMode, QuoteId, TimePeriod, TradeStatus, TradingAction, TradingCommand, TransactionStatus, TransactionType};
6
7#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize, Setters)]
9#[setters(into, strip_option, prefix = "with_")]
10#[serde(rename_all = "camelCase")]
11pub struct LoginRequest {
12 pub user_id: String,
14 pub password: String,
16 #[serde(skip_serializing_if = "Option::is_none")]
18 pub app_id: Option<String>,
19 #[serde(skip_serializing_if = "Option::is_none")]
21 pub app_name: Option<String>,
22}
23
24
25#[derive(Default, Copy, Clone, PartialEq, Debug, Serialize, Deserialize)]
28pub struct LoginResponse;
29
30
31#[derive(Default, Copy, Clone, PartialEq, Debug, Serialize, Deserialize)]
34pub struct GetAllSymbolsRequest;
35
36
37#[derive(Clone, PartialEq, Debug, Default, Serialize, Deserialize)]
39pub struct GetAllSymbolsResponse(pub Vec<SymbolRecord>);
40
41impl Deref for GetAllSymbolsResponse {
42 type Target = Vec<SymbolRecord>;
43
44 fn deref(&self) -> &Self::Target {
45 &self.0
46 }
47}
48
49
50impl DerefMut for GetAllSymbolsResponse {
51 fn deref_mut(&mut self) -> &mut Self::Target {
52 &mut self.0
53 }
54}
55
56
57#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize, Setters)]
59#[setters(into, strip_option, prefix = "with_")]
60#[serde(rename_all = "camelCase")]
61pub struct SymbolRecord {
62 pub ask: Decimal,
64 pub bid: Decimal,
66 pub category_name: String,
68 pub contract_size: i64,
70 pub currency: String,
72 pub currency_pair: bool,
74 pub currency_profit: String,
76 pub description: String,
78 pub expiration: Option<u64>,
80 pub group_name: String,
82 pub high: Decimal,
84 pub initial_margin: i64,
86 pub instant_max_volume: i64,
88 pub leverage: Decimal,
90 pub long_only: bool,
92 pub lot_max: Decimal,
94 pub lot_min: Decimal,
96 pub lot_step: Decimal,
98 pub low: Decimal,
100 pub margin_hedged: i64,
102 pub margin_hedged_strong: bool,
104 pub margin_maintenance: Option<i64>,
106 pub margin_mode: MarginMode,
108 pub percentage: Decimal,
110 pub pips_precision: i64,
112 pub precision: i64,
114 pub profit_mode: ProfitMode,
116 pub quote_id: QuoteId,
118 pub short_selling: bool,
120 pub spread_raw: Decimal,
122 pub spread_table: Decimal,
124 pub starting: Option<u64>,
126 pub step_rule_id: i64,
128 pub stops_level: i64,
130 #[serde(rename = "swap_rollover3days")]
132 pub swap_rollover_3days: i64,
133 pub swap_enable: bool,
135 pub swap_long: Decimal,
137 pub swap_short: Decimal,
139 pub swap_type: i64,
141 pub symbol: String,
143 pub tick_size: Option<Decimal>,
145 pub tick_value: Option<Decimal>,
147 pub time: u64,
149 pub time_string: String,
151 pub trailing_enabled: bool,
153 pub type_: i64,
155}
156
157
158#[derive(Default, Copy, Clone, PartialEq, Debug, Serialize, Deserialize)]
160pub struct GetCalendarRequest;
161
162
163#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize)]
164pub struct GetCalendarResponse(pub Vec<CalendarRecord>);
165
166
167impl Deref for GetCalendarResponse {
168 type Target = Vec<CalendarRecord>;
169
170 fn deref(&self) -> &Self::Target {
171 &self.0
172 }
173}
174
175impl DerefMut for GetCalendarResponse {
176 fn deref_mut(&mut self) -> &mut Self::Target {
177 &mut self.0
178 }
179}
180
181
182#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize, Setters)]
184#[setters(into, strip_option, prefix = "with_")]
185#[serde(rename_all = "camelCase")]
186pub struct CalendarRecord {
187 pub country: String,
189 pub current: String,
191 pub forecast: String,
193 pub impact: ImpactLevel,
195 pub period: String,
197 pub previous: String,
199 pub time: u64,
201 pub title: String,
203}
204
205
206#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize, Setters)]
210#[setters(into, strip_option, prefix = "with_")]
211#[serde(rename_all = "camelCase")]
212pub struct GetChartLastRequestRequest {
213 info: ChartLastInfoRecord
214}
215
216
217#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize, Setters)]
219#[setters(into, strip_option, prefix = "with_")]
220#[serde(rename_all = "camelCase")]
221pub struct ChartLastInfoRecord {
222 pub period: TimePeriod,
224 pub start: u64,
226 pub symbol: String,
228}
229
230
231#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize, Setters)]
233#[setters(into, strip_option, prefix = "with_")]
234#[serde(rename_all = "camelCase")]
235pub struct GetChartLastRequestResponse {
236 pub digits: i64,
238 pub rate_infos: Vec<RateInfoRecord>,
240}
241
242
243#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize, Setters)]
245#[setters(into, strip_option, prefix = "with_")]
246#[serde(rename_all = "camelCase")]
247pub struct RateInfoRecord {
248 pub close: Decimal,
250 pub ctm: u64,
252 pub ctm_string: String,
254 pub high: Decimal,
256 pub low: Decimal,
258 pub open: Decimal,
260 pub vol: Decimal,
262}
263
264
265impl From<StreamGetCandlesData> for RateInfoRecord {
266 fn from(value: StreamGetCandlesData) -> Self {
267 Self {
268 close: value.close,
269 ctm: value.ctm,
270 ctm_string: value.ctm_string,
271 high: value.high,
272 low: value.low,
273 open: value.open,
274 vol: value.vol,
275 }
276 }
277}
278
279
280#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize, Setters)]
282#[setters(into, strip_option, prefix = "with_")]
283#[serde(rename_all = "camelCase")]
284pub struct GetChartRangeRequestRequest {
285 pub info: ChartRangeInfoRecord,
287}
288
289
290#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize, Setters)]
292#[setters(into, strip_option, prefix = "with_")]
293#[serde(rename_all = "camelCase")]
294pub struct ChartRangeInfoRecord {
295 pub end: u64,
297 pub period: TimePeriod,
299 pub start: u64,
301 pub symbol: String,
303 pub ticks: Option<i64>,
305}
306
307
308pub type GetChartRangeRequestResponse = GetChartLastRequestResponse;
310
311
312#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize, Setters)]
314#[setters(into, strip_option, prefix = "with_")]
315#[serde(rename_all = "camelCase")]
316pub struct GetCommissionDefRequest {
317 pub symbol: String,
319 pub volume: Decimal,
321}
322
323
324#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize, Setters)]
325#[setters(into, strip_option, prefix = "with_")]
326#[serde(rename_all = "camelCase")]
327pub struct GetCommissionDefResponse {
328 commission: Option<Decimal>,
330 rate_of_exchange: Option<Decimal>,
332}
333
334
335#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize)]
336pub struct GetCurrentUserDataRequest;
337
338
339#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize, Setters)]
341#[setters(into, strip_option, prefix = "with_")]
342#[serde(rename_all = "camelCase")]
343pub struct GetCurrentUserDataResponse {
344 pub company_unit: i64,
346 pub currency: String,
348 pub group: String,
350 pub ib_account: bool,
352 pub leverage: i64,
354 pub leverage_multiplier: Decimal,
356 pub spread_type: Option<String>,
358 pub trailing_stop: bool,
360}
361
362
363#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize, Setters)]
365#[setters(into, strip_option, prefix = "with_")]
366#[serde(rename_all = "camelCase")]
367pub struct GetIbsHistoryRequest {
368 pub end: u64,
370 pub start: u64,
372}
373
374
375#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize)]
376pub struct GetIbsHistoryResponse(pub Vec<IBRecord>);
377
378
379impl Deref for GetIbsHistoryResponse {
380 type Target = Vec<IBRecord>;
381
382 fn deref(&self) -> &Self::Target {
383 &self.0
384 }
385}
386
387
388impl DerefMut for GetIbsHistoryResponse {
389 fn deref_mut(&mut self) -> &mut Self::Target {
390 &mut self.0
391 }
392}
393
394
395#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize, Setters)]
397#[setters(into, strip_option, prefix = "with_")]
398#[serde(rename_all = "camelCase")]
399pub struct IBRecord {
400 pub close_price: Option<Decimal>,
402 pub login: Option<String>,
404 pub nominal: Option<Decimal>,
406 pub open_price: Option<Decimal>,
408 pub side: Option<TradingAction>,
410 pub surname: Option<String>,
412 pub symbol: Option<String>,
414 pub timestamp: Option<u64>,
416 pub volume: Option<Decimal>,
418}
419
420
421#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize)]
422pub struct GetMarginLevelRequest;
423
424
425#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize, Setters)]
427#[setters(into, strip_option, prefix = "with_")]
428#[serde(rename_all = "camelCase")]
429pub struct GetMarginLevelResponse {
430 pub balance: Decimal,
432 pub credit: Decimal,
434 pub currency: String,
436 pub equity: Decimal,
438 pub margin: Decimal,
440 #[serde(rename = "margin_free")]
442 pub margin_free: Decimal,
443 #[serde(rename = "margin_level")]
445 pub margin_level: Decimal,
446}
447
448
449#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize, Setters)]
450#[setters(into, strip_option, prefix = "with_")]
451#[serde(rename_all = "camelCase")]
452pub struct GetMarginTradeRequest {
453 pub symbol: String,
455 pub volume: Decimal,
457}
458
459
460#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize, Setters)]
462#[setters(into, strip_option, prefix = "with_")]
463#[serde(rename_all = "camelCase")]
464pub struct GetMarginTradeResponse {
465 pub margin: Decimal,
467}
468
469
470#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize, Setters)]
472#[setters(into, strip_option, prefix = "with_")]
473#[serde(rename_all = "camelCase")]
474pub struct GetNewsRequest {
475 pub end: u64,
477 pub start: u64,
479}
480
481
482#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize)]
483pub struct GetNewsResponse(pub Vec<NewsBodyRecord>);
484
485impl Deref for GetNewsResponse {
486 type Target = Vec<NewsBodyRecord>;
487
488 fn deref(&self) -> &Self::Target {
489 &self.0
490 }
491}
492
493impl DerefMut for GetNewsResponse {
494 fn deref_mut(&mut self) -> &mut Self::Target {
495 &mut self.0
496 }
497}
498
499
500#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize, Setters)]
502#[setters(into, strip_option, prefix = "with_")]
503#[serde(rename_all = "camelCase")]
504pub struct NewsBodyRecord {
505 pub body: String,
507 #[serde(rename = "bodylen")]
509 pub body_len: usize,
510 pub key: String,
512 pub time: u64,
514 pub time_string: String,
516 pub title: String,
518}
519
520#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize, Setters)]
522#[setters(into, strip_option, prefix = "with_")]
523#[serde(rename_all = "camelCase")]
524pub struct GetProfitCalculationRequest {
525 pub close_price: Decimal,
527 pub cmd: TradingCommand,
529 pub open_price: Decimal,
531 pub symbol: String,
533 pub volume: Decimal,
535}
536
537
538#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize, Setters)]
540#[setters(into, strip_option, prefix = "with_")]
541#[serde(rename_all = "camelCase")]
542pub struct GetProfitCalculationResponse {
543 pub profit: Decimal,
545}
546
547
548#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize)]
549pub struct GetServerTimeRequest;
550
551
552#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize, Setters)]
554#[setters(into, strip_option, prefix = "with_")]
555#[serde(rename_all = "camelCase")]
556pub struct GetServerTimeResponse {
557 pub time: u64,
559 pub time_string: String,
561}
562
563
564#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize)]
565pub struct GetStepRulesRequest;
566
567#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize)]
568pub struct GetStepRulesResponse(pub Vec<StepRuleRecord>);
569
570
571impl Deref for GetStepRulesResponse {
572 type Target = Vec<StepRuleRecord>;
573
574 fn deref(&self) -> &Self::Target {
575 &self.0
576 }
577}
578
579impl DerefMut for GetStepRulesResponse {
580 fn deref_mut(&mut self) -> &mut Self::Target {
581 &mut self.0
582 }
583}
584
585
586#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize, Setters)]
588#[setters(into, strip_option, prefix = "with_")]
589#[serde(rename_all = "camelCase")]
590pub struct StepRuleRecord {
591 pub id: u32,
593 pub name: String,
595 pub steps: Vec<StepRecord>,
598}
599
600
601#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize, Setters)]
603#[setters(into, strip_option, prefix = "with_")]
604#[serde(rename_all = "camelCase")]
605pub struct StepRecord {
606 pub from_value: Decimal,
608 pub step: Decimal,
610}
611
612
613#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize, Setters)]
615#[setters(into, strip_option, prefix = "with_")]
616#[serde(rename_all = "camelCase")]
617pub struct GetSymbolRequest {
618 pub symbol: String,
620}
621
622
623pub type GetSymbolResponse = SymbolRecord;
624
625
626#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize, Setters)]
628#[setters(into, strip_option, prefix = "with_")]
629#[serde(rename_all = "camelCase")]
630pub struct GetTickPricesRequest {
631 pub level: u32,
633 pub symbols: Vec<String>,
635 pub timestamp: u64,
637}
638
639
640#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize, Setters)]
641#[setters(into, strip_option, prefix = "with_")]
642#[serde(rename_all = "camelCase")]
643pub struct GetTickPricesResponse {
644 pub quotations: Vec<TickRecord>,
645}
646
647
648#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize, Setters)]
650#[setters(into, strip_option, prefix = "with_")]
651#[serde(rename_all = "camelCase")]
652pub struct TickRecord {
653 pub ask: Decimal,
655 pub ask_volume: Option<u32>,
657 pub bid: Decimal,
659 pub bid_volume: Option<u32>,
661 pub high: Decimal,
663 pub level: u32,
665 pub low: Decimal,
667 pub spread_raw: Decimal,
669 pub spread_table: Decimal,
671 pub symbol: String,
673 pub timestamp: u64,
675}
676
677
678#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize, Setters)]
679#[setters(into, strip_option, prefix = "with_")]
680#[serde(rename_all = "camelCase")]
681pub struct GetTradeRecordsRequest {
682 pub orders: Vec<u32>,
684}
685
686
687#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize)]
688pub struct GetTradeRecordsResponse(pub Vec<TradeRecord>);
689
690
691impl Deref for GetTradeRecordsResponse {
692 type Target = Vec<TradeRecord>;
693
694 fn deref(&self) -> &Self::Target {
695 &self.0
696 }
697}
698
699
700impl DerefMut for GetTradeRecordsResponse {
701 fn deref_mut(&mut self) -> &mut Self::Target {
702 &mut self.0
703 }
704}
705
706
707#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize, Setters)]
709#[setters(into, strip_option, prefix = "with_")]
710#[serde(rename_all = "camelCase")]
711pub struct TradeRecord {
712 #[serde(rename = "close_price")]
714 pub close_price: Decimal,
715 #[serde(rename = "close_time")]
717 pub close_time: Option<u64>,
718 #[serde(rename="close_timeString")]
720 pub close_time_string: Option<String>,
721 pub closed: bool,
723 pub cmd: TradingCommand,
725 pub comment: String,
727 pub commission: Option<Decimal>,
729 pub custom_comment: String,
731 pub digits: u32,
733 pub expiration: Option<u64>,
735 pub expiration_string: Option<String>,
737 #[serde(rename = "margin_rate")]
739 pub margin_rate: Decimal,
740 pub offset: u32,
742 #[serde(rename = "open_price")]
744 pub open_price: Decimal,
745 #[serde(rename = "open_time")]
747 pub open_time: u64,
748 #[serde(rename = "open_timeString")]
750 pub open_time_string: String,
751 pub order: u32,
753 pub order2: u32,
755 pub position: u32,
757 pub profit: Decimal,
759 pub sl: Decimal,
761 pub storage: Decimal,
763 pub symbol: Option<String>,
765 pub timestamp: u64,
767 pub tp: Decimal,
769 pub volume: Decimal,
771}
772
773
774#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize, Setters)]
775#[setters(into, strip_option, prefix = "with_")]
776#[serde(rename_all = "camelCase")]
777pub struct GetTradesRequest {
778 pub opened_only: bool,
780}
781
782
783pub type GetTradesResponse = GetTradeRecordsResponse;
785
786
787#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize, Setters)]
789#[setters(into, strip_option, prefix = "with_")]
790#[serde(rename_all = "camelCase")]
791pub struct GetTradesHistoryRequest {
792 pub end: u64,
794 pub start: u64,
796}
797
798
799pub type GetTradesHistoryResponse = GetTradeRecordsResponse;
801
802
803#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize, Setters)]
804#[setters(into, strip_option, prefix = "with_")]
805#[serde(rename_all = "camelCase")]
806pub struct GetTradingHoursRequest {
807 pub symbols: Vec<String>,
809}
810
811
812#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize)]
813pub struct GetTradingHoursResponse(pub Vec<TradingHoursRecord>);
814
815
816impl Deref for GetTradingHoursResponse {
817 type Target = Vec<TradingHoursRecord>;
818
819 fn deref(&self) -> &Self::Target {
820 &self.0
821 }
822}
823
824impl DerefMut for GetTradingHoursResponse {
825 fn deref_mut(&mut self) -> &mut Self::Target {
826 &mut self.0
827 }
828}
829
830
831#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize, Setters)]
832#[setters(into, strip_option, prefix = "with_")]
833#[serde(rename_all = "camelCase")]
834pub struct TradingHoursRecord {
835 pub quotes: Vec<HoursRecord>,
837 pub symbol: String,
839 pub trading: Vec<HoursRecord>,
841}
842
843
844#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize, Setters)]
845#[setters(into, strip_option, prefix = "with_")]
846#[serde(rename_all = "camelCase")]
847pub struct HoursRecord {
848 pub day: u8,
850 pub from_t: u64,
852 pub to_t: u64,
854}
855
856
857#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize)]
858pub struct GetVersionRequest;
859
860
861#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize, Setters)]
862#[setters(into, strip_option, prefix = "with_")]
863#[serde(rename_all = "camelCase")]
864pub struct GetVersionResponse {
865 pub version: String,
867}
868
869
870#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize)]
871pub struct PingRequest;
872
873
874#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize)]
875pub struct PingResponse;
876
877
878#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize, Setters)]
880#[setters(into, strip_option, prefix = "with_")]
881#[serde(rename_all = "camelCase")]
882pub struct TradeTransactionRequest {
883 pub trade_trans_info: TradeTransInfo,
885}
886
887
888#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize, Setters)]
889#[setters(into, strip_option, prefix = "with_")]
890#[serde(rename_all = "camelCase")]
891pub struct TradeTransInfo {
892 pub cmd: TradingCommand,
894 pub custom_comment: String,
896 pub expiration: u64,
898 pub offset: i32,
900 pub order: i32,
902 pub price: f64,
904 pub sl: f64,
906 pub symbol: String,
908 pub tp: f64,
910 pub type_: TransactionType,
912 pub volume: f64,
914}
915
916
917#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize, Setters)]
918#[setters(into, strip_option, prefix = "with_")]
919#[serde(rename_all = "camelCase")]
920pub struct TradeTransactionResponse {
921 pub order: i32,
923}
924
925
926#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize, Setters)]
927#[setters(into, strip_option, prefix = "with_")]
928#[serde(rename_all = "camelCase")]
929pub struct TradeTransactionStatusRequest {
930 pub order: i32,
932}
933
934
935#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize, Setters)]
937#[setters(into, strip_option, prefix = "with_")]
938#[serde(rename_all = "camelCase")]
939pub struct TradeTransactionStatusResponse {
940 pub ask: Decimal,
942 pub bid: Decimal,
944 pub custom_comment: String,
946 pub message: Option<String>,
948 pub order: i32,
950 pub request_status: TransactionStatus,
952}
953
954
955#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize)]
956pub struct StreamGetBalanceSubscribe;
957
958#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize)]
959pub struct StreamGetBalanceUnsubscribe;
960
961
962#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize, Setters)]
963#[setters(into, strip_option, prefix = "with_")]
964#[serde(rename_all = "camelCase")]
965pub struct StreamGetBalanceData {
966 pub balance: Decimal,
968 pub credit: Decimal,
970 pub equity: Decimal,
972 pub margin: Decimal,
974 pub margin_free: Decimal,
976 pub margin_level: Decimal,
978}
979
980
981#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize, Setters)]
982#[setters(into, strip_option, prefix = "with_")]
983#[serde(rename_all = "camelCase")]
984pub struct StreamGetCandlesSubscribe {
985 pub symbol: String,
987}
988
989
990#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize, Setters)]
991#[setters(into, strip_option, prefix = "with_")]
992#[serde(rename_all = "camelCase")]
993pub struct StreamGetCandlesUnsubscribe {
994 pub symbol: String,
996}
997
998
999#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize, Setters)]
1000#[setters(into, strip_option, prefix = "with_")]
1001#[serde(rename_all = "camelCase")]
1002pub struct StreamGetCandlesData {
1003 pub close: Decimal,
1005 pub ctm: u64,
1007 pub ctm_string: String,
1009 pub high: Decimal,
1011 pub low: Decimal,
1013 pub open: Decimal,
1015 pub quote_id: QuoteId,
1017 pub symbol: String,
1019 pub vol: Decimal,
1021}
1022
1023
1024#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize)]
1025pub struct StreamGetKeepAliveSubscribe;
1026
1027#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize)]
1028pub struct StreamGetKeepAliveUnsubscribe;
1029
1030
1031#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize, Setters)]
1032#[setters(into, strip_option, prefix = "with_")]
1033#[serde(rename_all = "camelCase")]
1034pub struct StreamGetKeepAliveData {
1035 pub timestamp: u64,
1037}
1038
1039
1040#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize)]
1041pub struct StreamGetNewsSubscribe;
1042
1043#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize)]
1044pub struct StreamGetNewsUnsubscribe;
1045
1046
1047#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize, Setters)]
1048#[setters(into, strip_option, prefix = "with_")]
1049#[serde(rename_all = "camelCase")]
1050pub struct StreamGetNewsData {
1051 pub body: String,
1053 pub key: String,
1055 pub time: u64,
1057 pub title: String,
1059}
1060
1061
1062#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize)]
1063pub struct StreamGetProfitSubscribe;
1064
1065
1066#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize)]
1067pub struct StreamGetProfitUnsubscribe;
1068
1069
1070#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize, Setters)]
1071#[setters(into, strip_option, prefix = "with_")]
1072#[serde(rename_all = "camelCase")]
1073pub struct StreamGetProfitData {
1074 pub order: i32,
1076 pub order2: i32,
1078 pub position: i32,
1080 pub profit: Decimal,
1082}
1083
1084
1085#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize, Setters)]
1086#[setters(into, strip_option, prefix = "with_")]
1087#[serde(rename_all = "camelCase")]
1088pub struct StreamGetTickPricesSubscribe {
1089 pub symbol: String,
1091 pub min_arrival_time: Option<u64>,
1093 pub max_level: Option<u64>,
1095}
1096
1097
1098#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize, Setters)]
1099#[setters(into, strip_option, prefix = "with_")]
1100#[serde(rename_all = "camelCase")]
1101pub struct StreamGetTickPricesUnsubscribe {
1102 pub symbol: String,
1104}
1105
1106
1107#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize, Setters)]
1108#[setters(into, strip_option, prefix = "with_")]
1109#[serde(rename_all = "camelCase")]
1110pub struct StreamGetTickPricesData {
1111 pub ask: Decimal,
1113 pub ask_volume: Option<i32>,
1115 pub bid: Decimal,
1117 pub bid_volume: Option<i32>,
1119 pub high: Decimal,
1121 pub level: i32,
1123 pub low: Decimal,
1125 pub quote_id: QuoteId,
1127 pub spread_raw: Decimal,
1129 pub spread_table: Decimal,
1131 pub symbol: String,
1133 pub timestamp: u64,
1135}
1136
1137
1138#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize)]
1139pub struct StreamGetTradesSubscribe;
1140
1141#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize)]
1142pub struct StreamGetTradesUnsubscribe;
1143
1144
1145#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize, Setters)]
1146#[setters(into, strip_option, prefix = "with_")]
1147#[serde(rename_all = "camelCase")]
1148pub struct StreamGetTradesData {
1149 #[serde(rename = "close_price")]
1151 pub close_price: Decimal,
1152 #[serde(rename = "close_time")]
1154 pub close_time: Option<u64>,
1155 pub closed: bool,
1157 pub cmd: TradingCommand,
1159 pub comment: String,
1161 pub commission: Option<Decimal>,
1163 pub custom_comment: String,
1165 pub digits: i32,
1167 pub expiration: Option<u64>,
1169 #[serde(rename = "margin_rate")]
1171 pub margin_rate: Decimal,
1172 pub offset: i32,
1174 #[serde(rename = "open_price")]
1176 pub open_price: Decimal,
1177 #[serde(rename = "open_time")]
1179 pub open_time: u64,
1180 pub order: i32,
1182 pub order2: i32,
1184 pub position: i32,
1186 pub profit: Option<Decimal>,
1188 pub sl: Decimal,
1190 pub state: TradeStatus,
1192 pub storage: Decimal,
1194 pub symbol: String,
1196 pub tp: Decimal,
1198 pub type_: TransactionType,
1200 pub volume: Decimal,
1202}
1203
1204
1205#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize)]
1206pub struct StreamGetTradeStatusSubscribe;
1207
1208
1209#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize)]
1210pub struct StreamGetTradeStatusUnsubscribe;
1211
1212
1213#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize, Setters)]
1214#[setters(into, strip_option, prefix = "with_")]
1215#[serde(rename_all = "camelCase")]
1216pub struct StreamGetTradeStatusData {
1217 pub custom_comment: String,
1219 pub message: Option<String>,
1221 pub order: i32,
1223 pub price: Decimal,
1225 pub request_status: TransactionStatus,
1227}
1228
1229
1230#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize)]
1231pub struct StreamPingSubscribe;
1232
1233
1234#[cfg(test)]
1235mod tests {
1236 use serde_json::Value;
1237
1238 fn assert_all_keys(value: &Value, keys: Vec<&str>) {
1239 assert!(value.is_object());
1240 let Value::Object(mapping) = value else { unreachable!() };
1241 let extra_keys: Vec<_> = mapping.keys().filter(|k| !keys.contains(&k.as_str())).map(|k| k.to_owned()).collect();
1242 let missing_keys: Vec<_> = keys.into_iter().filter(|k| !mapping.contains_key(k.to_string().as_str())).map(|k| k.to_owned()).collect();
1243
1244 if !extra_keys.is_empty() || !missing_keys.is_empty() {
1245 panic!("Keys in value does not match to expected keys.\nExtra keys: {:?}\nMissing keys: {:?}", extra_keys, missing_keys);
1246 }
1247 }
1248
1249 mod conversions {
1250 use crate::schema::{QuoteId, RateInfoRecord, StreamGetCandlesData};
1251
1252 fn make_sgcd() -> StreamGetCandlesData {
1253 StreamGetCandlesData::default()
1254 .with_close(20)
1255 .with_ctm(123u64)
1256 .with_ctm_string("some_string")
1257 .with_high(40)
1258 .with_low(10)
1259 .with_open(20)
1260 .with_quote_id(QuoteId::Cross)
1261 .with_symbol("EURUSD".to_owned())
1262 .with_vol(50)
1263 }
1264
1265 #[test]
1267 fn convert_sgcd_to_rir_from() {
1268 let orig = make_sgcd();
1269 let rir = RateInfoRecord::from(orig.clone());
1270
1271 assert_eq!(rir.close, orig.close);
1272 assert_eq!(rir.ctm, orig.ctm);
1273 assert_eq!(rir.ctm_string, orig.ctm_string);
1274 assert_eq!(rir.high, orig.high);
1275 assert_eq!(rir.low, orig.low);
1276 assert_eq!(rir.open, orig.open);
1277 assert_eq!(rir.vol, orig.vol);
1278 }
1279
1280 #[test]
1282 fn convert_sgcd_to_rir_into() {
1283 let orig = make_sgcd();
1284 let rir: RateInfoRecord = orig.clone().into();
1285
1286 assert_eq!(rir.close, orig.close);
1287 assert_eq!(rir.ctm, orig.ctm);
1288 assert_eq!(rir.ctm_string, orig.ctm_string);
1289 assert_eq!(rir.high, orig.high);
1290 assert_eq!(rir.low, orig.low);
1291 assert_eq!(rir.open, orig.open);
1292 assert_eq!(rir.vol, orig.vol);
1293 }
1294 }
1295
1296 mod serialize_deserialize {
1297 use std::fmt::Debug;
1298 use std::ops::Deref;
1299 use rstest::rstest;
1300 use serde::{Deserialize, Serialize};
1301 use serde_json::{from_str, from_value, to_string, to_value};
1302 use crate::schema::data::{GetTickPricesResponse, StreamPingSubscribe, StreamGetTradeStatusSubscribe, StreamGetTradeStatusUnsubscribe, StreamGetTradesData, StreamGetTradesSubscribe, StreamGetTradesUnsubscribe, StreamGetTickPricesSubscribe, StreamGetTickPricesUnsubscribe, StreamGetTickPricesData, StreamGetProfitData, StreamGetProfitSubscribe, StreamGetProfitUnsubscribe, StreamGetKeepAliveData, StreamGetNewsSubscribe, StreamGetNewsData, StreamGetNewsUnsubscribe, StreamGetKeepAliveSubscribe, StreamGetKeepAliveUnsubscribe, StreamGetCandlesSubscribe, StreamGetCandlesUnsubscribe, StreamGetBalanceData, StreamGetCandlesData, StreamGetBalanceSubscribe, StreamGetBalanceUnsubscribe, TradeTransactionStatusResponse, TradeTransactionStatusRequest, TradeTransactionResponse, TradeTransInfo, TradeTransactionRequest, GetVersionResponse, PingRequest, PingResponse, GetVersionRequest, TradingHoursRecord, HoursRecord, GetTradingHoursResponse, GetTradingHoursRequest, GetTradesHistoryRequest, GetTradesRequest, GetTradeRecordsResponse, TradeRecord, GetTradeRecordsRequest, TickRecord, GetTickPricesRequest, GetSymbolRequest, GetStepRulesResponse, StepRuleRecord, StepRecord, GetStepRulesRequest, GetServerTimeRequest, GetServerTimeResponse, GetProfitCalculationRequest, GetProfitCalculationResponse, GetNewsRequest, GetNewsResponse, NewsBodyRecord, GetMarginTradeRequest, GetMarginTradeResponse, GetMarginLevelRequest, GetMarginLevelResponse, IBRecord, GetIbsHistoryResponse, GetCurrentUserDataResponse, GetCurrentUserDataRequest, GetCommissionDefRequest, GetCommissionDefResponse, GetChartRangeRequestRequest, ChartRangeInfoRecord, GetChartLastRequestResponse, RateInfoRecord, ChartLastInfoRecord, GetChartLastRequestRequest, GetCalendarResponse, CalendarRecord, GetAllSymbolsRequest, GetAllSymbolsResponse, LoginRequest, LoginResponse, SymbolRecord, GetCalendarRequest, StreamGetTradeStatusData};
1303 use crate::schema::data::tests::assert_all_keys;
1304
1305 #[rstest]
1306 #[case::LoginRequest_1(LoginRequest::default(), vec ! ["userId", "password"])]
1307 #[case::LoginRequest_2(LoginRequest::default().with_app_id("foo").with_app_name("bar"), vec ! ["userId", "password", "appId", "appName"])]
1308 #[case::SymbolRecord_1(SymbolRecord::default(), vec ! ["ask", "bid", "categoryName", "contractSize", "currency", "currencyPair", "currencyProfit", "description", "expiration", "groupName", "high", "initialMargin", "instantMaxVolume", "leverage", "longOnly", "lotMax", "lotMin", "lotStep", "low", "marginHedged", "marginHedgedStrong", "marginMaintenance", "marginMode", "percentage", "pipsPrecision", "precision", "profitMode", "quoteId", "shortSelling", "spreadRaw", "spreadTable", "starting", "stepRuleId", "stopsLevel", "swap_rollover3days", "swapEnable", "swapLong", "swapShort", "swapType", "symbol", "tickSize", "tickValue", "time", "timeString", "trailingEnabled", "type"])]
1309 #[case::CalendarRecord_1(CalendarRecord::default(), vec!["country", "current", "forecast", "impact", "period", "previous", "time", "title"])]
1310 #[case::GetChartLastRequestRequest_1(GetChartLastRequestRequest::default(), vec!["info"])]
1311 #[case::ChartLastInfoRecord_1(ChartLastInfoRecord::default(), vec!["period", "start", "symbol"])]
1312 #[case::GetChartLastRequestResponse_1(GetChartLastRequestResponse::default(), vec!["digits", "rateInfos"])]
1313 #[case::RateInfoRecord_1(RateInfoRecord::default(), vec!["close", "ctm", "ctmString", "high", "low", "open", "vol"])]
1314 #[case::GetChartRangeRequestRequest_1(GetChartRangeRequestRequest::default(), vec!["info"])]
1315 #[case::ChartRangeInfoRecord_1(ChartRangeInfoRecord::default(), vec!["end", "period", "start", "symbol", "ticks"])]
1316 #[case::GetCommissionDefRequest_1(GetCommissionDefRequest::default(), vec!["symbol", "volume"])]
1317 #[case::GetCommissionDefResponse_1(GetCommissionDefResponse::default(), vec!["commission", "rateOfExchange"])]
1318 #[case::GetCurrentUserDataResponse_1(GetCurrentUserDataResponse::default(), vec!["companyUnit", "currency", "group", "ibAccount", "leverage", "leverageMultiplier", "spreadType", "trailingStop"])]
1319 #[case::IBRecord_1(IBRecord::default(), vec!["closePrice", "login", "nominal", "openPrice", "side", "surname", "symbol", "timestamp", "volume"])]
1320 #[case::GetMarginLevelResponse_1(GetMarginLevelResponse::default(), vec!["balance", "credit", "currency", "equity", "margin", "margin_free", "margin_level"])]
1321 #[case::GetMarginTradeRequest_1(GetMarginTradeRequest::default(), vec!["symbol", "volume"])]
1322 #[case::GetMarginTradeResponse_1(GetMarginTradeResponse::default(), vec!["margin"])]
1323 #[case::GetNewsRequest_1(GetNewsRequest::default(), vec!["end", "start"])]
1324 #[case::NewsBodyRecord_1(NewsBodyRecord::default(), vec!["body", "bodylen", "key", "time", "timeString", "title"])]
1325 #[case::GetProfitCalculationRequest_1(GetProfitCalculationRequest::default(), vec!["closePrice", "cmd", "openPrice", "symbol", "volume"])]
1326 #[case::GetProfitCalculationResponse_1(GetProfitCalculationResponse::default(), vec!["profit"])]
1327 #[case::GetServerTimeResponse_1(GetServerTimeResponse::default(), vec!["time", "timeString"])]
1328 #[case::StepRuleRecord_1(StepRuleRecord::default(), vec!["id", "name", "steps"])]
1329 #[case::StepRecord_1(StepRecord::default(), vec!["fromValue", "step"])]
1330 #[case::GetSymbolRequest_1(GetSymbolRequest::default(), vec!["symbol"])]
1331 #[case::GetTickPricesRequest_1(GetTickPricesRequest::default(), vec!["level", "symbols", "timestamp"])]
1332 #[case::GetTickPricesResponse_1(GetTickPricesResponse::default(), vec!["quotations"])]
1333 #[case::TickRecord_1(TickRecord::default(), vec!["ask", "askVolume", "bid", "bidVolume", "high", "level", "low", "spreadRaw", "spreadTable", "symbol", "timestamp"])]
1334 #[case::GetTradeRecordsRequest_1(GetTradeRecordsRequest::default(), vec!["orders"])]
1335 #[case::TradeRecord_1(TradeRecord::default(), vec!["close_price", "close_time", "close_timeString", "closed", "cmd", "comment", "commission", "customComment", "digits", "expiration", "expirationString", "margin_rate", "offset", "open_price", "open_time", "open_timeString", "order", "order2", "position", "profit", "sl", "storage", "symbol", "timestamp", "tp", "volume"])]
1336 #[case::GetTradesRequest_1(GetTradesRequest::default(), vec!["openedOnly"])]
1337 #[case::GetTradesHistoryRequest_1(GetTradesHistoryRequest::default(), vec!["end", "start"])]
1338 #[case::GetTradingHoursRequest_1(GetTradingHoursRequest::default(), vec!["symbols"])]
1339 #[case::TradingHoursRecord_1(TradingHoursRecord::default(), vec!["quotes", "symbol", "trading"])]
1340 #[case::HoursRecord_1(HoursRecord::default(), vec!["day", "fromT", "toT"])]
1341 #[case::GetVersionResponse_1(GetVersionResponse::default(), vec!["version"])]
1342 #[case::TradeTransactionRequest_1(TradeTransactionRequest::default(), vec!["tradeTransInfo"])]
1343 #[case::TradeTransInfo_1(TradeTransInfo::default(), vec!["cmd", "customComment", "expiration", "offset", "order", "price", "sl", "symbol", "tp", "type", "volume"])]
1344 #[case::TradeTransactionResponse_1(TradeTransactionResponse::default(), vec!["order"])]
1345 #[case::TradeTransactionStatusRequest_1(TradeTransactionStatusRequest::default(), vec!["order"])]
1346 #[case::TradeTransactionStatusResponse_1(TradeTransactionStatusResponse::default(), vec!["ask", "bid", "customComment", "message", "order", "requestStatus"])]
1347 #[case::StreamGetBalanceData_1(StreamGetBalanceData::default(), vec!["balance", "credit", "equity", "margin", "marginFree", "marginLevel"])]
1348 #[case::StreamGetCandlesData_1(StreamGetCandlesData::default(), vec!["close", "ctm", "ctmString", "high", "low", "open", "quoteId", "symbol", "vol"])]
1349 #[case::StreamGetCandlesSubscribe_1(StreamGetCandlesSubscribe::default(), vec!["symbol"])]
1350 #[case::StreamGetCandlesUnsubscribe_1(StreamGetCandlesUnsubscribe::default(), vec!["symbol"])]
1351 #[case::StreamGetKeepAliveData_1(StreamGetKeepAliveData::default(), vec!["timestamp"])]
1352 #[case::StreamGetNewsData_1(StreamGetNewsData::default(), vec!["body", "key", "time", "title"])]
1353 #[case::StreamGetProfitData_1(StreamGetProfitData::default(), vec!["order", "order2", "position", "profit"])]
1354 #[case::StreamGetTickPricesSubscribe_1(StreamGetTickPricesSubscribe::default(), vec!["symbol", "minArrivalTime", "maxLevel"])]
1355 #[case::StreamGetTickPricesUnsubscribe_1(StreamGetTickPricesUnsubscribe::default(), vec!["symbol"])]
1356 #[case::StreamGetTickPricesData_1(StreamGetTickPricesData::default(), vec!["ask", "askVolume", "bid", "bidVolume", "high", "level", "low", "quoteId", "spreadRaw", "spreadTable", "symbol", "timestamp"])]
1357 #[case::StreamGetTradesData_1(StreamGetTradesData::default(), vec!["close_price", "close_time", "closed", "cmd", "comment", "commission", "customComment", "digits", "expiration", "margin_rate", "offset", "open_price", "open_time", "order", "order2", "position", "profit", "sl", "state", "storage", "symbol", "tp", "type", "volume"])]
1358 #[case::StreamGetTradeStatusData_1(StreamGetTradeStatusData::default(), vec!["customComment", "message", "order", "price", "requestStatus"])]
1359 fn serialize_deserialize_payload_struct<T: Serialize + Clone + Default + Debug + PartialEq + for<'de> Deserialize<'de>>(#[case] original: T, #[case] keys: Vec<&str>) {
1360 let serialized_value = to_value(original.clone()).unwrap();
1361 assert_all_keys(&serialized_value, keys);
1362 let new_value = from_value(serialized_value).unwrap();
1363 assert_eq!(original, new_value);
1364 }
1365
1366 #[rstest]
1367 #[case::LoginResponse_1(LoginResponse)]
1368 #[case::GetAllSymbolsRequest_1(GetAllSymbolsRequest)]
1369 #[case::GetCalendarRequest_1(GetCalendarRequest)]
1370 #[case::GetCalendarRequest_1(GetCurrentUserDataRequest)]
1371 #[case::GetMarginLevelRequest_1(GetMarginLevelRequest)]
1372 #[case::GetServerTimeRequest_1(GetServerTimeRequest)]
1373 #[case::GetStepRulesRequest_1(GetStepRulesRequest)]
1374 #[case::GetVersionRequest_1(GetVersionRequest)]
1375 #[case::PingRequest_1(PingRequest)]
1376 #[case::PingResponse_1(PingResponse)]
1377 #[case::StreamGetBalanceSubscribe_1(StreamGetBalanceSubscribe)]
1378 #[case::StreamGetBalanceUnsubscribe_1(StreamGetBalanceUnsubscribe)]
1379 #[case::StreamGetKeepAliveSubscribe_1(StreamGetKeepAliveSubscribe)]
1380 #[case::StreamGetKeepAliveUnsubscribe_1(StreamGetKeepAliveUnsubscribe)]
1381 #[case::StreamGetNewsSubscribe_1(StreamGetNewsSubscribe)]
1382 #[case::StreamGetNewsUnsubscribe_1(StreamGetNewsUnsubscribe)]
1383 #[case::StreamGetProfitSubscribe_1(StreamGetProfitSubscribe)]
1384 #[case::StreamGetProfitUnsubscribe_1(StreamGetProfitUnsubscribe)]
1385 #[case::StreamGetTradesSubscribe_1(StreamGetTradesSubscribe)]
1386 #[case::StreamGetTradesUnsubscribe_1(StreamGetTradesUnsubscribe)]
1387 #[case::StreamGetTradeStatusSubscribe_1(StreamGetTradeStatusSubscribe)]
1388 #[case::StreamGetTradeStatusUnsubscribe_1(StreamGetTradeStatusUnsubscribe)]
1389 #[case::StreamPingSubscribe_1(StreamPingSubscribe)]
1390 fn serialize_deserialize_logic_struct<T: Serialize + Clone + Default + Debug + PartialEq + for<'de> Deserialize<'de>>(#[case] original: T) {
1391 let serialized_value = to_value(original.clone()).unwrap();
1392 assert!(serialized_value.is_null());
1393 let new_value = from_value(serialized_value).unwrap();
1394 assert_eq!(original, new_value);
1395 }
1396
1397 #[rstest]
1398 #[case::GetAllSymbolsResponse_1(GetAllSymbolsResponse::default())]
1399 #[case::GetCalendarResponse_1(GetCalendarResponse::default())]
1400 #[case::GetIbsHistoryResponse_1(GetIbsHistoryResponse::default())]
1401 #[case::GetNewsResponse_1(GetNewsResponse::default())]
1402 #[case::GetStepRulesResponse_1(GetStepRulesResponse::default())]
1403 #[case::GetTradeRecordsResponse_1(GetTradeRecordsResponse::default())]
1404 #[case::GetTradingHoursResponse_1(GetTradingHoursResponse::default())]
1405 fn deserialize_empty_array_of_records<T: Serialize + for<'de> Deserialize<'de> + PartialEq + Debug>(#[case] reference: T) {
1406 let response: T = from_str("[]").unwrap();
1407 let serialized_reference = to_string(&reference).unwrap();
1408 assert_eq!(response, reference);
1409 assert_eq!(&serialized_reference, "[]");
1410 }
1411
1412 #[rstest]
1413 #[case::GetAllSymbolsResponse_1(GetAllSymbolsResponse::default())]
1414 #[case::GetCalendarResponse_1(GetCalendarResponse::default())]
1415 #[case::GetIbsHistoryResponse_1(GetIbsHistoryResponse::default())]
1416 #[case::GetNewsResponse_1(GetNewsResponse::default())]
1417 #[case::GetStepRulesResponse_1(GetStepRulesResponse::default())]
1418 #[case::GetTradeRecordsResponse_1(GetTradeRecordsResponse::default())]
1419 #[case::GetTradingHoursResponse_1(GetTradingHoursResponse::default())]
1420 fn deserialize_array_of_records_with_one_record<T, I>(#[case] inp: T)
1421 where
1422 T: Serialize + for<'de> Deserialize<'de> + PartialEq + Debug + Deref<Target = Vec<I>>,
1423 I: Default + PartialEq + Debug + Serialize + for<'de> Deserialize<'de>
1424 {
1425 let ref_val = SymbolRecord::default();
1426 let source_data = format!("[{}]", to_string(&ref_val).unwrap());
1427 let response: GetAllSymbolsResponse = from_str(&source_data).unwrap();
1428
1429 assert_eq!(response.len(), 1);
1430 assert_eq!(response[0], ref_val);
1431 }
1432 }
1433}