use crate::OptionType;
use crate::traits::Instrument;
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct EuropeanOption {
pub strike: f64,
pub option_type: OptionType,
pub tau: Option<f64>,
pub eval: Option<chrono::NaiveDate>,
pub expiry: Option<chrono::NaiveDate>,
}
impl EuropeanOption {
pub const fn new_tau(strike: f64, option_type: OptionType, tau: f64) -> Self {
Self {
strike,
option_type,
tau: Some(tau),
eval: None,
expiry: None,
}
}
pub const fn new_dates(
strike: f64,
option_type: OptionType,
eval: chrono::NaiveDate,
expiry: chrono::NaiveDate,
) -> Self {
Self {
strike,
option_type,
tau: None,
eval: Some(eval),
expiry: Some(expiry),
}
}
}
impl Instrument for EuropeanOption {
fn instrument_kind(&self) -> &'static str {
match self.option_type {
OptionType::Call => "EuropeanCall",
OptionType::Put => "EuropeanPut",
}
}
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct DigitalOption {
pub strike: f64,
pub option_type: OptionType,
pub kind: DigitalKind,
pub tau: Option<f64>,
pub eval: Option<chrono::NaiveDate>,
pub expiry: Option<chrono::NaiveDate>,
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum DigitalKind {
CashOrNothing { cash: f64 },
AssetOrNothing,
}
impl DigitalOption {
pub const fn cash_or_nothing(strike: f64, option_type: OptionType, cash: f64, tau: f64) -> Self {
Self {
strike,
option_type,
kind: DigitalKind::CashOrNothing { cash },
tau: Some(tau),
eval: None,
expiry: None,
}
}
pub const fn asset_or_nothing(strike: f64, option_type: OptionType, tau: f64) -> Self {
Self {
strike,
option_type,
kind: DigitalKind::AssetOrNothing,
tau: Some(tau),
eval: None,
expiry: None,
}
}
}
impl Instrument for DigitalOption {
fn instrument_kind(&self) -> &'static str {
"DigitalOption"
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn european_option_kind() {
let call = EuropeanOption::new_tau(100.0, OptionType::Call, 0.5);
let put = EuropeanOption::new_tau(100.0, OptionType::Put, 0.5);
assert_eq!(call.instrument_kind(), "EuropeanCall");
assert_eq!(put.instrument_kind(), "EuropeanPut");
}
#[test]
fn digital_option_kind() {
let opt = DigitalOption::cash_or_nothing(100.0, OptionType::Call, 1.0, 0.5);
assert_eq!(opt.instrument_kind(), "DigitalOption");
}
}