drm_core/models/
market.rs

1use 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}