Quand RV ment-elle, et de combien ?
RV mesure la variance vraiment réalisée tick-by-tick — pas celle qu'on a supposée le matin.
La realized variance est l'estimateur empirique le plus simple qu'on puisse écrire sur des log-returns intraday : on les met au carré et on les somme sur une fenêtre temporelle. Mais simple n'est pas exact. Cette page nomme de combien RV ment quand on la lit à \(τ = 60 s\), et où elle pourrait mentir silencieusement si on l'implémentait sans discipline.
Définition
Soit m_i = (bid_i + ask_i) / 2 le mid-quote au tick i, et r_i = log(m_i) − log(m_{i-1}) le log-return entre deux ticks consécutifs. Pour une fenêtre
temporelle \(τ\) (en nanosecondes) :
La cible théorique est la integrated variance sur la même fenêtre :
— c'est l'intégrale de la variance instantanée du processus sous-jacent ([§2]). RV est l'estimateur empirique discret, IV est ce qu'on cherche vraiment à mesurer ; toute la suite de la page nomme l'écart entre les deux.
La fenêtre est temporelle, pas en éléments fixés. Raison : la densité de
ticks varie d'un facteur cinq entre 09:35 et 11:00 New York time
([Chap. 2 §2.4 — U-shape intraday] ;
docs/adr/0003-stats-and-classifier.md §1 L67-69). Compter en éléments
mélangerait deux régimes microstructurels distincts ; compter en temps les
sépare.
Convention en bordure : Err(EmptyWindow) si la fenêtre ne contient aucun
tick. Pas de NaN silencieux — invariant INV-RV-1 à INV-RV-5 de
l'ADR-0003 (docs/adr/0003-stats-and-classifier.md §1).
Algorithme — deque temporelle online
L'implémentation tient dans une VecDeque<(i64, f64)> qui mémorise les
couples (ts_ns, r²), plus un cumul sum_sq: f64. Voir
research/crates/salim-core/src/stats.rs
§RvAccumulator lignes 30-111 pour le code complet.
Étape de push(ts_ns, log_return) :
- Eviction temporelle :
while buf.front().0 < ts_ns - window_ns { sum_sq -= front.1; pop_front(); }. - Append :
sum_sq += r²; buf.push_back((ts_ns, r²)). - Snapshot :
sum_sqdirectement — pas de re-calcul.
Coût amorti O(1) par push, pire cas O(k) où k est le nombre d'éléments
expulsés au tick courant (rare en pratique, borné par INV-RV-2 ci-dessous).
Une discipline debug_assert!(sum_sq ≥ 0) post-eviction protège contre la
dérive négative quand la fenêtre se vide
(research/crates/salim-core/src/stats.rs:76-81).
Borne d'erreur — Andersen–Bollerslev–Diebold–Labys 2003
C'est le nombre qui doit être lu en même temps que la valeur. Sous le modèle BS-Heston, pour un nombre \(N = τ/Δ\) de ticks à pas régulier :
Cette variance asymptotique remonte à Barndorff-Nielsen & Shephard (2002, JRSS-B 64) — c'est là qu'elle est dérivée la première fois pour une diffusion stochastic-volatility générale. Andersen et al. (2003) la restatent dans le contexte du modèle BS-Heston empirique adopté ici ([§3 Eq. 3, p. 587] pour la formule de variance ; [§3 Thm. 2, p. 587] pour la consistance \(RV →_p IV\) quand \(Δ → 0\)). La référence canonique sur cette page reste Andersen-Bollerslev-Diebold-Labys, parce que c'est le cadre empirique qu'on instrumentalise — la dette de paternité va à BN&S 2002.
Numériquement, à \(τ = 60 s\) avec un pas régulier \(Δ = 1 s\) (donc N = 60,
hypothèse de tick rate constant à 1 Hz) :
— le 18,3 % est dérivé directement de la formule de variance ci-dessus
([§3 Eq. 3, p. 587]). C'est du bruit estimateur,
pas de la vraie volatilité. Salim qui lit RV_short(60s) = 2 · baseline
lit en réalité, à 1-σ :
(propagation multiplicative directe ; [§3 Eq. 3, p. 587]). Le seuil binaire « calme/agité » devient une zone floue.
Attention au tick rate. Le N = 60 ci-dessus suppose \(Δ = 1 s\) régulier.
Sur un MBP-10 NY-open réel, le tick rate atteint 10-50 Hz, donc N est
plutôt 600-3000 sur une fenêtre de 60 s, et le bruit relatif tombe à
\(√(2/600) ≈ 5,8 \%\) voire \(√(2/3000) ≈ 2,6 \%\). Le 18,3 % est une
borne pessimiste pour un pas régulier 1 Hz ; le détail tick-rate-dépendant
est repris plus bas (§ Pour ton cas).
Stabilité numérique — f64 naïf suffit (table compressée)
Le \(Σ r²\) peut être implémenté de cinq façons connues. Pour RV non-centered
sur n ticks bornés \(|n| ≤ 6·10⁶\) (peak ARM open dans
docs/adr/0003-stats-and-classifier.md §1 L72) :
| Méthode | Borne erreur relative | Verdict |
|---|---|---|
f64 naïf sum_sq += r² | \((n−1)·u ≈ 7·10⁻¹⁰\) à \(n = 6·10⁶\) ([Thm. 4.1, p. 82]) | OK — adopté |
| Pairwise summation | \(O(log n)·u ≈ 2·10⁻¹⁵\) ([§4.2 Algo., p. 89]) | Overkill |
| Kahan compensated | \(≈ 2u ≈ 2·10⁻¹⁶\) ([Thm. 4.8, p. 84]) | Overkill |
| Welford one-pass | O(u) indep de n (Welford 1962) | Interdit pour RV — voir docs/adr/0003-stats-and-classifier.md §1 L72-86 |
Pourquoi Welford est interdit, en une phrase : RV n'a pas de moyenne soustraite
(c'est \(Σ r²\), pas \(Σ (r − r̄)²\)), donc la cancellation que Welford corrige
n'existe pas, et la version Welford de RV exigerait un état supplémentaire
sans gain d'exactitude
(docs/adr/0003-stats-and-classifier.md §1 L79-86).
L'erreur du f64 naïf à \(7·10⁻¹⁰\) ([Thm. 4.1, p. 82])
est dix-huit ordres de grandeur plus petite que le bruit estimateur de
18 % ([§3 Eq. 3, p. 587]) calculé ci-dessus.
Optimiser la première sans bouger la seconde est du cargo cult.
Pour ton cas
Pour toi, Salim, en clair :
- Si tu surveilles
RV_short(60s)avec un pas de calcul \(Δ = 1 s\) (doncN = 60), ta valeur t'arrive avec \(\pm18,3\) % de bruit relatif ([§3 Eq. 3, p. 587]) — c'est intrinsèque à l'estimateur, pas un bug. Sur un vrai flux MBP-10 NY-open à 10-50 Hz,Nest bien plus grand (600-3000sur 60 s) et le bruit tombe proportionnellement à \(√(2/N)\) — donc5,8 %à 10 Hz,2,6 %à 50 Hz. Le18,3 %est la borne pessimiste à 1 Hz. - Un seuil mental « rough quand \(RV > 2 × baseline\) » est en réalité « rough quand \(RV / baseline ∈ [1{,}634,\ 2{,}366]\) » à 1-σ (propagation directe des \(±18{,}3\ \%\) ci-dessus, en supposant \(N = 60\)). Le seuil flotte.
- C'est pour ça que le classifier de régime utilise hystérèse + dwell
(regime-classifier ;
docs/adr/0003-stats-and-classifier.md§4) plutôt qu'un seuil dur : l'hystérèse couvre la zone floue d'incertitude estimateur, le dwell évite qu'un tick chanceux ne bascule l'état.
Si tu veux serrer le \(±18,3 \%\), deux leviers honnêtes :
- Augmenter \(τ\) (donc
N, donc latence de décision) : à \(τ = 600 s\) avec \(Δ = 1 s\),N = 600et le bruit tombe à \(√(2/600) ≈ 5,8 \%\) ([§3 Eq. 3, p. 587]). C'est la raison du double horizonRV_short(60s) / RV_long(600s)de l'ADR-0003 §1. - Exploiter le tick rate réel : sur un flux dense,
N = τ · tick_rateest déjà grand sans toucher \(τ\). À 10 Hz NY-open,RV_short(60s)a déjà \(N ≈ 600\) et donc5,8 %de bruit. La latence reste à 60 s mais la précision suit le tick rate.
Limites du résultat
- Le
r_i = log(m_i) − log(m_{i-1})suppose le mid-price stable d'un tick à l'autre. Quand le spread saute (> 1 tick),m_ibouge mécaniquement et injecte du bruit microstructure dansRV— biais documenté dans [Chap. 2] (« bid-ask bounce »). - La formule \(Var(RV) ≈ 2 IV²(Δ/τ)\) ([§3 Eq. 3, p. 587] ; dérivation originale Barndorff-Nielsen & Shephard 2002, JRSS-B
64) suppose des returns i.i.d. quasi-normaux sans saut. Avec sauts
purs, le biais est dans le numérateur (
RVcapte aussi \(Σ J²\)) — c'est exactement ce queJ = 1 − BV/RVmesure, voir bipower-and-jumps. - Le
N = 60qu'on cite pour le18,3 %suppose \(Δ = 1 s\) régulier. Sur un vrai flux MBP-10, le tick rate est variable (5-50 Hz selon l'heure) et leNeffectif est généralement bien plus grand — le18,3 %est une borne pessimiste, pas une mesure typique du bruit. - La discipline
f64naïf bornée à \(7·10⁻¹⁰\) ([Thm. 4.1, p. 82]) suppose que \(n ≤ 6·10⁶\) ; au-delà, repasser par pairwise ou Kahan sans changer le contrat. Re-vérifierINV-RV-4de l'ADR-0003 §1.
Adversaire endogène
estimator-instability — le risque que Salim sur-interprète une valeur
ponctuelle de RV ou un franchissement de seuil isolé. Antidote nommé dans
cette page : la borne \(±18,3 \%\) à N = 60 ([§3 Eq. 3, p. 587]) est lue en même temps que la valeur, et reliée
explicitement à la nécessité d'hystérèse côté classifier
(docs/adr/0003-stats-and-classifier.md §4).
Références
- ADR mère :
docs/adr/0003-stats-and-classifier.md§1 (L30-L110) - Code Rust :
research/crates/salim-core/src/stats.rs§RvAccumulator(L30-L111) - Pages adjacentes : bipower-and-jumps (cite RV pour
J = 1 − BV/RV), regime-classifier (consommeR(t) = RV_short / RV_long) -
Sources externes :
- Andersen, T. G., Bollerslev, T., Diebold, F. X., & Labys, P. (2003). Modeling and Forecasting Realized Volatility. Econometrica 71(2), 579–625. §3 Thm. 2 (p. 587) (consistance \(RV →_p IV\) quand \(Δ → 0\)) ; §3 Eq. 3 (p. 587) (variance d'estimateur \(Var(RV) ≈ 2·IV²·(Δ/τ)\), restatement empirique du résultat originalement dérivé dans Barndorff-Nielsen & Shephard 2002).
- Barndorff-Nielsen, O. E. & Shephard, N. (2002). Econometric analysis of realized volatility and its use in estimating stochastic volatility models. Journal of the Royal Statistical Society: Series B 64(2), 253–280. Dérivation originale de la variance asymptotique de RV sous diffusion stochastic-volatility (cité ici pour paternité, pas chargé dans Zotero — cosmon-ward ticket à ouvrir pour citekey si re-cité ailleurs).
- Higham, N. J. (2002). Accuracy and Stability of Numerical Algorithms, 2nd ed., SIAM. Thm. 4.1 (p. 82) (somme récursive, borne \((n−1)·u\)) ; §4.2 (p. 89) (pairwise summation, borne \(O(log n)·u\)) ; Thm. 4.8 (p. 84) (Kahan compensated sum, borne \(≈ 2u\)).
- Bouchaud, J.-P., Bonart, J., Donier, J., Gould, M. (2018). Trades, Quotes and Prices. Cambridge University Press. Chap. 2 §2.4 (U-shape intraday) ; Chap. 2 (bid-ask bounce).