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 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) :

\[ \mathrm{RV}(t, \tau) = \sum_{i\ :\ t_i \in (t-\tau,\ t]} r_i^{\,2} \]

La cible théorique est la integrated variance sur la même fenêtre :

\[ \mathrm{IV}(t, \tau) = \int_{t-\tau}^{t} \sigma^{2}(s)\, ds \]

— 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) :

  1. Eviction temporelle : while buf.front().0 < ts_ns - window_ns { sum_sq -= front.1; pop_front(); }.
  2. Append : sum_sq += r²; buf.push_back((ts_ns, r²)).
  3. Snapshot : sum_sq directement — pas de re-calcul.

Coût amorti O(1) par push, pire cas O(k)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 :

\[ \mathrm{Var}(\mathrm{RV}) \approx 2 \cdot \mathrm{IV}^{2} \cdot \frac{\Delta}{\tau} \qquad \sigma(\mathrm{RV}) \approx \mathrm{IV} \cdot \sqrt{\frac{2}{N}} \]

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) :

\[ \sigma(\mathrm{RV}_{\text{short}}) / \mathrm{IV} \approx \sqrt{2/60} \approx 18{,}3\ \% \]

— 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-σ :

\[ \mathrm{RV}_{\text{short}} / \text{baseline}\ \in\ 2 \cdot (1 \pm 0{,}183)\ =\ [1{,}634,\ 2{,}366] \]

(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éthodeBorne erreur relativeVerdict
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-passO(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 veux serrer le \(±18,3 \%\), deux leviers honnêtes :

  1. Augmenter \(τ\) (donc N, donc latence de décision) : à \(τ = 600 s\) avec \(Δ = 1 s\), N = 600 et le bruit tombe à \(√(2/600) ≈ 5,8 \%\) ([§3 Eq. 3, p. 587]). C'est la raison du double horizon RV_short(60s) / RV_long(600s) de l'ADR-0003 §1.
  2. Exploiter le tick rate réel : sur un flux dense, N = τ · tick_rate est déjà grand sans toucher \(τ\). À 10 Hz NY-open, RV_short(60s) a déjà \(N ≈ 600\) et donc 5,8 % de bruit. La latence reste à 60 s mais la précision suit le tick rate.

Limites du résultat


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