1use std::fmt;
2use std::io::Write;
3
4use crate::utils::SignedDecimal;
5use cosmwasm_std::{Decimal, StdError};
6use cw_storage_plus::{Key, KeyDeserialize, Prefixer, PrimaryKey};
7use schemars::JsonSchema;
8use serde::{Deserialize, Serialize};
9
10#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
11pub struct Order {
12 pub id: u64,
13 pub account: String,
14 pub price_denom: String,
15 pub asset_denom: String,
16 pub price: SignedDecimal,
17 pub quantity: SignedDecimal,
18 pub remaining_quantity: SignedDecimal,
19 pub direction: PositionDirection,
20 pub effect: PositionEffect,
21 pub leverage: SignedDecimal,
22 pub order_type: OrderType,
23}
24
25#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
26pub struct FundingPaymentRate {
27 pub price_diff: SignedDecimal,
28 pub epoch: i64,
29}
30
31#[derive(Serialize, Deserialize, Copy, Clone, Debug, PartialEq, JsonSchema, Eq, Hash)]
32pub enum PositionDirection {
33 Unknown,
34 Long,
35 Short,
36}
37
38impl fmt::Display for PositionDirection {
39 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
40 match self {
41 PositionDirection::Unknown => write!(f, "Unknown"),
42 PositionDirection::Long => write!(f, "Long"),
43 PositionDirection::Short => write!(f, "Short"),
44 }
45 }
46}
47
48#[derive(Serialize, Deserialize, Copy, Clone, Debug, PartialEq, JsonSchema, Eq, Hash)]
49pub enum PositionEffect {
50 Unknown,
51 Open,
52 Close,
53}
54
55impl fmt::Display for PositionEffect {
56 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
57 match self {
58 PositionEffect::Unknown => write!(f, "Unknown"),
59 PositionEffect::Open => write!(f, "Open"),
60 PositionEffect::Close => write!(f, "Close"),
61 }
62 }
63}
64
65#[derive(Serialize, Deserialize, Copy, Clone, Debug, PartialEq, JsonSchema, Eq, Hash)]
66pub enum OrderType {
67 Unknown,
68 Limit,
69 Market,
70 Liquidation,
71 Fokmarket,
72 Fokmarketbyvalue,
73}
74
75impl fmt::Display for OrderType {
76 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
77 match self {
78 OrderType::Unknown => write!(f, "Unknown"),
79 OrderType::Limit => write!(f, "Limit"),
80 OrderType::Market => write!(f, "Market"),
81 OrderType::Liquidation => write!(f, "Liquidation"),
82 OrderType::Fokmarket => write!(f, "Fokmarket"),
83 OrderType::Fokmarketbyvalue => write!(f, "Fokmarketbyvalue"),
84 }
85 }
86}
87
88pub fn i32_to_order_type(i: i32) -> OrderType {
89 match i {
90 0i32 => OrderType::Limit,
91 1i32 => OrderType::Market,
92 2i32 => OrderType::Liquidation,
93 3i32 => OrderType::Fokmarket,
94 4i32 => OrderType::Fokmarketbyvalue,
95 _ => OrderType::Unknown,
96 }
97}
98
99pub fn order_type_to_i32(o: OrderType) -> i32 {
100 match o {
101 OrderType::Limit => 0i32,
102 OrderType::Market => 1i32,
103 OrderType::Liquidation => 2i32,
104 OrderType::Fokmarket => 3i32,
105 OrderType::Fokmarketbyvalue => 4i32,
106 OrderType::Unknown => -1i32,
107 }
108}
109
110pub fn i32_to_direction(i: i32) -> PositionDirection {
111 match i {
112 0i32 => PositionDirection::Long,
113 1i32 => PositionDirection::Short,
114 _ => PositionDirection::Unknown,
115 }
116}
117
118pub fn direction_to_i32(d: PositionDirection) -> i32 {
119 match d {
120 PositionDirection::Long => 0i32,
121 PositionDirection::Short => 1i32,
122 PositionDirection::Unknown => -1i32,
123 }
124}
125
126#[derive(Clone, Serialize, Deserialize, Hash, PartialEq, Eq, Debug, JsonSchema)]
127pub struct Pair {
130 pub price_denom: String,
131 pub asset_denom: String,
132}
133
134impl Pair {
135 fn to_bytes(&self) -> [u8; 16] {
136 let mut price_denom_bytes: [u8; 8] = [0; 8];
137 let mut asset_denom_bytes: [u8; 8] = [0; 8];
138 let mut bytes = [0 as u8; 16];
139
140 self.fill_bytes_from_price_denom(&mut price_denom_bytes);
141 self.fill_bytes_from_asset_denom(&mut asset_denom_bytes);
142
143 for i in 0..8 {
144 bytes[i] = price_denom_bytes[i];
145 bytes[i + 8] = asset_denom_bytes[i];
146 }
147
148 bytes
149 }
150
151 pub fn fill_bytes_from_price_denom(&self, mut bytes: &mut [u8]) {
152 bytes.write(self.price_denom.as_bytes()).unwrap();
153 }
154
155 pub fn fill_bytes_from_asset_denom(&self, mut bytes: &mut [u8]) {
156 bytes.write(self.asset_denom.as_bytes()).unwrap();
157 }
158}
159
160impl KeyDeserialize for Pair {
162 type Output = Pair;
163
164 fn from_vec(value: Vec<u8>) -> cosmwasm_std::StdResult<Self::Output> {
165 if value.len() != 16 {
166 return Err(StdError::ParseErr {
167 target_type: "pair".to_owned(),
168 msg: "bytes should have a length of 16".to_owned(),
169 });
170 }
171 let mut price_denom_last_char_idx = 8;
172 while price_denom_last_char_idx > 0 && value[price_denom_last_char_idx - 1] == 0 {
173 price_denom_last_char_idx -= 1;
174 }
175 let price_value = value.get(0..price_denom_last_char_idx).unwrap();
176 let price_denom = std::str::from_utf8(price_value).unwrap().to_string();
177 let mut asset_denom_last_char_idx = 16;
178 while asset_denom_last_char_idx > 8 && value[asset_denom_last_char_idx - 1] == 0 {
179 asset_denom_last_char_idx -= 1;
180 }
181 let asset_value = value.get(8..asset_denom_last_char_idx).unwrap();
182 let asset_denom = std::str::from_utf8(asset_value).unwrap().to_string();
183
184 Ok(Pair {
185 price_denom: price_denom,
186 asset_denom: asset_denom,
187 })
188 }
189}
190
191impl<'a> Prefixer<'a> for Pair {
192 fn prefix(&self) -> Vec<Key> {
193 vec![Key::Val128(self.to_bytes())]
194 }
195}
196
197impl<'a> PrimaryKey<'a> for Pair {
199 type Prefix = ();
200
201 type SubPrefix = ();
202
203 type Suffix = Self;
204
205 type SuperSuffix = Self;
206
207 fn key(&self) -> Vec<cw_storage_plus::Key> {
208 vec![Key::Val128(self.to_bytes())]
209 }
210}
211
212#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema, Copy)]
213pub struct Position {
214 pub direction: PositionDirection,
217 pub quantity: SignedDecimal,
219 pub total_margin_debt: SignedDecimal,
221 pub total_cost: SignedDecimal,
224 pub last_funding_payment_epoch: i64,
226 pub last_paid_funding_payment_rate: SignedDecimal,
229}
230
231pub fn opposite_direction(direction: PositionDirection) -> PositionDirection {
232 match direction {
233 PositionDirection::Long => PositionDirection::Short,
234 PositionDirection::Short => PositionDirection::Long,
235 PositionDirection::Unknown => PositionDirection::Unknown,
236 }
237}
238
239#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
240pub struct MarginRatios {
241 pub initial: Decimal,
242 pub partial: Decimal,
243 pub maintenance: Decimal,
244}