|
| 1 | +// use std::fmt::Binary; |
| 2 | +// use chrono::{Datelike, Local, NaiveDate}; |
| 3 | +// use crate::equity::{binomial,finite_difference,montecarlo}; |
| 4 | +// use super::super::core::termstructure::YieldTermStructure; |
| 5 | +// use super::super::core::quotes::Quote; |
| 6 | +// use super::super::core::traits::{Instrument,Greeks}; |
| 7 | +// use super::blackscholes; |
| 8 | +// use crate::equity::utils::{Engine}; |
| 9 | +// use crate::core::trade::{OptionType,Transection}; |
| 10 | +// use crate::core::utils::{Contract,ContractStyle}; |
| 11 | +// use crate::core::trade; |
| 12 | +// impl Instrument for BinaryOption { |
| 13 | +// fn npv(&self) -> f64 { |
| 14 | +// match self.engine{ |
| 15 | +// Engine::BlackScholes => { |
| 16 | +// let value = blackscholes::npv(&self); |
| 17 | +// value |
| 18 | +// } |
| 19 | +// Engine::MonteCarlo => { |
| 20 | +// |
| 21 | +// let value = montecarlo::npv(&self,false); |
| 22 | +// value |
| 23 | +// } |
| 24 | +// Engine::Binomial => { |
| 25 | +// |
| 26 | +// let value = binomial::npv(&self); |
| 27 | +// value |
| 28 | +// } |
| 29 | +// Engine::FiniteDifference => { |
| 30 | +// let value = finite_difference::npv(&self); |
| 31 | +// value |
| 32 | +// } |
| 33 | +// |
| 34 | +// } |
| 35 | +// } |
| 36 | +// } |
| 37 | +// /// This struct represents a real world equity option contract |
| 38 | +// #[derive(Debug)] |
| 39 | +// pub struct BinaryOption { |
| 40 | +// pub option_type: OptionType, |
| 41 | +// pub payoff_type: String, |
| 42 | +// pub binary_type: String, |
| 43 | +// pub transection: Transection, |
| 44 | +// pub underlying_price: Quote, |
| 45 | +// pub current_price: Quote, |
| 46 | +// pub strike_price: f64, |
| 47 | +// pub dividend_yield: f64, |
| 48 | +// pub volatility: f64, |
| 49 | +// pub maturity_date: NaiveDate, |
| 50 | +// pub valuation_date: NaiveDate, |
| 51 | +// pub term_structure: YieldTermStructure<f64>, |
| 52 | +// pub risk_free_rate: f64, |
| 53 | +// pub transection_price: f64, |
| 54 | +// pub engine: Engine, |
| 55 | +// pub simulation:Option<u64>, |
| 56 | +// pub style: ContractStyle, |
| 57 | +// } |
| 58 | +// impl BinaryOption{ |
| 59 | +// pub fn time_to_maturity(&self) -> f64{ |
| 60 | +// let time_to_maturity = (self.maturity_date - self.valuation_date).num_days() as f64/365.0; |
| 61 | +// time_to_maturity |
| 62 | +// } |
| 63 | +// } |
| 64 | +// impl BinaryOption { |
| 65 | +// pub fn from_json(data: &Contract) -> Box<BinaryOption> { |
| 66 | +// let market_data = data.market_data.as_ref().unwrap(); |
| 67 | +// let underlying_quote = Quote::new(market_data.underlying_price); |
| 68 | +// //TODO: Add term structure |
| 69 | +// let date = vec![0.01, 0.02, 0.05, 0.1, 0.5, 1.0, 2.0, 3.0]; |
| 70 | +// let rates = vec![0.05,0.05,0.05,0.05,0.05,0.05,0.05,0.05]; |
| 71 | +// let ts = YieldTermStructure::new(date, rates); |
| 72 | +// let option_type = &market_data.option_type; |
| 73 | +// let side: OptionType; |
| 74 | +// match option_type.trim() { |
| 75 | +// "C" | "c" | "Call" | "call" => side = OptionType::Call, |
| 76 | +// "P" | "p" | "Put" | "put" => side = OptionType::Put, |
| 77 | +// _ => panic!("Invalide side argument! Side has to be either 'C' or 'P'."), |
| 78 | +// } |
| 79 | +// let maturity_date = &market_data.maturity; |
| 80 | +// let today = Local::today(); |
| 81 | +// let future_date = NaiveDate::parse_from_str(&maturity_date, "%Y-%m-%d").expect("Invalid date format"); |
| 82 | +// |
| 83 | +// let risk_free_rate = Some(market_data.risk_free_rate).unwrap(); |
| 84 | +// let dividend = Some(market_data.dividend).unwrap(); |
| 85 | +// //let mut op = 0.0; |
| 86 | +// |
| 87 | +// let option_price = Quote::new(match market_data.option_price { |
| 88 | +// Some(x) => x, |
| 89 | +// None => 0.0, |
| 90 | +// }); |
| 91 | +// //let volatility = Some(market_data.volatility); |
| 92 | +// let volatility = match market_data.volatility { |
| 93 | +// Some(x) => { |
| 94 | +// x |
| 95 | +// } |
| 96 | +// None => 0.2 |
| 97 | +// }; |
| 98 | +// let mut option = BinaryOption { |
| 99 | +// option_type: side, |
| 100 | +// transection: Transection::Buy, |
| 101 | +// underlying_price: underlying_quote, |
| 102 | +// current_price: option_price, |
| 103 | +// strike_price: market_data.strike_price, |
| 104 | +// volatility: volatility, |
| 105 | +// maturity_date: future_date, |
| 106 | +// risk_free_rate: risk_free_rate.unwrap_or(0.0), |
| 107 | +// dividend_yield: dividend.unwrap_or(0.0), |
| 108 | +// transection_price: 0.0, |
| 109 | +// term_structure: ts, |
| 110 | +// engine: Engine::BlackScholes, |
| 111 | +// simulation: None, |
| 112 | +// style: ContractStyle::European, |
| 113 | +// valuation_date: today.naive_utc(), |
| 114 | +// }; |
| 115 | +// match data.pricer.trim() { |
| 116 | +// "Analytical" | "analytical"|"bs" => { |
| 117 | +// option.engine = Engine::BlackScholes; |
| 118 | +// } |
| 119 | +// "MonteCarlo" | "montecarlo" | "MC"|"mc" => { |
| 120 | +// option.engine = Engine::MonteCarlo; |
| 121 | +// } |
| 122 | +// "Binomial" | "binomial"|"bino" => { |
| 123 | +// option.engine = Engine::Binomial; |
| 124 | +// } |
| 125 | +// "FiniteDifference" | "finitdifference" |"FD" |"fd" => { |
| 126 | +// option.engine = Engine::FiniteDifference; |
| 127 | +// } |
| 128 | +// _ => { |
| 129 | +// panic!("Invalid pricer"); |
| 130 | +// } |
| 131 | +// } |
| 132 | +// match data.style.as_ref().unwrap_or(&"European".to_string()).trim() { |
| 133 | +// "European" | "european" => { |
| 134 | +// option.style = ContractStyle::European; |
| 135 | +// } |
| 136 | +// "American" | "american" => { |
| 137 | +// option.style = ContractStyle::American; |
| 138 | +// } |
| 139 | +// _ => { |
| 140 | +// option.style = ContractStyle::European; |
| 141 | +// } |
| 142 | +// } |
| 143 | +// option.set_risk_free_rate(); |
| 144 | +// return Box::new(option); |
| 145 | +// } |
| 146 | +// } |
| 147 | +// |
| 148 | +// #[cfg(test)] |
| 149 | +// mod tests { |
| 150 | +// //write a unit test for from_json |
| 151 | +// use super::*; |
| 152 | +// use crate::core::utils::{Contract,MarketData}; |
| 153 | +// use crate::core::trade::OptionType; |
| 154 | +// use crate::core::trade::Transection; |
| 155 | +// use crate::core::utils::ContractStyle; |
| 156 | +// use crate::core::termstructure::YieldTermStructure; |
| 157 | +// use crate::core::quotes::Quote; |
| 158 | +// use chrono::{Datelike, Local, NaiveDate}; |
| 159 | +// #[test] |
| 160 | +// fn test_from_json() { |
| 161 | +// let data = Contract { |
| 162 | +// action: "PV".to_string(), |
| 163 | +// market_data: Some(MarketData { |
| 164 | +// underlying_price: 100.0, |
| 165 | +// strike_price: 100.0, |
| 166 | +// volatility: None, |
| 167 | +// option_price: Some(10.0), |
| 168 | +// risk_free_rate: Some(0.05), |
| 169 | +// dividend: Some(0.0), |
| 170 | +// maturity: "2024-01-01".to_string(), |
| 171 | +// option_type: "C".to_string(), |
| 172 | +// simulation: None |
| 173 | +// }), |
| 174 | +// pricer: "Analytical".to_string(), |
| 175 | +// asset: "".to_string(), |
| 176 | +// style: Some("European".to_string()), |
| 177 | +// rate_data: None |
| 178 | +// }; |
| 179 | +// let option = BinaryOption::from_json(&data); |
| 180 | +// assert_eq!(option.option_type, OptionType::Call); |
| 181 | +// assert_eq!(option.transection, Transection::Buy); |
| 182 | +// assert_eq!(option.underlying_price.value, 100.0); |
| 183 | +// assert_eq!(option.strike_price, 100.0); |
| 184 | +// assert_eq!(option.current_price.value, 10.0); |
| 185 | +// assert_eq!(option.dividend_yield, 0.0); |
| 186 | +// assert_eq!(option.volatility, 0.2); |
| 187 | +// assert_eq!(option.maturity_date, NaiveDate::from_ymd(2024, 1, 1)); |
| 188 | +// assert_eq!(option.valuation_date, Local::today().naive_utc()); |
| 189 | +// assert_eq!(option.engine, Engine::BlackScholes); |
| 190 | +// assert_eq!(option.style, ContractStyle::European); |
| 191 | +// } |
| 192 | +// } |
| 193 | +// |
0 commit comments