Skip to main content

hypercall_vol_oracle/
fixed_oracle.rs

1use std::collections::HashSet;
2
3use crate::{RiskVolOracle, VolLookupError, VolOracleStatus, VolProviderKind};
4
5const DEFAULT_TEST_UNDERLYINGS: [&str; 4] = ["BTC", "ETH", "US500", "USOIL"];
6
7/// Deterministic fixed-vol oracle used only by testnet-only startup paths and tests.
8pub struct FixedTestRiskVolOracle {
9    fixed_vol: f64,
10    underlyings: HashSet<String>,
11}
12
13impl FixedTestRiskVolOracle {
14    pub fn new(fixed_vol: f64) -> Self {
15        Self::with_underlyings(
16            fixed_vol,
17            DEFAULT_TEST_UNDERLYINGS
18                .into_iter()
19                .map(str::to_string)
20                .collect(),
21        )
22    }
23
24    pub fn with_underlyings(fixed_vol: f64, underlyings: Vec<String>) -> Self {
25        Self {
26            fixed_vol,
27            underlyings: underlyings.into_iter().collect(),
28        }
29    }
30}
31
32impl RiskVolOracle for FixedTestRiskVolOracle {
33    fn get_iv(
34        &self,
35        underlying: &str,
36        _strike: f64,
37        _expiry_ts: i64,
38    ) -> Result<f64, VolLookupError> {
39        self.underlyings
40            .contains(underlying)
41            .then_some(self.fixed_vol)
42            .ok_or_else(|| VolLookupError::UnsupportedUnderlying {
43                underlying: underlying.to_string(),
44            })
45    }
46
47    fn statuses(&self) -> Vec<VolOracleStatus> {
48        let mut underlyings = self.underlyings.iter().cloned().collect::<Vec<_>>();
49        underlyings.sort();
50        underlyings
51            .into_iter()
52            .map(|underlying| VolOracleStatus {
53                underlying,
54                provider: VolProviderKind::Fixed,
55                route_facing: true,
56                connected: true,
57                ready: true,
58                last_update_ts_ms: None,
59                staleness_seconds: None,
60                staleness_threshold_seconds: None,
61                surface_points: 1,
62                messages_received: 0,
63                last_error: None,
64            })
65            .collect()
66    }
67}