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 avg_entry_price: Decimal,
39 pub avg_exit_price: Decimal,
40 pub cost_basis: Decimal,
41 pub realized_pnl: Decimal,
42 pub realized_pnl_usd: Decimal,
43 pub opening_trades: JsonValue,
44 pub closing_trades: JsonValue,
45 pub realized_roi: Option<Decimal>,
46 pub leverage: Option<Decimal>,
47 pub opened_at: DateTime<Utc>,
48 pub closed_at: Option<DateTime<Utc>>,
49 pub fee_json: Option<JsonValue>,
50 pub id: Uuid,
51 pub created_at: DateTime<Utc>,
52 pub updated_at: DateTime<Utc>,
53 pub created_by: Option<String>,
54 pub updated_by: Option<String>,
55}
56
57impl Position {
58 pub fn new(
60 position_id: Uuid,
61 chain_id: i32,
62 exchange: String,
63 market_type: String,
64 position_direction: String,
65 wallet_address: String,
66 token_symbol_pair: String,
67 token_address_pair: String,
68 base_token_symbol: String,
69 base_token_address: String,
70 quote_token_symbol: String,
71 quote_token_address: String,
72 status: String,
73 current_base_amount: Decimal,
74 original_base_amount: 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 opening_trades: JsonValue,
81 closing_trades: JsonValue,
82 realized_roi: Decimal,
83 leverage: Decimal,
84 opened_at: DateTime<Utc>,
85 closed_at: DateTime<Utc>,
86 fee_json: JsonValue,
87 id: Uuid,
88 created_at: DateTime<Utc>,
89 updated_at: DateTime<Utc>,
90 created_by: String,
91 updated_by: String,
92 ) -> Self {
93 Self {
94 position_id,
95 chain_id,
96 exchange,
97 market_type,
98 position_direction,
99 wallet_address,
100 token_symbol_pair,
101 token_address_pair: Some(token_address_pair),
102 base_token_symbol,
103 base_token_address: Some(base_token_address),
104 quote_token_symbol,
105 quote_token_address: Some(quote_token_address),
106 status,
107 current_base_amount,
108 original_base_amount,
109 avg_entry_price,
110 avg_exit_price,
111 cost_basis,
112 realized_pnl,
113 realized_pnl_usd,
114 opening_trades,
115 closing_trades,
116 realized_roi: Some(realized_roi),
117 leverage: Some(leverage),
118 opened_at,
119 closed_at: Some(closed_at),
120 fee_json: Some(fee_json),
121 id,
122 created_at,
123 updated_at,
124 created_by: Some(created_by),
125 updated_by: Some(updated_by),
126 }
127 }
128
129 pub fn to_json(&self) -> Result<String, serde_json::Error> {
131 serde_json::to_string(self)
132 }
133
134 pub fn from_json(json: &str) -> Result<Self, serde_json::Error> {
136 serde_json::from_str(json)
137 }
138
139 pub fn to_dict(&self) -> serde_json::Map<String, serde_json::Value> {
141 let json = serde_json::to_value(self).unwrap_or(serde_json::Value::Null);
142 if let serde_json::Value::Object(map) = json {
143 map
144 } else {
145 serde_json::Map::new()
146 }
147 }
148}