use serde::Deserialize;
use crate::equity::vanila_option::EquityOptionBase;
use std::str::FromStr;
use std::error::Error;
use crate::core::trade::{PutOrCall};
use std::fmt::Debug;
use crate::core::utils::ContractStyle;
#[derive(PartialEq,Clone,Debug)]
pub enum Engine{
BlackScholes,
MonteCarlo,
Binomial,
FiniteDifference
}
#[derive(Debug)]
pub enum LongShort{
LONG,
SHORT
}
#[derive(Deserialize, Debug, Clone, Copy, PartialEq, Eq)]
#[serde(rename_all = "snake_case")]
pub enum PayoffType {
Vanilla,
Binary,
Barrier,
Asian,
ForwardStart,
Autocallable,
}
impl FromStr for PayoffType {
type Err = Box<dyn Error>;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s.to_lowercase().as_str() {
"vanilla" => Ok(PayoffType::Vanilla),
"binary" => Ok(PayoffType::Binary),
"barrier" => Ok(PayoffType::Barrier),
"asian" => Ok(PayoffType::Asian),
"forward_start" | "forwardstart" => Ok(PayoffType::ForwardStart),
"autocallable" | "autocall" => Ok(PayoffType::Autocallable),
_ => Err("Invalid payoff type".into()),
}
}
}
pub trait Payoff: Debug + Send + Sync {
fn payoff(&self, spot: f64, strike: f64) -> f64;
fn path_payoff(&self, path: &[f64], strike: f64) -> f64 {
self.payoff(*path.last().expect("empty path"), strike)
}
fn is_path_dependent(&self) -> bool {
false
}
fn payoff_amount(&self, base: &EquityOptionBase) -> f64 {
self.payoff(base.underlying_price.value(), base.strike_price)
}
fn payoff_kind(&self) -> PayoffType;
fn put_or_call(&self) -> &PutOrCall;
fn exercise_style(&self)->&ContractStyle;
fn as_any(&self) -> &dyn std::any::Any;
}