use crate::currency::Currency;
use crate::errors::QlResult;
use crate::handle::Handle;
use crate::indexes::ibor::libor::Libor;
use crate::indexes::iborindex::IborIndex;
use crate::settings::Settings;
use crate::shared::Shared;
use crate::termstructures::yieldtermstructure::YieldTermStructure;
use crate::time::calendars::unitedstates::{Market as UsMarket, UnitedStates};
use crate::time::date::Date;
use crate::time::daycounters::actual360::Actual360;
use crate::time::period::Period;
pub struct UsdLibor;
impl UsdLibor {
#[allow(clippy::new_ret_no_self)]
pub fn new(
tenor: Period,
forwarding: Handle<dyn YieldTermStructure>,
settings: Shared<Settings<Date>>,
) -> QlResult<IborIndex> {
Libor::new(
"USDLibor".into(),
tenor,
2,
Currency::usd(),
UnitedStates::new(UsMarket::LiborImpact),
Actual360::new(),
forwarding,
settings,
)
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::indexes::index::Index;
use crate::indexes::interestrateindex::InterestRateIndex;
use crate::shared::shared;
use crate::termstructures::bootstraphelper::RateHelper;
use crate::termstructures::yields::SwapRateHelper;
use crate::time::businessdayconvention::BusinessDayConvention;
use crate::time::calendars::unitedkingdom::{Market as UkMarket, UnitedKingdom};
use crate::time::date::Month;
use crate::time::daycounters::thirty360::{Convention, Thirty360};
use crate::time::frequency::Frequency;
use crate::time::timeunit::TimeUnit;
fn usd_libor_3m(settings: Shared<Settings<Date>>) -> IborIndex {
UsdLibor::new(Period::new(3, TimeUnit::Months), Handle::empty(), settings)
.expect("a 3M USDLibor tenor is valid")
}
#[test]
fn usd_libor_carries_the_ice_configuration() {
let index = usd_libor_3m(shared(Settings::<Date>::new()));
assert_eq!(index.name(), "USDLibor3M Actual/360");
assert_eq!(index.fixing_days(), 2);
assert_eq!(index.currency(), &Currency::usd());
assert_eq!(
index.business_day_convention(),
BusinessDayConvention::ModifiedFollowing
);
assert!(index.end_of_month());
}
#[test]
fn swap_rate_helper_spot_date_advances_on_the_uk_calendar() {
let settings = shared(Settings::<Date>::new());
settings.set_evaluation_date(Date::new(11, Month::October, 2019));
let index = usd_libor_3m(settings);
let helper = SwapRateHelper::from_rate(
0.02,
Period::new(5, TimeUnit::Years),
UnitedStates::new(UsMarket::GovernmentBond),
Frequency::Semiannual,
BusinessDayConvention::ModifiedFollowing,
Thirty360::with_convention(Convention::BondBasis),
&index,
);
assert_eq!(helper.earliest_date(), Date::new(15, Month::October, 2019));
}
#[test]
fn value_date_is_adjusted_on_the_joint_calendar() {
let index = usd_libor_3m(shared(Settings::<Date>::new()));
let value = index
.value_date(Date::new(7, Month::November, 2019))
.unwrap();
assert_eq!(value, Date::new(12, Month::November, 2019));
}
#[test]
fn maturity_date_advances_on_the_joint_calendar() {
let index = usd_libor_3m(shared(Settings::<Date>::new()));
let v = Date::new(11, Month::August, 2020);
let maturity = index.maturity_date(v).unwrap();
let uk = UnitedKingdom::new(UkMarket::Exchange);
let joint = index.maturity_calendar();
let expected = joint.advance_by_period(
v,
index.tenor(),
index.business_day_convention(),
index.end_of_month(),
);
let uk_only = uk.advance_by_period(
v,
index.tenor(),
index.business_day_convention(),
index.end_of_month(),
);
assert_eq!(maturity, expected);
assert_eq!(maturity, Date::new(12, Month::November, 2020));
assert_eq!(uk_only, Date::new(11, Month::November, 2020));
assert_ne!(maturity, uk_only);
let clone = index.clone_with(Handle::empty());
assert_eq!(clone.maturity_date(v).unwrap(), maturity);
}
#[test]
fn fixing_date_rolls_back_on_the_uk_calendar_alone() {
let index = usd_libor_3m(shared(Settings::<Date>::new()));
assert_eq!(
index.fixing_date(Date::new(13, Month::November, 2020)),
Date::new(11, Month::November, 2020)
);
}
}