nash_protocol/protocol/get_account_order/
response.rs1use super::types::GetAccountOrderResponse;
2use crate::errors::{ProtocolError, Result};
3use crate::graphql::get_account_order;
4use crate::types::{
5 AccountTradeSide, BuyOrSell, Order, OrderCancellationPolicy, OrderCancellationReason,
6 OrderStatus, OrderType, Trade,
7};
8use crate::protocol::{State, traits::TryFromState};
9use chrono::{DateTime, Utc};
10use std::str::FromStr;
11use bigdecimal::BigDecimal;
12use std::sync::Arc;
13use tokio::sync::RwLock;
14use async_trait::async_trait;
15
16#[async_trait]
17impl TryFromState<get_account_order::ResponseData> for GetAccountOrderResponse {
18 async fn from(response: get_account_order::ResponseData, _state: Arc<RwLock<State>>) -> Result<GetAccountOrderResponse> {
19 let order_data = response.get_account_order;
20 let market = order_data.market.name.clone();
21 let amount_placed = BigDecimal::from_str(&order_data.amount.amount)?;
22 let amount_remaining = BigDecimal::from_str(&order_data.amount_remaining.amount)?;
23 let amount_executed = BigDecimal::from_str(&order_data.amount_executed.amount)?;
24 let limit_price = match &order_data.limit_price {
25 Some(price) => Some(BigDecimal::from_str(&price.amount)?),
26 None => None,
27 };
28 let stop_price = match &order_data.stop_price {
29 Some(price) => Some(BigDecimal::from_str(&price.amount)?),
30 None => None,
31 };
32 let placed_at = DateTime::<Utc>::from_str(&order_data.placed_at)
33 .map_err(|_| ProtocolError("Could not convert value to DateTime"))?;
34 let mut trades = Vec::new();
35 for trade_data in order_data.trades.as_ref().unwrap() {
37 let trade_data = trade_data.as_ref().unwrap();
38 let market = trade_data.market.name.clone();
39 let taker_fee = BigDecimal::from_str(&trade_data.taker_fee.amount)?;
40 let maker_fee = BigDecimal::from_str(&trade_data.maker_fee.amount)?;
41 let amount = BigDecimal::from_str(&trade_data.amount.amount)?;
42 let maker_recieved = BigDecimal::from_str(&trade_data.maker_received.amount)?;
43 let taker_recieved = BigDecimal::from_str(&trade_data.taker_received.amount)?;
44 let limit_price = BigDecimal::from_str(&trade_data.limit_price.amount)?;
45 trades.push(Trade {
46 market,
47 amount,
48 taker_fee,
49 maker_fee,
50 maker_recieved,
51 taker_recieved,
52 taker_order_id: trade_data.taker_order_id.clone(),
53 maker_order_id: trade_data.maker_order_id.clone(),
54 account_side: (&trade_data.account_side).into(),
55 id: trade_data.id.clone(),
56 executed_at: DateTime::<Utc>::from_str(&trade_data.executed_at)
57 .map_err(|_| ProtocolError("Could not convert value to DateTime"))?,
58 limit_price,
59 direction: (&trade_data.direction).into(),
60 })
61 }
62 Ok(GetAccountOrderResponse {
63 order: Order {
64 id: order_data.id.clone(),
65 client_order_id: order_data.client_order_id.clone(),
66 market,
67 amount_placed,
68 amount_remaining,
69 amount_executed,
70 limit_price,
71 stop_price,
72 placed_at,
73 trades,
74 cancellation_policy: (&order_data).into(),
75 cancellation_reason: order_data.cancellation_reason.as_ref().map(|x| x.into()),
76 buy_or_sell: order_data.buy_or_sell.into(),
77 order_type: order_data.type_.into(),
78 status: order_data.status.into(),
79 },
80 })
81 }
82}
83
84impl From<get_account_order::OrderBuyOrSell> for BuyOrSell {
85 fn from(response: get_account_order::OrderBuyOrSell) -> Self {
86 match response {
87 get_account_order::OrderBuyOrSell::BUY => Self::Buy,
88 get_account_order::OrderBuyOrSell::SELL => Self::Sell,
89 _ => panic!("Unexpected value in BuyOrSell enum"),
90 }
91 }
92}
93
94impl From<get_account_order::OrderType> for OrderType {
95 fn from(response: get_account_order::OrderType) -> Self {
96 match response {
97 get_account_order::OrderType::MARKET => Self::Market,
98 get_account_order::OrderType::LIMIT => Self::Limit,
99 get_account_order::OrderType::STOP_MARKET => Self::StopMarket,
100 get_account_order::OrderType::STOP_LIMIT => Self::StopLimit,
101 _ => panic!("Unexpected value in OrderType enum"),
102 }
103 }
104}
105
106impl From<get_account_order::OrderStatus> for OrderStatus {
107 fn from(response: get_account_order::OrderStatus) -> Self {
108 match response {
109 get_account_order::OrderStatus::PENDING => OrderStatus::Pending,
110 get_account_order::OrderStatus::OPEN => OrderStatus::Open,
111 get_account_order::OrderStatus::CANCELLED => OrderStatus::Canceled,
112 get_account_order::OrderStatus::FILLED => OrderStatus::Filled,
113 _ => panic!("Unexpected value in OrderStatus enum"),
114 }
115 }
116}
117
118impl From<&get_account_order::OrderCancellationReason> for OrderCancellationReason {
119 fn from(cancellation_reason: &get_account_order::OrderCancellationReason) -> Self {
120 match cancellation_reason {
121 get_account_order::OrderCancellationReason::ADMIN_CANCELED => {
122 OrderCancellationReason::AdminCancelled
123 }
124 get_account_order::OrderCancellationReason::EXPIRATION => {
125 OrderCancellationReason::Expiration
126 }
127 get_account_order::OrderCancellationReason::USER => OrderCancellationReason::User,
128 get_account_order::OrderCancellationReason::NO_FILL => OrderCancellationReason::NoFill,
129 get_account_order::OrderCancellationReason::INVALID_FOR_ORDERBOOK_STATE => {
130 OrderCancellationReason::InvalidForOrderbookState
131 }
132 _ => panic!("Unsupported OrderCancellationReason"),
133 }
134 }
135}
136
137impl From<&get_account_order::GetAccountOrderGetAccountOrder> for Option<OrderCancellationPolicy> {
138 fn from(order: &get_account_order::GetAccountOrderGetAccountOrder) -> Self {
139 if let Some(cancellation_policy) = &order.cancellation_policy {
140 Some(match cancellation_policy {
141 get_account_order::OrderCancellationPolicy::FILL_OR_KILL => {
142 OrderCancellationPolicy::FillOrKill
143 }
144 get_account_order::OrderCancellationPolicy::GOOD_TIL_CANCELLED => {
145 OrderCancellationPolicy::GoodTilCancelled
146 }
147 get_account_order::OrderCancellationPolicy::GOOD_TIL_TIME => {
148 let cancel_at =
150 DateTime::<Utc>::from_str(order.cancel_at.as_ref().unwrap()).unwrap();
151 OrderCancellationPolicy::GoodTilTime(cancel_at)
152 }
153 get_account_order::OrderCancellationPolicy::IMMEDIATE_OR_CANCEL => {
154 OrderCancellationPolicy::ImmediateOrCancel
155 }
156 _ => panic!("Unsupported OrderCancellationPolicy"),
157 })
158 } else {
159 None
160 }
161 }
162}
163
164impl From<&get_account_order::AccountTradeSide> for AccountTradeSide {
165 fn from(trade_side: &get_account_order::AccountTradeSide) -> Self {
166 match trade_side {
167 get_account_order::AccountTradeSide::MAKER => AccountTradeSide::Maker,
168 get_account_order::AccountTradeSide::TAKER => AccountTradeSide::Taker,
169 get_account_order::AccountTradeSide::NONE => AccountTradeSide::None,
170 _ => panic!("Unsupported value in AccountTradeSide"),
171 }
172 }
173}
174
175impl From<&get_account_order::Direction> for BuyOrSell {
176 fn from(response: &get_account_order::Direction) -> Self {
177 match response {
178 get_account_order::Direction::BUY => Self::Buy,
179 get_account_order::Direction::SELL => Self::Sell,
180 _ => panic!("Unexpected value in BuyOrSell enum"),
181 }
182 }
183}