use serde::Deserialize;
use crate::utils::dec::Dec;
use crate::utils::ids::whole;
use crate::utils::{AccountIndex, AssetId, MarginMode, MarketId, Side};
#[derive(Debug, Clone, PartialEq, Eq, Deserialize)]
pub struct Position {
pub market_id: MarketId,
#[serde(default)]
pub symbol: String,
pub initial_margin_fraction: Dec,
#[serde(default, deserialize_with = "whole")]
pub open_order_count: u64,
#[serde(default, deserialize_with = "whole")]
pub pending_order_count: u64,
#[serde(default, deserialize_with = "whole")]
pub position_tied_order_count: u64,
pub sign: i8,
pub position: Dec,
pub avg_entry_price: Dec,
pub position_value: Dec,
pub unrealized_pnl: Dec,
pub realized_pnl: Dec,
pub liquidation_price: Dec,
#[serde(default)]
pub total_funding_paid_out: Option<Dec>,
pub margin_mode: MarginMode,
pub allocated_margin: Dec,
#[serde(default)]
pub total_discount: Option<Dec>,
}
impl Position {
#[must_use]
pub fn is_open(&self) -> bool {
!self.position.is_zero()
}
#[must_use]
pub fn signed_size(&self) -> Dec {
match self.sign < 0 {
true => self.position.negate(),
false => self.position,
}
}
#[must_use]
pub fn side(&self) -> Option<Side> {
match (self.is_open(), self.sign < 0) {
(false, _) => None,
(true, true) => Some(Side::Ask),
(true, false) => Some(Side::Bid),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Deserialize)]
pub struct Asset {
pub symbol: String,
pub asset_id: AssetId,
pub balance: Dec,
pub locked_balance: Dec,
#[serde(default)]
pub margin_balance: Dec,
#[serde(default)]
pub margin_mode: String,
#[serde(default)]
pub multiplier: Dec,
}
impl Asset {
#[must_use]
pub fn backs_perps(&self) -> bool {
self.margin_mode == "enabled"
}
#[must_use]
pub fn free(&self) -> Dec {
self.balance.checked_sub(self.locked_balance).unwrap_or(self.balance)
}
}
#[derive(Debug, Clone, PartialEq, Eq, Deserialize)]
pub struct PoolShare {
#[serde(rename = "public_pool_index")]
pub pool: AccountIndex,
#[serde(rename = "shares_amount", deserialize_with = "whole")]
pub shares: u64,
pub entry_usdc: Dec,
pub principal_amount: Dec,
#[serde(default, deserialize_with = "whole")]
pub entry_timestamp: u64,
}
#[cfg(test)]
#[path = "tests/positions.rs"]
mod tests;