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}