use chrono::NaiveDate;
use crate::calendar::DayCountConvention;
use crate::cashflows::Cashflow;
use crate::cashflows::CurveProvider;
use crate::cashflows::Leg;
use crate::traits::FloatExt;
pub(crate) fn fixed_leg_bpv_annuity<T: FloatExt>(
leg: &Leg<T>,
valuation_date: NaiveDate,
discount_day_count: DayCountConvention,
curves: &(impl CurveProvider<T> + ?Sized),
) -> T {
leg
.cashflows()
.iter()
.map(|cashflow| match cashflow {
Cashflow::Fixed(coupon) if coupon.period.payment_date >= valuation_date => {
let tau = discount_day_count.year_fraction(valuation_date, coupon.period.payment_date);
let df = curves.discount_curve().discount_factor(tau);
df * coupon.notional * coupon.period.accrual_factor
}
_ => T::zero(),
})
.fold(T::zero(), |acc, value| acc + value)
}
pub(crate) fn floating_leg_spread_annuity<T: FloatExt>(
leg: &Leg<T>,
valuation_date: NaiveDate,
discount_day_count: DayCountConvention,
curves: &(impl CurveProvider<T> + ?Sized),
) -> T {
leg
.cashflows()
.iter()
.map(|cashflow| match cashflow {
Cashflow::Floating(coupon) if coupon.period.payment_date >= valuation_date => {
let tau = discount_day_count.year_fraction(valuation_date, coupon.period.payment_date);
let df = curves.discount_curve().discount_factor(tau);
df * coupon.notional * coupon.period.accrual_factor
}
_ => T::zero(),
})
.fold(T::zero(), |acc, value| acc + value)
}