Skip to main content

rustyqlib/equity/
equity_forward.rs

1use 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;
8///A forward contract is an agreement between two parties to buy or sell, as the case may be,
9/// a commodity (or financial instrument or currency or any other underlying)
10/// on a pre-determined future date at a price agreed when the contract is entered into.
11pub 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, //Forward price you actually locked in.
23    pub risk_free_rate: f64,
24    pub dividend_yield: f64,
25    /// Continuous stock borrow (repo) cost; part of the carry.
26    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 market_data = data.market_data.as_ref().unwrap();
35        //let future_date = NaiveDate::parse_from_str(&maturity_date, "%Y-%m-%d").expect("Invalid date format");
36        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        // e −r(T−t) (Ft −K),
90        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}