Skip to content

Commit

Permalink
chore: #142 - Add more calendars (Czech Rep., Denmark, Finland, Franc…
Browse files Browse the repository at this point in the history
…e, Germany, Hong Kong)
  • Loading branch information
avhz committed Nov 14, 2023
1 parent bc8c0a1 commit b273339
Show file tree
Hide file tree
Showing 20 changed files with 628 additions and 115 deletions.
10 changes: 5 additions & 5 deletions src/curves/nelson_siegel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ impl CurveModel for NelsonSiegel {
#[cfg(test)]
mod tests_nelson_siegel {
use super::*;
use crate::plot_vector;
// use crate::plot_vector;
use time::Duration;

#[test]
Expand All @@ -116,17 +116,17 @@ mod tests_nelson_siegel {
.map(|i| OffsetDateTime::now_utc() + Duration::days(i))
.collect::<Vec<OffsetDateTime>>();

let forward_curve = dates
let _forward_curve = dates
.iter()
.map(|date| ns.forward_rate(*date))
.collect::<Vec<_>>();

let discount_curve = dates
let _discount_curve = dates
.iter()
.map(|date| ns.discount_factor(*date))
.collect::<Vec<_>>();

plot_vector!(forward_curve, "./images/nelson_siegel_forward.png");
plot_vector!(discount_curve, "./images/nelson_siegel_discount.png");
// plot_vector!(forward_curve, "./images/nelson_siegel_forward.png");
// plot_vector!(discount_curve, "./images/nelson_siegel_discount.png");
}
}
16 changes: 8 additions & 8 deletions src/curves/nelson_siegel_svensson.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ impl CurveModel for NelsonSiegelSvensson {
#[cfg(test)]
mod tests_nelson_siegel_svensson {
use super::*;
use crate::plot_vector;
// use crate::plot_vector;
use time::Duration;

#[test]
Expand All @@ -125,20 +125,20 @@ mod tests_nelson_siegel_svensson {
.map(|i| OffsetDateTime::now_utc() + Duration::days(i))
.collect::<Vec<OffsetDateTime>>();

let forward_curve = dates
let _forward_curve = dates
.iter()
.map(|date| nss.forward_rate(*date))
.collect::<Vec<_>>();

let discount_curve = dates
let _discount_curve = dates
.iter()
.map(|date| nss.discount_factor(*date))
.collect::<Vec<_>>();

plot_vector!(forward_curve, "./images/nelson_siegel_svensson_forward.png");
plot_vector!(
discount_curve,
"./images/nelson_siegel_svensson_discount.png"
);
// plot_vector!(forward_curve, "./images/nelson_siegel_svensson_forward.png");
// plot_vector!(
// discount_curve,
// "./images/nelson_siegel_svensson_discount.png"
// );
}
}
3 changes: 3 additions & 0 deletions src/time/calendar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ pub trait Calendar {
/// Returns the ISO 3166-1 country code.
fn country_code(&self) -> crate::iso::ISO_3166;

/// Returns the ISO 10383 market identifier code.
fn market_identifier_code(&self) -> crate::iso::ISO_10383;

/// Unpacks an OffsetDateTime into a tuple in the following form:
///
/// ```ignore
Expand Down
44 changes: 23 additions & 21 deletions src/time/calendars/argentina.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,42 +19,44 @@ impl Calendar for Argentina {
}

fn country_code(&self) -> crate::iso::ISO_3166 {
crate::iso::ISO_3166 {
alpha_2: "AR",
alpha_3: "ARG",
numeric: "032",
}
crate::iso::ARGENTINA
}

fn market_identifier_code(&self) -> crate::iso::ISO_10383 {
crate::iso::XBUE
}

/// Argentina holidays:
/// - New Year's Day
/// - Holy Thursday
/// - Good Friday
/// - Labour Day
/// - May Revolution
/// - Death of General Manuel Belgrano
/// - Independence Day
/// - Death of General José de San Martín
/// - Columbus Day
/// - Immaculate Conception
/// - Christmas Eve
/// - New Year's Eve
fn is_business_day(&self, date: OffsetDateTime) -> bool {
let (w, d, m, y, dd) = self.unpack_date(date);
let em = Self::easter_monday(y as usize, false);

if Self::is_weekend(date)
// New Year's Day
|| (d == 1 && m == Month::January)
// Holy Thursday
|| (dd == em-4)
// Good Friday
|| (dd == em-3)
// Labour Day
|| (dd == em - 4)
|| (dd == em - 3)
|| (d == 1 && m == Month::May)
// May Revolution
|| (d == 25 && m == Month::May)
// Death of General Manuel Belgrano
|| ((15..=21).contains(&d) && w == Weekday::Monday && m == Month::June)
// Independence Day
|| (d == 9 && m == Month::July)
// Death of General José de San Martín
|| ((15..=21).contains(&d) && w ==Weekday::Monday && m == Month::August)
// Columbus Day
|| ((15..=21).contains(&d) && w == Weekday::Monday && m == Month::August)
|| ((d == 10 || d == 11 || d == 12 || d == 15 || d == 16)
&& w == Weekday::Monday && m == Month::October)
// Immaculate Conception
&& w == Weekday::Monday
&& m == Month::October)
|| (d == 8 && m == Month::December)
// Christmas Eve
|| (d == 24 && m == Month::December)
// New Year's Eve
|| ((d == 31 || (d == 30 && w == Weekday::Friday)) && m == Month::December)
{
return false;
Expand Down
10 changes: 5 additions & 5 deletions src/time/calendars/australia.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,11 @@ impl Calendar for Australia {
}

fn country_code(&self) -> crate::iso::ISO_3166 {
crate::iso::ISO_3166 {
alpha_2: "AU",
alpha_3: "AUS",
numeric: "036",
}
crate::iso::AUSTRALIA
}

fn market_identifier_code(&self) -> crate::iso::ISO_10383 {
crate::iso::XASX
}

fn is_business_day(&self, date: OffsetDateTime) -> bool {
Expand Down
10 changes: 5 additions & 5 deletions src/time/calendars/austria.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ impl Calendar for Austria {
}

fn country_code(&self) -> crate::iso::ISO_3166 {
crate::iso::ISO_3166 {
alpha_2: "AT",
alpha_3: "AUT",
numeric: "040",
}
crate::iso::AUSTRIA
}

fn market_identifier_code(&self) -> crate::iso::ISO_10383 {
crate::iso::EXAA
}

fn is_business_day(&self, date: OffsetDateTime) -> bool {
Expand Down
10 changes: 5 additions & 5 deletions src/time/calendars/botswana.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ impl Calendar for Botswana {
}

fn country_code(&self) -> crate::iso::ISO_3166 {
crate::iso::ISO_3166 {
alpha_2: "BW",
alpha_3: "BWA",
numeric: "072",
}
crate::iso::BOTSWANA
}

fn market_identifier_code(&self) -> crate::iso::ISO_10383 {
crate::iso::XBOT
}

fn is_business_day(&self, date: OffsetDateTime) -> bool {
Expand Down
10 changes: 5 additions & 5 deletions src/time/calendars/brazil.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ impl Calendar for Brazil {
}

fn country_code(&self) -> crate::iso::ISO_3166 {
crate::iso::ISO_3166 {
alpha_2: "BR",
alpha_3: "BRA",
numeric: "076",
}
crate::iso::BRAZIL
}

fn market_identifier_code(&self) -> crate::iso::ISO_10383 {
crate::iso::BVMF
}

fn is_business_day(&self, date: OffsetDateTime) -> bool {
Expand Down
10 changes: 5 additions & 5 deletions src/time/calendars/canada.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ impl Calendar for Canada {
}

fn country_code(&self) -> crate::iso::ISO_3166 {
crate::iso::ISO_3166 {
alpha_2: "CA",
alpha_3: "CAN",
numeric: "124",
}
crate::iso::CANADA
}

fn market_identifier_code(&self) -> crate::iso::ISO_10383 {
crate::iso::XCNQ
}

fn is_business_day(&self, date: OffsetDateTime) -> bool {
Expand Down
10 changes: 5 additions & 5 deletions src/time/calendars/chile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ impl Calendar for Chile {
}

fn country_code(&self) -> crate::iso::ISO_3166 {
crate::iso::ISO_3166 {
alpha_2: "CL",
alpha_3: "CHL",
numeric: "152",
}
crate::iso::CHILE
}

fn market_identifier_code(&self) -> crate::iso::ISO_10383 {
crate::iso::XSGO
}

fn is_business_day(&self, date: OffsetDateTime) -> bool {
Expand Down
10 changes: 5 additions & 5 deletions src/time/calendars/china.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ impl Calendar for China {
}

fn country_code(&self) -> crate::iso::ISO_3166 {
crate::iso::ISO_3166 {
alpha_2: "CN",
alpha_3: "CHN",
numeric: "156",
}
crate::iso::CHINA
}

fn market_identifier_code(&self) -> crate::iso::ISO_10383 {
crate::iso::XSHG
}

#[allow(clippy::manual_range_contains)]
Expand Down
47 changes: 43 additions & 4 deletions src/time/calendars/czech_republic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,60 @@
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

use crate::time::Calendar;
use time::{Month, OffsetDateTime, Weekday};
use time::{Month, OffsetDateTime};

/// Czech Republic calendar.
pub struct CzechRepublic;

impl Calendar for CzechRepublic {
fn name(&self) -> &'static str {
""
"Czech Republic"
}

fn country_code(&self) -> crate::iso::ISO_3166 {
crate::iso::CZECHIA
}

fn market_identifier_code(&self) -> crate::iso::ISO_10383 {
crate::iso::XPRA
}

/// Czech Republic holidays:
/// - New Year's Day
/// - Good Friday
/// - Easter Monday
/// - Labour Day
/// - Liberation Day
/// - SS. Cyril and Methodius
/// - Jan Hus Day
/// - Czech Statehood Day
/// - Independence Day
/// - Struggle for Freedom and Democracy Day
/// - Christmas Eve
/// - Christmas
/// - St. Stephen
/// - Miscellaneous (2004-01-02, 2004-12-31)
fn is_business_day(&self, date: OffsetDateTime) -> bool {
let (w, d, m, y, dd) = self.unpack_date(date);
let (_, d, m, y, dd) = self.unpack_date(date);
let em = Self::easter_monday(y as usize, false);

if Self::is_weekend(date) {
if Self::is_weekend(date)
|| (d == 1 && m == Month::January)
|| (dd == em - 3 && y >= 2016)
|| (dd == em)
|| (d == 1 && m == Month::May)
|| (d == 8 && m == Month::May)
|| (d == 5 && m == Month::July)
|| (d == 6 && m == Month::July)
|| (d == 28 && m == Month::September)
|| (d == 28 && m == Month::October)
|| (d == 17 && m == Month::November)
|| (d == 24 && m == Month::December)
|| (d == 25 && m == Month::December)
|| (d == 26 && m == Month::December)
|| (d == 2 && m == Month::January && y == 2004)
|| (d == 31 && m == Month::December && y == 2004)
{
return false;
}

Expand Down
48 changes: 42 additions & 6 deletions src/time/calendars/denmark.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,57 @@
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

use crate::time::Calendar;
use time::{Month, OffsetDateTime, Weekday};
use time::{Month, OffsetDateTime};

/// Czech Republic calendar.
pub struct CzechRepublic;
pub struct Denmark;

impl Calendar for CzechRepublic {
impl Calendar for Denmark {
fn name(&self) -> &'static str {
""
"Denmark"
}

fn country_code(&self) -> crate::iso::ISO_3166 {
crate::iso::DENMARK
}

fn market_identifier_code(&self) -> crate::iso::ISO_10383 {
crate::iso::XCSE
}

/// Denmark holidays:
/// - Maunday Thursday
/// - Good Friday
/// - Easter Monday
/// - General Prayer Day
/// - Ascension
/// - Day after Ascension
/// - Whit Monday
/// - New Year's Day
/// - Constitution Day, June 5th
/// - Christmas Eve
/// - Christmas
/// - Boxing Day
/// - New Year's Eve
fn is_business_day(&self, date: OffsetDateTime) -> bool {
let (w, d, m, y, dd) = self.unpack_date(date);
let (_, d, m, y, dd) = self.unpack_date(date);
let em = Self::easter_monday(y as usize, false);

if Self::is_weekend(date) {
if Self::is_weekend(date)
|| (dd == em - 4)
|| (dd == em - 3)
|| (dd == em)
|| (dd == em + 25)
|| (dd == em + 38)
|| (dd == em + 39 && y >= 2009)
|| (dd == em + 49)
|| (d == 1 && m == Month::January)
|| (d == 5 && m == Month::June)
|| (d == 24 && m == Month::December)
|| (d == 25 && m == Month::December)
|| (d == 26 && m == Month::December)
|| (d == 31 && m == Month::December)
{
return false;
}

Expand Down
Loading

0 comments on commit b273339

Please sign in to comment.