use crate::OptionType;
pub trait PricerExt: super::time::TimeExt {
fn calculate_call_put(&self) -> (f64, f64);
fn calculate_price(&self) -> f64;
fn implied_volatility(&self, _c_price: f64, _option_type: OptionType) -> f64 {
f64::NAN
}
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct Greeks {
pub delta: f64,
pub gamma: f64,
pub vega: f64,
pub theta: f64,
pub rho: f64,
pub vanna: f64,
pub charm: f64,
pub volga: f64,
pub veta: f64,
}
impl Default for Greeks {
fn default() -> Self {
Self::nan()
}
}
impl Greeks {
pub const fn nan() -> Self {
Self {
delta: f64::NAN,
gamma: f64::NAN,
vega: f64::NAN,
theta: f64::NAN,
rho: f64::NAN,
vanna: f64::NAN,
charm: f64::NAN,
volga: f64::NAN,
veta: f64::NAN,
}
}
}
pub trait ModelPricer {
fn price_call(&self, s: f64, k: f64, r: f64, q: f64, tau: f64) -> f64;
fn price_put(&self, s: f64, k: f64, r: f64, q: f64, tau: f64) -> f64 {
let call = self.price_call(s, k, r, q, tau);
call - s * (-q * tau).exp() + k * (-r * tau).exp()
}
fn price_option(&self, s: f64, k: f64, r: f64, q: f64, tau: f64, option_type: OptionType) -> f64 {
match option_type {
OptionType::Call => self.price_call(s, k, r, q, tau),
OptionType::Put => self.price_put(s, k, r, q, tau),
}
}
}
pub trait GreeksExt {
fn delta(&self) -> f64;
fn gamma(&self) -> f64 {
f64::NAN
}
fn vega(&self) -> f64 {
f64::NAN
}
fn theta(&self) -> f64 {
f64::NAN
}
fn rho(&self) -> f64 {
f64::NAN
}
fn vanna(&self) -> f64 {
f64::NAN
}
fn charm(&self) -> f64 {
f64::NAN
}
fn volga(&self) -> f64 {
f64::NAN
}
fn veta(&self) -> f64 {
f64::NAN
}
fn greeks(&self) -> Greeks {
Greeks {
delta: self.delta(),
gamma: self.gamma(),
vega: self.vega(),
theta: self.theta(),
rho: self.rho(),
vanna: self.vanna(),
charm: self.charm(),
volga: self.volga(),
veta: self.veta(),
}
}
}