Savoir comment calculer la volatilité des devises, c'est la différence entre une application multidevise qui absorbe sans broncher un mouvement de 2 % du jour au lendemain et une autre qui vous réveille à 3 heures du matin. La volatilité est le seul chiffre qui vous dit jusqu'où un taux de change est susceptible d'aller — et presque toutes les décisions concrètes d'un système exposé au change en dépendent : combien de temps une cotation reste valable, quelle marge ajouter à un prix, quand se couvrir et quand déclencher une alerte.
Le problème, c'est que la plupart des tutoriels sur le calcul de la volatilité ont été écrits pour les actions. Ils supposent un cours de clôture quotidien, une année boursière de 252 jours et une cotation unique et sans ambiguïté. Le marché des changes n'a rien de tout cela. Il fonctionne 24 heures sur 24, cinq jours sur sept, sur un marché de gré à gré décentralisé sans clôture officielle, et le « prix » de EUR/USD dépend du sens dans lequel vous cotez la paire.
Ce guide parcourt les mathématiques réelles, les pièges propres au change et du code fonctionnel en Python et JavaScript qui calcule la volatilité réalisée à partir de données historiques de taux de change.
Pourquoi la volatilité des devises compte en ce moment
Septembre 2026 est un moment particulièrement bien choisi pour réfléchir à la volatilité, car le marché a passé la majeure partie de l'année dans un régime suspicieusement calme — avant de cesser brièvement de l'être.
Pendant l'été, les devises émergentes ont été moins volatiles que celles du G7 pendant près de 200 séances consécutives, une série qui, selon Bloomberg, serait la plus longue depuis 2000 si elle se maintenait. Les opérations de carry trade financées en dollars ont enchaîné leur meilleure série depuis 2008, et un panier populaire financé en euros composé de real brésilien, de peso colombien et de livre turque affichait, d'après les chiffres publiés, une hausse d'environ 19 % depuis le début de l'année — la meilleure performance à cette période depuis 2005. Les stratégies de carry ne fonctionnent que sur des marchés calmes : leur performance est donc en soi un signal de volatilité.
Puis, début septembre, le yen a bondi de plus de 2 % face au dollar en une seule séance pour toucher 155,28, son plus haut niveau depuis début août, les opérateurs anticipant une nouvelle intervention du ministère japonais des Finances. Cet épisode faisait suite à une intervention conjointe États-Unis–Japon le 31 juillet et à un record de 11 730 milliards de yens (environ 73 milliards de dollars) d'intervention du MOF sur avril et mai, après que USD/JPY a franchi 160.
Ce contraste résume toute la leçon. La volatilité moyenne était faible. La volatilité réalisée un jour donné a été énorme. Un système qui aurait dimensionné ses marges de change sur une moyenne annuelle glissante se serait lourdement trompé précisément le jour où cela comptait. Mesurer la volatilité correctement — et en continu — est ce qui évite cela.
Ce que mesure réellement la volatilité des devises
La volatilité est l'écart-type des rendements, exprimé sur une base annualisée. Ce n'est pas une prévision de direction, et ce n'est pas la taille d'un mouvement. C'est une mesure de dispersion : à quel point les rendements quotidiens d'une paire de devises se dispersent autour de leur moyenne.
Deux variantes comptent :
- La volatilité réalisée (historique) — calculée rétrospectivement à partir des taux réellement observés. C'est celle que vous pouvez calculer vous-même à partir d'une série temporelle, et c'est celle que couvre ce guide.
- La volatilité implicite — extraite des prix des options de change. C'est l'estimation prospective du marché. Vous ne pouvez pas la déduire des taux au comptant ; il vous faut un flux de données d'options.
Pour la plupart des développeurs d'applications — tarification, facturation, tableaux de bord de trésorerie, alertes de risque — la volatilité réalisée est à la fois suffisante et gratuite à calculer si vous disposez déjà de taux historiques.
Un ordre de grandeur : les paires majeures comme EUR/USD évoluent généralement entre 5 et 10 % annualisés en période calme, et entre 10 et 15 % en période de tension. Les paires émergentes tournent couramment deux à trois fois plus haut. Ces fourchettes se déplacent dans le temps, et c'est précisément pour cela qu'il faut mesurer plutôt que supposer.
La formule : rendements logarithmiques, écart-type, annualisation
Le calcul tient en trois étapes.
Étape 1 — Convertir les taux en rendements logarithmiques.
r_t = ln(P_t / P_t-1)Étape 2 — Calculer l'écart-type de ces rendements sur la fenêtre choisie (utilisez l'écart-type d'échantillon, en divisant par n − 1).
Étape 3 — Annualiser en multipliant par la racine carrée du nombre d'observations par an.
annualised_volatility = stdev(r) * sqrt(N)Au total :
σ_annual = stdev( ln(P_t / P_t-1) ) × √NPourquoi des rendements logarithmiques plutôt qu'une variation en pourcentage
La variation en pourcentage simple est asymétrique : passer de 1,10 à 1,20 fait +9,09 %, mais le trajet retour de 1,20 à 1,10 fait −8,33 %. Les deux devraient être égaux et opposés. Les rendements logarithmiques le sont : ln(1.20/1.10) et ln(1.10/1.20) ne diffèrent que par le signe.
Cela compte bien plus sur le change que sur les actions, à cause de l'inversion de la cotation. EUR/USD et USD/EUR décrivent le même marché. Si vous calculez la volatilité avec des variations en pourcentage, vous obtenez deux réponses légèrement différentes selon le sens dans lequel vous avez coté la paire, ce qui est manifestement faux. Les rendements logarithmiques sont symétriques par inversion : ln(1/x) = −ln(x), et l'écart-type ignore le signe. Même paire, même volatilité, dans les deux sens.
Les rendements logarithmiques sont aussi additifs dans le temps, ce qui rend l'agrégation sur plusieurs jours triviale.
Pourquoi √N — et quelle valeur donner à N pour le change
La volatilité évolue comme la racine carrée du temps, parce que la variance évolue linéairement avec le temps (sous l'hypothèse standard de marche aléatoire). Pour convertir une volatilité quotidienne en volatilité annuelle, multipliez par √(days per year).
Les tutoriels actions utilisent 252, le nombre approximatif de jours de cotation des bourses américaines. Le change, c'est différent. Le marché tourne en continu du dimanche soir au vendredi soir — soit environ 260 séances en jours ouvrés par an, moins une poignée de jours fériés peu actifs. La plupart des fournisseurs de données de change publient des taux tous les jours ouvrés, y compris ceux où le marché d'un pays donné est fermé.
La règle pratique : N doit correspondre à la fréquence d'échantillonnage de vos données, et non à une convention empruntée à une autre classe d'actifs.
| Fréquence des données | N (facteur d'annualisation) |
|---|---|
| Quotidienne (jours ouvrés, convention change) | 260 |
| Quotidienne (convention actions à 252 jours) | 252 |
| Hebdomadaire | 52 |
| Mensuelle | 12 |
| Horaire (24×5) | ~6 240 |
Étape 1 : récupérer des données historiques de taux de change propres
Une volatilité ne vaut que la série qui la sous-tend. Récupérez une série quotidienne en un seul appel à l'endpoint /v1/timeseries :
curl -G "https://api.finexly.com/v1/timeseries" \
-H "Authorization: Bearer YOUR_API_KEY" \
-d base=EUR \
-d symbols=USD,JPY,GBP \
-d start_date=2026-06-08 \
-d end_date=2026-09-05La réponse est une map indexée par date :
{
"success": true,
"base": "EUR",
"start_date": "2026-06-08",
"end_date": "2026-09-05",
"rates": {
"2026-06-08": { "USD": 1.1421, "JPY": 178.62, "GBP": 0.8447 },
"2026-06-09": { "USD": 1.1408, "JPY": 178.94, "GBP": 0.8451 }
}
}Une requête, une série, pas de boucle de pagination. La référence complète des paramètres se trouve dans la documentation de l'API Finexly, et les schémas plus généraux pour travailler avec des plages de dates sont traités dans notre guide de l'API de taux de change historiques.
Quatre problèmes de données propres au change
Avant de faire confiance au résultat, réglez ces points. Aucun n'apparaît dans un tutoriel de volatilité actions, et les quatre fausseront votre chiffre.
1. Il n'existe pas de clôture officielle. Le change est décentralisé ; personne ne sonne la cloche. Chaque fournisseur prend son instantané à un moment différent — 22:00 UTC, minuit UTC, le fixing de référence de la BCE de 14:15 CET, ou le fixing WM/Reuters de 16 h à Londres. Mélanger des heures d'instantané au sein d'une même série injecte de la variance artificielle. Choisissez une convention et ne la mélangez jamais. Si vous ne savez pas exactement ce que fait votre fournisseur, notre explication sur d'où les API de taux de change tirent leurs données est un bon point de départ.
2. Week-ends et trous. Le marché ferme le vendredi soir et rouvre le dimanche soir. Un rendement du vendredi au lundi couvre environ 65 heures de temps calendaire, mais il est traité comme un seul « jour » dans un calcul naïf. La plupart des praticiens l'acceptent et annualisent sur un décompte en jours ouvrés — l'approche standard — mais il faut rester cohérent. Ne reportez pas les taux du week-end par recopie dans la série : une suite de valeurs identiques tirera votre écart-type artificiellement vers le bas.
3. Asymétrie de la devise de base. Comme vu plus haut, les rendements logarithmiques règlent mathématiquement le problème de l'inversion. Mais il reste à décider dans quelle base vous mesurez le risque. La volatilité de votre exposition en USD mesurée en EUR est une question métier différente de celle de la même paire mesurée en USD, même si le chiffre sort identique. Soyez explicite sur le numéraire.
4. Croisements triangulés. Si votre fournisseur dérive par exemple SEK/NOK en divisant SEK/USD par NOK/USD, le résultat hérite du bruit des deux jambes et de tout décalage temporel entre elles. Les croisements synthétiques peuvent afficher une volatilité nettement supérieure à celle du marché coté directement. Notre guide sur les taux de change croisés explique quand la triangulation est sûre et quand elle ne l'est pas.
Surveillez aussi la précision. Tronquer les paires en JPY à deux décimales avant de calculer les rendements écrase les petits mouvements à zéro et biaise la volatilité vers le bas — voir arrondis et décimales des devises pour la règle générale. Stockez en pleine précision ; n'arrondissez qu'à l'affichage.
Étape 2 : calculer la volatilité réalisée en Python
Voici une implémentation complète et légère en dépendances. Elle utilise requests et la bibliothèque standard — pas besoin de pandas.
import math
import statistics
import requests
FX_DAYS_PER_YEAR = 260 # weekday sessions; use 252 for the equity convention
def fetch_series(base, symbol, start, end, api_key):
url = "https://api.finexly.com/v1/timeseries"
params = {
"base": base,
"symbols": symbol,
"start_date": start,
"end_date": end,
}
headers = {"Authorization": "Bearer " + api_key}
response = requests.get(url, params=params, headers=headers, timeout=10)
response.raise_for_status()
return response.json()["rates"]
def log_returns(rates, symbol):
"""Ordered log returns from a date-keyed rates map."""
dates = sorted(rates.keys())
series = [rates[d][symbol] for d in dates]
return [
math.log(series[i] / series[i - 1])
for i in range(1, len(series))
if series[i] > 0 and series[i - 1] > 0
]
def annualised_volatility(returns, periods_per_year=FX_DAYS_PER_YEAR):
if len(returns) < 2:
raise ValueError("need at least two returns")
return statistics.stdev(returns) * math.sqrt(periods_per_year)
rates = fetch_series("EUR", "USD", "2026-06-08", "2026-09-05", "YOUR_API_KEY")
returns = log_returns(rates, "USD")
vol = annualised_volatility(returns)
print("Observations: {}".format(len(returns)))
print("Daily volatility: {:.4%}".format(vol / math.sqrt(FX_DAYS_PER_YEAR)))
print("Annual volatility: {:.2%}".format(vol))statistics.stdev est l'écart-type d'échantillon (dénominateur n − 1), ce qui est bien ce que vous voulez. Si vous passez à NumPy, rappelez-vous que numpy.std utilise par défaut la version de population — passez ddof=1 pour retrouver le même résultat.
Deux garde-fous à conserver en production : écartez les taux non positifs avant de prendre un logarithme, et refusez de renvoyer un chiffre pour une fenêtre comptant trop peu d'observations. Une volatilité 30 jours calculée sur neuf points n'est pas une volatilité 30 jours.
Étape 3 : le même calcul en JavaScript
Ici non plus, aucune bibliothèque numérique n'est nécessaire.
const FX_DAYS_PER_YEAR = 260;
async function fetchSeries(base, symbol, start, end, apiKey) {
const url = new URL('https://api.finexly.com/v1/timeseries');
url.searchParams.set('base', base);
url.searchParams.set('symbols', symbol);
url.searchParams.set('start_date', start);
url.searchParams.set('end_date', end);
const res = await fetch(url, {
headers: { Authorization: `Bearer ${apiKey}` },
});
if (!res.ok) throw new Error(`Finexly returned ${res.status}`);
const body = await res.json();
return body.rates;
}
function logReturns(rates, symbol) {
const dates = Object.keys(rates).sort();
const series = dates.map((d) => rates[d][symbol]);
const out = [];
for (let i = 1; i < series.length; i += 1) {
if (series[i] > 0 && series[i - 1] > 0) {
out.push(Math.log(series[i] / series[i - 1]));
}
}
return out;
}
function annualisedVolatility(returns, periodsPerYear = FX_DAYS_PER_YEAR) {
if (returns.length < 2) throw new Error('need at least two returns');
const mean = returns.reduce((a, b) => a + b, 0) / returns.length;
const variance =
returns.reduce((acc, r) => acc + (r - mean) ** 2, 0) / (returns.length - 1);
return Math.sqrt(variance) * Math.sqrt(periodsPerYear);
}
const rates = await fetchSeries('EUR', 'USD', '2026-06-08', '2026-09-05', 'YOUR_API_KEY');
const vol = annualisedVolatility(logReturns(rates, 'USD'));
console.log(`Annualised volatility: ${(vol * 100).toFixed(2)}%`);Notez le dénominateur (returns.length - 1) — la même correction de variance d'échantillon que dans la version Python.
Volatilité glissante et détection d'un changement de régime
Un chiffre unique sur une fenêtre fixe ne dit presque rien sur le moment où les choses se sont agitées. La volatilité glissante, si — et c'est la version que vous voulez réellement sur un tableau de bord.
def rolling_volatility(rates, symbol, window=30,
periods_per_year=FX_DAYS_PER_YEAR):
dates = sorted(rates.keys())
series = [rates[d][symbol] for d in dates]
returns = [math.log(series[i] / series[i - 1]) for i in range(1, len(series))]
return_dates = dates[1:]
out = []
for i in range(window - 1, len(returns)):
chunk = returns[i - window + 1:i + 1]
out.append((
return_dates[i],
statistics.stdev(chunk) * math.sqrt(periods_per_year),
))
return out
for date, vol in rolling_volatility(rates, "USD", window=30)[-5:]:
print("{} {:.2%}".format(date, vol))Le choix de la fenêtre est un compromis, pas une vérité :
- 10 jours — très réactive, très bruitée. Bien pour les alertes, mauvais pour la tarification.
- 30 jours — la valeur par défaut habituelle. Réagit en quelques séances sans partir dans tous les sens.
- 90 jours — lisse et stable. Bien pour fixer des ratios de couverture et des marges de prix.
Un signal pratique de changement de régime est le ratio de volatilité : divisez la volatilité 10 jours par la volatilité 90 jours. Des lectures durablement supérieures à environ 1,5 signifient que la dispersion à court terme a nettement dépassé la référence longue. Appliqué aux paires en yen autour des épisodes d'intervention décrits plus haut, ce ratio s'envole alors que le chiffre à 90 jours bouge à peine — et c'est précisément l'intérêt. Les fenêtres longues masquent les événements ; les courtes les trouvent.
Si vous comptez faire tourner cela en continu sur de nombreuses paires, lisez d'abord nos notes sur le cache et la gestion des erreurs pour les API de devises. Les taux quotidiens historiques sont immuables une fois publiés : ils se mettent donc en cache indéfiniment — ne recalculez que la fenêtre la plus récente au lieu de retélécharger un an d'historique à chaque chargement de page. La page tarifs indique les volumes de requêtes selon les formules.
Transformer un chiffre de volatilité en décision
Calculer la volatilité est facile. C'est son usage qui crée de la valeur. Quatre applications concrètes :
- Fenêtres de validité des cotations. Un prix que vous affichez à un client est une option courte que vous lui avez vendue. La dérive attendue sur une période de t jours vaut environ
σ_annual × √(t / 260). À 8 % de volatilité annualisée, une cotation valable 24 heures porte environ 0,5 % de dérive attendue ; à 20 %, plutôt 1,2 %. Raccourcissez le TTL quand la volatilité monte, au lieu de garder 15 minutes fixes pour l'éternité.
- Marges de tarification. Plutôt que de coder en dur une marge de change de 2 %, mettez-la à l'échelle :
buffer = k × σ_annual × √(settlement_days / 260). La marge s'élargit automatiquement en régime de tension et se resserre quand les marchés se calment, ce qui vous garde compétitif sans risque caché.
- Déclencheurs de couverture. L'exposition seule n'est pas le risque ; le risque, c'est l'exposition multipliée par la volatilité. Une exposition de 2 M$ sur une paire à 4 % de volatilité est un problème plus petit que 400 k$ sur une paire à 30 %. Classez vos décisions de couverture par
exposure × σ, pas par notionnel. Notre guide de la couverture de change présente les instruments ; le chiffre de volatilité vous dit ce qui en mérite un.
- Détection d'anomalies. Convertissez chaque nouveau mouvement quotidien en score z par rapport à l'écart-type des 30 derniers jours, et alertez au-delà de ±3. Cela attrape aussi bien les vrais événements de marché que les données erronées — un flux figé ou un croisement mal triangulé se signale généralement par une valeur aberrante invraisemblable avant que quiconque ne le remarque dans un rapport.
Pour exprimer ces mouvements en unités de trading plutôt qu'en pourcentages, voyez ce qu'est un pip.
Erreurs courantes
- Utiliser la variation en pourcentage au lieu des rendements logarithmiques. Cela introduit une asymétrie et rend votre réponse dépendante du sens de cotation.
- Utiliser l'écart-type de population.
numpy.std()sansddof=1sous-estime la volatilité, fortement sur les fenêtres courtes. - Recopier les week-ends et jours fériés. Les valeurs répétées sont des jours à rendement nul qui tirent mécaniquement la volatilité vers le bas.
- Annualiser avec le mauvais N. Des données hebdomadaires annualisées avec 260 au lieu de 52 donnent un chiffre environ 2,2 fois trop grand.
- Comparer des volatilités calculées à des heures d'instantané différentes. Deux fournisseurs, deux heures de fixing, deux chiffres incomparables.
- Publier un seul chiffre annuel et l'appeler « risque ». La volatilité se regroupe en grappes. Des mois calmes et des semaines violentes se moyennent en un chiffre intermédiaire qui ne décrit ni les uns ni les autres. Publiez toujours une série glissante à côté de la valeur mise en avant.
- Supposer qu'une faible volatilité signifie un faible risque. Les régimes calmes et favorables au carry de 2026 l'ont été jusqu'au moment précis où les titres sur l'intervention ont fait bouger le yen de 2 % en une séance. Une volatilité réalisée faible décrit le passé récent, elle ne promet rien sur la semaine à venir.
Questions fréquentes
Quel est un niveau de volatilité normal pour une paire de devises ?
Les paires majeures comme EUR/USD et GBP/USD ont historiquement évolué entre 5 et 10 % annualisés en conditions calmes, et entre 10 et 15 % en période de tension. Les paires émergentes sont typiquement deux à trois fois plus hautes. Plutôt que de vous fier à des règles empiriques, calculez une volatilité glissante à 90 jours pour les paires qui vous intéressent et servez-vous de votre propre référence — les niveaux bougent avec le régime.
Faut-il utiliser 252 ou 260 jours de cotation pour annualiser la volatilité de change ?
260 est plus adapté, car le marché des changes traite tous les jours ouvrés au lieu de suivre le calendrier d'une bourse unique. 252 est la convention actions, et elle reste largement utilisée. L'écart est d'environ 1,6 % en relatif : l'essentiel est d'en choisir une, de la documenter et de l'appliquer partout où vous comparez des chiffres.
Puis-je calculer la volatilité implicite à partir d'une API de taux de change ?
Non. La volatilité implicite s'extrait des prix d'options de change et nécessite un flux de données d'options. Ce que vous pouvez calculer à partir d'une série de taux au comptant ou historiques, c'est la volatilité réalisée. Pour la tarification, les seuils de couverture et les alertes dans du code applicatif, la volatilité réalisée est généralement la bonne mesure.
De combien de données historiques ai-je besoin ?
Au minimum, une observation de plus que la longueur de votre fenêtre — mais cela donne une estimation instable. Comme plancher pratique, utilisez 30 observations pour une fenêtre de 30 jours et récupérez au moins un an d'historique afin de pouvoir comparer la lecture actuelle à une référence plus longue. L'endpoint /v1/timeseries renvoie une plage de dates arbitraire en une seule requête.
Pourquoi mon chiffre de volatilité diffère-t-il de celui de mon fournisseur de données ?
Presque toujours pour l'une de ces quatre raisons : un facteur d'annualisation différent (252 contre 260), un écart-type de population au lieu d'échantillon, une heure d'instantané différente pour le taux quotidien, ou des rendements simples au lieu de logarithmiques. Vérifiez ces quatre points avant de conclure que les données sont fausses.
La volatilité prédit-elle dans quel sens une devise va bouger ?
Non. La volatilité mesure la dispersion, pas la direction. Une paire à 20 % de volatilité annualisée devrait beaucoup bouger ; le calcul ne dit rien sur le fait qu'elle monte ou descende. Utilisez-la pour dimensionner le risque, pas pour prendre position.
Prêt à calculer la volatilité sur des données en direct ? Obtenez votre clé d'API Finexly gratuite — sans carte bancaire. Vous accédez aux taux en temps réel et historiques de plus de 170 devises, avec 1 000 requêtes gratuites par mois et un endpoint /v1/timeseries qui renvoie une plage de dates complète en un seul appel. Commencez avec l'API de taux de change gratuite et montez en gamme à mesure que vos besoins en données grandissent.
Explore More
Vlado Grigirov
Senior Currency Markets Analyst & Financial Strategist
Vlado Grigirov is a senior currency markets analyst and financial strategist with over 14 years of experience in foreign exchange markets, cross-border finance, and currency risk management. He has wo...
View full profile →