4 - Désaisonnalisation avec correction des jours ouvrables

Désaisonnaliser une série temporelle

Auteur

Alain Quartier-la-Tente

Dans JDemetra+ 2.x.y, si l’on crée soit-même un calendrier seul deux types de régresseurs sont possibles (trading days et working days) : il est donc vite utile de créer soit même des régresseurs de calendrier et de les importer dans JDemetra+ (section 2). Dans JDemetra+ 3.x.y, il est possible d’utiliser bien plus de régresseurs de calendrier à partir d’un calendrier personnalisé. Dans la majorité des cas il n’est donc plus utile d’exporter les régresseurs et ce calendrier peut directeur être utilisé (section 1) : c’est la solution que nous privilégierons.

1 Utilisation d’un calendrier personnalisé dans JDemetra+

1.1 Création du calendrier depuis JDemetra+

  • Dans l’onglet Workspace, cliquer droit sur Utilities > Calendars puis Add Calendar > National

  • Donner un nom au calendrier (par exemple CAL)

  • Ajouter des jours en cliquant sur le + :

    • Fixed pour ajouter un jour férié qui tombe à date fixe (par exemple 8 mai)

    • Easter Related pour ajouter un jour férié dont le jour dépend de Pâques (le dimanche) : le paramètre offset permet de spécifier le nombre de jours avant (si négatif) ou après Pâques (si positif).

    • Fixed week qui permet d’ajouter des jours fériés qui apparaissent certaines semaines de certains mois (par exemple le premier lundi du mois de septembre aux USA)

    • Single Date pour ajouter un jour ferié qui n’a eu lieu qu’une seule fois (i.e. une année seulement).

    • Special Day qui permet d’ajouter des jours fériés par rapport à des dates déjà connues dans JDemetra+ (voir tableau ci-dessous). Comme pour la fonction easter_day(), le paramètre offset permet de spécifier la position du jour voulu par rapport rapport à la fête pré-spécifié (par défaut offset = 0, le jour férié coïncide avec le jour pré-spécifié).

Jours pré-spécifiés (`Special Day`)
Event Définition
NEWYEAR Fête fixe, 1er janvier.
SHROVEMONDAY Fête mobile, lundi avant le mecredi des cendres (48 jours avant pâques).
SHROVETUESDAY Fête mobile, mardi avant le mecredi des cendres (47 jours avant pâques).
ASHWEDNESDAY Fête mobile, 46 jours avant Pâques.
EASTER Fête mobile, Pâques, varie entre le 22 mars et le 25 avril.
MAUNDYTHURSDAY Fête mobile, le jeudi avant Pâques.
GOODFRIDAY Fête mobile, le vendredi avant Pâques.
EASTERMONDAY Fête mobile, le lendemain de Pâques.
ASCENSION Fête mobile, célébrée un jeudi, 40 jours après Pâques.
PENTECOST Fête mobile, 50 jours après Pâques.
CORPUSCHRISTI Fête mobile, 60 jours après Pâques.
WHITMONDAY Fête mobile, le jour après la Pentecôte.
MAYDAY Fête fixe, 1er mai.
ASSUMPTION Fête fixe, 15 août.
HALLOWEEN Fête fixe, 31 octobre.
ALLSAINTSDAY Fête fixe, 1er novembre.
ARMISTICE Fête fixe, 11 novembre.
CHRISTMAS Fête fixe, 25 décembre.

1.2 Création du calendrier depuis R (v3.x.y)

