Skip to content

Commit 3188545

Browse files
committed
feat: add loss score to heston pricing
1 parent 66a38c4 commit 3188545

File tree

2 files changed

+41
-9
lines changed

2 files changed

+41
-9
lines changed

src/quant.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,3 +45,22 @@ impl Display for Moneyness {
4545
}
4646
}
4747
}
48+
49+
/// Calibration Loss scores
50+
#[derive(Default, Debug, Clone, Copy)]
51+
pub struct CalibrationLossScore {
52+
/// Mean Absolute Error
53+
pub mae: f64,
54+
/// Mean Squared Error
55+
pub mse: f64,
56+
/// Root Mean Squared Error
57+
pub rmse: f64,
58+
/// Mean Percentage Error
59+
pub mpe: f64,
60+
/// Mean Absolute Percentage Error
61+
pub mape: f64,
62+
/// Mean Squared Percentage Error
63+
pub mspe: f64,
64+
/// Root Mean Squared Percentage Error
65+
pub rmspe: f64,
66+
}

src/quant/calibration/heston.rs

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use crate::{
1010
quant::{
1111
pricing::heston::HestonPricer,
1212
r#trait::{CalibrationLossExt, PricerExt},
13-
OptionType,
13+
CalibrationLossScore, OptionType,
1414
},
1515
stats::mle::nmle_heston,
1616
};
@@ -50,10 +50,11 @@ impl From<DVector<f64>> for HestonParams {
5050
}
5151

5252
#[derive(Clone, Debug)]
53-
pub struct LmData {
53+
pub struct CalibrationHistory {
5454
pub residuals: DVector<f64>,
5555
pub call_put: DVector<(f64, f64)>,
5656
pub params: HestonParams,
57+
pub loss_scores: CalibrationLossScore,
5758
}
5859

5960
/// A calibrator.
@@ -76,15 +77,15 @@ pub struct HestonCalibrator {
7677
/// Option type
7778
pub option_type: OptionType,
7879
/// Levenberg-Marquardt algorithm residauls.
79-
calibration_history: RefCell<Vec<LmData>>,
80+
calibration_history: RefCell<Vec<CalibrationHistory>>,
8081
/// Derivate matrix.
8182
derivates: RefCell<Vec<Vec<f64>>>,
8283
}
8384

8485
impl CalibrationLossExt for HestonCalibrator {}
8586

8687
impl HestonCalibrator {
87-
pub fn calibrate(&self) -> Result<Vec<LmData>> {
88+
pub fn calibrate(&self) -> Result<Vec<CalibrationHistory>> {
8889
println!("Initial guess: {:?}", self.params);
8990

9091
let (result, ..) = LevenbergMarquardt::new().minimize(self.clone());
@@ -154,11 +155,23 @@ impl<'a> LeastSquaresProblem<f64, Dyn, Dyn> for HestonCalibrator {
154155
OptionType::Put => c_model[idx] = put,
155156
}
156157

157-
self.calibration_history.borrow_mut().push(LmData {
158-
residuals: c_model.clone() - self.c_market.clone(),
159-
call_put: vec![(call, put)].into(),
160-
params: self.params.clone().into(),
161-
});
158+
self
159+
.calibration_history
160+
.borrow_mut()
161+
.push(CalibrationHistory {
162+
residuals: c_model.clone() - self.c_market.clone(),
163+
call_put: vec![(call, put)].into(),
164+
params: self.params.clone().into(),
165+
loss_scores: CalibrationLossScore {
166+
mae: self.mae(&c_model, &self.c_market),
167+
mse: self.mse(&c_model, &self.c_market),
168+
rmse: self.rmse(&c_model, &self.c_market),
169+
mpe: self.mpe(&c_model, &self.c_market),
170+
mape: self.mape(&c_model, &self.c_market),
171+
mspe: self.mspe(&c_model, &self.c_market),
172+
rmspe: self.rmspe(&c_model, &self.c_market),
173+
},
174+
});
162175
derivates.push(pricer.derivatives());
163176
}
164177

0 commit comments

Comments
 (0)