Skip to main content

futu_cache/
risk_free_rate.rs

1//! Risk-free-rate snapshot cache for option probability calculations.
2//!
3//! C++ stores the raw backend value in `INNData_Qot_RiskFreeRate` and feeds
4//! `raw / NNData_10_9` directly into `ComboOptionBreakEven`.  Keep the same
5//! unit as an explicit `cpp_units` helper so public percent rendering cannot
6//! accidentally leak into the probability formula.
7
8use 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;