Skip to main content

px_core/models/
position.rs

1use serde::{Deserialize, Serialize};
2
3/// An open position held by the caller.
4#[derive(Debug, Clone, Serialize, Deserialize)]
5#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
6pub struct Position {
7    /// Unified market ticker the position is held on (e.g. `"KXBTCD-25APR1517"`).
8    pub market_ticker: String,
9    /// Outcome label as published by the exchange (e.g. `"Yes"`, `"No"`).
10    pub outcome: String,
11    /// Number of contracts held (e.g. `100.0`).
12    pub size: f64,
13    /// Volume-weighted average entry price as YES probability in `[0, 1]` (e.g. `0.55`).
14    pub average_price: f64,
15    /// Current mark price as YES probability in `[0, 1]` (e.g. `0.62`).
16    pub current_price: f64,
17}
18
19impl Position {
20    #[inline]
21    pub fn cost_basis(&self) -> f64 {
22        self.size * self.average_price
23    }
24
25    #[inline]
26    pub fn current_value(&self) -> f64 {
27        self.size * self.current_price
28    }
29
30    #[inline]
31    pub fn unrealized_pnl(&self) -> f64 {
32        self.current_value() - self.cost_basis()
33    }
34
35    #[inline]
36    pub fn unrealized_pnl_percent(&self) -> f64 {
37        let cost = self.cost_basis();
38        if cost == 0.0 {
39            return 0.0;
40        }
41        (self.unrealized_pnl() / cost) * 100.0
42    }
43}