1#![allow(clippy::too_many_arguments, unused_imports, non_camel_case_types)]
2use serde::{Deserialize, Serialize};
8
9use chrono::{DateTime, Utc};
11use rust_decimal::Decimal;
12use serde_json::Value as JsonValue;
13use uuid::Uuid;
14
15use crate::enums::MarketType;
17use crate::enums::PositionDirection;
18use crate::enums::PositionStatus;
19
20#[derive(Debug, Clone, Serialize, Deserialize)]
22pub struct Position {
23 pub position_id: Uuid,
24 pub chain_id: i32,
25 pub exchange: String,
26 pub market_type: String,
27 pub position_direction: String,
28 pub wallet_address: String,
29 pub token_symbol_pair: String,
30 pub token_address_pair: Option<String>,
31 pub base_token_symbol: String,
32 pub base_token_address: Option<String>,
33 pub quote_token_symbol: String,
34 pub quote_token_address: Option<String>,
35 pub status: String,
36 pub current_base_amount: Decimal,
37 pub original_base_amount: Decimal,
38 pub current_avg_entry_price: Decimal,
39 pub avg_entry_price: Decimal,
40 pub avg_exit_price: Decimal,
41 pub cost_basis: Decimal,
42 pub realized_pnl: Decimal,
43 pub realized_pnl_usd: Decimal,
44 pub realized_roi: Option<Decimal>,
45 pub leverage: Option<Decimal>,
46 pub opened_at: DateTime<Utc>,
47 pub closed_at: Option<DateTime<Utc>>,
48 pub fee_json: Option<JsonValue>,
49 pub id: Uuid,
50 pub created_at: DateTime<Utc>,
51 pub updated_at: DateTime<Utc>,
52 pub created_by: Option<String>,
53 pub updated_by: Option<String>,
54}
55
56impl Position {
57 pub fn new(
59 position_id: Uuid,
60 chain_id: i32,
61 exchange: String,
62 market_type: String,
63 position_direction: String,
64 wallet_address: String,
65 token_symbol_pair: String,
66 token_address_pair: String,
67 base_token_symbol: String,
68 base_token_address: String,
69 quote_token_symbol: String,
70 quote_token_address: String,
71 status: String,
72 current_base_amount: Decimal,
73 original_base_amount: Decimal,
74 current_avg_entry_price: Decimal,
75 avg_entry_price: Decimal,
76 avg_exit_price: Decimal,
77 cost_basis: Decimal,
78 realized_pnl: Decimal,
79 realized_pnl_usd: Decimal,
80 realized_roi: Decimal,
81 leverage: Decimal,
82 opened_at: DateTime<Utc>,
83 closed_at: DateTime<Utc>,
84 fee_json: JsonValue,
85 id: Uuid,
86 created_at: DateTime<Utc>,
87 updated_at: DateTime<Utc>,
88 created_by: String,
89 updated_by: String,
90 ) -> Self {
91 Self {
92 position_id,
93 chain_id,
94 exchange,
95 market_type,
96 position_direction,
97 wallet_address,
98 token_symbol_pair,
99 token_address_pair: Some(token_address_pair),
100 base_token_symbol,
101 base_token_address: Some(base_token_address),
102 quote_token_symbol,
103 quote_token_address: Some(quote_token_address),
104 status,
105 current_base_amount,
106 original_base_amount,
107 current_avg_entry_price,
108 avg_entry_price,
109 avg_exit_price,
110 cost_basis,
111 realized_pnl,
112 realized_pnl_usd,
113 realized_roi: Some(realized_roi),
114 leverage: Some(leverage),
115 opened_at,
116 closed_at: Some(closed_at),
117 fee_json: Some(fee_json),
118 id,
119 created_at,
120 updated_at,
121 created_by: Some(created_by),
122 updated_by: Some(updated_by),
123 }
124 }
125
126 pub fn to_json(&self) -> Result<String, serde_json::Error> {
128 serde_json::to_string(self)
129 }
130
131 pub fn from_json(json: &str) -> Result<Self, serde_json::Error> {
133 serde_json::from_str(json)
134 }
135
136 pub fn to_dict(&self) -> serde_json::Map<String, serde_json::Value> {
138 let json = serde_json::to_value(self).unwrap_or(serde_json::Value::Null);
139 if let serde_json::Value::Object(map) = json {
140 map
141 } else {
142 serde_json::Map::new()
143 }
144 }
145}