Skip to main content

rustyqlib/equity/
equity_future.rs

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