if (! "rjd3toolkit" %in% installed.packages()[,"Package"]) {
  install.packages("rjd3toolkit", repos = c("https://aqlt.r-universe.dev", "https://cloud.r-project.org"))
}
if (! "rjd3workspace" %in% installed.packages()[,"Package"]) {
  install.packages("rjd3workspace", repos = c("https://aqlt.r-universe.dev", "https://cloud.r-project.org"))
}
library(rjd3toolkit)
# Exemple de calendrier associé à la France
FR <- national_calendar(list(
    special_day("NEWYEAR"),
    special_day("EASTERMONDAY"), # Lundi de Pâques
    special_day("MAYDAY"), # 1er mai
    special_day("ASCENSION"), # Jour de l'Ascension
    fixed_day(5, 8),
    special_day("WHITMONDAY"), # Lundi de Pentecôte
    fixed_day(7, 14),
    special_day("ASSUMPTION"), # Assomption
    special_day("ALLSAINTSDAY"), # Toussaint
    special_day("ARMISTICE")
))
CAL <- national_calendar(FR)

Ici certains jours fériés sont associés à des fêtes mobiles qui sont inscrites dans un fichier Excel

if (! "rjd3toolkit" %in% installed.packages()[,"Package"]) {
  install.packages("rjd3toolkit", repos = c("https://aqlt.r-universe.dev", "https://cloud.r-project.org"))
}
library(rjd3toolkit)
jours_macronia <- list(
  special_day("NEWYEAR"),
    special_day("EASTERMONDAY"), # Lundi de Pâques
  fixed_day(4, 4), # Jour de l'indépendance de la Macronia
  special_day("MAYDAY"), # 1er mai
  special_day("ASCENSION"), # Jour de l'Ascension
    special_day("WHITMONDAY"), # Lundi de Pentecôte
  special_day("ASSUMPTION"), # Assomption de Marie
    special_day("ALLSAINTSDAY"), # Toussaint
  special_day("CHRISTMAS") # Noël
)
jours_macronia <- c(
  jours_macronia,
  list(
    # DEBUT_RAMADAN,
single_day("2000-11-28"),
single_day("2001-11-17"),
single_day("2002-11-07"),
single_day("2003-10-27"),
single_day("2004-10-15"),
single_day("2005-10-05"),
single_day("2006-09-24"),
single_day("2007-09-14"),
single_day("2008-09-02"),
single_day("2009-08-22"),
single_day("2010-08-12"),
single_day("2011-08-01"),
single_day("2012-07-20"),
single_day("2013-07-10"),
single_day("2014-06-29"),
single_day("2015-07-18"),
single_day("2016-06-07"),
single_day("2017-05-27"),
single_day("2018-05-17"),
single_day("2019-05-06"),
single_day("2020-04-24"),
single_day("2021-04-14"),
single_day("2022-04-03"),
single_day("2023-03-23"),
single_day("2024-03-12")
  ))
CAL <- national_calendar(jours_macronia)

Une fois le calendrier défini, un workspace peut être créé de la façon suivante :

# On va créer deux groupes de variables, on peut donc simplifier les noms
ctxt <- rjd3toolkit::modelling_context(
    # on appelle "CAL" le calendrier
    calendars = list(CAL = CAL)
) 

jws <- rjd3workspace::jws_new(ctxt)
rjd3workspace::save_workspace(jws, "wk_CJO_v3.xml")
# # Si le workspace existe déjà on peut utiliser le code suivant :
# jws <- rjd3workspace::.jws_open("chemin_vers_workspace")
# rjd3workspace::add_calendar(jws, "CAL", CAL)
# rjd3workspace::save_workspace(jws, "chemin_vers_nouveau_workspace")

1.3 Créer une spécification incluant le calendrier personnalisé

  • Cliquer sur l’onglet Workspace.

  • Double cliquer sur Seasonal adjustment.

  • Double cliquer sur specifications.

  • Double cliquer sur x13.

  • Clic-droit sur RSA5c (ou RSA5 dans la version 3.x.y).

  • Cliquer sur Clone.

  • Que se passe-t-il ?

  • Double-cliquer sur X13Spec-1.

  • Cliquer sur le + à côté de Calendar.

  • Cliquer sur le + à côté de tradingDays.

  • Cliquer sur Default à côté de option (ligne 1) et choisir l’option Holidays.

  • Cliquer sur Default à côté de holidays (ligne 3) et choisir votre calendrier

