rustyqlib/equity/
equity_forward.rs1use chrono::{Local, NaiveDate};
2use crate::core::data_models::EquityForwardData;
3use crate::core::quotes::Quote;
4use crate::core::traits::Instrument;
5use crate::core::utils::Contract;
6use crate::equity::equity_future::EquityFuture;
7use crate::equity::utils::LongShort;
8pub struct EquityForward {
12
13 pub symbol: String,
14 pub currency: Option<String>,
15 pub exchange: Option<String>,
16 pub name: Option<String>,
17 pub cusip: Option<String>,
18 pub isin: Option<String>,
19 pub settlement_type: Option<String>,
20
21 pub underlying_price: Quote,
22 pub forward_price: Quote, pub risk_free_rate: f64,
24 pub dividend_yield: f64,
25 pub borrow_cost: f64,
27 pub maturity_date: NaiveDate,
28 pub valuation_date: NaiveDate,
29 pub long_short:LongShort,
30 pub notional:f64
31}
32impl EquityForward {
33 pub fn from_json(data: &EquityForwardData) -> Box<Self> {
34 let today = Local::now().date_naive();
37 let maturity_date = NaiveDate::parse_from_str(&data.maturity, "%Y-%m-%d")
38 .expect("Invalid maturity date");
39
40 let underlying_price = Quote::new(data.base.underlying_price);
41 let quote = Some(data.entry_price).unwrap();
42 let entry_quote = Quote::new(quote.unwrap_or(0.0));
43 let risk_free_rate = data.base.risk_free_rate.unwrap_or(0.0);
44 let dividend = data.dividend.unwrap_or(0.0);
45 let long_short = data.base.long_short.unwrap_or(1);
46 let position = match long_short{
47 1=>LongShort::LONG,
48 -1=>LongShort::SHORT,
49 _=>LongShort::LONG,
50 };
51 Box::new(Self {
52 symbol:data.base.symbol.clone(),
53 currency: data.base.currency.clone(),
54 exchange:data.base.exchange.clone(),
55 name: data.base.name.clone(),
56 cusip: data.base.cusip.clone(),
57 isin: data.base.isin.clone(),
58 settlement_type: data.base.settlement_type.clone(),
59
60
61 underlying_price: underlying_price,
62 forward_price:entry_quote,
63 risk_free_rate: risk_free_rate,
64 dividend_yield: dividend,
65 borrow_cost: data.base.borrow_cost.unwrap_or(0.0),
66 maturity_date: maturity_date,
67 valuation_date: today,
68 notional:data.notional.unwrap_or(1.0),
69 long_short:position
70 })
71 }
72
73 fn time_to_maturity(&self) -> f64 {
74 let days = (self.maturity_date - self.valuation_date).num_days();
75 (days as f64) / 365.0
76 }
77 fn premiun(&self)->f64{
78 self.forward()-self.underlying_price.value()
79 }
80 fn forward(&self)->f64{
81 let discount_df = 1.0/(self.risk_free_rate*self.time_to_maturity()).exp();
82 let dividend_df = 1.0/((self.dividend_yield + self.borrow_cost)*self.time_to_maturity()).exp();
83 let forward = self.underlying_price.value()*dividend_df/discount_df;
84 forward
85 }
86}
87impl Instrument for EquityForward {
88 fn npv(&self) -> f64 {
89 let df_r = 1.0/(self.risk_free_rate*self.time_to_maturity()).exp();
91 let share = self.notional/self.forward_price.value();
92 match self.long_short{
93 LongShort::LONG => (self.forward()-self.forward_price.value()) * share *df_r,
94 LongShort::SHORT => -(self.forward()-self.forward_price.value()) * share *df_r,
95 }
96
97 }
98}
99
100impl EquityForward{
101 pub fn delta(&self) -> f64 { 1.0 }
102 pub fn gamma(&self) -> f64 { 0.0 }
103 pub fn vega(&self) -> f64 { 0.0 }
104 pub fn theta(&self) -> f64 { 0.0 }
105 pub fn rho(&self) -> f64 { 0.0 }
106}