surface_lib/
model_params.rs

1//! Model-specific parameter containers used to tweak calibrators without hard-coding
2//! constants in the model implementation. Each model should provide its own struct
3//! that implements the [`ModelParams`] trait so that the calibration pipeline can
4//! pass arbitrary parameters down to the calibrator in a type-erased fashion.
5
6use serde::{Deserialize, Serialize};
7use std::any::Any;
8
9/// Marker trait for type-erased parameter structs.
10///
11/// The trait is deliberately minimal: it only provides a safe down-casting hook
12/// via `as_any`.  This keeps the object safe and avoids imposing additional
13/// requirements on concrete parameter types.
14pub trait ModelParams: Send + Sync + std::fmt::Debug {
15    /// Returns the boxed value as `&dyn Any` so that callers can attempt a
16    /// concrete `downcast_ref::<T>()` when the concrete type is known.
17    fn as_any(&self) -> &dyn Any;
18}
19
20/// Parameters that influence the SVI calibrator.
21#[derive(Debug, Clone, Serialize, Deserialize)]
22pub struct SviModelParams {
23    /// Exponential weight multiplier for ATM options in the objective function.
24    ///
25    /// The weight applied to an observation is computed as `exp(-atm_boost_factor
26    /// * |k|)` where `k` is log-moneyness.  A higher value therefore increases
27    ///   the relative importance of points close to ATM.
28    pub atm_boost_factor: f64,
29
30    /// Whether to multiply the objective weight by option vega.  Setting this to
31    /// `false` makes every strike contribute equally (after ATM weighting).
32    pub use_vega_weighting: bool,
33}
34
35impl Default for SviModelParams {
36    fn default() -> Self {
37        Self {
38            atm_boost_factor: 25.0,
39            use_vega_weighting: true,
40        }
41    }
42}
43
44impl ModelParams for SviModelParams {
45    fn as_any(&self) -> &dyn Any {
46        self
47    }
48}