TradingView is the charting platform of choice for the majority of retail FX traders, and Pine Script is the language that brings custom indicators and strategy signals to life on those charts. The challenge is that Pine Script runs entirely inside TradingView's sandbox — it cannot make outbound HTTP calls to external APIs at runtime. This guide bridges that gap with a two-part workflow: a small Python script fetches macro announcement data from FXMacroData, generates ready-to-paste Pine Script code, and the resulting indicator overlays those data points directly onto your TradingView chart with event markers, a signal line, and a live macro data table.
建設する
- Python スクリプト 政策金利,CPI,PMIの発表をFXMacroDataから任意の通貨で取得し,Pine Scriptソースコードを自動的に生成する
- パインスクリプト v5 インジケーター マクロ値の覆い線を描き,最後の数枚のプリントを要約したデータテーブルを表示します
- 取引視野の警告 → webhook ブリッジ 自動的に新しいFXMacroData文脈と信号をクロス参照できるようにします.
条件
- Python 3.10+ 付き合って
requests設置されている - FXMacroData API キーを 登録する / サブスクリプトドル指標データは鍵を必要とせず無料です.
- トレーディングビューアカウント 無料層はPine Script v5とカスタムインジケーターをサポートします
- パイン文字の基礎知識 パインスクリプト v5 ドック cover the core concepts in under an hour
ステップ 1
Step 1 — Understand the FXMacroData announcement endpoint
FXMacroData のすべての指標は同じ REST 形をとっています. EUR の政策レートの要求は,以下のように見えます.
curl "https://fxmacrodata.com/api/v1/announcements/eur/policy_rate?api_key=YOUR_API_KEY&start=2023-01-01"
JSON応答は,平面のオブジェクトで, data 配列:
{
"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"
}
]
}
記録には date (RYYY-MM-DD 発行の現地日) 番号 val,
and a second-level UTC announcement_datetime通貨と指標の均一な形は,コード生成器の構築を簡単にするものです. 可能な指標の完全なリストについては, 政策金利の文書 対象通貨の指標カタログを探索してください.
ステップ2
ステップ2 Python でマクロデータを取得する
ファイルを作成します generate_pine.py指示ファイルに貼る. このスクリプトは,選択した通貨と指標の発表データを取得し,結果をパインスクリップ配列にシリアル化します.
"""
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()
API キーを保存してスクリプトを実行します.
export FXMD_API_KEY="YOUR_API_KEY"
python generate_pine.py --currency eur --indicator policy_rate --start 2023-01-01
ファイルを出力 pine_data_eur_policy_rate.txt CPI (CPI) のために同じスクリプトを実行できます.--indicator inflation),PMI (--indicator pmi),または他の指標から
FXMacroData カタログほら
ステップ3
ステップ3 ピン文字表示を構築する
図の下にある"Pine Editor"タブに移動し,次のインジケーターを貼り付けます. _ann_ts ほら _ann_val ステップ2からの出力です.
// @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)
なぜ? steplineほら ほっといて
マクロインジケーター値は ステップ関数 政策金利は,会合の間には,円滑に間接しない. plot.style_stepline 公開されたデータに正確に一致する新しい発表が印刷されるまで,ラインがレベルを維持します.
クリック グラフに追加. インディケーターはマクロ値進行にマッチするステップラインを重ね,各発表日にラベル付きダイヤモンドマーカーを落とします. 履歴書をスクロールして,各政策レートの印刷が選択した通貨ペアの価格アクションにどのように一致しているかを見る.
ステップ4
ステップ4 複数の指標の層
A single indicator tells part of the story. The real edge comes from layering policy rate, CPI, and PMI together. Repeat Step 2 for each indicator and add an additional section to the Pine Script, or create three separate indicators and stack them on the same chart pane.
Python スクリプトを拡張します.
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)")
各出力ファイルには,別のPine Script指標のドロップインセクションがあります.それぞれをチャートに追加し,指標ごとに異なる色を割り当てます.例えば,政策利率のオレンジ,CPIの青,PMIの緑です. EUR PMI ドキュメント 幅広い指標のカタログです.
ステップ5
ステップ 5 リリースカレンダーチェックで更新を自動化
新しい発表がプリントされる瞬間,Pine Script配列のマクロデータは古い状態になります.最後のリジェネレーション以降に何かプリントされたかどうかを確認するために,FXMacroDataのリリースカレンダーエンドポイントに毎回の取引セッションの前に電話してリフレッシュを自動化してください.もしそうであれば,ジェネレータを再起動してPineScriptを更新してください.
"""
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()
このスクリプトをCronの仕事,GitHubのActionsワークフロー,または任意のタスクスケジューラーを使用して,ロンドンオープン前に月曜~金曜の08:00 UTCで実行するようにスケジュールします. 更新が実行されると,更新されたものをコピーします.
pine_data_*.txt コンテンツをTradingViewのPine Editorに入力してクリックします 保存するグラフのマーカーが すぐ最新発表データを反映します
ステップ6
ステップ 6 FXMacroData コンテキストに TradingView 警告を返信する
作業流程はマクロデータに 押し付けられています 入り TradingView.ステップ6は,逆の方向でループを閉じる.Pine Scriptが取引信号を発射する (CPIプリント後に抵抗値を超えるブレイクなど) 時,TradingViewのWebhookアラートシステムは,そのイベントを小さなFlaskエンドポイントに転送し,FXMacroDataに新しいコンテキストをすぐに問い合わせます.
創る webhook_server.pyについて
"""
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)
Flask をインストールしてサーバーを実行します.
pip install flask
python webhook_server.py
ローカルポートをインターネットに ゲンロックありがとうございました
ngrok http 5050
取引視野で,開きます. 警告 → 警告を作成選択してください.
Webhook の URL終了する ngrok HTTPS URL を貼り付けます /tradingview/alert. JSON 便用負荷に警告メッセージを設定する:
{
"currency": "eur",
"signal": "breakout_long",
"ticker": "{{ticker}}",
"price": {{close}}
}
パインスクリプト条件が起動するたびに,TradingViewはその JSON をエンドポイントに投稿します. Webhook ハンドラーはFXMacroDataから最新のEUR政策レートとCPIを取得し,信号とともに完全なマクロコンテキストをログします. 拡張されたデータを使用してTelegramまたはSlack通知を送信するためにこれを拡張することができます. 詳細は,このページのページのリストに記載されています.
生産のヒント
恒久的な配備のために,ホスト webhook_server.py クラウドVM,鉄道,またはレンダリングで. 環境変数を使用します. FXMD_API_KEY 偽造されたアラートを防ぐために Webhook ウェフロードに基本的な HMAC 検証を追加します. TradingView は Webhooks ウェフはネイティブにサインしません. /tradingview/alert/SECRET_TOKEN警備員としては一番シンプルです
ステップ7
Step 7 — Extend with COT positioning and FX spot context
Macro announcement data is one layer of the picture. For a more complete signal, add CFTC Commitment of Traders positioning and FX spot trend context from FXMacroData.
EUR先物に対するFETCH COTポジショニング:
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
}
]
}
ステップ2と同じパターンを使ってPine Scriptジェネレーターに COTネット位置付けシリーズを追加します.
net_noncommercial 予想取引者は,EUR先物取引の純長期取引を表示します. 予想の背景は,ECBの政策の強い信号と組み合わせると,確信を高めます.
COTダッシュボード 指示器に埋め込む前に
Python 生成器を拡張して COT セクションを追加します
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})
"""
パインスクリプトで 劇場 _cot_net セット overlay=false 価格とマクロの発表の横に投機的なポジションの傾向が見られます.
── 結論 ──
あなたが作ったもの
- ✅ FXMacroData の発表を呼び出し,Pine Script の配列文字を生成する Python スクリプト
- ✅ TradeViewチャートにマクロイベント日付をマークするPine Script v5インジケーター,ラベル,ステップラインのオーバーレイ,データテーブル
- ✅ 各セッション前に新しいプリントを確認し,必要に応じてパインの配列を再生する自動更新スクリプト
- ✅ FXMacroDataから生きたマクロコンテキストでそれらを豊かにする,TradingViewのアラートを受信するFlask webhookエンドポイント
- ✅ 投機的な感情をイメージに追加するCOTの位置付け拡張
次のステップ: ウェブフックハンドラーを拡張して Telegram や Slack に投稿し,表示が強調されるようにリリースカレンダーチェックを追加します 来る events as well as past ones, or combine two currencies (e.g. EUR and USD policy rates) to derive a rate-differential overlay on EUR/USD. Explore the full indicator catalogue at /api-data-docs ファイルファイル 戦略に最も合致するマクロシリーズを見つけます