use crate::currency::Currency;
use crate::indexes::inflationindex::{YoYInflationIndex, ZeroInflationIndex};
use crate::indexes::region::Region;
use crate::settings::Settings;
use crate::shared::Shared;
use crate::time::date::Date;
use crate::time::frequency::Frequency;
use crate::time::period::Period;
use crate::time::timeunit::TimeUnit;
pub struct EuHicp;
impl EuHicp {
#[allow(clippy::new_ret_no_self)]
pub fn new(settings: Shared<Settings<Date>>) -> ZeroInflationIndex {
ZeroInflationIndex::new(
"HICP".into(),
Region::eu(),
false,
Frequency::Monthly,
Period::new(1, TimeUnit::Months),
Currency::eur(),
settings,
)
}
}
pub struct YyEuHicp;
impl YyEuHicp {
#[allow(clippy::new_ret_no_self)]
pub fn new(settings: Shared<Settings<Date>>) -> YoYInflationIndex {
YoYInflationIndex::new(
"YY_HICP".into(),
Region::eu(),
false,
Frequency::Monthly,
Period::new(1, TimeUnit::Months),
Currency::eur(),
settings,
)
}
}
pub struct YyEuHicpXt;
impl YyEuHicpXt {
#[allow(clippy::new_ret_no_self)]
pub fn new(settings: Shared<Settings<Date>>) -> YoYInflationIndex {
YoYInflationIndex::new(
"YY_HICPXT".into(),
Region::eu(),
false,
Frequency::Monthly,
Period::new(1, TimeUnit::Months),
Currency::eur(),
settings,
)
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::indexes::index::Index;
use crate::indexes::inflationindex::InflationIndex;
use crate::shared::shared;
use crate::time::date::Month::{April, December, February, January, March};
#[test]
fn construction_matches_the_cpp_table() {
let index = EuHicp::new(shared(Settings::<Date>::new()));
assert_eq!(index.name(), "EU HICP");
assert_eq!(index.frequency(), Frequency::Monthly);
assert!(!index.revised());
assert_eq!(index.availability_lag(), Period::new(1, TimeUnit::Months));
assert_eq!(index.currency().code(), "EUR");
}
#[test]
fn the_year_on_year_construction_matches_the_cpp_header() {
let index = YyEuHicp::new(shared(Settings::<Date>::new()));
assert_eq!(index.name(), "EU YY_HICP");
assert_eq!(index.frequency(), Frequency::Monthly);
assert!(!index.revised());
assert!(!index.ratio());
assert!(index.underlying_index().is_none());
assert_eq!(index.availability_lag(), Period::new(1, TimeUnit::Months));
assert_eq!(index.currency().code(), "EUR");
}
#[test]
fn the_ex_tobacco_year_on_year_construction_matches_the_cpp_header() {
let index = YyEuHicpXt::new(shared(Settings::<Date>::new()));
assert_eq!(index.name(), "EU YY_HICPXT");
assert_eq!(index.frequency(), Frequency::Monthly);
assert!(!index.revised());
assert!(!index.ratio());
assert!(index.underlying_index().is_none());
assert_eq!(index.availability_lag(), Period::new(1, TimeUnit::Months));
assert_eq!(index.currency().code(), "EUR");
}
#[test]
fn a_stored_figure_beyond_the_publication_horizon_still_forecasts() {
let settings = shared(Settings::<Date>::new());
settings.set_evaluation_date(Date::new(10, April, 2024));
let index = EuHicp::new(settings);
for (date, value) in [
(Date::new(1, December, 2023), 100.0),
(Date::new(1, January, 2024), 100.1),
(Date::new(1, February, 2024), 100.2),
] {
index
.add_fixing(date, value)
.expect("adding a published figure");
}
let february = index
.fixing(Date::new(1, February, 2024), false)
.expect("February 2024 is stored");
assert!((february - 100.2).abs() < 1e-12, "{february}");
let march = Date::new(1, March, 2024);
let error = index
.fixing(march, false)
.expect_err("March 2024 has no figure yet and no curve to forecast off");
assert!(
error.to_string().contains("empty Handle"),
"err was: {error}"
);
index
.add_fixing(march, 100.3)
.expect("March gets published");
let published = index.fixing(march, false).expect("March 2024 is stored");
assert!((published - 100.3).abs() < 1e-12, "{published}");
let april = Date::new(1, April, 2024);
let error = index
.fixing(april, false)
.expect_err("April 2024 cannot have been published on 10 April");
assert!(
error.to_string().contains("empty Handle"),
"err was: {error}"
);
index
.add_fixing(april, 100.4)
.expect("recording a figure ahead of its publication");
let error = index
.fixing(april, false)
.expect_err("April 2024 is beyond the horizon, stored or not");
assert!(
error.to_string().contains("empty Handle"),
"err was: {error}"
);
}
}