Skip to main content

rustyqlib/rates/
deposits.rs

1use chrono::{Local, NaiveDate};
2use crate::core::traits::Rates;
3use crate::rates::utils::{DayCountConvention,TermStructure};
4/*
5"" An deposit is an agreement to borrow money interbank at the Ibor fixing rate starting on the start
6    date and repaid on the maturity date with the interest amount calculated according to a day
7    count convention and dates calculated according to a calendar and business day adjustment rule.
8 */
9pub struct Deposit {
10    pub start_date: NaiveDate,
11    pub maturity_date: NaiveDate,
12    pub valuation_date: NaiveDate,
13    pub notional: f64,
14    pub fix_rate: f64,
15    pub day_count: DayCountConvention,
16    pub business_day_adjustment: i8,
17    pub term_structure: Option<TermStructure>,
18}
19impl Deposit {
20    pub fn new(start_date: NaiveDate, maturity_date: NaiveDate, valuation_date: NaiveDate,
21               notional: f64, fix_rate: f64, day_count: DayCountConvention,
22               business_day_adjustment: i8) -> Deposit {
23        Deposit {
24            start_date,
25            maturity_date,
26            valuation_date,
27            notional,
28            fix_rate,
29            day_count,
30            business_day_adjustment,
31            term_structure: None,
32        }
33    }
34    pub fn builder(start_date: String,maturity_date:String,_notional: f64, _fix_rate: f64,day_count: String) ->Deposit{
35
36        let today = Local::now().date_naive();
37        let start_date = NaiveDate::parse_from_str(&start_date, "%Y-%m-%d").expect("Invalid date format");
38        let maturity_date = NaiveDate::parse_from_str(&maturity_date, "%Y-%m-%d").expect("Invalid date format");
39        let mut deposit = Deposit {
40            start_date: start_date,
41            maturity_date: maturity_date,
42            valuation_date: today,
43            notional: 1000000.0,
44            fix_rate: 0.05,
45            day_count: DayCountConvention::Act360,
46            business_day_adjustment: 0,
47            term_structure: None,
48        };
49        match day_count.as_str() {
50            "Act360" |"A360" => {
51                deposit.day_count = DayCountConvention::Act360;
52            }
53            "Act365" |"A365" => {
54                deposit.day_count = DayCountConvention::Act365;
55            }
56            "Thirty360" |"30/360" => {
57                deposit.day_count = DayCountConvention::Thirty360;
58            }
59            _ => {}
60        }
61        return deposit;
62    }
63    pub fn get_start_date(&self) -> NaiveDate {
64        self.start_date
65    }
66
67    pub fn get_notional(&self) -> f64 {
68        self.notional
69    }
70    pub fn get_rate(&self) -> f64 {
71        let df = self.get_discount_factor();
72        let year_fraction = self.get_year_fraction(self.start_date);
73        -df.ln() / year_fraction
74    }
75    pub fn get_business_day_adjustment(&self) -> i8 {
76        self.business_day_adjustment
77    }
78    pub fn get_year_fraction(&self,date:NaiveDate) -> f64 {
79        let duration = self.maturity_date.signed_duration_since(date);
80        let year_fraction = duration.num_days() as f64 / self.day_count.num_of_days() as f64;
81        year_fraction
82    }
83    pub fn get_discount_factor(&self) -> f64 {
84        let year_fraction = self.get_year_fraction(self.start_date);
85        let discount_factor = 1.0 / (1.0 + self.fix_rate * year_fraction);
86        discount_factor
87    }
88    pub fn get_remaining_interest_amount(&self) -> f64 {
89        let year_fraction = self.get_year_fraction(self.valuation_date);
90        let interest_amount = self.notional * self.fix_rate * year_fraction;
91        interest_amount
92    }
93    pub fn get_value(&self) -> f64 {
94        //let discount_factor = self.get_discount_factor();
95        //
96        //let pv = self.notional * discount_factor + interest_amount;
97        let value = (1.0 + self.fix_rate * self.get_year_fraction(self.start_date)) * self.notional;
98        value
99    }
100
101    pub fn get_pv(&self,curve:&TermStructure) -> f64 {
102        let df = curve.interpolate_log_linear(self.valuation_date,self.maturity_date);
103        let value = self.get_value() * df;
104        return value;
105    }
106}
107impl Rates for Deposit{
108    fn get_implied_rates(&self) -> f64 {
109        let curve = self.term_structure.as_ref().expect("Term structure is not set");
110        let df = curve.interpolate_log_linear(self.valuation_date,self.maturity_date);
111        let implied_rate = (1.0/df - 1.0)/self.get_year_fraction(self.valuation_date);
112        return implied_rate;
113    }
114    fn get_maturity_date(&self) -> NaiveDate {
115        self.maturity_date
116    }
117    fn get_rate(&self) -> f64 {
118        self.fix_rate
119    }
120    fn get_maturity_discount_factor(&self) -> f64 {
121        self.get_discount_factor()
122    }
123    fn get_day_count(&self) -> &DayCountConvention {
124        &self.day_count
125    }
126    fn set_term_structure(&mut self,term_structure:TermStructure) {
127        self.term_structure = Some(term_structure);
128    }
129}
130// impl Instrument for Deposit {
131//     fn npv(&self) -> f64 {
132//         self.get_pv()
133//     }
134// }