Par défaut l’option trading days (TD7) les autres options possibles dans JDemetra+ 3.x.y sont :

Modèle Définition Référence (contraste) Nombre de régresseurs
TD7 (Lundi), (Mardi), \(\dots\), (Samedi) Dimanche 6 + LPY
TD4 (Lundi = \(\dots\) = Jeudi), (Vendredi), (Samedi) Dimanche 3 + LPY
TD3 (Lundi = \(\dots\) = Vendredi), (Samedi) Dimanche 2 + LPY
TD3c (Lundi = \(\dots\) = Jeudi), (Vendredi = Samedi) Dimanche 2 + LPY
TD2c (Lundi = \(\dots\) = Samedi) Dimanche 1 + LPY
TD2 (Lundi = \(\dots\) = Vendredi) Samedi + Dimanche 1+LPY

Même si un raisonnement économique est à privilégier pour le choix des régresseurs, une sélection automatique peut être faite par JDemetra+ (option automatic, ligne 2) en utilisant des tests de Wald ou en minimisant un critère d’information (BIC ou AIC).

Exporter son calendrier dans un autre workspace

Si vous souhaitez exporter votre calendrier (sans utiliser R), il est possible de créer un fichier config depuis l’interface qui peut ensuite être importé :

  • Dans l’onglet Workspace > Utilities > Calendars, clic-droit sur le calendrier souhaité puis Export to > File... celui crée un fichier .cfgx.

  • Si vous créer un nouveau workspace, cet objet est importable dans JDemetra+ via l’onglet Workspace > Utilities > Calendars, clic-droit sur Calendars puis Import from > File... et en sélectionnant le fichier .cfgx précédemment créé.

2 Importer les jeux de régresseurs « Jours Ouvrables » sous JDemetra+

2.1 Importer des régresseurs manuellement

  • Cliquer sur l’onglet Providers.

  • Clic-droit sur Spreadsheets.

  • Cliquer sur Open.

  • Cliquer sur le bouton .

  • Sélectionner le fichier Excel « reg_cjo_macronia.xlsx » contenant les régresseurs « Jours Ouvrables » de la Macronia.

  • Cliquer sur OK.

  • Cliquer sur l’onglet Workspace.

  • Cliquer sur le + à côté d’Utilities.

  • Clic-droit sur Variables.

  • Cliquer sur New.

  • Cliquer sur le + à côté de Variables.

  • Double cliquer sur l’icône Vars-1.

  • Que se passe-t-il ?

  • Retourner dans l’onglet Providers.

  • Faire glisser l’ensemble des séries du fichier « regcjo.xls » dans l’onglet Vars-1.

  • Renommer les séries en reprenant leur nom d’origine dans le fichier excel « regcjo.xls ».

Ce travail peut être très fastidieux… Heureusement depuis R il existe une solution plus automatique !

2.2 Importer des régresseurs grâce à R

Il existe deux façons de faire, en fonction de si l’on utilise une version 2.x.y ou 3.x.y de JDemetra+. Repartons déjà des régresseurs jours ouvrables (pour leur création, voir le TP R associé en V2 ou V3) :

if (! "rjd3toolkit" %in% installed.packages()[,"Package"]) {
  install.packages("rjd3toolkit", repos = c("https://aqlt.r-universe.dev", "https://cloud.r-project.org"))
}
if (! "rjd3workspace" %in% installed.packages()[,"Package"]) {
  install.packages("rjd3workspace", repos = c("https://aqlt.r-universe.dev", "https://cloud.r-project.org"))
}
library(rjd3toolkit)
# Exemple de calendrier associé à la France
FR <- national_calendar(list(
    special_day("NEWYEAR"),
    special_day("EASTERMONDAY"), # Lundi de Pâques
    special_day("MAYDAY"), # 1er mai
    special_day("ASCENSION"), # Jour de l'Ascension
    fixed_day(5, 8),
    special_day("WHITMONDAY"), # Lundi de Pentecôte
    fixed_day(7, 14),
    special_day("ASSUMPTION"), # Assomption
    special_day("ALLSAINTSDAY"), # Toussaint
    special_day("ARMISTICE")
))
CAL <- national_calendar(FR)

