FXMacroData के साथ Yield Spread Pair ट्रेडिंग रणनीति कैसे बनाएं banner image

Implementation

How-To Guides

FXMacroData के साथ Yield Spread Pair ट्रेडिंग रणनीति कैसे बनाएं

एक पूर्ण पायथन नियम आधारित FX रणनीति बनाने के लिए चलती है जो सरकारी बांड उपज अंतर द्वारा संचालित होती है एफएक्समैक्रोडाटा एपीआई के माध्यम से 10 साल की उपज प्राप्त करने से लेकर यूरो/डॉलर पर स्प्रेड संकेतों के बैकटेस्टिंग तक।

इसमें भी उपलब्ध है English

उपज के बीच के अंतर को विनिमय करें, उपज को नहीं

दो अर्थव्यवस्थाओं के बीच सरकारी बांड उपज अंतर विदेशी मुद्रा बाजारों में सबसे विश्वसनीय संरचनात्मक बलों में से हैं। जब अमेरिकी 10 साल की उपज जर्मन बंड समकक्ष से काफी ऊपर चलती है, तो पूंजी USD परिसंपत्तियों की ओर बहती है और EUR/USD को निरंतर बिक्री दबाव का सामना करना पड़ता है। जब वह स्प्रेड संकुचित होता है, तब जोड़ी ठीक हो जाती है। संबंध यांत्रिक नहीं है, लेकिन इसके चारों ओर एक नियम-आधारित ट्रेडिंग रणनीति बनाने के लिए यह पर्याप्त दृढ़ है।

यह गाइड आपको FXMacroData एपीआई का उपयोग करके एक पूर्ण उपज-स्प्रेड जोड़ी-व्यापार रणनीति के निर्माण के माध्यम से चलता है। अंत तक आपके पास एक कामकाजी पायथन प्रणाली होगी जोः

  • दो मुद्राओं के लिए सरकारी बांड उपज समय श्रृंखला को के माध्यम से प्राप्त करता है FXMacroData बांड की उपज के अंत बिंदु
  • उपज के अंतर और उसके चलती औसत और मानक विचलन की गणना करता है
  • Z-स्कोर औसत प्रतिगमन का उपयोग करके सांख्यिकीय रूप से संचालित लंबे/लघु FX संकेत उत्पन्न करता है
  • खुले पदों को ट्रैक करता है, बुनियादी जोखिम नियंत्रण लागू करता है और प्रवेश/निकास अलर्ट को प्रदर्शित करता है

मूल थीसिस

आय में वृद्धि की औसत दर संरचनात्मक रूप से स्थिर संतुलन के आसपास उलट जाती है। जब एक स्प्रेड अपने हालिया औसत से अधिक तेजी से बढ़ता है, तो संबंधित विदेशी मुद्रा जोड़ी सांख्यिकीय रूप से ओवर-एक्स्टेन्ड होती है और वापस जाने की संभावना होती है। स्प्रेड्स सामान्य होने पर परिभाषित निकास के साथ औसत रिवर्स की दिशा में प्रवेश करना इस दृष्टिकोण का आधार है।

पूर्व शर्तें

शुरू करने से पहले, सुनिश्चित करें कि आपके पास निम्नलिखित तैयार हैंः

  • पायथन 3.9+ सभी स्निपेट्स मानक प्रकार के एनोटेशन का उपयोग करते हैं
  • FXMacroData एपीआई कुंजी पर साइन अप करें /अपना नाम लिखें और खाता डैशबोर्ड से अपनी कुंजी की प्रतिलिपि
  • पायथन पैकेज requests, pandas, numpy
pip install requests pandas numpy

अपनी एपीआई कुंजी को पर्यावरण चर के रूप में स्टोर करें इसे स्रोत फ़ाइलों में हार्ड-कोड कभी न करें:

export FXMACRO_API_KEY="YOUR_API_KEY"

