surface_lib/calibration/
types.rs

1use serde::{Deserialize, Serialize};
2// Note: HashMap removed as param_map is no longer used
3use crate::calibration::config::OptimizationConfig;
4use std::any::Any;
5
6/// Minimal market data structure with only essential fields for surface calibration
7#[derive(Debug, Clone)]
8pub struct MarketDataRow {
9    /// Option type: "call" or "put"
10    pub option_type: String,
11    /// Strike price
12    pub strike_price: f64,
13    /// Underlying asset price
14    pub underlying_price: f64,
15    /// Time to expiration in years
16    pub years_to_exp: f64,
17    /// Market implied volatility (as decimal, e.g., 0.25 for 25%)
18    pub market_iv: f64,
19    /// Option vega (for weighting)
20    pub vega: f64,
21    /// Expiration timestamp (for grouping by expiry)
22    pub expiration: i64,
23}
24
25/// Fixed parameters that are not calibrated by the optimizer
26#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
27pub struct FixedParameters {
28    pub r: f64,
29    pub q: f64,
30}
31
32impl Default for FixedParameters {
33    fn default() -> Self {
34        Self { r: 0.02, q: 0.0 }
35    }
36}
37
38/// Model calibrator trait for parameter optimization
39pub trait ModelCalibrator: Send + Sync {
40    /// Returns the name of the model (e.g., "svi")
41    fn model_name(&self) -> &str;
42
43    /// How many parameters are in the model's optimization vector
44    fn param_count(&self) -> usize;
45
46    /// Returns the vector of (min, max) bounds for each parameter
47    fn param_bounds(&self) -> &[(f64, f64)];
48
49    /// Given a parameter vector `x` and data, returns the objective value
50    fn evaluate_objective(&self, x: &[f64], data: &[MarketDataRow]) -> f64;
51
52    // Note: relaxed_param_bounds and relaxed_evaluate_objective removed
53    // as they were redundant with param_bounds and evaluate_objective
54
55    // Note: create_param_map removed as param_map is no longer returned from calibration API
56
57    /// Price options using the calibrated parameters
58    fn price_options(
59        &self,
60        market_data: &[MarketDataRow],
61        best_params: &[f64],
62        config: &OptimizationConfig,
63    ) -> Vec<PricingResult>;
64
65    /// Returns parameter names in the order they appear in the optimization vector
66    fn param_names(&self) -> Vec<&str>;
67
68    /// Set the previous solution for temporal regularization
69    fn set_prev_solution(&mut self, _prev_solution: Vec<f64>) {
70        // Default implementation does nothing
71    }
72
73    /// Set the lambda parameter for temporal regularization
74    fn set_temporal_reg_lambda(&mut self, _lambda: f64) {
75        // Default implementation does nothing
76    }
77
78    /// Expand internal parameter bounds if parameters are near current bounds.
79    /// Returns true if any bound was adjusted.
80    fn expand_bounds_if_needed(
81        &mut self,
82        _params: &[f64],
83        _proximity_threshold: f64,
84        _expansion_factor: f64,
85    ) -> bool {
86        false
87    }
88
89    /// Support for downcasting
90    fn as_any(&self) -> &dyn Any;
91}
92
93/// Lightweight struct to hold the essential pricing results for each option
94#[derive(Debug, Clone)]
95pub struct PricingResult {
96    /// Option type: "call" or "put"
97    pub option_type: String,
98    /// Strike price
99    pub strike_price: f64,
100    /// Underlying asset price
101    pub underlying_price: f64,
102    /// Time to expiration in years
103    pub years_to_exp: f64,
104    /// Model option price
105    pub model_price: f64,
106    /// Model implied volatility (as decimal)
107    pub model_iv: f64,
108}