gen_calendrier <- function(cal, frequency, start = c(1990, 1), end = c(2030, 1)) {
    length = (end[1] - start[1]) * frequency + end[2] - start[2]
    ly <- rjd3toolkit::lp_variable(frequency = frequency, start = start,
                                   length = length)
    # N'hésitez pas à ajouter les votre !
    TD7 <- calendar_td(cal, frequency = frequency, start = start, length = length,
                       groups = c(1, 2, 3, 4, 5, 6, 0))
    TD4 <- calendar_td(cal, frequency = frequency, start = start, length = length,
                       groups = c(1, 1, 1, 1, 2, 3, 0))
    TD3 <- calendar_td(cal, frequency = frequency, start = start, length = length,
                       groups = c(1, 1, 1, 1, 1, 2, 0))
    TD3c <- calendar_td(cal, frequency = frequency, start = start, length = length,
                        groups = c(1, 1, 1, 1, 2, 2, 0))
    TD2 <- calendar_td(cal, frequency = frequency, start = start, length = length,
                       groups = c(1, 1, 1, 1, 1, 0, 0))
    TD2c <- calendar_td(cal, frequency = frequency, start = start, length = length,
                        groups = c(1, 1, 1, 1, 1, 1, 0))
    
    reg_jo <- ts(cbind(TD2, TD2c, TD3, TD3c, TD4, TD7),
                 start = start, frequency = frequency)
    reg_jo <- ts.intersect(reg_jo,
                           ly)
    colnames(reg_jo) <- c(
        "TD2_semaine",
        "TD2c_lundi_samedi",
        sprintf("TD3_%s", c("semaine", "samedi")),
        sprintf("TD3c_%s", c("lundi_jeudi", "vendredi_samedi")),
        sprintf("TD4_%s", c("lundi_jeudi", "vendredi", "samedi")),
        sprintf("TD7_%s", c("lundi", "mardi", "mercredi", "jeudi", "vendredi", "samedi")),
        "leap_year")
    reg_jo
}
regresseurs_JO_trim <- gen_calendrier(CAL, frequency = 4)
regresseurs_JO_mens <- gen_calendrier(CAL, frequency = 12)

colnames(regresseurs_JO_trim) <- paste0(colnames(regresseurs_JO_trim), "_trim")
colnames(regresseurs_JO_mens) <- paste0(colnames(regresseurs_JO_mens), "_mens")

Ici certains jours fériés sont associés à des fêtes mobiles qui sont inscrites dans un fichier Excel

if (! "rjd3toolkit" %in% installed.packages()[,"Package"]) {
  install.packages("rjd3toolkit", repos = c("https://aqlt.r-universe.dev", "https://cloud.r-project.org"))
}
library(rjd3toolkit)
jours_macronia <- list(
  special_day("NEWYEAR"),
    special_day("EASTERMONDAY"), # Lundi de Pâques
  fixed_day(4, 4), # Jour de l'indépendance de la Macronia
  special_day("MAYDAY"), # 1er mai
  special_day("ASCENSION"), # Jour de l'Ascension
    special_day("WHITMONDAY"), # Lundi de Pentecôte
  special_day("ASSUMPTION"), # Assomption de Marie
    special_day("ALLSAINTSDAY"), # Toussaint
  special_day("CHRISTMAS") # Noël
)
jours_macronia <- c(
  jours_macronia,
  list(
    # DEBUT_RAMADAN,
single_day("2000-11-28"),
single_day("2001-11-17"),
single_day("2002-11-07"),
single_day("2003-10-27"),
single_day("2004-10-15"),
single_day("2005-10-05"),
single_day("2006-09-24"),
single_day("2007-09-14"),
single_day("2008-09-02"),
single_day("2009-08-22"),
single_day("2010-08-12"),
single_day("2011-08-01"),
single_day("2012-07-20"),
single_day("2013-07-10"),
single_day("2014-06-29"),
single_day("2015-07-18"),
single_day("2016-06-07"),
single_day("2017-05-27"),
single_day("2018-05-17"),
single_day("2019-05-06"),
single_day("2020-04-24"),
single_day("2021-04-14"),
single_day("2022-04-03"),
single_day("2023-03-23"),
single_day("2024-03-12")
  ))
