Goldpreis-API in Python: Preise abrufen, cachen und plotten
Goldpreis-API in Python nutzen: Live-Goldpreise mit requests abrufen, Fehler und Wiederholungen behandeln, Antworten cachen und Zeitreihen mit pandas plotten.
Goldpreis-API in Python: Was Sie brauchen
Dieses Tutorial zeigt, wie Sie eine Goldpreis-API in Python nutzen, von der ersten Anfrage bis zu einem Client mit Cache und einem Chart der letzten zehn Monate. Es verwendet MetalAPI, eine JSON-REST-API für Edelmetalle, Industriemetalle, Energie, Währungen und Krypto, zusammen mit drei bekannten Bibliotheken: requests für HTTP, pandas für die Zeitreihe und matplotlib für den Chart. Jedes Snippet läuft mit Python 3.9 oder neuer.
Erstellen Sie ein kostenloses Konto und legen Sie im Dashboard unter API keys einen API-Schlüssel an. Schlüssel beginnen mit mk_live_ und werden nur einmal angezeigt. Kopieren Sie Ihren Schlüssel daher sofort in eine Umgebungsvariable. Der Free-Tarif erfordert keine Kreditkarte und umfasst 100 Anfragen pro Monat mit täglicher Preisaktualisierung, genug für alles in diesem Artikel.
pip install requests pandas matplotlib
# macOS und Linux
export METALAPI_KEY="mk_live_your_key_here"
# Windows PowerShell
$env:METALAPI_KEY = "mk_live_your_key_here"Lesen Sie den Schlüssel mit os.environ["METALAPI_KEY"] aus, statt ihn in ein Skript einzufügen. Fehlt die Variable, bricht dieser Aufruf mit einer deutlichen Fehlermeldung ab. Wenn Sie eine .env-Datei bevorzugen, lädt das Paket python-dotenv sie mit einem einzigen Aufruf von load_dotenv(). Tragen Sie .env in .gitignore ein, damit der Schlüssel nie in Ihr Repository gelangt.
So rufen Sie den Goldpreis in Python ab
Jeder MetalAPI-Endpunkt ist eine GET-Anfrage unter https://metalapi.com/api/v1. Der Schlüssel kann als Query-Parameter api_key, im Header Authorization: Bearer oder im Header X-API-Key übergeben werden. Verwenden Sie einen Header: Vollständige URLs landen in Logs, und manche requests-Exceptions geben die URL samt Query-String aus. Der Endpunkt /latest liefert aktuelle Preise, base legt die Währung fest, und currencies beschränkt die Antwort auf die Symbole, die Sie brauchen:
import os
import requests
resp = requests.get(
"https://metalapi.com/api/v1/latest",
params={"base": "USD", "currencies": "XAU"},
headers={"X-API-Key": os.environ["METALAPI_KEY"]},
timeout=10,
)
data = resp.json()
if not data["success"]:
raise SystemExit(f"MetalAPI error {data['error']['code']}: {data['error']['info']}")
price = data["rates"][data["base"] + "XAU"]
print(f"Gold: {price:,.2f} {data['base']} per troy ounce")Die Antwort sieht so aus. Die Zahlen sind die Beispielwerte, die in der gesamten MetalAPI-Dokumentation verwendet werden, keine Live-Preise:
{
"success": true,
"timestamp": 1792834892,
"date": "2026-10-24",
"base": "USD",
"rates": { "XAU": 0.0002501319, "USDXAU": 3997.89 },
"rate_limit": { "limit": 100, "remaining": 99, "used": 1, "plan": "Free", "...": "..." }
}Mit diesen Werten gibt das Skript Gold: 3,997.89 USD per troy ounce aus. rates["USDXAU"] ist der Preis einer Feinunze Gold in der Basiswährung. rates["XAU"] ist der Kehrwert, also Unzen Gold pro Dollar, und diesen Wert versehentlich zu lesen ist der häufigste Fehler in Goldpreis-Code. Weil der Schlüssel aus data["base"] gebildet wird, bleibt das Skript korrekt, wenn Sie zu base=EUR (Schlüssel EURXAU) oder base=INR wechseln. Ergänzen Sie unit=gram oder unit=kilogram für Preise pro Gramm oder Kilogramm. timestamp ist der Zeitpunkt der Preisdaten in Unix-Sekunden, nicht der Zeitpunkt Ihrer Anfrage.
Fehler der Goldpreis-API in Python behandeln
Ein fehlgeschlagener Aufruf liefert einen HTTP-Fehlerstatus und einen JSON-Body mit success: false sowie einem error-Objekt, das einen numerischen code, einen type und eine info-Meldung enthält. Verzweigen Sie anhand des Codes, niemals anhand des Meldungstexts. Nur bei wenigen Codes lohnt sich ein erneuter Versuch:
104(too_many_requests, HTTP 429): das Limit pro Minute. Warten Sie so viele Sekunden, wie der HeaderRetry-Afterangibt.500,503und Netzwerkfehler: mit exponentiellem Backoff wiederholen.- Alles andere, etwa
101oder102(fehlender oder ungültiger Schlüssel),105(Monatskontingent aufgebraucht),106(Endpunkt nicht in Ihrem Tarif) und die2xx-Validierungsfehler: Korrigieren Sie stattdessen Anfrage, Schlüssel oder Tarif.
Dieses kleine Modul kapselt diese Logik. Es verwendet eine einzige requests.Session wieder, sodass Verbindungen zwischen den Aufrufen offen bleiben, und löst eine Exception aus, die Sie auswerten können:
import os
import time
import requests
API_URL = "https://metalapi.com/api/v1"
session = requests.Session()
session.headers["X-API-Key"] = os.environ["METALAPI_KEY"]
class MetalAPIError(Exception):
def __init__(self, code, type_, info, retry_after=None):
super().__init__(f"MetalAPI {code} ({type_}): {info}")
self.code = code
self.type = type_
self.retry_after = retry_after
def _get(path, params):
r = session.get(f"{API_URL}/{path}", params=params, timeout=10)
try:
data = r.json()
except ValueError: # kein JSON, z. B. eine HTML-Fehlerseite eines Proxys
raise MetalAPIError(r.status_code, "http_error", r.reason) from None
if not data.get("success"):
err = data["error"]
retry_after = r.headers.get("Retry-After")
raise MetalAPIError(err["code"], err["type"], err["info"], int(retry_after) if retry_after else None)
return data
def call(path, params=None, retries=3):
"""GET auf einen Endpunkt. Wiederholt nur bei Anfragelimits, Serverfehlern und Netzwerkausfällen."""
for attempt in range(retries + 1):
try:
return _get(path, params or {})
except (MetalAPIError, requests.RequestException) as exc:
code = getattr(exc, "code", None) # None bei Netzwerkfehlern
if attempt == retries or (code is not None and code != 104 and code < 500):
raise
time.sleep(getattr(exc, "retry_after", None) or 2**attempt)Der Backoff wartet 1, 2 und 4 Sekunden, bevor er aufgibt. Wiederholungen kosten hier nichts, denn Anfragen, die mit 104 oder einem Serverfehler abgelehnt werden, werden nicht berechnet. Validierungsfehler werden dagegen berechnet, ein weiterer Grund, sie nie in einer Schleife zu wiederholen. Die Anleitung zur Fehlerbehandlung listet jeden Code mit seinem HTTP-Status auf.
Goldpreise cachen und Anfragen sparen
Jeder Tarif aktualisiert die Preise in einem festen Intervall: einmal täglich im Free-Tarif, alle 30 Minuten im Lite-Tarif, alle 10 Minuten im Standard-Tarif und alle 60 Sekunden in Advanced und Pro. Die Aktualisierungen fallen auf Vielfache dieses Intervalls, gezählt ab 00:00 UTC. Eine erneute Abfrage vor der nächsten Aktualisierung liefert also dieselben Zahlen und verbraucht Kontingent ohne Nutzen. Dieser Cache behält jede Antwort bis zur nächsten Aktualisierung und liefert die letzten gültigen Preise aus, wenn die API nicht erreichbar ist:
import math
import time
import requests
from metalapi import MetalAPIError, call
# Sekunden. Free: 86_400, Lite: 3_600 (stündlich passt zu den 1.000 Anfragen), Standard: 600
UPDATE_INTERVAL = 600
_cache = {} # (base, symbols, unit) -> (expires_at, data)
def latest(base="USD", symbols="XAU,XAG", unit="troy_oz"):
key = (base, symbols, unit)
now = time.time()
hit = _cache.get(key)
if hit and now < hit[0]:
return hit[1]
try:
data = call("latest", {"base": base, "currencies": symbols, "unit": unit})
except (MetalAPIError, requests.RequestException):
if not hit:
raise
_cache[key] = (now + 60, hit[1]) # letzte gültige Preise ausliefern, in einer Minute erneut versuchen
return hit[1]
next_update = (math.floor(now / UPDATE_INTERVAL) + 1) * UPDATE_INTERVAL
_cache[key] = (next_update + 5, data) # läuft einige Sekunden nach der nächsten Aktualisierung ab
return datalatest("EUR", "XAU", "gram")["rates"]["EURXAU"] liefert den Euro-Preis pro Gramm. Fragen Sie alle benötigten Symbole in einem Aufruf ab: XAU,XAG,XPT,XPD kostet eine Anfrage, nicht vier. Bedenken Sie, dass dieser Cache im Arbeitsspeicher liegt. Ein per Cron gestartetes Skript beginnt jedes Mal mit einem leeren Cache, dort ist also der Zeitplan der Cache: Führen Sie das Skript höchstens einmal pro Aktualisierungsintervall aus. Um Ihr Kontingent im Blick zu behalten, rufen Sie /usage auf; dieser Endpunkt wird nie auf das Kontingent angerechnet.
Eine Goldpreis-Zeitreihe in pandas laden
Für die Historie liefert der Endpunkt /timeframe (Alias /timeseries) tägliche Schlusskurse zwischen start_date und end_date, mit dem Datum als Schlüssel. Eine Anfrage umfasst bis zu 30 Tage im Free-Tarif und 365 Tage in kostenpflichtigen Tarifen; ein längerer Zeitraum schlägt mit dem Fehler 207 fehl. Diese Funktion teilt jeden Zeitraum in zulässige Abschnitte auf und gibt eine pandas-Series zurück:
from datetime import date, timedelta
import pandas as pd
from metalapi import call
def gold_history(start, end, base="USD", max_days=30): # max_days=365 in kostenpflichtigen Tarifen
rates = {}
chunk_start = start
while chunk_start <= end:
chunk_end = min(chunk_start + timedelta(days=max_days - 1), end)
data = call("timeframe", {
"start_date": chunk_start.isoformat(),
"end_date": chunk_end.isoformat(),
"currencies": "XAU",
"base": base,
})
rates.update(data["rates"])
chunk_start = chunk_end + timedelta(days=1)
df = pd.DataFrame.from_dict(rates, orient="index")
df.index = pd.to_datetime(df.index)
return df[f"{base}XAU"].sort_index().rename(f"gold_{base.lower()}")
gold = gold_history(date(2026, 1, 1), date(2026, 10, 23))
gold.to_csv("gold_usd.csv")
print(f"{len(gold)} trading days, high {gold.max():,.2f}, low {gold.min():,.2f}")Im Free-Tarif benötigen diese zehn Monate 10 Anfragen. Die Series hat eine Zeile pro Handelstag: Wochenenden und Börsenfeiertage fehlen, statt aufgefüllt zu werden. Rechnen Sie also mit weniger Zeilen als Kalendertagen. Wenn Sie für jeden Tag einen Wert brauchen, übernimmt gold.asfreq("D").ffill() den Schlusskurs vom Freitag über das Wochenende. Danach stehen die üblichen pandas-Werkzeuge zur Verfügung, etwa gold.pct_change() für tägliche Renditen oder gold.rolling(20).mean() für einen gleitenden Durchschnitt.
Vergangene Schlusskurse ändern sich nie, daher ist die CSV-Datei Ihr Cache für die Historie: Laden Sie sie beim nächsten Mal, statt denselben Zeitraum erneut abzufragen. Wie Sie die vollständige Historie seit 2000 in eine Datenbank laden, zeigt Historische Gold- und Silberpreise per API.
Den Goldpreis mit matplotlib plotten
Der Chart liest die CSV-Datei, das Neuzeichnen kostet also keine Anfragen. Er zeigt den täglichen Schlusskurs zusammen mit einem gleitenden 20-Tage-Durchschnitt:
import matplotlib.pyplot as plt
import pandas as pd
gold = pd.read_csv("gold_usd.csv", index_col=0, parse_dates=True)["gold_usd"]
sma20 = gold.rolling(20).mean()
fig, ax = plt.subplots(figsize=(10, 5))
ax.plot(gold.index, gold, linewidth=1, label="Gold, USD per troy oz")
ax.plot(sma20.index, sma20, linewidth=2, label="20-day moving average")
ax.set_title(f"Gold price, {gold.index[0]:%d %b %Y} to {gold.index[-1]:%d %b %Y}")
ax.yaxis.set_major_formatter("{x:,.0f}")
ax.grid(alpha=0.3)
ax.legend()
fig.autofmt_xdate()
fig.tight_layout()
fig.savefig("gold.png", dpi=150)Da der Index echte Datumswerte enthält, verteilt matplotlib die Punkte zeitlich korrekt, und der gleitende Durchschnitt beginnt am 20. Handelstag. Um Gold in einer anderen Währung darzustellen, rufen Sie gold_history mit base="EUR" auf: Die Kursschlüssel folgen demselben Muster, die Funktion funktioniert also unverändert.
Nächste Schritte
Sie haben jetzt, was die meisten Python-Integrationen brauchen: eine authentifizierte Anfrage, Fehlerbehandlung mit sinnvollen Wiederholungen, einen Cache, der dem Aktualisierungsintervall Ihres Tarifs folgt, und Historie in pandas. Entwickeln und testen Sie im Free-Tarif. Wenn Sie aktuellere Preise brauchen, wählen Sie einen Tarif nach Aktualisierungsintervall und Volumen: Ein Job, der alle 10 Minuten läuft, verbraucht etwa 4.500 Anfragen im Monat und passt damit in die 10.000 des Standard-Tarifs. Vergleichen Sie die Tarife auf der Preisseite.
Wenn die Preise auf einer Website erscheinen sollen, zeigt Goldpreis-API in JavaScript, wie Sie sie über eine Node.js-Route ausliefern, ohne Ihren Schlüssel preiszugeben.
Häufige Fragen
Gibt es eine kostenlose Goldpreis-API für Python?
Ja. Der Free-Tarif von MetalAPI umfasst 100 Anfragen pro Monat mit täglicher Preisaktualisierung, erfordert keine Kreditkarte, und jedes Snippet in diesem Artikel funktioniert damit. Die aktuellen Preise sind dort der Schlusskurs des Vortags, und eine /timeframe-Anfrage umfasst bis zu 30 Tage. Kostenlose Goldpreis-API erklärt den kostenlosen Tarif ausführlicher.
Warum ist der XAU-Kurs so eine kleine Zahl?
rates["XAU"] ist der Kehrwert: Feinunzen Gold pro Einheit der Basiswährung. Der Preis steht unter dem Schlüssel mit Präfix, rates["USDXAU"] für die Basis USD oder rates["EURXAU"] für die Basis EUR. Mit den Beispielwerten ergibt 1 ÷ 0,0002501319 wieder 3.997,89.
Wie erhalte ich den Goldpreis pro Gramm in Python?
Ergänzen Sie die Anfrage um unit=gram, zum Beispiel call("latest", {"base": "EUR", "currencies": "XAU", "unit": "gram"}). rates["EURXAU"] ist dann der Preis in Euro pro Gramm, und die Antwort enthält "unit": "gram". Vermeiden Sie unit=ounce: Das ist die Avoirdupois-Unze, nicht die Feinunze, in der Gold gehandelt wird.
Wie weit reicht die Goldpreis-Historie zurück?
Tägliche Goldpreise beginnen im Jahr 2000, und jeder Tarif kann die gesamte Historie abfragen. Die Tarife unterscheiden sich nur darin, wie viele Tage eine einzelne /timeframe-Anfrage umfassen darf: 30 im Free-Tarif und 365 in kostenpflichtigen Tarifen. Mit max_days=365 benötigt der gesamte Zeitraum von 2000 bis heute 27 Anfragen.
Wie oft sollte ein Python-Skript die API aufrufen?
Nicht öfter, als Ihr Tarif die Preise aktualisiert: im Free-Tarif einmal täglich nach 00:00 UTC; im Lite-Tarif stündlich, denn alle 30 Minuten wären etwa 1.490 Anfragen im Monat bei einem Kontingent von 1.000; im Standard-Tarif alle 10 Minuten. Rechnen Sie am Wochenende mit unveränderten Preisen, denn Spot-Gold wird von Freitag 17:00 bis Sonntag 17:00 New Yorker Zeit nicht gehandelt.
Probieren Sie es mit Ihren eigenen Daten aus
Erstellen Sie ein kostenloses Konto und senden Sie Ihre erste Anfrage in unter zwei Minuten. 100 Anfragen pro Monat, keine Kreditkarte.
Weiterlesen
XAU/USD Bedeutung: Wofür XAU, XAG, XPT und XPD stehen
XAU/USD einfach erklärt: warum Gold einen ISO-4217-Währungscode hat, wofür XAG, XPT und XPD stehen und wie Sie die Kursrichtung in Preisen und API-Daten lesen.
Kostenlose Goldpreis-API: Was 100 Anfragen im Monat leisten
Kostenlose Goldpreis-API ehrlich erklärt: was der Free-Tarif von MetalAPI enthält, wie 100 Anfragen im Monat mit Caching reichen und wann ein Upgrade lohnt.
Goldpreis-API in JavaScript: Node.js, TypeScript und Next.js
Goldpreis in JavaScript per API abrufen: fetch mit async/await, TypeScript-Typen, eine gecachte Express- oder Next.js-Route und ein sicherer API-Schlüssel.