चरण 1: सरकारी बांड की उपज के आंकड़े प्राप्त करें

इस रणनीति का आधार विश्वसनीय बांड रिटर्न समय श्रृंखला है। FXMacroData सभी प्रमुख मुद्रा ब्लॉक के लिए 10 साल के सरकारी बांड की आय प्रदान करता है। gov_bond_10y प्रत्येक अवलोकन में एक date, एक val (प्रतिशत में उपज), और एक announcement_datetime दूसरे स्तर के रिलीज टाइमस्टैम्प के लिए।

यहाँ हम USD और EUR 10 साल की पैदावार खींच, तो उन्हें एक एकल डेटा फ्रेम में गठबंधन दिनांक पर संरेखितः

import os
import requests
import pandas as pd
from datetime import datetime, timedelta

BASE_URL = "https://fxmacrodata.com/api/v1"
API_KEY = os.environ["FXMACRO_API_KEY"]


def fetch_yield(currency: str, tenor: str = "gov_bond_10y", start: str = "2022-01-01") -> pd.Series:
    """Fetch a bond yield series from FXMacroData and return as a dated Series."""
    resp = requests.get(
        f"{BASE_URL}/announcements/{currency}/{tenor}",
        params={"api_key": API_KEY, "start": start},
        timeout=15,
    )
    resp.raise_for_status()
    records = resp.json()["data"]
    if not records:
        raise ValueError(f"No data returned for {currency}/{tenor}")
    series = pd.Series(
        {r["date"]: r["val"] for r in records},
        name=f"{currency.upper()}_10Y",
        dtype=float,
    )
    series.index = pd.to_datetime(series.index)
    return series.sort_index()


# Fetch USD and EUR 10-year yields
usd_10y = fetch_yield("usd")
eur_10y = fetch_yield("eur")

# Align on a shared date index (inner join drops days missing in either series)
yields = pd.DataFrame({"USD_10Y": usd_10y, "EUR_10Y": eur_10y}).dropna()

print(yields.tail())
# Output:
#            USD_10Y  EUR_10Y
# 2025-04-08    4.41     2.71
# 2025-04-09    4.39     2.69
# 2025-04-10    4.49     2.70
# 2025-04-11    4.52     2.73
# 2025-04-14    4.47     2.70

आप द्वारा समर्थित किसी भी मुद्रा जोड़ी का उपयोग कर सकते हैं gov_bond_10y अंत बिंदु लोकप्रिय संयोजनों में USD/JPY, AUD/USD और GBP/USD स्प्रेड शामिल हैं।

अमेरिकी बनाम यूरो 10 साल की उपज उदाहरणात्मक

20222024 तक अमरीकी डालर की उपज यूरो समकक्षों से तेजी से बढ़ी, जिससे एक व्यापक स्प्रेड बना रहा जिसने पूरे चक्र में यूरो/यूएसडी पर भार डाला।

चरण 2: उपज स्प्रेड और जेड-स्कोर की गणना करें

कच्चे स्प्रेड (यूएसडी माइनस यूरो उपज) आपको बताता है कि किस दिशा में पूंजी संरचनात्मक रूप से पक्षपाती है। जेड-स्कोर अपने हाल के इतिहास के खिलाफ उस प्रसार को सामान्य करता है, जिससे आपको एक आयामी संकेत मिलता है जो समय अवधि और मुद्रा जोड़े में सीधे तुलनीय है।

+1.5 से ऊपर का Z-स्कोर इंगित करता है कि स्प्रेड असामान्य रूप से व्यापक हो गया है एक संभावित EUR/USD (लंबी USD) सेटअप। -1.5 से नीचे का Z स्कोर असामान्य संपीड़न संभावित EUR / USD सेटअप को इंगित करते हैं।