CAL <- national_calendar(jours_macronia)

gen_calendrier <- function(cal, frequency, start = c(1990, 1), end = c(2030, 1)) {
    length = (end[1] - start[1]) * frequency + end[2] - start[2]
    ly <- rjd3toolkit::lp_variable(frequency = frequency, start = start,
                                   length = length)
    # N'hésitez pas à ajouter les votre !
    TD7 <- calendar_td(cal, frequency = frequency, start = start, length = length,
                       groups = c(1, 2, 3, 4, 5, 6, 0))
    TD4 <- calendar_td(cal, frequency = frequency, start = start, length = length,
                       groups = c(1, 1, 1, 1, 2, 3, 0))
    TD3 <- calendar_td(cal, frequency = frequency, start = start, length = length,
                       groups = c(1, 1, 1, 1, 1, 2, 0))
    TD3c <- calendar_td(cal, frequency = frequency, start = start, length = length,
                        groups = c(1, 1, 1, 1, 2, 2, 0))
    TD2 <- calendar_td(cal, frequency = frequency, start = start, length = length,
                       groups = c(1, 1, 1, 1, 1, 0, 0))
    TD2c <- calendar_td(cal, frequency = frequency, start = start, length = length,
                        groups = c(1, 1, 1, 1, 1, 1, 0))
    
    reg_jo <- ts(cbind(TD2, TD2c, TD3, TD3c, TD4, TD7),
                 start = start, frequency = frequency)
    reg_jo <- ts.intersect(reg_jo,
                           ly)
    colnames(reg_jo) <- c(
        "TD2_semaine",
        "TD2c_lundi_samedi",
        sprintf("TD3_%s", c("semaine", "samedi")),
        sprintf("TD3c_%s", c("lundi_jeudi", "vendredi_samedi")),
        sprintf("TD4_%s", c("lundi_jeudi", "vendredi", "samedi")),
        sprintf("TD7_%s", c("lundi", "mardi", "mercredi", "jeudi", "vendredi", "samedi")),
        "leap_year")
    reg_jo
}
regresseurs_JO_trim <- gen_calendrier(CAL, frequency = 4)
regresseurs_JO_mens <- gen_calendrier(CAL, frequency = 12)

colnames(regresseurs_JO_trim) <- paste0(colnames(regresseurs_JO_trim), "_trim")
colnames(regresseurs_JO_mens) <- paste0(colnames(regresseurs_JO_mens), "_mens")

Une fois votre calendrier créé, vous pouvez l’exporter dans un workspace JDemetra+ :

Ci-dessous un code pour vous éviter de faire le travail manuel. Il est un peu peu compliqué mais une fois le code écrit, vous pouvez l’utiliser tel quel ! Vous pourrez ensuite repartir du workspace créé pour y ajouter vos propres séries.

# On va créer un nouveau workspace où l'on va ajouter les nouvelles variables
library(RJDemetra)
library(rJava)
complete_variables <- function(liste_var, workspace){
    if(!is.mts(liste_var))
        stop("liste_var doit être de type mts")
    context_dictionary <- .jcall(workspace,"Lec/tstoolkit/algorithm/ProcessingContext;", "getContext")
    ts_variable_managers <- context_dictionary$getTsVariableManagers()
    ts_variables <- .jnew("ec/tstoolkit/timeseries/regression/TsVariables")
    jd_r_variables <- ts_variable_managers$get("r")
    if (is.null(jd_r_variables)) {
        ts_variable_managers$set("r",
                                 .jnew("ec/tstoolkit/timeseries/regression/TsVariables"))
        jd_r_variables <- ts_variable_managers$get("r")
    }
    jd_var_names <- jd_r_variables$getNames()
    
    model_var_names <- colnames(liste_var)
    
    for (i in seq_along(model_var_names)) {
        name <- model_var_names[i]
        dictionary_var <- jd_r_variables$get(name)
        tsvar <- .jnew("ec/tstoolkit/timeseries/regression/TsVariable",
                       name, RJDemetra:::ts_r2jd(liste_var[, i]))
        if (is.null(dictionary_var)) {
            jd_r_variables$set(name, tsvar)
        } else {
            warning(sprintf("La variable %s existe déjà", name))
        }
    }
}

