use crate::time::businessdayconvention::BusinessDayConvention;
use crate::time::calendars::unitedkingdom::UnitedKingdomMarket;
use crate::time::calendars::unitedstates::UnitedStatesMarket;
use crate::time::calendars::{Austria, Calendar, Target, UnitedKingdom, UnitedStates};
use crate::time::daycounters::DayCounters;
use crate::time::daycounters::actual360::Actual360;
use crate::time::daycounters::actual365fixed::Actual365Fixed;
use crate::time::period::Period;
use iso_currency::Currency;
use iso_currency::Currency::{AUD, EUR, GBP, USD};
use serde::{Deserialize, Serialize};
#[allow(clippy::upper_case_acronyms)]
#[derive(Deserialize, Serialize, PartialEq, Debug)]
pub enum InterestRateIndexEnum {
AONIA,
CDOR(Period),
EONIA,
ESTR,
EUIBOR(Period),
SONIA,
SOFR,
}
#[derive(Deserialize, Serialize, Debug)]
pub struct InterestRateIndex {
pub period: Period,
pub settlement_days: i64,
pub currency: Currency,
pub calendar: Box<dyn Calendar>,
pub convention: BusinessDayConvention,
pub day_counter: Box<dyn DayCounters>,
pub end_of_month: bool,
}
impl InterestRateIndex {
pub fn from_enum(code: InterestRateIndexEnum) -> Option<InterestRateIndex> {
match code {
InterestRateIndexEnum::AONIA => Some(InterestRateIndex {
period: Period::SPOT,
settlement_days: 0,
currency: AUD,
calendar: Box::<Austria>::default(),
convention: BusinessDayConvention::ModifiedFollowing,
day_counter: Box::<Actual365Fixed>::default(),
end_of_month: false,
}),
InterestRateIndexEnum::CDOR(period) => Some(InterestRateIndex {
period,
settlement_days: 0,
currency: USD,
calendar: Box::new(UnitedStates {
market: Some(UnitedStatesMarket::SOFR),
}),
convention: BusinessDayConvention::ModifiedFollowing,
day_counter: Box::new(Actual360),
end_of_month: false,
}),
InterestRateIndexEnum::EONIA => Some(InterestRateIndex {
period: Period::SPOT,
settlement_days: 0,
currency: EUR,
calendar: Box::<Target>::default(),
convention: BusinessDayConvention::ModifiedFollowing,
day_counter: Box::new(Actual360),
end_of_month: false,
}),
InterestRateIndexEnum::ESTR => Some(InterestRateIndex {
period: Period::SPOT,
settlement_days: 0,
currency: EUR,
calendar: Box::<Target>::default(),
convention: BusinessDayConvention::ModifiedFollowing,
day_counter: Box::new(Actual360),
end_of_month: false,
}),
InterestRateIndexEnum::EUIBOR(period) => match period {
Period::Days(_) | Period::Weeks(_) => Some(InterestRateIndex {
period,
settlement_days: 2,
currency: EUR,
calendar: Box::<Target>::default(),
convention: BusinessDayConvention::Following,
day_counter: Box::new(Actual360),
end_of_month: false,
}),
_ => Some(InterestRateIndex {
period,
settlement_days: 2,
currency: EUR,
calendar: Box::<Target>::default(),
convention: BusinessDayConvention::ModifiedFollowing,
day_counter: Box::new(Actual360),
end_of_month: false,
}),
},
InterestRateIndexEnum::SOFR => Some(InterestRateIndex {
period: Period::SPOT,
settlement_days: 0,
currency: USD,
calendar: Box::new(UnitedStates {
market: Some(UnitedStatesMarket::SOFR),
}),
convention: BusinessDayConvention::ModifiedFollowing,
day_counter: Box::new(Actual360),
end_of_month: false,
}),
InterestRateIndexEnum::SONIA => Some(InterestRateIndex {
period: Period::SPOT,
settlement_days: 0,
currency: GBP,
calendar: Box::new(UnitedKingdom {
market: Some(UnitedKingdomMarket::Exchange),
}),
convention: BusinessDayConvention::ModifiedFollowing,
day_counter: Box::<Actual365Fixed>::default(),
end_of_month: false,
}),
}
}
}
#[cfg(test)]
mod tests {
use super::{InterestRateIndex, InterestRateIndexEnum};
use crate::time::period::Period;
#[test]
fn test_from_enum() {
let interest_rate_index =
InterestRateIndex::from_enum(InterestRateIndexEnum::EUIBOR(Period::Months(3))).unwrap();
assert_eq!(interest_rate_index.settlement_days, 2i64);
}
}