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