quant_suite/models/
price_alert.rs1use std::collections::HashMap;
2
3use nanoid::nanoid;
4
5use crate::AlertSet;
6
7pub struct PriceAlert {
12 alert_price: HashMap<u32, HashMap<String, AlertSet>>,
14 id2symbol: HashMap<String, u32>,
16 price: HashMap<u32, (f64, f64)>,
18}
19
20impl PriceAlert {
21 pub fn new() -> Self {
22 Self {
23 alert_price: HashMap::new(),
24 price: HashMap::new(),
25 id2symbol: HashMap::new(),
26 }
27 }
28 pub fn get_price(&self, symbol_id: u32) -> Option<f64> {
29 self.price.get(&symbol_id).map(|(b, _)| *b)
30 }
31
32 pub fn on_price(&mut self, symbol_id: u32, price: (f64, f64)) -> Option<Vec<String>> {
33 let Some(alert_list) = self.alert_price.get_mut(&symbol_id) else {
34 return None;
35 };
36 let old_price = self.price.insert(symbol_id, price.clone()).unwrap_or(price);
37 let ids = alert_list
38 .iter()
39 .map(|(id, alertset)| match alertset {
40 AlertSet::High(p) => (id, *p <= old_price.0 || *p <= price.0),
41 AlertSet::Low(p) => (id, *p >= old_price.0 || *p >= price.0),
42 })
43 .filter(|(_, b)| *b)
44 .map(|(id, _)| id.clone())
45 .collect::<Vec<_>>();
46
47 ids.iter().for_each(|id| {
48 let _alertset = alert_list.remove(id);
49 self.id2symbol.remove(id);
50 });
51
52 if ids.is_empty() {
53 return None;
54 }
55 Some(ids)
56 }
57
58 pub fn modify_price(&mut self, alert_id: String, price: f64) -> Option<AlertSet> {
62 if let Some(symbol) = self.id2symbol.get(&alert_id) {
63 if let Some(cont) = self.alert_price.get_mut(&symbol) {
64 if let Some(alert) = cont.remove(&alert_id) {
65 let new_alert = match alert {
66 AlertSet::Low(_) => AlertSet::Low(price),
67 AlertSet::High(_) => AlertSet::High(price),
68 };
69 cont.insert(alert_id, new_alert.clone());
70 return Some(new_alert);
71 }
72 }
73 }
74 None
75 }
76
77 pub fn remove(&mut self, alert_id: String) -> Option<AlertSet> {
78 if let Some(symbol) = self.id2symbol.remove(&alert_id) {
79 if let Some(cont) = self.alert_price.get_mut(&symbol) {
80 return cont.remove(&alert_id);
81 }
82 }
83 None
84 }
85
86 pub fn set_alert(&mut self, symbol_id: u32, set: AlertSet, alert_id: Option<String>) -> String {
87 let alert_id = alert_id.unwrap_or(nanoid!(10));
90
91 self.id2symbol.insert(alert_id.clone(), symbol_id);
92 self.alert_price
93 .entry(symbol_id)
94 .or_insert(HashMap::new())
95 .insert(alert_id.clone(), set);
96
97 alert_id
98 }
99}