1use crate::{
2 symbology::MarketdataVenue, utils::pagination::OffsetAndLimit, Dir,
3 SequenceIdAndNumber,
4};
5use chrono::{DateTime, NaiveDate, Utc};
6use derive::grpc;
7use derive_more::Deref;
8use rust_decimal::Decimal;
9use rust_decimal_macros::dec;
10use schemars::JsonSchema;
11use serde::{Deserialize, Serialize};
12use serde_with::skip_serializing_none;
13
14pub mod candle_width;
15pub use candle_width::CandleWidth;
16use strum::EnumString;
17
18#[grpc(package = "json.architect")]
19#[grpc(service = "Marketdata", name = "l1_book_snapshot", response = "L1BookSnapshot")]
20#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
21pub struct L1BookSnapshotRequest {
22 pub symbol: String,
23}
24
25#[grpc(package = "json.architect")]
26#[grpc(service = "Marketdata", name = "l1_book_snapshots", response = "L1BookSnapshot")]
27#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
28pub struct L1BookSnapshotsRequest {
29 #[serde(default, skip_serializing_if = "Option::is_none")]
30 pub symbols: Option<Vec<String>>,
31}
32
33pub type L1BookSnapshots = Vec<L1BookSnapshot>;
34
35#[grpc(package = "json.architect")]
36#[grpc(
37 service = "Marketdata",
38 name = "subscribe_l1_book_snapshots",
39 response = "L1BookSnapshot",
40 server_streaming
41)]
42#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
43pub struct SubscribeL1BookSnapshotsRequest {
44 #[serde(default, skip_serializing_if = "Option::is_none")]
46 pub symbols: Option<Vec<String>>,
47}
48
49#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
50pub struct L1BookSnapshot {
51 #[serde(rename = "s")]
52 #[schemars(title = "symbol")]
53 pub symbol: String,
54 #[serde(rename = "ts")]
55 #[schemars(title = "timestamp")]
56 pub timestamp: i64,
57 #[serde(rename = "tn")]
58 #[schemars(title = "timestamp_ns")]
59 pub timestamp_ns: u32,
60 #[serde(rename = "b")]
61 #[schemars(title = "best_bid")]
62 pub best_bid: Option<(Decimal, Decimal)>,
63 #[serde(rename = "a")]
64 #[schemars(title = "best_ask")]
65 pub best_ask: Option<(Decimal, Decimal)>,
66}
67
68impl L1BookSnapshot {
69 pub fn timestamp(&self) -> Option<DateTime<Utc>> {
70 chrono::DateTime::from_timestamp(self.timestamp, self.timestamp_ns)
71 }
72}
73
74#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
75pub struct L2BookSnapshot {
76 #[serde(rename = "ts")]
77 #[schemars(title = "timestamp")]
78 pub timestamp: i64,
79 #[serde(rename = "tn")]
80 #[schemars(title = "timestamp_ns")]
81 pub timestamp_ns: u32,
82 #[serde(flatten)]
83 pub sequence: SequenceIdAndNumber,
84 #[serde(rename = "b")]
85 #[schemars(title = "bids")]
86 pub bids: Vec<(Decimal, Decimal)>,
87 #[serde(rename = "a")]
88 #[schemars(title = "asks")]
89 pub asks: Vec<(Decimal, Decimal)>,
90}
91
92impl L2BookSnapshot {
93 pub fn timestamp(&self) -> Option<DateTime<Utc>> {
94 chrono::DateTime::from_timestamp(self.timestamp, self.timestamp_ns)
95 }
96}
97
98#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
99pub struct L2BookDiff {
100 #[serde(rename = "ts")]
101 #[schemars(title = "timestamp")]
102 pub timestamp: i64,
103 #[serde(rename = "tn")]
104 #[schemars(title = "timestamp_ns")]
105 pub timestamp_ns: u32,
106 #[serde(flatten)]
107 pub sequence: SequenceIdAndNumber,
108 #[serde(rename = "b")]
111 #[schemars(title = "bids")]
112 pub bids: Vec<(Decimal, Decimal)>,
113 #[serde(rename = "a")]
116 #[schemars(title = "asks")]
117 pub asks: Vec<(Decimal, Decimal)>,
118}
119
120impl L2BookDiff {
121 pub fn timestamp(&self) -> Option<DateTime<Utc>> {
122 chrono::DateTime::from_timestamp(self.timestamp, self.timestamp_ns)
123 }
124}
125
126#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
206#[serde(tag = "t")]
207pub enum L2BookUpdate {
209 #[serde(rename = "s")]
210 #[schemars(title = "Snapshot|L2BookSnapshot")]
211 Snapshot(L2BookSnapshot),
212 #[serde(rename = "d")]
213 #[schemars(title = "Diff|L2BookDiff")]
214 Diff(L2BookDiff),
215}
216
217impl L2BookUpdate {
218 pub fn timestamp(&self) -> Option<DateTime<Utc>> {
219 match self {
220 Self::Snapshot(snapshot) => snapshot.timestamp(),
221 Self::Diff(diff) => diff.timestamp(),
222 }
223 }
224
225 pub fn sequence(&self) -> SequenceIdAndNumber {
226 match self {
227 Self::Snapshot(snapshot) => snapshot.sequence,
228 Self::Diff(diff) => diff.sequence,
229 }
230 }
231
232 pub fn is_snapshot(&self) -> bool {
233 match self {
234 Self::Snapshot(_) => true,
235 Self::Diff(_) => false,
236 }
237 }
238}
239
240#[grpc(package = "json.architect")]
241#[grpc(service = "Marketdata", name = "l2_book_snapshot", response = "L2BookSnapshot")]
242#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
243pub struct L2BookSnapshotRequest {
244 #[serde(default, skip_serializing_if = "Option::is_none")]
245 pub venue: Option<MarketdataVenue>,
246 pub symbol: String,
247}
248
249#[grpc(package = "json.architect")]
250#[grpc(
251 service = "Marketdata",
252 name = "subscribe_l2_book_updates",
253 response = "L2BookUpdate",
254 server_streaming
255)]
256#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
257pub struct SubscribeL2BookUpdatesRequest {
258 #[serde(default, skip_serializing_if = "Option::is_none")]
259 pub venue: Option<MarketdataVenue>,
260 pub symbol: String,
261}
262
263#[grpc(package = "json.architect")]
265#[grpc(
266 service = "Marketdata",
267 name = "subscribe_candles",
268 response = "Candle",
269 server_streaming
270)]
271#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
272pub struct SubscribeCandlesRequest {
273 #[serde(default, skip_serializing_if = "Option::is_none")]
274 pub venue: Option<MarketdataVenue>,
275 pub symbol: String,
276 pub candle_widths: Option<Vec<CandleWidth>>,
278}
279
280#[grpc(package = "json.architect")]
282#[grpc(
283 service = "Marketdata",
284 name = "subscribe_many_candles",
285 response = "Candle",
286 server_streaming
287)]
288#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
289pub struct SubscribeManyCandlesRequest {
290 #[serde(default, skip_serializing_if = "Option::is_none")]
291 pub venue: Option<MarketdataVenue>,
292 #[serde(default, skip_serializing_if = "Option::is_none")]
294 pub symbols: Option<Vec<String>>,
295 pub candle_width: CandleWidth,
296}
297
298#[grpc(package = "json.architect")]
301#[grpc(
302 service = "Marketdata",
303 name = "subscribe_current_candles",
304 response = "Candle",
305 server_streaming
306)]
307#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
308pub struct SubscribeCurrentCandlesRequest {
309 #[serde(default, skip_serializing_if = "Option::is_none")]
310 pub venue: Option<MarketdataVenue>,
311 pub symbol: String,
312 pub candle_width: CandleWidth,
313 #[serde(default, skip_serializing_if = "Option::is_none")]
316 pub tick_period_ms: Option<u32>,
317}
318
319#[derive(
320 Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize, JsonSchema,
321)]
322pub struct Candle {
323 #[serde(rename = "ts")]
324 #[schemars(title = "timestamp")]
325 pub timestamp: i64,
326 #[serde(rename = "tn")]
327 #[schemars(title = "timestamp_ns")]
328 pub timestamp_ns: u32,
329 #[serde(rename = "w")]
330 #[schemars(title = "width")]
331 pub width: CandleWidth,
332 #[serde(rename = "s")]
333 #[schemars(title = "symbol")]
334 pub symbol: String,
335 #[serde(rename = "o")]
336 #[schemars(title = "open")]
337 pub open: Option<Decimal>,
338 #[serde(rename = "h")]
339 #[schemars(title = "high")]
340 pub high: Option<Decimal>,
341 #[serde(rename = "l")]
342 #[schemars(title = "low")]
343 pub low: Option<Decimal>,
344 #[serde(rename = "c")]
345 #[schemars(title = "close")]
346 pub close: Option<Decimal>,
347 #[serde(rename = "v")]
348 #[schemars(title = "volume")]
349 pub volume: Decimal,
350 #[serde(rename = "bv")]
351 #[schemars(title = "buy_volume")]
352 pub buy_volume: Decimal,
353 #[serde(rename = "av")]
354 #[schemars(title = "sell_volume")]
355 pub sell_volume: Decimal,
356 #[serde(default, rename = "mo", skip_serializing_if = "Option::is_none")]
357 #[schemars(title = "mid_open")]
358 pub mid_open: Option<Decimal>,
359 #[serde(default, rename = "mc", skip_serializing_if = "Option::is_none")]
360 #[schemars(title = "mid_close")]
361 pub mid_close: Option<Decimal>,
362 #[serde(default, rename = "mh", skip_serializing_if = "Option::is_none")]
363 #[schemars(title = "mid_high")]
364 pub mid_high: Option<Decimal>,
365 #[serde(default, rename = "ml", skip_serializing_if = "Option::is_none")]
366 #[schemars(title = "mid_low")]
367 pub mid_low: Option<Decimal>,
368 #[serde(default, rename = "bo", skip_serializing_if = "Option::is_none")]
369 #[schemars(title = "bid_open")]
370 pub bid_open: Option<Decimal>,
371 #[serde(default, rename = "bc", skip_serializing_if = "Option::is_none")]
372 #[schemars(title = "bid_close")]
373 pub bid_close: Option<Decimal>,
374 #[serde(default, rename = "bh", skip_serializing_if = "Option::is_none")]
375 #[schemars(title = "bid_high")]
376 pub bid_high: Option<Decimal>,
377 #[serde(default, rename = "bl", skip_serializing_if = "Option::is_none")]
378 #[schemars(title = "bid_low")]
379 pub bid_low: Option<Decimal>,
380 #[serde(default, rename = "ao", skip_serializing_if = "Option::is_none")]
381 #[schemars(title = "ask_open")]
382 pub ask_open: Option<Decimal>,
383 #[serde(default, rename = "ac", skip_serializing_if = "Option::is_none")]
384 #[schemars(title = "ask_close")]
385 pub ask_close: Option<Decimal>,
386 #[serde(default, rename = "ah", skip_serializing_if = "Option::is_none")]
387 #[schemars(title = "ask_high")]
388 pub ask_high: Option<Decimal>,
389 #[serde(default, rename = "al", skip_serializing_if = "Option::is_none")]
390 #[schemars(title = "ask_low")]
391 pub ask_low: Option<Decimal>,
392}
393
394impl Candle {
395 pub fn default(timestamp: DateTime<Utc>, width: CandleWidth, symbol: String) -> Self {
396 Self {
397 timestamp: timestamp.timestamp(),
398 timestamp_ns: timestamp.timestamp_subsec_nanos(),
399 width,
400 symbol,
401 open: None,
402 high: None,
403 low: None,
404 close: None,
405 volume: dec!(0),
406 buy_volume: dec!(0),
407 sell_volume: dec!(0),
408 mid_open: None,
409 mid_close: None,
410 mid_high: None,
411 mid_low: None,
412 bid_open: None,
413 bid_close: None,
414 bid_high: None,
415 bid_low: None,
416 ask_open: None,
417 ask_close: None,
418 ask_high: None,
419 ask_low: None,
420 }
421 }
422
423 pub fn timestamp(&self) -> Option<DateTime<Utc>> {
424 DateTime::<Utc>::from_timestamp(self.timestamp, self.timestamp_ns)
425 }
426}
427
428#[grpc(package = "json.architect")]
430#[grpc(
431 service = "Marketdata",
432 name = "historical_candles",
433 response = "HistoricalCandlesResponse"
434)]
435#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
436pub struct HistoricalCandlesRequest {
437 pub symbol: String,
438 pub candle_width: CandleWidth,
439 pub start_date: DateTime<Utc>,
440 pub end_date: DateTime<Utc>,
441}
442
443#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
444pub struct HistoricalCandlesResponse {
445 pub candles: Vec<Candle>,
446}
447
448#[grpc(package = "json.architect")]
449#[grpc(
450 service = "Marketdata",
451 name = "subscribe_trades",
452 response = "Trade",
453 server_streaming
454)]
455#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
456pub struct SubscribeTradesRequest {
457 #[serde(default, skip_serializing_if = "Option::is_none")]
458 pub venue: Option<MarketdataVenue>,
459 #[serde(default, skip_serializing_if = "Option::is_none")]
461 pub symbol: Option<String>,
462}
463
464#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
465pub struct Trade {
466 #[serde(rename = "s")]
467 #[schemars(title = "symbol")]
468 pub symbol: String,
469 #[serde(rename = "ts")]
470 #[schemars(title = "timestamp")]
471 pub timestamp: i64,
472 #[serde(rename = "tn")]
473 #[schemars(title = "timestamp_ns")]
474 pub timestamp_ns: u32,
475 #[serde(rename = "d")]
476 #[schemars(title = "direction")]
477 pub direction: Option<Dir>, #[serde(rename = "p")]
479 #[schemars(title = "price")]
480 pub price: Decimal,
481 #[serde(rename = "q")]
482 #[schemars(title = "size")]
483 pub size: Decimal,
484}
485
486impl Trade {
487 pub fn timestamp(&self) -> Option<DateTime<Utc>> {
488 DateTime::<Utc>::from_timestamp(self.timestamp, self.timestamp_ns)
489 }
490}
491
492#[grpc(package = "json.architect")]
493#[grpc(service = "Marketdata", name = "market_status", response = "MarketStatus")]
494#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
495pub struct MarketStatusRequest {
496 #[serde(default, skip_serializing_if = "Option::is_none")]
497 pub venue: Option<MarketdataVenue>,
498 pub symbol: String,
499}
500
501#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
502#[cfg_attr(feature = "graphql", derive(juniper::GraphQLObject))]
503pub struct MarketStatus {
504 #[serde(rename = "s")]
505 #[schemars(title = "symbol")]
506 pub symbol: String,
507 pub is_trading: Option<bool>,
508 pub is_quoting: Option<bool>,
509}
510
511#[grpc(package = "json.architect")]
512#[grpc(service = "Marketdata", name = "ticker", response = "Ticker")]
513#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
514pub struct TickerRequest {
515 #[serde(default, skip_serializing_if = "Option::is_none")]
516 pub venue: Option<MarketdataVenue>,
517 pub symbol: String,
518}
519
520#[skip_serializing_none]
521#[derive(Default, Debug, Clone, Copy, Serialize, Deserialize, JsonSchema)]
522pub struct TickerValues {
523 #[serde(rename = "bp")]
524 #[schemars(title = "bid_price")]
525 pub bid_price: Option<Decimal>,
526 #[serde(rename = "bs")]
527 #[schemars(title = "bid_size")]
528 pub bid_size: Option<Decimal>,
529 #[serde(rename = "ap")]
530 #[schemars(title = "ask_price")]
531 pub ask_price: Option<Decimal>,
532 #[serde(rename = "as")]
533 #[schemars(title = "ask_size")]
534 pub ask_size: Option<Decimal>,
535 #[serde(rename = "p")]
536 #[schemars(title = "last_price")]
537 pub last_price: Option<Decimal>,
538 #[serde(rename = "q")]
539 #[schemars(title = "last_size")]
540 pub last_size: Option<Decimal>,
541 #[serde(rename = "xo")]
542 #[schemars(title = "session_open")]
543 pub session_open: Option<Decimal>,
544 #[serde(rename = "xl")]
545 #[schemars(title = "session_low")]
546 pub session_low: Option<Decimal>,
547 #[serde(rename = "xh")]
548 #[schemars(title = "session_high")]
549 pub session_high: Option<Decimal>,
550 #[serde(rename = "xv")]
551 #[schemars(title = "session_volume")]
552 pub session_volume: Option<Decimal>,
553 #[serde(rename = "o")]
554 #[schemars(title = "open_24h")]
555 pub open_24h: Option<Decimal>,
556 #[serde(rename = "l")]
557 #[schemars(title = "low_24h")]
558 pub low_24h: Option<Decimal>,
559 #[serde(rename = "h")]
560 #[schemars(title = "high_24h")]
561 pub high_24h: Option<Decimal>,
562 #[serde(rename = "v")]
563 #[schemars(title = "volume_24h")]
564 pub volume_24h: Option<Decimal>,
565 #[serde(rename = "vm")]
566 #[schemars(title = "volume_30d")]
567 pub volume_30d: Option<Decimal>,
568 #[serde(rename = "oi")]
569 #[schemars(title = "open_interest")]
570 pub open_interest: Option<Decimal>,
571 #[serde(rename = "sp")]
572 #[schemars(title = "last_settlement_price")]
573 pub last_settlement_price: Option<Decimal>,
574 #[serde(rename = "sd")]
575 #[schemars(title = "last_settlement_date")]
576 pub last_settlement_date: Option<NaiveDate>,
577 #[serde(rename = "mp")]
578 #[schemars(title = "mark_price")]
579 pub mark_price: Option<Decimal>,
580 #[serde(rename = "ip")]
581 #[schemars(title = "index_price")]
582 pub index_price: Option<Decimal>,
583 #[serde(rename = "fr")]
584 #[schemars(title = "funding_rate")]
585 pub funding_rate: Option<Decimal>,
586 #[serde(rename = "ft")]
587 #[schemars(title = "next_funding_time")]
588 pub next_funding_time: Option<DateTime<Utc>>,
589 pub market_cap: Option<Decimal>,
590 pub price_to_earnings: Option<Decimal>,
591 pub eps_adj: Option<Decimal>,
592 pub shares_outstanding_weighted_adj: Option<Decimal>,
593 pub dividend: Option<Decimal>,
594 pub dividend_yield: Option<Decimal>,
595 }
601
602impl TickerValues {
603 pub fn is_none(&self) -> bool {
604 self.session_open.is_none()
605 && self.session_low.is_none()
606 && self.session_high.is_none()
607 && self.open_24h.is_none()
608 && self.low_24h.is_none()
609 && self.high_24h.is_none()
610 && self.volume_24h.is_none()
611 && self.volume_30d.is_none()
612 && self.open_interest.is_none()
613 && self.last_settlement_price.is_none()
614 && self.mark_price.is_none()
615 && self.index_price.is_none()
616 && self.funding_rate.is_none()
617 && self.next_funding_time.is_none()
618 }
619
620 pub fn last_or_mid_price(&self) -> Option<Decimal> {
621 self.last_price.or_else(|| {
622 let bid_price = self.bid_price?;
623 let ask_price = self.ask_price?;
624 Some((bid_price + ask_price) / dec!(2))
625 })
626 }
627}
628
629#[derive(Debug, Deref, Clone, Serialize, Deserialize, JsonSchema)]
630pub struct Ticker {
631 #[serde(rename = "s")]
632 #[schemars(title = "symbol")]
633 pub symbol: String,
634 #[serde(rename = "ve")]
635 #[schemars(title = "venue")]
636 pub venue: MarketdataVenue,
637 #[serde(rename = "ts")]
638 #[schemars(title = "timestamp")]
639 pub timestamp: i64,
640 #[serde(rename = "tn")]
641 #[schemars(title = "timestamp_ns")]
642 pub timestamp_ns: u32,
643 #[serde(flatten)]
644 #[deref]
645 pub values: TickerValues,
646}
647
648impl Ticker {
649 pub fn timestamp(&self) -> Option<DateTime<Utc>> {
650 DateTime::<Utc>::from_timestamp(self.timestamp, self.timestamp_ns)
651 }
652}
653
654#[derive(Debug, Copy, Clone, EnumString, Serialize, Deserialize, JsonSchema)]
655#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
656#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
657#[cfg_attr(feature = "graphql", derive(juniper::GraphQLEnum))]
658pub enum SortTickersBy {
659 VolumeDesc,
660 ChangeAsc,
661 ChangeDesc,
662 AbsChangeDesc,
663}
664
665#[grpc(package = "json.architect")]
666#[grpc(service = "Marketdata", name = "tickers", response = "TickersResponse")]
667#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
668pub struct TickersRequest {
669 #[serde(default, skip_serializing_if = "Option::is_none")]
670 pub venue: Option<MarketdataVenue>,
671 #[serde(default, skip_serializing_if = "Option::is_none")]
672 pub symbols: Option<Vec<String>>,
673 #[serde(default, flatten)]
674 pub pagination: OffsetAndLimit<SortTickersBy>,
675}
676
677#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
678pub struct TickersResponse {
679 pub tickers: Vec<Ticker>,
680}
681
682#[grpc(package = "json.architect")]
685#[grpc(
686 service = "Marketdata",
687 name = "ticker",
688 response = "TickerUpdate",
689 server_streaming
690)]
691#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
692pub struct SubscribeTickersRequest {
693 #[serde(default, skip_serializing_if = "Option::is_none")]
695 pub symbols: Option<Vec<String>>,
696}
697
698#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
699#[serde(tag = "t")]
700pub enum TickerUpdate {
703 #[serde(rename = "s")]
704 #[schemars(title = "Snapshot|Ticker")]
705 Snapshot(Ticker),
706 #[serde(rename = "d")]
707 #[schemars(title = "Diff|Ticker")]
708 Diff(Ticker),
709}
710
711#[grpc(package = "json.architect")]
712#[grpc(service = "Marketdata", name = "subscribe_liquidations", response = "Liquidation")]
713#[derive(Debug, Clone, PartialEq, Eq, Hash, Deserialize, Serialize, JsonSchema)]
714pub struct SubscribeLiquidationsRequest {
715 #[serde(default, skip_serializing_if = "Option::is_none")]
716 pub symbols: Option<Vec<String>>,
717}
718
719#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize, JsonSchema)]
720pub struct Liquidation {
721 #[serde(rename = "s")]
722 #[schemars(title = "symbol")]
723 pub symbol: String,
724 #[serde(rename = "ts")]
725 #[schemars(title = "timestamp")]
726 pub timestamp: i64,
727 #[serde(rename = "tn")]
728 #[schemars(title = "timestamp_ns")]
729 pub timestamp_ns: u32,
730 #[serde(rename = "d")]
731 #[schemars(title = "direction")]
732 pub direction: Dir,
733 #[serde(rename = "p")]
734 #[schemars(title = "price")]
735 pub price: Decimal,
736 #[serde(rename = "q")]
737 #[schemars(title = "size")]
738 pub size: Decimal,
739}