use std::fmt::Display;
use chrono::NaiveDate;
use crate::traits::FloatExt;
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum InterestRateOptionKind {
#[default]
Cap,
Floor,
}
impl Display for InterestRateOptionKind {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Cap => write!(f, "Cap"),
Self::Floor => write!(f, "Floor"),
}
}
}
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum SwaptionDirection {
#[default]
Payer,
Receiver,
}
impl Display for SwaptionDirection {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Payer => write!(f, "Payer"),
Self::Receiver => write!(f, "Receiver"),
}
}
}
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum VolatilityQuoteKind {
#[default]
Lognormal,
Normal,
}
impl Display for VolatilityQuoteKind {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Lognormal => write!(f, "Lognormal"),
Self::Normal => write!(f, "Normal"),
}
}
}
#[derive(Debug, Clone)]
pub struct CapFloorValuation<T: FloatExt> {
pub npv: T,
pub annuity: T,
pub caplet_prices: Vec<T>,
pub forward_rates: Vec<T>,
pub accrual_factors: Vec<T>,
}
#[derive(Debug, Clone)]
pub struct CollarValuation<T: FloatExt> {
pub npv: T,
pub cap: CapFloorValuation<T>,
pub floor: CapFloorValuation<T>,
}
#[derive(Debug, Clone)]
pub struct SwaptionValuation<T: FloatExt> {
pub npv: T,
pub forward_swap_rate: T,
pub annuity: T,
pub tau: T,
pub volatility: T,
pub volatility_quote: VolatilityQuoteKind,
}
#[derive(Debug, Clone)]
pub struct BermudanSwaptionValuation<T: FloatExt> {
pub npv: T,
pub exercise_count: usize,
}
#[derive(Debug, Clone)]
pub struct ExerciseSchedule {
pub levels: Vec<usize>,
}
impl ExerciseSchedule {
pub fn new(mut levels: Vec<usize>) -> Self {
levels.sort_unstable();
levels.dedup();
Self { levels }
}
pub fn contains(&self, level: usize) -> bool {
self.levels.binary_search(&level).is_ok()
}
}
#[derive(Debug, Clone)]
pub struct TreeCouponSchedule<T: FloatExt> {
pub levels: Vec<usize>,
pub accrual_factors: Vec<T>,
}
impl<T: FloatExt> TreeCouponSchedule<T> {
pub fn new(levels: Vec<usize>, accrual_factors: Vec<T>) -> Self {
assert_eq!(
levels.len(),
accrual_factors.len(),
"coupon levels and accrual factors must have the same length"
);
Self {
levels,
accrual_factors,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct ExerciseDate {
pub date: NaiveDate,
pub level: usize,
}