def compute_spread_signal(
    yields_df: pd.DataFrame,
    base_col: str,
    quote_col: str,
    lookback: int = 60,
    entry_z: float = 1.5,
    exit_z: float = 0.3,
) -> pd.DataFrame:
    """
    Compute yield spread, rolling Z-score, and directional signals.

    A positive spread means base currency yields are higher → base currency
    is structurally favoured → signal to be long base / short quote FX pair.

    Mean reversion: enter when Z-score is extreme, exit when it normalises.
    """
    df = yields_df.copy()
    df["spread"] = df[base_col] - df[quote_col]

    # Rolling statistics over the lookback window
    roll = df["spread"].rolling(lookback, min_periods=lookback // 2)
    df["spread_mean"] = roll.mean()
    df["spread_std"]  = roll.std()

    # Z-score: how many standard deviations from the rolling mean
    df["zscore"] = (df["spread"] - df["spread_mean"]) / df["spread_std"].replace(0, float("nan"))

    # Signal: +1 = long base/short quote, -1 = short base/long quote, 0 = flat
    df["signal"] = 0
    df.loc[df["zscore"] >  entry_z, "signal"] = -1   # spread too wide → expect compression → short base pair
    df.loc[df["zscore"] < -entry_z, "signal"] = +1   # spread too tight → expect widening → long base pair
    # Exit (override) when Z-score returns toward zero
    df.loc[df["zscore"].abs() < exit_z, "signal"] = 0

    return df.dropna(subset=["zscore"])


analysis = compute_spread_signal(yields, base_col="USD_10Y", quote_col="EUR_10Y")

print(analysis[["spread", "spread_mean", "zscore", "signal"]].tail(10))

USDEUR 10Y स्प्रेड और Z-स्कोर स्पष्टीकरणात्मक

Z- स्कोर ±1.5 से परे ऐतिहासिक रूप से चिह्नित एपिसोड जहां प्रसार बहुत दूर बहुत तेजी से आगे बढ़ गया था और अगले हफ्तों में औसत-वापसी की प्रवृत्ति थी।

चरण 3: कई जोड़े तक विस्तारित करें

EUR/USD पर एक एकल स्प्रेड रणनीति उपयोगी है, लेकिन वास्तविक शक्ति तब सामने आती है जब आप एक ही तर्क को कई जोड़े में एक साथ चलाते हैं। USD/JPY, AUD/USD, और GBP/USD स्प्रेડ सिग्नल को मिलाकर आपको एक विविध मैक्रो-चालित पोर्टफोलियो मिलता है जहां प्रत्येक स्थिति को स्वतंत्र रूप से आकार दिया जाता है।

आप कम टेंडर उपज का भी उपयोग कर सकते हैं gov_bond_2y अंतराल दर नीतिगत दरों की अपेक्षाओं के प्रति विशेष रूप से संवेदनशील है, जिससे यह दस वर्षीय श्रृंखला की तुलना में एक प्रमुख संकेतक बन गया हैः

PAIRS = [
    # (base_currency, quote_currency, fx_pair_label)
    ("usd", "eur", "EUR/USD"),
    ("usd", "jpy", "USD/JPY"),
    ("aud", "usd", "AUD/USD"),
    ("gbp", "usd", "GBP/USD"),
]

TENOR = "gov_bond_10y"   # swap for gov_bond_2y for rate-expectation signals

results = {}
for base_ccy, quote_ccy, fx_label in PAIRS:
    try:
        base_series  = fetch_yield(base_ccy, tenor=TENOR)
        quote_series = fetch_yield(quote_ccy, tenor=TENOR)
        df = pd.DataFrame({
            f"{base_ccy.upper()}_10Y":  base_series,
            f"{quote_ccy.upper()}_10Y": quote_series,
        }).dropna()
        signal_df = compute_spread_signal(
            df,
            base_col=f"{base_ccy.upper()}_10Y",
            quote_col=f"{quote_ccy.upper()}_10Y",
        )
        latest = signal_df.iloc[-1]
        results[fx_label] = {
            "spread_pct": round(latest["spread"], 3),
            "zscore":     round(latest["zscore"], 2),
            "signal":     int(latest["signal"]),
        }
        print(f"{fx_label}: spread={latest['spread']:.3f}%, z={latest['zscore']:+.2f}, signal={int(latest['signal']):+d}")
    except Exception as exc:
        print(f"{fx_label}: skipped — {exc}")

# Example output:
# EUR/USD: spread=1.770%, z=+1.21, signal=0
# USD/JPY: spread=4.050%, z=+2.18, signal=-1
# AUD/USD: spread=0.340%, z=-0.55, signal=0
# GBP/USD: spread=0.890%, z=-1.62, signal=+1

संकेत संदर्भ

  • + 1: स्प्रेड बहुत संकुचित विस्तार की उम्मीद बेस-मुद्रा लंबी पैर (जैसे, लंबी GBP/USD)
  • -1: बहुत व्यापक फैलाव संपीड़न की उम्मीद आधार मुद्रा के बीच छोटा पैर (उदाहरण के लिए, USD/JPY का छोटा हिस्सा JPY का लंबा हिस्सा है)
  • 0: सामान्य सीमा के भीतर फैला हुआ कोई दिशात्मक किनारा नहीं समतल रहना

चरण 4: 2-वर्ष बनाम 10-वर्ष की ढलान ओवरले जोड़ें

उपज वक्र का आकार रणनीति में एक दूसरा आयाम जोड़ता है। एक खड़ी वक्र (लंबी अंत की उपज कम अंत की तुलना में तेजी से बढ़ रही है) आमतौर पर विकास की उम्मीदों में सुधार का संकेत देती है और मुद्रा का समर्थन करती है। उल्टा या सपाट वक्र अक्सर मंदी और केंद्रीय बैंक पिवोट से पहले होता है।

दोनों को खींचो दो वर्ष और 10 वर्ष ढलान की गणना करने के लिए उपज देता है, और इसे एक शासन फ़िल्टर के रूप में उपयोग करता हैः केवल घरेलू मुद्रा वक्र ढलाने के साथ संरेखित दिशा में एक प्रसार संकेत ले लो।

def fetch_curve_slope(currency: str, start: str = "2022-01-01") -> pd.Series:
    """Return the 10Y–2Y slope for a currency (positive = normal/steep, negative = inverted)."""
    y10 = fetch_yield(currency, tenor="gov_bond_10y", start=start)
    y2  = fetch_yield(currency, tenor="gov_bond_2y",  start=start)
    slope = (y10 - y2).dropna()
    slope.name = f"{currency.upper()}_slope"
    return slope


def apply_curve_filter(
    signal_df: pd.DataFrame,
    base_slope: pd.Series,
    quote_slope: pd.Series,
) -> pd.DataFrame:
    """
    Suppress signals that contradict the curve-slope regime.

    Long base / short quote (signal=+1) is only taken when:
      - base curve is steep (positive slope) AND
      - quote curve is flat or inverted (slope < base_slope)

    Short base / long quote (signal=-1) is only taken when:
      - quote curve is steep relative to base
    """
    df = signal_df.copy()
    df = df.join(base_slope.rename("base_slope"), how="left")
    df = df.join(quote_slope.rename("quote_slope"), how="left")
    df[["base_slope", "quote_slope"]] = df[["base_slope", "quote_slope"]].ffill()

    # Slope differential: positive → base is steeper → supportive for base
    df["slope_diff"] = df["base_slope"] - df["quote_slope"]

    # Filter: suppress longs when slope_diff is negative (quote steeper)
    df.loc[(df["signal"] == +1) & (df["slope_diff"] < 0), "signal"] = 0
    # Filter: suppress shorts when slope_diff is positive (base steeper)
    df.loc[(df["signal"] == -1) & (df["slope_diff"] > 0), "signal"] = 0

    return df


# Example for EUR/USD
usd_slope = fetch_curve_slope("usd")
eur_slope = fetch_curve_slope("eur")

analysis_filtered = apply_curve_filter(analysis, base_slope=usd_slope, quote_slope=eur_slope)
print(analysis_filtered[["zscore", "signal", "slope_diff"]].tail(8))

USD और EUR वक्र ढलान (10Y2Y) उदाहरणात्मक

दोनों वक्रों ने 20222023 में उलट दिया; सापेक्ष ढलान अंतर ने अभी भी एक व्यापार योग्य संकेत प्रदान किया, भले ही पूर्ण ढलाने नकारात्मक हों।

चरण 5: अलर्ट उत्पन्न करें और एक लाइव मॉनिटर बनाएं

अंतिम चरण एक मॉनिटर में सिग्नल तर्क इकट्ठा करता है जिसे आप एक कार्यक्रम पर चला सकते हैं (दैनिक बंद, प्रति घंटा, या बांड उपज की घोषणा के तुरंत बाद ट्रिगर किया जाता है। FXMacroData रिलीज़ कैलेंडर) जब कोई नया संकेत चलाता है, तो मॉनिटर एक संरचित अलर्ट प्रिंट करता है जिसे आप स्लैक, ईमेल या ट्रेडिंग वेबहूक पर रूट कर सकते हैं।

from dataclasses import dataclass
from typing import Literal

SignalType = Literal["LONG", "SHORT", "EXIT", "HOLD"]


@dataclass
class SpreadAlert:
    fx_pair:     str
    signal:      SignalType
    spread_pct:  float
    zscore:      float
    slope_diff:  float
    timestamp:   str


def latest_signal(
    base_ccy: str,
    quote_ccy: str,
    fx_pair:   str,
    tenor:     str = "gov_bond_10y",
    lookback:  int = 60,
) -> SpreadAlert:
    base_yields  = fetch_yield(base_ccy,  tenor=tenor)
    quote_yields = fetch_yield(quote_ccy, tenor=tenor)
    df = pd.DataFrame({
        "base":  base_yields,
        "quote": quote_yields,
    }).dropna()

    base_col, quote_col = "base", "quote"
    df = compute_spread_signal(
        df.rename(columns={"base": base_col, "quote": quote_col}),
        base_col=base_col,
        quote_col=quote_col,
        lookback=lookback,
    )

    # Curve filter
    base_slope  = fetch_curve_slope(base_ccy)
    quote_slope = fetch_curve_slope(quote_ccy)
    df = apply_curve_filter(df, base_slope, quote_slope)

    row = df.iloc[-1]
    sig_map = {1: "LONG", -1: "SHORT", 0: "HOLD"}

    return SpreadAlert(
        fx_pair=fx_pair,
        signal=sig_map[int(row["signal"])],
        spread_pct=round(float(row["spread"]), 3),
        zscore=round(float(row["zscore"]), 2),
        slope_diff=round(float(row.get("slope_diff", float("nan"))), 3),
        timestamp=datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%SZ"),
    )


# Run for all pairs
for base_ccy, quote_ccy, fx_label in PAIRS:
    try:
        alert = latest_signal(base_ccy, quote_ccy, fx_label)
        print(
            f"[{alert.timestamp}] {alert.fx_pair:8s} | {alert.signal:5s} | "
            f"spread={alert.spread_pct:+.3f}%  z={alert.zscore:+.2f}  slope_diff={alert.slope_diff:+.3f}"
        )
    except Exception as exc:
        print(f"{fx_label}: error — {exc}")

# Example output:
# [2025-04-14T08:32:11Z] EUR/USD   | HOLD  | spread=+1.770%  z=+1.21  slope_diff=+0.210
# [2025-04-14T08:32:14Z] USD/JPY   | SHORT | spread=+4.050%  z=+2.18  slope_diff=+0.580
# [2025-04-14T08:32:17Z] AUD/USD   | HOLD  | spread=+0.340%  z=-0.55  slope_diff=-0.120
# [2025-04-14T08:32:20Z] GBP/USD   | LONG  | spread=+0.890%  z=-1.62  slope_diff=-0.340

समय-निर्धारण युक्तियाँ

बांड उपज के आंकड़े तब अपडेट किए जाते हैं जब सरकारें नए निष्कासन परिणाम प्रकाशित करती हैं और जब केंद्रीय बैंक नीतिगत निर्णय जारी करते हैं। FXMacroData रिलीज़ कैलेंडर अगले निर्धारित बांड नीलामी या नीति की घोषणा खोजने के लिए, और उस घटना आग लगने के तुरंत बाद अपने संकेत ताज़ा करने के लिए ट्रिगर।

संकेत का जोड़े में वितरण चित्रणात्मक

60 दिनों के रोलिंग विंडो पर ±1.5 के Z-स्कोर की सीमाओं के साथ, दिनों का एक महत्वपूर्ण बहुमत फ्लैट जोन में पड़ता है, उच्च-अभिव्यक्ति सेटअप पर पूंजी की तैनाती को केंद्रित करता है।

सारांश और आगे के कदम

अब आपके पास एक पूर्ण रिटर्न-स्प्रेड जोड़ी व्यापार ढांचा है।

  1. बांड उपज प्राप्त करना /announcements/{currency}/gov_bond_10y और /announcements/{currency}/gov_bond_2y दूसरे स्तर के समय के साथ कच्चे माल की आपूर्ति
  2. स्प्रेड और जेड स्कोर 60 दिन की रोलिंग विंडो के आसपास औसत प्रतिगमन एक एकल सीमा पर वक्र फिट किए बिना उद्देश्य प्रवेश और निकास स्तर उत्पन्न करता है
  3. वक्र-नमी फ़िल्टर 10Y2Y अंतर एक शासन गेट के रूप में कार्य करता है, प्रत्येक मुद्रा के अपने उपज वक्र के संरचनात्मक पूर्वाग्रह के खिलाफ चलने वाले संकेतों को दबाता है
  4. प्रत्यक्ष अलर्ट संरचित SpreadAlert आउटपुट को किसी भी सूचना, लॉगिंग या निष्पादन पाइपलाइन में रूट करना आसान है

प्राकृतिक विस्तार में उपज के अंतर को नीतिगत दरों के अंतर और सीपीआई अंतर या िकया िक ा िक ब्रेक बीन मुद्रास्फीति दर मुद्रास्फीति से समायोजित पोजिशनिंग के लिए नाममात्र से वास्तविक उपज के स्प्रेड में बदलाव करना।

सभी उपलब्ध उपज और दर अंत बिंदुओं के लिए पूर्ण प्रलेखन /api- संदर्भ. अपनी एपीआई कुंजी प्राप्त करने के लिए, /अपना नाम लिखें.

AI Answer-Ready

Key Facts

Page
How To Yield Spread Pair Trading
Section
Articles
Canonical URL
https://fxmacrodata.com/articles/how-to-yield-spread-pair-trading
Source
FXMacroData editorial and official publisher references
Last Updated
2026-04-22 12:36 UTC

Provenance And Trust

Cite the canonical URL and source field above. Where available, this page maps to official publisher releases and timestamped updates.

Quick Q&A

What is this page about? This page explains How To Yield Spread Pair Trading with directly usable context for trading, research, and API workflows.

What source should be cited? Use the canonical URL and the listed source field; cite official publisher references when available.

How fresh is this content? The last updated value above reflects the page metadata or latest available data timestamp.

Can this be used in AI assistants? Yes. This section is intentionally structured for retrieval and citation in chat assistants.

Prompt Packs

Use these in ChatGPT, Claude, Gemini, Mistral, Perplexity, or Grok for consistent source-aware outputs.

Blogroll