# Création d'un nouveaux
jws <- new_workspace()
# regresseurs_JO est l'objet mts qui contient tous vos régresseurs
# Il doit donc déjà être créé (voir code ci-dessus) !
complete_variables(regresseurs_JO_mens, jws)
complete_variables(regresseurs_JO_trim, jws)
save_workspace(jws,"wk_CJO.xml")

Pour la version 3 de JDemetra+, le code est plus simple. Le code ci-dessous permet également d’ajouter le calendrier en tant qu’objet calendrier de JDemetra+ (et donc pas nécessairement besoin de passer par l’ajout de variables externes).

# On va créer deux groupes de variables, on peut donc simplifier les noms
colnames(regresseurs_JO_mens) <- 
    colnames(regresseurs_JO_trim) <- 
    gsub("_mens", "", colnames(regresseurs_JO_mens))
ctxt <- rjd3toolkit::modelling_context(
    # on appelle "CAL" le calendrier
    calendars = list(CAL = CAL), 
    # on crée un groupe de variables "cjo_mens" contenant les régresseurs mensuels
    # et un groupe de variables "cjo_trim" contenant les régresseurs trimestriels
    variables = list(cjo_mens = regresseurs_JO_mens,
                     cjo_trim = regresseurs_JO_trim)
) 

jws <- rjd3workspace::jws_new(ctxt)
# On peut également ajouter les calendriers et les variables avec les fonctions :
# rjd3workspace::add_variables()
# rjd3workspace::add_calendar()
# Pour modifier un workspace existant :
# rjd3workspace::set_context()
rjd3workspace::save_workspace(jws, "wk_CJO_v3.xml")

2.3 Créer une spécification incluant les jeux de régresseurs « jours ouvrables » personnalisés

  • Cliquer sur l’onglet Workspace.

  • Double cliquer sur Seasonal adjustment.

  • Double cliquer sur specifications.

  • Double cliquer sur x13.

  • Clic-droit sur RSA5c (ou RSA5 dans la version 3.x.y).

  • Cliquer sur Clone.

  • Que se passe-t-il ?

  • Double-cliquer sur X13Spec-1.

  • Cliquer sur le + à côté de Calendar.

  • Cliquer sur le + à côté de tradingDays.

  • Cliquer sur Default à côté de option et cliquer ensuite sur UserDefined.

  • Cliquer sur Unused à côté de userVariables.

  • Que se passe-t-il ?

  • Faire passer les 6 régresseurs du jeu de régresseurs TD6 + leap_year de la gauche vers la droite.

  • Cliquer sur le bouton Done.

  • Cliquer sur OK.

3 Réaliser une désaisonnalisation automatique de vos séries en utilisant la spécification X13Spec-1

Voir TP1.

4 Analyser les diagnostics relatifs à la correction des effets de calendrier

Pour chaque série, répondez aux questions suivantes :

  • Y a-t-il eu une correction des effets de calendrier ?

  • Si oui, est-ce que tous les coefficients associés aux régresseurs « JO » sont significativement différents de 0 ?

  • Si non, essayer d’autres jeux de régresseurs « JO »

  • Y a-t-il eu une correction de l’effet Pâques ?

  • La série CVS-CJO présente-t-elle des effets « Jours Ouvrables » résiduels ?