TradingView ist die Charting-Plattform der Wahl für die Mehrheit der Einzelhandels-FX-Händler, und Pine Script ist die Sprache, die benutzerdefinierte Indikatoren und Strategiesignale auf diesen Charts zum Leben erweckt. Die Herausforderung besteht darin, dass Pine Script vollständig in der Sandbox von TradingVIEW ausgeführt wird es kann nicht ausgehende HTTP-Anrufe an externe APIs während der Laufzeit tätigen. Dieser Leitfaden schließt diese Lücke mit einem zweiteiligen Workflow: Ein kleines Python-Skript holt Makroankündigungsdaten von FXMacroData ab, generiert bereit zum Einfügen Pine Script-Code und der resultierende Indikator überlagert diese Datenpunkte direkt auf Ihr TradingViewschema mit Ereignismarkern, einer Signalzeile und einer Live-Makro-Datentabelle.
Was du bauen wirst
- Ein Python-Skript der die Ankündigungen zu Kurs, CPI und PMI für jede Währung von FXMacroData abruft und den Quellcode von Pine Script automatisch generiert
- Ein Pine Script v5 Indikator Das Markiert Makro-Ereignis-Daten auf Ihrem Diagramm mit gekennzeichneten Diamanten, zieht eine Makrowert-Überlagerungslinie und zeigt eine Datentabelle, die die letzten mehreren Drucke zusammenfasst
- Eine TradingView-Warnung → Webhook-Brücke Das pings einen kleinen Flask Endpunkt, wenn Ihre Pine Script Bedingung Feuer, so dass Sie die Kreuzverweisung des Signals mit frischem FXMacroData Kontext automatisch
Voraussetzungen
- Python 3.10+ Mit
requestsinstalliert - FXMacroData-API-Schlüssel melden Sie sich an /abonnieren; USD-Indikatordaten sind kostenlos und ohne Schlüssel erforderlich
- Ein TradingView-Konto die kostenlose Ebene unterstützt Pine Script v5 und benutzerdefinierte Indikatoren
- Grundlegende Kenntnisse der Pine-Schrift die Pine Script v5 Dokumente die Kernkonzepte in weniger als einer Stunde abdecken
- Schritt 1 -
Schritt 1 Verständnis für den Endpunkt der Ankündigung von FXMacroData
Jeder Indikator in FXMacroData folgt der gleichen REST-Form. Eine Anfrage zum Kurs der Euro-Policy sieht so aus verwenden Sie Ihren API-Schlüssel als Abfrageparameter:
curl "https://fxmacrodata.com/api/v1/announcements/eur/policy_rate?api_key=YOUR_API_KEY&start=2023-01-01"
Die JSON-Antwort ist ein flaches Objekt mit einem data - Das ist nicht wahr.
{
"currency": "eur",
"indicator": "policy_rate",
"data": [
{
"date": "2025-03-06",
"val": 2.65,
"announcement_datetime": "2025-03-06T13:15:00Z"
},
{
"date": "2025-01-30",
"val": 2.90,
"announcement_datetime": "2025-01-30T13:15:00Z"
},
{
"date": "2024-12-12",
"val": 3.15,
"announcement_datetime": "2024-12-12T13:15:00Z"
}
]
}
Jede Platte trägt eine date (JJJ-MM-DD Lokaldatum der Veröffentlichung), eine numerische val, und eine UTC der zweiten Ebene announcement_datetimeDie Konsistenz der Form in allen Währungen und Indikatoren macht den Code-Generator einfach zu erstellen. Kursbewertung in EUR und den Indikatorkatalog für Ihre Zielwährung zu erforschen.
- Schritt 2 -
Schritt 2 Makrodaten mit Python abrufen
Erstellen Sie eine Datei namens generate_pine.pyDieses Skript holt Ankündigungsdaten für eine ausgewählte Währung und Indikator, dann serialisiert die Ergebnisse in Pine Script Arrays, die Sie in die Indikatorendatei einfügen.
"""
generate_pine.py — fetch FXMacroData announcements and output Pine Script arrays.
Usage:
python generate_pine.py --currency eur --indicator policy_rate --start 2023-01-01
"""
import argparse
import json
import os
from datetime import datetime, timezone
import requests
BASE_URL = "https://fxmacrodata.com/api/v1"
API_KEY = os.environ.get("FXMD_API_KEY", "")
def fetch_announcements(currency: str, indicator: str, start: str) -> list[dict]:
url = f"{BASE_URL}/announcements/{currency}/{indicator}"
params: dict = {"start": start}
if API_KEY:
params["api_key"] = API_KEY
resp = requests.get(url, params=params, timeout=15)
resp.raise_for_status()
return resp.json().get("data", [])
def ts_to_pine_timestamp(iso_str: str) -> int:
"""Convert an ISO-8601 UTC string to a Unix timestamp (milliseconds for Pine)."""
dt = datetime.fromisoformat(iso_str.replace("Z", "+00:00"))
return int(dt.timestamp() * 1000)
def build_pine_arrays(records: list[dict]) -> str:
"""Render the data as Pine Script array literals."""
ts_list = []
val_list = []
for r in records:
ann = r.get("announcement_datetime") or f"{r['date']}T00:00:00Z"
ts_list.append(str(ts_to_pine_timestamp(ann)))
val_list.append(str(r["val"]))
ts_str = ", ".join(ts_list)
val_str = ", ".join(val_list)
n = len(records)
return f"""
// ── Auto-generated by generate_pine.py — do not edit manually ──
// Currency: {records[0].get('currency', '?').upper() if records else '?'}
// Indicator: {records[0].get('indicator', '?') if records else '?'}
// Records: {n}
var int[] _ann_ts = array.from({ts_str})
var float[] _ann_val = array.from({val_str})
"""
def main() -> None:
parser = argparse.ArgumentParser()
parser.add_argument("--currency", required=True)
parser.add_argument("--indicator", required=True)
parser.add_argument("--start", default="2023-01-01")
args = parser.parse_args()
print(f"Fetching {args.indicator} for {args.currency.upper()} from {args.start} …")
records = fetch_announcements(args.currency, args.indicator, args.start)
print(f" {len(records)} records returned.")
pine = build_pine_arrays(records)
print(pine)
output_file = f"pine_data_{args.currency}_{args.indicator}.txt"
with open(output_file, "w") as f:
f.write(pine)
print(f"Arrays written to {output_file}")
if __name__ == "__main__":
main()
Speichern Sie Ihren API-Schlüssel und führen Sie das Skript aus:
export FXMD_API_KEY="YOUR_API_KEY"
python generate_pine.py --currency eur --indicator policy_rate --start 2023-01-01
Die Ausgabedatei . pine_data_eur_policy_rate.txt Sie können das gleiche Skript für CPI (--indicator inflation), PMI (--indicator pmi), oder irgendein anderer Indikator aus dem
FXMacroData Katalog- Ich weiß .
- Schritt 3 -
Schritt 3 Erstellen Sie den Pine Script-Indikator
Öffnen Sie TradingView, navigieren Sie zum Pine Script Editor (die Registerkarte "Pine Editor" am unteren Rand des Diagramms) und fügen Sie den folgenden Indikator ein. _ann_ts Und ... _ann_val Die Ergebnisse der Schritte 2 sind oben zu sehen.
// @version=5
// FXMacroData Overlay — policy rate event markers + value line
// Replace the arrays below with output from generate_pine.py
indicator("FXMacroData Macro Overlay", overlay=true, max_labels_count=50, max_lines_count=50)
// ── User inputs ──
i_show_labels = input.bool(true, "Show event labels")
i_show_line = input.bool(true, "Show macro value line")
i_show_table = input.bool(true, "Show data table")
i_label_color = input.color(color.new(color.orange, 0), "Label colour")
i_line_color = input.color(color.new(color.orange, 30), "Line colour")
// ── Paste generated arrays here ──
// ---- BEGIN GENERATED SECTION ----
var int[] _ann_ts = array.from(1672531200000, 1675209600000, 1677628800000)
var float[] _ann_val = array.from(2.50, 2.65, 3.00)
// ---- END GENERATED SECTION ----
// ── Helper: find the most recent announcement value at or before this bar ──
f_current_val() =>
float result = na
int bar_t = time
for i = 0 to array.size(_ann_ts) - 1
if array.get(_ann_ts, i) <= bar_t
result := array.get(_ann_val, i)
break
result
// ── Macro overlay line ──
float macro_val = f_current_val()
plot(i_show_line ? macro_val : na, title="Macro value", color=i_line_color,
linewidth=2, style=plot.style_stepline)
// ── Event marker labels ──
if i_show_labels
for i = 0 to array.size(_ann_ts) - 1
int ts = array.get(_ann_ts, i)
float val = array.get(_ann_val, i)
if ts >= chart.left_visible_bar_time and ts <= chart.right_visible_bar_time
label.new(
x = ts,
y = high * 1.002,
text = str.tostring(val, "#.##"),
style = label.style_diamond,
color = i_label_color,
textcolor = color.white,
size = size.small,
xloc = xloc.bar_time
)
// ── Summary table (top-right corner) ──
var table t = table.new(position.top_right, 2, 6,
bgcolor = color.new(color.navy, 85),
border_width = 1,
border_color = color.new(color.gray, 60))
if i_show_table and barstate.islast
table.cell(t, 0, 0, "Date", text_color=color.silver, text_size=size.small)
table.cell(t, 1, 0, "Value", text_color=color.silver, text_size=size.small)
int rows = math.min(5, array.size(_ann_ts))
for i = 0 to rows - 1
int ts = array.get(_ann_ts, i)
float val = array.get(_ann_val, i)
string date_str = str.format("{0,date,yyyy-MM-dd}", ts)
table.cell(t, 0, i + 1, date_str, text_color=color.white, text_size=size.tiny)
table.cell(t, 1, i + 1, str.tostring(val, "#.##"), text_color=color.orange, text_size=size.tiny)
Warum ? stepline- Ich weiß .
Die Makroindikatorenwerte sind Schrittfunktionen der Leitzins zwischen den Sitzungen nicht reibungslos interpoliert; er springt. plot.style_stepline Die Überlagerung bleibt ehrlich: Die Linie bleibt bis zu einem neuen Druck, der genau den veröffentlichten Daten entspricht, auf der gleichen Ebene.
Klicken Sie Hinzufügen zum DiagrammDer Indikator wird eine Schrittlinie überlagern, die dem Makrowertverlauf entspricht, und bei jedem Ankündigungsdatum einen markierten Diamantmarker fallen lassen.
- Schritt 4 -
Schritt 4 Einteilung in mehrere Indikatoren
Ein einzelner Indikator erzählt einen Teil der Geschichte. Der tatsächliche Rand kommt aus der Schichtung von Politikrate, CPI und PMI zusammen. Wiederholen Sie Schritt 2 für jeden Indikatoren und fügen Sie einen zusätzlichen Abschnitt zum Pine Script hinzu oder erstellen Sie drei separate Indikatore und stapeln Sie sie auf dem gleichen Diagrammfenster.
Für einen drei-Indikator-Befall in einem Zug, erweitern Sie das Python-Skript:
INDICATORS = ["policy_rate", "inflation", "pmi"]
CURRENCY = "eur"
START = "2023-01-01"
for ind in INDICATORS:
records = fetch_announcements(CURRENCY, ind, START)
pine = build_pine_arrays(records)
with open(f"pine_data_{CURRENCY}_{ind}.txt", "w") as f:
f.write(pine)
print(f"Written pine_data_{CURRENCY}_{ind}.txt ({len(records)} records)")
Jede Ausgabe gibt Ihnen einen Drop-in-Bereich für einen separaten Pine Script-Indikator. Fügen Sie jeden einzelnen zu Ihrem Diagramm hinzu und weisen Sie jedem Indikator eine unterschiedliche Farbe zu zum Beispiel Orange für den Leitzins, Blau für den KPI und Grün für den PMI , damit Sie auf einen Blick sehen können, welches Makroregierungssystem in Kraft ist. EUR PMI Dokumente und der breiteren Indikatorenkatalog.
- Schritt 5 -
Schritt 5 Automatisieren Sie die Aktualisierungen mit einer Überprüfung des Release-Kalenders
Die Makrodaten in den Pine Script-Arrays werden veraltet, sobald eine neue Ankündigung gedruckt wird. Automatisieren Sie die Aktualisierung, indem Sie vor jeder Handelssitzung den Endpunkt des Release-Kalenders von FXMacroData anrufen, um zu überprüfen, ob seit Ihrer letzten Regeneration etwas gedruckte wurde. Wenn ja, starten Sie den Generator erneut und aktualisieren Ihre Pine Script.
"""
check_and_refresh.py — Re-generate Pine arrays if new announcements have printed.
Run this before each session, e.g. via cron or GitHub Actions.
"""
import subprocess
import requests
import os
from datetime import date, timedelta
BASE_URL = "https://fxmacrodata.com/api/v1"
API_KEY = os.environ.get("FXMD_API_KEY", "")
PAIRS = [
("eur", "policy_rate"),
("eur", "inflation"),
("eur", "pmi"),
]
def latest_release_date(currency: str, indicator: str) -> str | None:
"""Return the most recent announcement date for this indicator."""
params: dict = {"start": str(date.today() - timedelta(days=7))}
if API_KEY:
params["api_key"] = API_KEY
r = requests.get(
f"{BASE_URL}/announcements/{currency}/{indicator}",
params=params, timeout=10
)
r.raise_for_status()
data = r.json().get("data", [])
return data[0]["date"] if data else None
def refresh_all() -> None:
for currency, indicator in PAIRS:
latest = latest_release_date(currency, indicator)
if latest and latest >= str(date.today() - timedelta(days=1)):
print(f"New print detected: {currency.upper()} {indicator} on {latest}. Regenerating …")
subprocess.run(
["python", "generate_pine.py",
"--currency", currency,
"--indicator", indicator,
"--start", "2023-01-01"],
check=True,
)
else:
print(f"{currency.upper()} {indicator}: no new prints since yesterday.")
if __name__ == "__main__":
refresh_all()
Schreiben Sie dieses Skript für Montag/Freitag um 08:00 UTC, bevor die Londoner Öffnung, mit einem Cron-Job, einem GitHub-Workflow oder einem anderen Aufgabenplaner aus.
pine_data_*.txt Inhalte in den Pine Editor von TradingView und klicken Sie auf SpeichernIhre Chartmarker werden sofort die neuesten Ankündigungsdaten wiedergeben.
- Schritt 6 -
Schritt 6 Senden Sie TradingView-Warnungen zurück in den Kontext von FXMacroData
Der bisherige Workflow schiebt Makrodaten . in TradingView. Schritt 6 schließt die Schleife in die andere Richtung: Wenn Ihr Pine Script ein Handelssignal auslöst (z. B. ein Ausbruch über den Widerstand nach einem CPI-Druck), leitet das Webhook-Alarmsystem von TradingViews dieses Ereignis an einen kleinen Flask-Endpunkt weiter, der sofort FXMacroData nach frischem Kontext den neuesten CPI -Trend, bevorstehende Releases und aktuelle COT-Positionierung abfragt und Sie mit dem vollständigen Makrobild protokolliert oder benachrichtigt.
Erstellen . webhook_server.pyDie Kommission
"""
webhook_server.py — Receive TradingView alert webhooks and enrich with FXMacroData context.
Run with: python webhook_server.py
Expose to the internet via ngrok or deploy to a cloud function / VPS.
"""
import os
import json
from datetime import date, timedelta
import requests
from flask import Flask, request, jsonify
app = Flask(__name__)
BASE_URL = "https://fxmacrodata.com/api/v1"
API_KEY = os.environ.get("FXMD_API_KEY", "")
def get_macro_context(currency: str) -> dict:
"""Fetch latest policy rate + CPI for the given currency."""
params: dict = {"start": str(date.today() - timedelta(days=90))}
if API_KEY:
params["api_key"] = API_KEY
ctx: dict = {}
for indicator in ("policy_rate", "inflation"):
try:
r = requests.get(
f"{BASE_URL}/announcements/{currency}/{indicator}",
params=params, timeout=10
)
r.raise_for_status()
data = r.json().get("data", [])
ctx[indicator] = data[0] if data else {}
except Exception as exc:
ctx[indicator] = {"error": str(exc)}
return ctx
@app.route("/tradingview/alert", methods=["POST"])
def receive_alert():
payload = request.get_json(force=True, silent=True) or {}
currency = payload.get("currency", "usd").lower()
signal = payload.get("signal", "unknown")
ctx = get_macro_context(currency)
result = {
"received_signal": signal,
"currency": currency.upper(),
"macro_context": ctx,
}
print(json.dumps(result, indent=2))
return jsonify(result), 200
if __name__ == "__main__":
app.run(port=5050, debug=False)
Installieren Sie Flask und starten Sie den Server:
pip install flask
python webhook_server.py
Die lokale Verbindung zum Internet mit Schlachtzüge- Ich weiß .
ngrok http 5050
In TradingView, öffnen Alarme → Alarm erstellen, wählen Sie Ihre Pine Script Bedingung, aktivieren
URL der Webhook, und fügen Sie die mit endende ngrok HTTPS-URL ein /tradingview/alert. Setzen Sie die Warnmeldung auf eine JSON-Nutzlast:
{
"currency": "eur",
"signal": "breakout_long",
"ticker": "{{ticker}}",
"price": {{close}}
}
Jedes Mal, wenn die Pine Script-Bedingung ausgelöst wird, veröffentlicht TradingView dieses JSON an Ihren Endpunkt. Der Webhook-Handler holt den neuesten EUR-Rat und den CPI von FXMacroData ab und protokolliert den vollständigen Makrokontext neben dem Signal. Sie können dies erweitern, um eine Telegramm- oder Slack-Benachrichtigung mit den angereicherten Daten zu senden.
Produktionstipp
Für einen dauerhaften Einsatz, Gastgeber. webhook_server.py Sie können die Umgebungsvariable für verwenden. FXMD_API_KEY und fügen Sie grundlegende HMAC-Verifizierung auf der Webhook-Nutzlast hinzu, um gefälschte Warnungen zu verhindern. /tradingview/alert/SECRET_TOKENDer einfachste Wächter.
- Schritt 7 -
Schritt 7 Erweitern mit COT-Positionierung und FX-Spot-Kontext
Für ein vollständigeres Signal fügen Sie die CFTC Commitment of Traders Positionierung und den Kontext des Devisenmarkttrends von FXMacroData hinzu.
Die Positioning-Positionen für EUR-Futures
curl "https://fxmacrodata.com/api/v1/cot/eur?api_key=YOUR_API_KEY&start=2024-01-01"
{
"currency": "eur",
"data": [
{
"date": "2025-03-18",
"net_noncommercial": 48320,
"long_noncommercial": 182500,
"short_noncommercial": 134180
}
]
}
Fügen Sie eine COT-Net-Positionierungsreihe zu Ihrem Pine Script Generator mit dem gleichen Muster wie Schritt 2 hinzu.
net_noncommercial Die Ergebnisse der Analyse der Daten der Europäischen Zentralbank (EKZB) zeigen , dass die Wertentwicklung der Euro-Futures in den letzten Jahren in den meisten Ländern der EU deutlich zurückgegangen ist.
COT-Armbrett Sie können es in Ihre Anzeige einbinden.
Erweitern Sie den Python-Generator um einen COT-Abschnitt:
def fetch_cot(currency: str, start: str) -> list[dict]:
url = f"{BASE_URL}/cot/{currency}"
params: dict = {"start": start}
if API_KEY:
params["api_key"] = API_KEY
resp = requests.get(url, params=params, timeout=15)
resp.raise_for_status()
return resp.json().get("data", [])
def build_cot_pine_arrays(records: list[dict]) -> str:
ts_list = [str(int(datetime.fromisoformat(r["date"] + "T00:00:00+00:00").timestamp() * 1000)) for r in records]
net_list = [str(r.get("net_noncommercial", 0)) for r in records]
ts_str = ", ".join(ts_list)
net_str = ", ".join(net_list)
return f"""
var int[] _cot_ts = array.from({ts_str})
var float[] _cot_net = array.from({net_str})
"""
In Pine Script, Plot _cot_net in einem separaten Fenster (Set overlay=false Für diesen Indikator) können Sie also neben Preis- und Makroankündigungen den Trend der spekulativen Positionierung sehen.
- - - Zusammenfassung
Was du gebaut hast
- ✅ Ein Python-Skript, das FXMacroData-Ankündigungen abruft und Pine Script-Array-Literals erzeugt
- ✅ Ein Pine Script v5 Indikator, der Makro-Ereignisdaten auf Ihrem TradingView-Chart mit Etiketten, einer Schrittzeile und einer Datentabelle markiert
- ✅ Ein automatisches Aktualisierungs-Skript, das vor jeder Sitzung nach neuen Drucken sucht und die Pine-Arrays bei Bedarf regeneriert
- ✅ Ein Flask Webhook Endpunkt, der TradingView Warnungen empfängt und sie mit Live-Makrokontext von FXMacroData bereichert
- ✅ Eine COT-Positionierungserweiterung, die dem Bild spekulative Stimmungen hinzufügt
Nächste Schritte: Erweitern Sie den Webhook-Handler, um auf Telegramm oder Slack zu posten, fügen Sie eine Veröffentlichungskalenderprüfung hinzu, damit der Indikator hervorhebt Nächste Die Indikatoren sind in der Regel in der Kategorie "Rate-Differenz-Überlagerung" zu finden. /api-daten-docs Die Makroserie, die am besten zu Ihrer Strategie passt.