rustyqlib/equity/
equity_future.rs1use 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;
8pub 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 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 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}