df_hyperliquid_core/markets/
context.rs1use serde::Deserialize;
5
6use crate::utils::dec::{Dec, Round};
7
8#[derive(Debug, Clone, PartialEq, Eq, Deserialize)]
11#[serde(rename_all = "camelCase")]
12pub struct PerpCtx {
13 pub mark_px: Dec,
14 #[serde(default)]
15 pub mid_px: Option<Dec>,
16 pub oracle_px: Dec,
17 pub prev_day_px: Dec,
18 pub funding: Dec,
20 pub open_interest: Dec,
22 pub day_ntl_vlm: Dec,
24 #[serde(default)]
26 pub day_base_vlm: Option<Dec>,
27 #[serde(default)]
28 pub premium: Option<Dec>,
29 #[serde(default)]
30 pub impact_pxs: Option<Vec<Dec>>,
31}
32
33impl PerpCtx {
34 #[must_use]
36 pub fn reference(&self) -> Dec {
37 self.mid_px.unwrap_or(self.mark_px)
38 }
39
40 #[must_use]
43 pub fn day_change(&self) -> Option<Dec> {
44 let then = Some(self.prev_day_px).filter(|then| then.is_positive())?;
45 self.mark_px.checked_sub(then)?.checked_mul(Dec::from_int(100))?.checked_div(then, 2, Round::Nearest)
46 }
47
48 #[must_use]
50 pub fn open_interest_value(&self) -> Option<Dec> {
51 self.open_interest.checked_mul(self.mark_px)
52 }
53}
54
55#[derive(Debug, Clone, PartialEq, Eq, Deserialize)]
58#[serde(rename_all = "camelCase")]
59pub struct SpotCtx {
60 pub coin: String,
62 pub mark_px: Dec,
63 #[serde(default)]
64 pub mid_px: Option<Dec>,
65 pub prev_day_px: Dec,
66 pub day_ntl_vlm: Dec,
68 #[serde(default)]
70 pub day_base_vlm: Option<Dec>,
71 pub circulating_supply: Dec,
72 #[serde(default)]
73 pub total_supply: Option<Dec>,
74}
75
76impl SpotCtx {
77 #[must_use]
79 pub fn reference(&self) -> Dec {
80 self.mid_px.unwrap_or(self.mark_px)
81 }
82}
83
84#[cfg(test)]
85#[path = "tests/context.rs"]
86mod tests;