Une API d'historique forex à la minute
Des bougies OHLC d'une minute par REST, jusqu'à 5 000 par page, en remontant avec un curseur : ce que lit un backtest ou un graphique, par l'API mesurée plutôt que par un fichier.
- Jusqu'où
- Depuis le 16.05.2025 pour EURUSD, GBPUSD, USDJPY, XAUUSD ; depuis le 17.03.2026 ou le 17.05.2026 pour les autres, la page de chaque symbole donnant sa date. L'essai lit les 7 derniers jours, sur EURUSD · XAUUSD.
- Remonter page par page
- Demandez des bougies M1 avec une limite d'au plus 5 000. Chaque page arrive de la plus ancienne à la plus récente, avec next_before, le curseur de la page précédente, nul quand il n'y a rien de plus ancien pour votre compte. La page la plus récente se termine par la bougie en cours. Les prix sont des chaînes, tels que servis.
- De quoi une bougie est faite
- Avant le 21.05.2026 (le 22.05.2026 pour EURUSD), l'historique à la minute vient d'un autre flux de prix que la série en direct, de même que certaines bougies d'une minute comblées ensuite, jusqu'au 04.06.2026 au plus tard ; /symbols.json donne les dates de chaque symbole. Le volume est un volume en ticks : le nombre de mises à jour de prix dans la bougie ; les bougies de l'autre flux, sur toutes les unités de temps jusqu'au 05.06.2026 au plus tard, portent son volume en ticks, qui n'est pas compté de la même façon.
- Ce que cela coûte
- Facturé en tranches de 1 000 bougies, arrondies par réponse : demandez ce dont vous avez besoin. Une journée de bougies d'une minute (1 440 au plus) lue en une réponse fait 2 tranches, et une page vide ne coûte rien. Une page qui porte la bougie en cours compte comme un suivi en direct du symbole : au-delà de 80 % de ses heures d'ouverture dans le mois, ce symbole ajoute CHF 150. Vendu à la capacité, dès CHF 500 par mois.
Faits à la date du 03.10.2026.
Le code : l'historique à la minute, page par page
# pip install requests
# One-minute history, paged back with the cursor: ADONA_API_KEY=... python history_m1.py EURUSD 3
import os
import sys
from datetime import datetime, timedelta, timezone
import requests
API = "https://api.adona-robot.com"
symbol = sys.argv[1] if len(sys.argv) > 1 else "EURUSD"
days = int(sys.argv[2]) if len(sys.argv) > 2 else 3
def get(path, bearer, **kwargs):
r = requests.request(kwargs.pop("method", "GET"), API + path, headers={"Authorization": f"Bearer {bearer}"}, timeout=30, **kwargs)
if not r.ok:
raise SystemExit(f"refused: {r.status_code} {r.text}")
return r.json()
# your server exchanges the key for a token
token = get("/v1/tokens", os.environ["ADONA_API_KEY"], method="POST", json={"end_user_id": "u-42"})["access_token"]
# pages of up to 5000 bars, newest first; next_before is the page before.
# Every bar served is billed, so each page asks only for the minutes it can still need.
start = datetime.now(timezone.utc) - timedelta(days=days)
since = start.strftime("%Y-%m-%dT%H:%M:%SZ")
bars, before, until = [], None, datetime.now(timezone.utc)
while True:
minutes = int((until - start).total_seconds() // 60) + 1
params = {"symbol": symbol, "timeframe": "M1", "limit": max(1, min(5000, minutes))}
if before:
params["before"] = before
page = get("/v1/candles", token, params=params)
if before is None and page["candles"]:
page["candles"].pop() # the newest bar is still forming: not history yet
bars = page["candles"] + bars
before = page["next_before"]
if before is None or before <= since: # nothing older, or far enough back
break
until = datetime.fromisoformat(before.replace("Z", "+00:00"))
bars = [b for b in bars if b["time"] >= since]
print(len(bars), "bars from", bars[0]["time"] if bars else None, "to", bars[-1]["time"] if bars else None)