architect_api/cpty/
coinbase_prime.rs

1use crate::{
2    folio::FolioMessage, orderflow::*, symbology::market::NormalizedMarketInfo, Dir, Str,
3};
4use chrono::{DateTime, Utc};
5#[cfg(feature = "netidx")]
6use derive::FromValue;
7use log::error;
8#[cfg(feature = "netidx")]
9use netidx_derive::Pack;
10use rust_decimal::Decimal;
11use schemars::JsonSchema;
12use serde::{Deserialize, Serialize};
13use std::ops::{Deref, DerefMut};
14
15#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
16#[cfg_attr(feature = "netidx", derive(Pack))]
17pub struct CoinbasePrimeMarketInfo {
18    pub base_increment: Decimal,
19    pub quote_increment: Decimal,
20    pub base_min_size: Decimal,
21    pub quote_min_size: Decimal,
22    pub base_max_size: Decimal,
23    pub quote_max_size: Decimal,
24}
25
26impl NormalizedMarketInfo for CoinbasePrimeMarketInfo {
27    fn tick_size(&self) -> Decimal {
28        self.quote_increment
29    }
30
31    fn step_size(&self) -> Decimal {
32        self.base_increment
33    }
34
35    fn is_delisted(&self) -> bool {
36        false
37    }
38}
39
40impl std::fmt::Display for CoinbasePrimeMarketInfo {
41    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
42        write!(f, "{}", serde_json::to_string_pretty(self).unwrap())?;
43        Ok(())
44    }
45}
46
47#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
48#[cfg_attr(feature = "netidx", derive(Pack))]
49#[cfg_attr(feature = "netidx", derive(FromValue))]
50pub enum CoinbasePrimeMessage {
51    Order(CoinbasePrimeOrder),
52    Cancel(Cancel),
53    Ack(Ack),
54    Reject(Reject),
55    Fill(CoinbasePrimeFill),
56    Out(Out),
57    ExchangeExecutionReport(ExchangeExecutionReport),
58    Folio(FolioMessage),
59}
60
61impl TryInto<CoinbasePrimeMessage> for &OrderflowMessage {
62    type Error = ();
63
64    fn try_into(self) -> Result<CoinbasePrimeMessage, ()> {
65        match self {
66            OrderflowMessage::Order(o) => {
67                Ok(CoinbasePrimeMessage::Order(CoinbasePrimeOrder { order: *o }))
68            }
69            OrderflowMessage::Ack(a) => Ok(CoinbasePrimeMessage::Ack(*a)),
70            OrderflowMessage::Cancel(c) => Ok(CoinbasePrimeMessage::Cancel(*c)),
71            OrderflowMessage::Reject(r) => Ok(CoinbasePrimeMessage::Reject(r.clone())),
72            OrderflowMessage::Fill(f) => {
73                Ok(CoinbasePrimeMessage::Fill(CoinbasePrimeFill { fill: *f }))
74            }
75            OrderflowMessage::Out(o) => Ok(CoinbasePrimeMessage::Out(*o)),
76            OrderflowMessage::CancelAll(_) => {
77                Err(error!("Cancel all not implemented for CoinbasePrime"))
78            }
79        }
80    }
81}
82
83impl TryInto<OrderflowMessage> for &CoinbasePrimeMessage {
84    type Error = ();
85
86    fn try_into(self) -> Result<OrderflowMessage, ()> {
87        match self {
88            CoinbasePrimeMessage::Order(o) => Ok(OrderflowMessage::Order(**o)),
89            CoinbasePrimeMessage::Ack(a) => Ok(OrderflowMessage::Ack(*a)),
90            CoinbasePrimeMessage::Cancel(c) => Ok(OrderflowMessage::Cancel(*c)),
91            CoinbasePrimeMessage::Reject(r) => Ok(OrderflowMessage::Reject(r.clone())),
92            CoinbasePrimeMessage::Fill(f) => Ok(OrderflowMessage::Fill(**f)),
93            CoinbasePrimeMessage::Out(o) => Ok(OrderflowMessage::Out(*o)),
94            CoinbasePrimeMessage::Folio(_)
95            | CoinbasePrimeMessage::ExchangeExecutionReport(_) => Err(()),
96        }
97    }
98}
99
100impl TryInto<FolioMessage> for &CoinbasePrimeMessage {
101    type Error = ();
102
103    fn try_into(self) -> Result<FolioMessage, ()> {
104        match self {
105            CoinbasePrimeMessage::Folio(f) => Ok(f.clone()),
106            _ => Err(()),
107        }
108    }
109}
110
111impl TryFrom<&FolioMessage> for CoinbasePrimeMessage {
112    type Error = ();
113
114    fn try_from(f: &FolioMessage) -> Result<Self, ()> {
115        Ok(Self::Folio(f.clone()))
116    }
117}
118
119#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
120#[cfg_attr(feature = "netidx", derive(Pack))]
121#[cfg_attr(feature = "netidx", derive(FromValue))]
122pub enum ExchangeExecType {
123    NewOrder,
124    PartialFill,
125    Filled,
126    Done,
127    Canceled,
128    PendingCancel,
129    Stopped,
130    Rejected,
131    Restated,
132    PendingNew,
133    OrderStatus,
134}
135
136#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
137#[cfg_attr(feature = "netidx", derive(Pack))]
138#[cfg_attr(feature = "netidx", derive(FromValue))]
139pub struct ExchangeExecutionReport {
140    pub order_average_price: Decimal,
141    pub client_order_id: Str,
142    pub commission: Option<Decimal>,
143    pub cum_qty: Decimal,
144    pub execution_id: Str,
145    pub last_price: Option<Decimal>,
146    pub last_qty: Option<Decimal>,
147    pub order_id: Str,
148    pub order_qty: Decimal,
149    pub order_status: Str,
150    pub sender_sub_id: Str,
151    pub side: Dir,
152    pub symbol: Str,
153    pub order_reject_reason: Option<ExchangeOrderRejectReason>,
154    pub exec_type: ExchangeExecType,
155    pub leaves_qty: Decimal,
156    //pub cash_order_qty: Option<Decimal>,
157    pub last_mkt: Option<Str>,
158    pub transact_time: DateTime<Utc>,
159}
160
161#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
162#[cfg_attr(feature = "netidx", derive(Pack))]
163#[cfg_attr(feature = "netidx", derive(FromValue))]
164pub enum ExchangeOrderRejectReason {
165    BrokerOption,
166    UnknownSymbol,
167    ExchangeClosed,
168    OrderExceedsLimit,
169    TooLateToEnter,
170    UnknownOrder,
171    DuplicateOrder,
172}
173
174#[derive(Debug, Clone, Copy, Serialize, Deserialize, JsonSchema)]
175#[cfg_attr(feature = "netidx", derive(Pack))]
176#[cfg_attr(feature = "netidx", derive(FromValue))]
177pub struct CoinbasePrimeOrder {
178    #[serde(flatten)]
179    pub order: Order,
180}
181
182impl From<Order> for CoinbasePrimeOrder {
183    fn from(order: Order) -> Self {
184        Self { order }
185    }
186}
187
188impl Deref for CoinbasePrimeOrder {
189    type Target = Order;
190
191    fn deref(&self) -> &Self::Target {
192        &self.order
193    }
194}
195
196impl DerefMut for CoinbasePrimeOrder {
197    fn deref_mut(&mut self) -> &mut Self::Target {
198        &mut self.order
199    }
200}
201
202#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
203#[cfg_attr(feature = "netidx", derive(Pack))]
204pub struct CoinbasePrimeFill {
205    #[serde(flatten)]
206    pub fill: Result<Fill, AberrantFill>,
207}
208
209impl Deref for CoinbasePrimeFill {
210    type Target = Result<Fill, AberrantFill>;
211
212    fn deref(&self) -> &Self::Target {
213        &self.fill
214    }
215}