rustyqlib/equity/binary_option.rs
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 = crate::equity::utils::PricingEngine::from_kind(Engine::BlackScholes);
118// }
119// "MonteCarlo" | "montecarlo" | "MC"|"mc" => {
120// option.engine = crate::equity::utils::PricingEngine::from_kind(Engine::MonteCarlo);
121// }
122// "Binomial" | "binomial"|"bino" => {
123// option.engine = crate::equity::utils::PricingEngine::from_kind(Engine::Binomial);
124// }
125// "FiniteDifference" | "finitdifference" |"FD" |"fd" => {
126// option.engine = crate::equity::utils::PricingEngine::from_kind(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//