1use crate::{
2 folio::FolioMessage,
3 orderflow::*,
4 symbology::{market::NormalizedMarketInfo, ProductId},
5 Dir, Str,
6};
7use arcstr::ArcStr;
8use chrono::{DateTime, Utc};
9#[cfg(feature = "netidx")]
10use derive::FromValue;
11use log::error;
12#[cfg(feature = "netidx")]
13use netidx_derive::Pack;
14use rust_decimal::Decimal;
15use schemars::JsonSchema;
16use serde_derive::{Deserialize, Serialize};
17use std::ops::{Deref, DerefMut};
18
19#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
20#[cfg_attr(feature = "netidx", derive(Pack))]
21pub struct WintermuteMarketInfo {
22 pub tick_size: Decimal,
23 pub step_size: Decimal,
24 pub is_delisted: bool,
25}
26
27impl NormalizedMarketInfo for WintermuteMarketInfo {
28 fn tick_size(&self) -> Decimal {
29 self.tick_size
30 }
31
32 fn step_size(&self) -> Decimal {
33 self.step_size
34 }
35
36 fn is_delisted(&self) -> bool {
37 self.is_delisted
38 }
39}
40
41impl std::fmt::Display for WintermuteMarketInfo {
42 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
43 write!(f, "{}", serde_json::to_string_pretty(self).unwrap())?;
44 Ok(())
45 }
46}
47
48#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
49#[cfg_attr(feature = "netidx", derive(Pack))]
50#[cfg_attr(feature = "netidx", derive(FromValue))]
51pub enum WintermuteMessage {
52 Order(WintermuteOrder),
53 Ack(Ack),
54 Reject(Reject),
55 Fill(WintermuteFill),
56 Out(Out),
57 ExecutionReport(ExecutionReport),
58 Balances(Vec<(ProductId, Decimal)>),
59 Folio(FolioMessage),
60}
61
62impl TryInto<WintermuteMessage> for &OrderflowMessage {
63 type Error = ();
64
65 fn try_into(self) -> Result<WintermuteMessage, ()> {
66 match self {
67 OrderflowMessage::Order(o) => {
68 Ok(WintermuteMessage::Order(WintermuteOrder { order: *o }))
69 }
70 OrderflowMessage::Ack(a) => Ok(WintermuteMessage::Ack(*a)),
71 OrderflowMessage::Cancel(_) => Err(()),
72 OrderflowMessage::Reject(r) => Ok(WintermuteMessage::Reject(r.clone())),
73 OrderflowMessage::CancelAll(_) => {
74 Err(error!("Cancel all not implemented for Wintermute"))
75 }
76 OrderflowMessage::Fill(f) => {
77 Ok(WintermuteMessage::Fill(WintermuteFill { fill: *f }))
78 }
79 OrderflowMessage::Out(o) => Ok(WintermuteMessage::Out(*o)),
80 }
81 }
82}
83
84impl TryInto<OrderflowMessage> for &WintermuteMessage {
85 type Error = ();
86
87 fn try_into(self) -> Result<OrderflowMessage, ()> {
88 match self {
89 WintermuteMessage::Order(o) => Ok(OrderflowMessage::Order(**o)),
90 WintermuteMessage::Ack(a) => Ok(OrderflowMessage::Ack(*a)),
91 WintermuteMessage::Reject(r) => Ok(OrderflowMessage::Reject(r.clone())),
92 WintermuteMessage::Fill(f) => Ok(OrderflowMessage::Fill(**f)),
93 WintermuteMessage::Out(o) => Ok(OrderflowMessage::Out(*o)),
94 WintermuteMessage::Balances(_)
95 | WintermuteMessage::Folio(_)
96 | WintermuteMessage::ExecutionReport(_) => Err(()),
97 }
98 }
99}
100
101impl TryInto<FolioMessage> for &WintermuteMessage {
102 type Error = ();
103
104 fn try_into(self) -> Result<FolioMessage, ()> {
105 match self {
106 WintermuteMessage::Folio(f) => Ok(f.clone()),
107 _ => Err(()),
108 }
109 }
110}
111
112impl TryFrom<&FolioMessage> for WintermuteMessage {
113 type Error = ();
114
115 fn try_from(f: &FolioMessage) -> Result<Self, ()> {
116 Ok(Self::Folio(f.clone()))
117 }
118}
119
120#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
121#[cfg_attr(feature = "netidx", derive(Pack))]
122#[cfg_attr(feature = "netidx", derive(FromValue))]
123pub struct ExecutionReport {
124 pub client_order_id: Str,
125 pub order_id: Str,
126 pub execution_id: Str,
127 pub exec_type: ExecType,
128 pub order_status: Str,
129 pub symbol: Str,
130 pub product: Str,
131 pub currency: Str,
132 pub side: Dir,
133 pub order_qty: Decimal,
134 pub last_qty: Decimal,
135 pub cum_qty: Decimal,
136 pub leaves_qty: Decimal,
137 pub price: Option<Decimal>,
138 pub transact_time: DateTime<Utc>,
139 pub text: Option<ArcStr>,
140}
141
142#[derive(Debug, Clone, Copy, Serialize, Deserialize, JsonSchema)]
143#[cfg_attr(feature = "netidx", derive(Pack))]
144#[cfg_attr(feature = "netidx", derive(FromValue))]
145pub enum ExecType {
146 Canceled,
147 Rejected,
148 Expired,
149 Trade,
150}
151
152#[derive(Debug, Clone, Copy, Serialize, Deserialize, JsonSchema)]
153#[cfg_attr(feature = "netidx", derive(Pack))]
154pub struct WintermuteOrder {
155 #[serde(flatten)]
156 pub order: Order,
157}
158
159impl From<Order> for WintermuteOrder {
160 fn from(order: Order) -> Self {
161 Self { order }
162 }
163}
164
165impl Deref for WintermuteOrder {
166 type Target = Order;
167
168 fn deref(&self) -> &Self::Target {
169 &self.order
170 }
171}
172
173impl DerefMut for WintermuteOrder {
174 fn deref_mut(&mut self) -> &mut Self::Target {
175 &mut self.order
176 }
177}
178
179#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
180#[cfg_attr(feature = "netidx", derive(Pack))]
181pub struct WintermuteFill {
182 #[serde(flatten)]
183 pub fill: Result<Fill, AberrantFill>,
184}
185
186impl Deref for WintermuteFill {
187 type Target = Result<Fill, AberrantFill>;
188
189 fn deref(&self) -> &Self::Target {
190 &self.fill
191 }
192}