use std::{
collections::{BTreeMap, HashMap},
sync::{Arc, RwLock},
};
use crate::{
math::interpolation::interpolator::Interpolator,
rates::{
traits::{HasReferenceDate, YieldProvider},
yieldtermstructure::traits::YieldTermStructureTrait,
},
time::{date::Date, enums::TimeUnit, period::Period},
utils::errors::Result,
};
pub trait FixingProvider {
fn fixing(&self, date: Date) -> Result<f64>;
fn fixings(&self) -> &HashMap<Date, f64>;
fn add_fixing(&mut self, date: Date, rate: f64);
fn fill_missing_fixings(&mut self, interpolator: Interpolator) {
if !self.fixings().is_empty() {
let (first_date, last_date) =
match (self.fixings().keys().min(), self.fixings().keys().max()) {
(Some(first), Some(last)) => (*first, *last),
_ => return,
};
let aux_btreemap = self
.fixings()
.iter()
.map(|(k, v)| (*k, *v))
.collect::<BTreeMap<Date, f64>>();
let x: Vec<f64> = aux_btreemap
.keys()
.map(|&d| {
let days = i32::try_from(d - first_date)
.unwrap_or_else(|_| panic!("fixing day count should fit in i32"));
f64::from(days)
})
.collect::<Vec<f64>>();
let y = aux_btreemap.values().copied().collect::<Vec<f64>>();
let mut current_date = first_date;
while current_date <= last_date {
if !self.fixings().contains_key(¤t_date) {
let days = i32::try_from(current_date - first_date)
.unwrap_or_else(|_| panic!("fixing day count should fit in i32")); let days = f64::from(days);
let rate = interpolator.interpolate(days, &x, &y, false).unwrap(); self.add_fixing(current_date, rate);
}
current_date = current_date + Period::new(1, TimeUnit::Days);
}
}
}
}
pub trait AdvanceInterestRateIndexInTime {
fn advance_to_period(&self, period: Period) -> Result<Arc<RwLock<dyn InterestRateIndexTrait>>>;
fn advance_to_date(&self, date: Date) -> Result<Arc<RwLock<dyn InterestRateIndexTrait>>>;
}
pub trait HasTenor {
fn tenor(&self) -> Period;
}
pub trait HasTermStructure {
fn term_structure(&self) -> Result<Arc<dyn YieldTermStructureTrait>>;
}
pub trait HasName {
fn name(&self) -> Result<String>;
}
pub trait RelinkableTermStructure {
fn link_to(&mut self, term_structure: Arc<dyn YieldTermStructureTrait>);
}
pub trait InterestRateIndexTrait:
FixingProvider
+ YieldProvider
+ HasReferenceDate
+ AdvanceInterestRateIndexInTime
+ HasTermStructure
+ RelinkableTermStructure
+ HasTenor
+ HasName
+ Send
+ Sync
{
}