futu_cache/
risk_free_rate.rs1use parking_lot::RwLock;
9use std::sync::Arc;
10
11#[derive(Debug, Clone, Copy, PartialEq, Eq)]
12pub enum RiskFreeRateMarket {
13 Hk,
14 Us,
15 Jp,
16}
17
18#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
19pub struct RiskFreeRateSnapshot {
20 pub update_time: Option<i64>,
21 pub hk_rate_raw: Option<u64>,
22 pub us_rate_raw: Option<u64>,
23 pub jp_rate_raw: Option<u64>,
24}
25
26impl RiskFreeRateSnapshot {
27 #[must_use]
28 pub fn raw_for_market(self, market: RiskFreeRateMarket) -> Option<u64> {
29 match market {
30 RiskFreeRateMarket::Hk => self.hk_rate_raw,
31 RiskFreeRateMarket::Us => self.us_rate_raw,
32 RiskFreeRateMarket::Jp => self.jp_rate_raw,
33 }
34 }
35}
36
37#[derive(Debug, Default)]
38pub struct RiskFreeRateCache {
39 snapshot: RwLock<Option<RiskFreeRateSnapshot>>,
40}
41
42impl RiskFreeRateCache {
43 #[must_use]
44 pub fn new() -> Arc<Self> {
45 Arc::new(Self::default())
46 }
47
48 pub fn set_snapshot(&self, snapshot: RiskFreeRateSnapshot) {
49 *self.snapshot.write() = Some(snapshot);
50 }
51
52 #[must_use]
53 pub fn snapshot(&self) -> Option<RiskFreeRateSnapshot> {
54 *self.snapshot.read()
55 }
56
57 #[must_use]
58 pub fn rate_cpp_units(&self, market: RiskFreeRateMarket) -> Option<f64> {
59 let raw = self.snapshot()?.raw_for_market(market)?;
60 Some(rate_raw_to_cpp_units(raw))
61 }
62}
63
64#[must_use]
65pub fn rate_raw_to_cpp_units(raw: u64) -> f64 {
66 raw as f64 / 1e9_f64
67}
68
69#[must_use]
70pub fn rate_raw_to_percent(raw: u64) -> f64 {
71 rate_raw_to_cpp_units(raw) * 100.0
72}
73
74#[cfg(test)]
75mod tests;