drm_core/models/
market.rs1use chrono::{DateTime, Utc};
2use serde::{Deserialize, Serialize};
3use std::collections::HashMap;
4
5#[derive(Debug, Clone, Serialize, Deserialize)]
6pub struct Market {
7 pub id: String,
8 pub question: String,
9 pub outcomes: Vec<String>,
10 #[serde(default, skip_serializing_if = "Option::is_none")]
11 pub close_time: Option<DateTime<Utc>>,
12 pub volume: f64,
13 pub liquidity: f64,
14 pub prices: HashMap<String, f64>,
15 #[serde(default)]
16 pub metadata: serde_json::Value,
17 pub tick_size: f64,
18 #[serde(default)]
19 pub description: String,
20}
21
22impl Market {
23 pub fn is_binary(&self) -> bool {
24 self.outcomes.len() == 2
25 }
26
27 pub fn is_open(&self) -> bool {
28 if let Some(metadata) = self.metadata.as_object() {
29 if let Some(closed) = metadata.get("closed").and_then(|v| v.as_bool()) {
30 return !closed;
31 }
32 }
33
34 match self.close_time {
35 Some(close_time) => Utc::now() < close_time,
36 None => true,
37 }
38 }
39
40 pub fn spread(&self) -> Option<f64> {
41 if !self.is_binary() || self.outcomes.len() != 2 {
42 return None;
43 }
44
45 let prices: Vec<f64> = self.prices.values().copied().collect();
46 if prices.len() != 2 {
47 return None;
48 }
49
50 Some((1.0 - prices.iter().sum::<f64>()).abs())
51 }
52
53 pub fn get_token_ids(&self) -> Vec<String> {
54 let token_ids = self.metadata.get("clobTokenIds");
55
56 match token_ids {
57 Some(serde_json::Value::String(s)) => serde_json::from_str(s).unwrap_or_default(),
58 Some(serde_json::Value::Array(arr)) => arr
59 .iter()
60 .filter_map(|v| v.as_str().map(String::from))
61 .collect(),
62 _ => vec![],
63 }
64 }
65
66 pub fn get_outcome_tokens(&self) -> Vec<OutcomeToken> {
67 let token_ids = self.get_token_ids();
68 self.outcomes
69 .iter()
70 .enumerate()
71 .map(|(i, outcome)| OutcomeToken {
72 outcome: outcome.clone(),
73 token_id: token_ids.get(i).cloned().unwrap_or_default(),
74 })
75 .collect()
76 }
77}
78
79#[derive(Debug, Clone, Serialize, Deserialize)]
80pub struct OutcomeToken {
81 pub outcome: String,
82 pub token_id: String,
83}