architect_api/cpty/
binance.rs

1use crate::{
2    folio::FolioMessage,
3    orderflow::{
4        AberrantFill, Ack, Cancel, CancelAll, Fill, Order, OrderflowMessage, Out, Reject,
5    },
6    symbology::market::{MinOrderQuantityUnit, NormalizedMarketInfo},
7    Amount, OrderId,
8};
9#[cfg(feature = "netidx")]
10use derive::FromValue;
11#[cfg(feature = "netidx")]
12use netidx_derive::Pack;
13use rust_decimal::Decimal;
14use schemars::JsonSchema;
15use serde::{Deserialize, Serialize};
16use std::{ops::Deref, sync::Arc};
17
18#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
19#[cfg_attr(feature = "netidx", derive(Pack))]
20pub struct BinanceMarketInfo {
21    pub tick_size: Decimal,
22    pub step_size: Decimal,
23    pub is_delisted: bool,
24    #[cfg_attr(feature = "netidx", pack(default))]
25    pub min_order_quantity: Amount<Decimal, MinOrderQuantityUnit>,
26}
27
28impl NormalizedMarketInfo for BinanceMarketInfo {
29    fn tick_size(&self) -> Decimal {
30        self.tick_size
31    }
32
33    fn step_size(&self) -> Decimal {
34        self.step_size
35    }
36
37    fn min_order_quantity(&self) -> Amount<Decimal, MinOrderQuantityUnit> {
38        self.min_order_quantity
39    }
40
41    fn is_delisted(&self) -> bool {
42        self.is_delisted
43    }
44}
45
46impl std::fmt::Display for BinanceMarketInfo {
47    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
48        write!(f, "{}", serde_json::to_string_pretty(self).unwrap())?;
49        Ok(())
50    }
51}
52
53#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
54#[cfg_attr(feature = "netidx", derive(Pack))]
55#[cfg_attr(feature = "netidx", derive(FromValue))]
56pub enum BinanceMessage {
57    Order(BinanceOrder),
58    Cancel(Cancel),
59    CancelAll(BinanceCancelAll),
60    Reject(Reject),
61    Ack(BinanceAck),
62    Fill(Result<Fill, AberrantFill>),
63    Out(Out),
64    Folio(FolioMessage),
65    ExchangeAccountSnapshot(Arc<BinanceSnapshot>),
66}
67
68#[derive(Debug, Clone, Copy, Serialize, Deserialize, JsonSchema)]
69#[cfg_attr(feature = "netidx", derive(Pack))]
70pub struct BinanceOrder {
71    #[serde(flatten)]
72    pub order: Order,
73    // CR alee: coming soon--more futures orders options
74}
75
76impl Deref for BinanceOrder {
77    type Target = Order;
78
79    fn deref(&self) -> &Self::Target {
80        &self.order
81    }
82}
83
84#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
85#[cfg_attr(feature = "netidx", derive(Pack))]
86pub struct BinanceAck {
87    pub ack: Ack,
88    pub exchange_order_id: u64,
89}
90
91impl Deref for BinanceAck {
92    type Target = Ack;
93
94    fn deref(&self) -> &Self::Target {
95        &self.ack
96    }
97}
98
99#[derive(Debug, Clone, Copy, Serialize, Deserialize, JsonSchema)]
100#[cfg_attr(feature = "netidx", derive(Pack))]
101pub struct BinanceCancelAll {}
102
103#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
104#[cfg_attr(feature = "netidx", derive(Pack))]
105pub struct BinanceSnapshot {
106    pub open_oids: Vec<OrderId>,
107}
108
109impl TryFrom<&BinanceMessage> for OrderflowMessage {
110    type Error = ();
111
112    fn try_from(value: &BinanceMessage) -> Result<Self, Self::Error> {
113        match value {
114            BinanceMessage::Order(o) => Ok(OrderflowMessage::Order(**o)),
115            BinanceMessage::Cancel(c) => Ok(OrderflowMessage::Cancel(*c)),
116            BinanceMessage::Reject(r) => Ok(OrderflowMessage::Reject(r.clone())),
117            BinanceMessage::Ack(a) => Ok(OrderflowMessage::Ack(**a)),
118            BinanceMessage::CancelAll(_) => {
119                Ok(OrderflowMessage::CancelAll(CancelAll { venue_id: None }))
120            }
121            BinanceMessage::Fill(f) => Ok(OrderflowMessage::Fill(f.clone())),
122            BinanceMessage::Out(o) => Ok(OrderflowMessage::Out(*o)),
123            BinanceMessage::Folio(_) | BinanceMessage::ExchangeAccountSnapshot(..) => {
124                Err(())
125            }
126        }
127    }
128}
129
130impl TryFrom<&OrderflowMessage> for BinanceMessage {
131    type Error = ();
132
133    fn try_from(value: &OrderflowMessage) -> Result<Self, Self::Error> {
134        match value {
135            OrderflowMessage::Order(o) => {
136                Ok(BinanceMessage::Order(BinanceOrder { order: *o }))
137            }
138            OrderflowMessage::Cancel(c) => Ok(BinanceMessage::Cancel(*c)),
139            OrderflowMessage::CancelAll(_) => {
140                Ok(BinanceMessage::CancelAll(BinanceCancelAll {}))
141            }
142            OrderflowMessage::Reject(r) => Ok(BinanceMessage::Reject(r.clone())),
143            OrderflowMessage::Ack(_a) => Err(()),
144            OrderflowMessage::Fill(f) => Ok(BinanceMessage::Fill(f.clone())),
145            OrderflowMessage::Out(o) => Ok(BinanceMessage::Out(*o)),
146        }
147    }
148}
149
150impl TryFrom<&BinanceMessage> for FolioMessage {
151    type Error = ();
152
153    fn try_from(value: &BinanceMessage) -> Result<Self, Self::Error> {
154        match value {
155            BinanceMessage::Folio(f) => Ok(f.clone()),
156            _ => Err(()),
157        }
158    }
159}
160
161impl TryFrom<&FolioMessage> for BinanceMessage {
162    type Error = ();
163
164    fn try_from(value: &FolioMessage) -> Result<Self, Self::Error> {
165        Ok(BinanceMessage::Folio(value.clone()))
166    }
167}