use std::cell::{Ref, RefMut};
use crate::{
ad::dual::DualFwd,
core::{marketdatahandling::constructedelementstore::SharedElement, pillars::Pillars},
indices::marketindex::MarketIndex,
math::interpolation::interpolator::Interpolator,
rates::yieldtermstructure::{
discounttermstructure::DiscountTermStructure,
interestratestermstructure::InterestRatesTermStructure,
},
time::daycounter::DayCounter,
utils::errors::{QSError, Result},
};
pub trait ADCurveElement:
InterestRatesTermStructure<DualFwd> + Pillars<DualFwd> + Send + Sync
{
fn ift_sensitivities(&self) -> Option<&[Vec<f64>]> {
None
}
}
#[derive(Clone)]
pub struct DiscountCurveElement {
market_index: MarketIndex,
curve: SharedElement<dyn ADCurveElement>,
}
impl DiscountCurveElement {
#[must_use]
pub const fn new(market_index: MarketIndex, curve: SharedElement<dyn ADCurveElement>) -> Self {
Self {
market_index,
curve,
}
}
#[must_use]
pub const fn market_index(&self) -> &MarketIndex {
&self.market_index
}
#[must_use]
pub fn curve(&self) -> Ref<'_, dyn ADCurveElement> {
self.curve.borrow()
}
pub fn to_f64_term_structure(
&self,
day_counter: DayCounter,
) -> Result<DiscountTermStructure<f64>> {
let curve = self.curve();
let nodes = curve
.nodes()
.ok_or_else(|| QSError::InvalidValueErr("Curve has no nodes".into()))?;
let (dates, dfs): (Vec<_>, Vec<f64>) =
nodes.into_iter().map(|(d, df)| (d, df.value())).unzip();
DiscountTermStructure::<f64>::new(dates, dfs, day_counter, Interpolator::LogLinear, true)
}
#[must_use]
pub fn curve_mut(&mut self) -> RefMut<'_, dyn ADCurveElement> {
self.curve.borrow_mut()
}
}
#[derive(Clone)]
pub struct DividendCurveElement {
market_index: MarketIndex,
curve: SharedElement<dyn ADCurveElement>,
}
impl DividendCurveElement {
#[must_use]
pub const fn new(market_index: MarketIndex, curve: SharedElement<dyn ADCurveElement>) -> Self {
Self {
market_index,
curve,
}
}
#[must_use]
pub const fn market_index(&self) -> &MarketIndex {
&self.market_index
}
#[must_use]
pub fn curve(&self) -> Ref<'_, dyn ADCurveElement> {
self.curve.borrow()
}
#[must_use]
pub fn curve_mut(&mut self) -> RefMut<'_, dyn ADCurveElement> {
self.curve.borrow_mut()
}
}
#[derive(Clone)]
pub struct CreditCurveElement {
market_index: MarketIndex,
recovery: f64,
curve: SharedElement<dyn ADCurveElement>,
}
impl CreditCurveElement {
#[must_use]
pub const fn new(
market_index: MarketIndex,
recovery: f64,
curve: SharedElement<dyn ADCurveElement>,
) -> Self {
Self {
market_index,
recovery,
curve,
}
}
#[must_use]
pub const fn market_index(&self) -> &MarketIndex {
&self.market_index
}
#[must_use]
pub const fn recovery(&self) -> f64 {
self.recovery
}
#[must_use]
pub fn curve(&self) -> Ref<'_, dyn ADCurveElement> {
self.curve.borrow()
}
#[must_use]
pub fn curve_mut(&mut self) -> RefMut<'_, dyn ADCurveElement> {
self.curve.borrow_mut()
}
}