Modélisation ARMA des rentabilités financières
Mise en œuvre sur R
- Présentation du cours
- Variable aléatoire et processus stochastique
- La stationnarité
- Le bruit blanc
- L'opérateur retard et l'écriture polynomiale
- Les processus autorégressifs AR(p)
- Les processus de moyenne mobile MA(q)
- Les processus mixtes ARMA(p,q)
- Conditions de stationnarité et d'inversibilité
- Les tests de racine unitaire
- Espérance, variance et fonction d'autocovariance
- Autocorrélation, autocorrélogramme et mémoire
- Box et Jenkins : l'identification
- Le choix du modèle par les critères d'information
- L'estimation : moindres carrés et maximum de vraisemblance
- La validation, et ce que les résidus révèlent
- La prévision : ponctuelle, par intervalle, par densité
- Mise en œuvre sur R
- Mise en œuvre sur Python
Modélisation ARMA des rentabilités financières
Chapitre 16 : Mise en œuvre sur R
Avant de commencer
Le jeu de données
2 000 rentabilités quotidiennes simulées, fournies avec le cours. Trois colonnes : date, prix, rentabilite (en pourcentage).
Parce qu’on sait ce qu’on y a mis. Le mécanisme générateur est connu : aucune mémoire en niveau, une forte persistance de la volatilité. On peut donc vérifier que la démarche retrouve ce qui s’y trouve — et ne trouve pas ce qui ne s’y trouve pas. Sur données réelles, on ne peut jamais faire cette vérification.
Les bibliothèques
install.packages(c("forecast", "tseries", "FinTS"))
library(forecast) # Acf, Pacf, auto.arima, forecast, checkresiduals
library(tseries) # adf.test, kpss.test, jarque.bera.test
library(FinTS) # ArchTestÉtape 1 — Lire et décrire
Charger la série
don <- read.csv("rentabilites.csv", stringsAsFactors = FALSE)
don$date <- as.Date(don$date)
r <- don$rentabilite
T <- length(r) # 2000c(moyenne = mean(r),
ecart_type = sd(r),
minimum = min(r),
maximum = max(r)) moyenne ecart_type minimum maximum
0.0300 1.1764 -5.8412 4.9037
Les faits stylisés, en trois nombres
library(moments)
skewness(r) # -0.19
kurtosis(r) # 6.60
jarque.bera.test(r)Un kurtosis de 6{,}6 contre 3 pour une gaussienne : les valeurs extrêmes sont bien plus fréquentes que la loi normale ne l’autorise. Jarque-Bera rejette massivement.
Ce n’est pas un obstacle à la modélisation ARMA — le chapitre 13 l’a établi, l’estimateur reste convergent. C’est un obstacle aux intervalles de prévision.
Regarder la série
plot(don$date, r, type = "l", col = "steelblue",
xlab = "", ylab = "rentabilité (%)")
abline(h = 0, lty = 2, col = "grey40")Pas de tendance, pas de dérive : la moyenne semble stable. Mais l’amplitude, elle, ne l’est pas — des blocs calmes alternent avec des blocs agités. Retenez cette observation : le test formel viendra à la fin.
Étape 2 — La stationnarité
Les trois tests du chapitre 8
adf.test(r) # H0 : racine unitaire
pp.test(r) # idem, Phillips-Perron
kpss.test(r, null = "Level") # H0 : stationnaritéAugmented Dickey-Fuller Test
Dickey-Fuller = -12.517, Lag order = 12, p-value = 0.01
alternative hypothesis: stationary
KPSS Test for Level Stationarity
KPSS Level = 0.1174, Truncation lag parameter = 8, p-value = 0.1
Croiser les conclusions
ADF rejette la racine unitaire (p < 0{,}01). KPSS ne rejette pas la stationnarité (p > 0{,}1).
C’est la première ligne de la table de décision du chapitre 8 : conclusion sans ambiguïté, la série est I(0).
R affiche p-value smaller than printed p-value. Cela signifie que la p-valeur est hors table, donc encore plus petite que 0{,}01 — pas qu’il y a un problème.
Étape 3 — Identifier
Les corrélogrammes
par(mfrow = c(1, 2))
Acf(r, lag.max = 20, main = "ACF des rentabilités")
Pacf(r, lag.max = 20, main = "PACF des rentabilités")Les 20 autocorrélations sont toutes à l’intérieur des bandes \pm 1{,}96/\sqrt{2000} = \pm 0{,}044. La plus forte vaut 0{,}034 au retard 3.
Aucune structure. Le candidat naturel est ARMA(0,0) — le bruit blanc.
Le test de blancheur, d’emblée
Box.test(r, lag = 20, type = "Ljung-Box")Box-Ljung test
X-squared = 20.351, df = 20, p-value = 0.4368
Q_{\mathrm{LB}}(20) = 20{,}4 contre une valeur critique de 31{,}4. On ne rejette pas : les rentabilités sont un bruit blanc au sens linéaire.
C’est l’efficience faible, mesurée. Le cours pourrait s’arrêter là — et c’est précisément pour cela qu’il ne s’arrête pas là.
La sélection automatique
auto.arima(r, max.p = 4, max.q = 4, d = 0,
seasonal = FALSE, ic = "bic", stepwise = FALSE)Series: r
ARIMA(0,0,0) with non-zero mean
sigma^2 = 1.3841: log likelihood = -3157.62
AIC=6319.24 AICc=6319.25 BIC=6330.44
Le modèle vide, avec une simple constante. La procédure du chapitre 12 confirme la lecture des corrélogrammes.
Comparer les candidats à la main
grille <- expand.grid(p = 0:3, q = 0:3)
res <- t(apply(grille, 1, function(o) {
m <- try(arima(r, order = c(o[1], 0, o[2])), silent = TRUE)
if (inherits(m, "try-error")) c(NA, NA)
else c(AIC = AIC(m), BIC = BIC(m))
}))
cbind(grille, res)[order(res[, 2]), ][1:4, ] p q AIC BIC
1 0 0 6319.240 6330.442
2 1 0 6320.518 6337.321
3 0 1 6320.531 6337.334
5 1 1 6321.921 6344.325
Le minimum du BIC est atteint en (0,0), et les écarts avec les voisins sont de l’ordre de 7 points — c’est net. Ajouter un paramètre coûte \ln(2000) = 7{,}6 et ne rapporte presque rien.
Étape 4 — Estimer et valider
Estimer, pour la démonstration
mod <- arima(r, order = c(1, 0, 0))
modCoefficients:
ar1 intercept
0.0192 0.0300
s.e. 0.0224 0.0269
\hat\alpha_1 = 0{,}019 avec un écart-type de 0{,}022 : le rapport de Student vaut 0{,}86, très loin de 1{,}96. Le coefficient n’est pas significatif.
Et même s’il l’avait été : un \alpha de 0{,}02 signifie que la rentabilité d’hier explique 0{,}04\,\% de celle d’aujourd’hui. Aucun coût de transaction ne le laisserait exploiter.
Valider
checkresiduals(mod, lag = 20)Ljung-Box test
Q* = 20.06, df = 19, p-value = 0.3907
res <- residuals(mod)
jarque.bera.test(res) # rejeté : queues épaissesValider (suite)
Valider (suite 2)
Résidus non autocorrélés, mais non gaussiens. Le modèle est valide au sens linéaire, et ses intervalles de prévision sont suspects.
Étape 5 — Prévoir
Prévision ponctuelle et intervalle
p <- forecast(mod, h = 10, level = c(80, 95))
p Point Forecast Lo 95 Hi 95
2001 0.0300 -2.2762 2.3362
2002 0.0300 -2.2766 2.3366
2005 0.0300 -2.2766 2.3366
La prévision ponctuelle est constante et égale à la moyenne dès le premier pas — puisque \alpha \simeq 0, il n’y a rien à propager.
L’intervalle est lui aussi constant : \pm 2{,}31, soit 1{,}96 \times 1{,}176. C’est la volatilité moyenne de tout l’échantillon, appliquée indifféremment à demain.
Étape 6 — Ce qui a échappé
Regarder les résidus au carré
Acf(res^2, lag.max = 20, main = "ACF des résidus au carré")
Box.test(res^2, lag = 20, type = "Ljung-Box")Box-Ljung test
X-squared = 814.02, df = 20, p-value < 2.2e-16
| Série testée | Q_{\mathrm{LB}}(20) | p-valeur |
|---|---|---|
| résidus \hat\varepsilon_t | 20{,}1 | 0{,}39 |
| résidus au carré \hat\varepsilon_t^2 | 814{,}0 | < 10^{-16} |
Le test ARCH
ArchTest(res, lags = 12)ARCH LM-test; Null hypothesis: no ARCH effects
Chi-squared = 274.53, df = 12, p-value < 2.2e-16
Les rentabilités sont non corrélées — Ljung-Box ne rejette pas. Elles ne sont pas indépendantes — le test ARCH rejette avec une force écrasante.
Bruit blanc faible, pas bruit blanc fort. La distinction du chapitre 2 se lit ici dans deux p-valeurs.
Ce qu’il faut modéliser maintenant
library(rugarch)
spec <- ugarchspec(
variance.model = list(model = "sGARCH", garchOrder = c(1, 1)),
mean.model = list(armaOrder = c(0, 0), include.mean = TRUE),
distribution.model = "std") # Student : queues épaisses
fit <- ugarchfit(spec, data = r)L’armaOrder est ce que ce cours a déterminé. Le variance.model est l’objet du cours suivant.
Synthèse
Ce qu’il faut retenir
adf.testetkpss.testse lisent ensemble ; ici, série I(0) sans ambiguïté.Acf/Pacf: rien hors des bandes.Box.test: Q = 20{,}4, non rejeté.auto.arimaavecic = "bic"retient ARMA(0,0).forecastdonne une prévision constante et un intervalle constant — la volatilité moyenne.Box.testsur les carrés : Q = 814.ArchTest: rejet massif.- Le diagnostic complet tient en six commandes, et il désigne les GARCH.
La même démarche, la même série, les mêmes conclusions — en Python. L’intérêt n’est pas la répétition : c’est de constater que la méthode ne dépend pas de l’outil.
Ressources du chapitre
- Diapositives
- Polycopié du chapitre
- Exercices corrigés
- Application interactive
- — Vidéo
- QCM (bientôt)