mod constantoptionletvol;
mod cubicsmile;
mod optionletstripper;
mod optionletstripper1;
mod optionletstripper2;
pub use optionletstripper2::OptionletStripper2;
mod strippedoptionletadapter;
mod strippedoptionletbase;
pub use constantoptionletvol::ConstantOptionletVolatility;
pub use optionletstripper::{OptionletStripper, OptionletStripperCaches};
pub use optionletstripper1::{OptionletStripper1, OptionletStripperOptions};
pub use strippedoptionletadapter::StrippedOptionletAdapter;
pub use strippedoptionletbase::StrippedOptionletBase;
use crate::errors::QlResult;
use crate::termstructures::volatility::{VolatilityTermStructure, VolatilityType};
use crate::time::date::Date;
use crate::time::period::Period;
use crate::types::{Rate, Real, Time, Volatility};
pub trait OptionletVolatilityStructure: VolatilityTermStructure {
fn smile_section_impl(
&self,
_time: Time,
) -> QlResult<crate::shared::Shared<dyn super::SmileSection>> {
crate::fail!("smile sections are not implemented for this optionlet surface")
}
fn smile_section(
&self,
time: Time,
extrapolate: bool,
) -> QlResult<crate::shared::Shared<dyn super::SmileSection>> {
self.check_range_time(time, extrapolate)?;
self.smile_section_impl(time)
}
fn smile_section_date(
&self,
date: Date,
extrapolate: bool,
) -> QlResult<crate::shared::Shared<dyn super::SmileSection>> {
self.check_range_date(date, extrapolate)?;
self.smile_section_impl(self.time_from_reference(date)?)
}
fn smile_section_tenor(
&self,
tenor: Period,
extrapolate: bool,
) -> QlResult<crate::shared::Shared<dyn super::SmileSection>> {
self.smile_section_date(self.option_date_from_tenor(tenor)?, extrapolate)
}
fn volatility_impl(&self, option_time: Time, strike: Rate) -> QlResult<Volatility>;
fn volatility_type(&self) -> VolatilityType {
VolatilityType::ShiftedLognormal
}
fn displacement(&self) -> Real {
0.0
}
fn volatility_date(
&self,
option_date: Date,
strike: Rate,
extrapolate: bool,
) -> QlResult<Volatility> {
self.check_range_date(option_date, extrapolate)?;
self.check_strike(strike, extrapolate)?;
let t = self.time_from_reference(option_date)?;
self.volatility_impl(t, strike)
}
fn volatility(
&self,
option_time: Time,
strike: Rate,
extrapolate: bool,
) -> QlResult<Volatility> {
self.check_range_time(option_time, extrapolate)?;
self.check_strike(strike, extrapolate)?;
self.volatility_impl(option_time, strike)
}
fn volatility_tenor(
&self,
option_tenor: Period,
strike: Rate,
extrapolate: bool,
) -> QlResult<Volatility> {
let option_date = self.option_date_from_tenor(option_tenor)?;
self.volatility_date(option_date, strike, extrapolate)
}
fn black_variance_date(
&self,
option_date: Date,
strike: Rate,
extrapolate: bool,
) -> QlResult<Real> {
let v = self.volatility_date(option_date, strike, extrapolate)?;
let t = self.time_from_reference(option_date)?;
Ok(v * v * t)
}
fn black_variance(&self, option_time: Time, strike: Rate, extrapolate: bool) -> QlResult<Real> {
let v = self.volatility(option_time, strike, extrapolate)?;
Ok(v * v * option_time)
}
fn black_variance_tenor(
&self,
option_tenor: Period,
strike: Rate,
extrapolate: bool,
) -> QlResult<Real> {
let option_date = self.option_date_from_tenor(option_tenor)?;
self.black_variance_date(option_date, strike, extrapolate)
}
}