Technology

Carry Trade Deutsch — กลยุทธ์ทำกำไรจากส่วนต่างดอกเบี้ยใน Forex

carry trade deutsch | SiamCafe Blog
2025-07-26· อ. บอม — SiamCafe.net· 1,346 คำ

Carry Trade คืออะไรและทำงานอย่างไร

Carry Trade เป็นกลยุทธ์การลงทุนที่กู้ยืมเงินในสกุลเงินที่มีอัตราดอกเบี้ยต่ำ (funding currency) แล้วนำไปลงทุนในสกุลเงินที่มีอัตราดอกเบี้ยสูง (target currency) กำไรมาจากส่วนต่างของอัตราดอกเบี้ย (interest rate differential) ระหว่างสองสกุลเงิน

ตัวอย่างคลาสสิกคือ Japanese Yen Carry Trade ที่กู้เงินเยนญี่ปุ่นซึ่งมีอัตราดอกเบี้ยใกล้ 0% แล้วนำไปลงทุนในสกุลเงินที่ดอกเบี้ยสูงกว่าเช่น AUD (4.35%), USD (5.25%) หรือ BRL (10.5%) ส่วนต่างดอกเบี้ยนี้เรียกว่า carry yield

ในตลาด Forex เมื่อถือ position ข้ามคืน broker จะคำนวณ swap rate ซึ่งสะท้อนส่วนต่างดอกเบี้ย ถ้า long สกุลเงินดอกเบี้ยสูงและ short สกุลเงินดอกเบี้ยต่ำจะได้รับ positive swap ทุกวัน ในวันพุธจะได้ triple swap เพราะรวมวันเสาร์อาทิตย์ด้วย

ความเสี่ยงหลักของ Carry Trade คือ exchange rate risk ถ้าสกุลเงินที่ลงทุน (target) อ่อนค่าลงเมื่อเทียบกับ funding currency กำไรจาก carry อาจไม่พอชดเชยการขาดทุนจากอัตราแลกเปลี่ยน นอกจากนี้ Carry Trade มักถูก unwind พร้อมกันในช่วง risk-off events ทำให้เกิดการเคลื่อนไหวรุนแรง

กลยุทธ์ Carry Trade ที่นิยมในตลาด Forex

คู่สกุลเงินและกลยุทธ์ที่นิยมใช้สำหรับ Carry Trade

# Carry Trade Pairs และ Interest Rate Differentials (2024)
#
# Central Bank Interest Rates:
# JPY (Bank of Japan):      0.10%
# CHF (Swiss National Bank): 1.50%
# EUR (ECB):                 4.50%
# GBP (Bank of England):    5.25%
# USD (Federal Reserve):    5.25-5.50%
# AUD (RBA):                4.35%
# NZD (RBNZ):               5.50%
# MXN (Banxico):            11.25%
# BRL (BCB):                10.50%
# TRY (TCMB):               50.00%
#
# Popular Carry Trade Pairs:
# Long NZD/JPY: +5.40% carry (NZD 5.50% - JPY 0.10%)
# Long USD/JPY: +5.15% carry (USD 5.25% - JPY 0.10%)
# Long AUD/JPY: +4.25% carry (AUD 4.35% - JPY 0.10%)
# Long MXN/JPY: +11.15% carry (MXN 11.25% - JPY 0.10%)
# Long USD/CHF: +3.75% carry (USD 5.25% - CHF 1.50%)
# Long GBP/CHF: +3.75% carry (GBP 5.25% - CHF 1.50%)
#
# Carry Trade Types:
#
# 1. Classic Carry Trade
#    - Long high-yield / Short low-yield
#    - ถือนานหลายเดือนหรือปี
#    - เน้น swap income
#
# 2. Enhanced Carry Trade
#    - รวม carry กับ trend following
#    - เข้าเมื่อ trend สอดคล้องกับ carry direction
#    - ออกเมื่อ trend กลับตัว
#
# 3. Volatility-Adjusted Carry
#    - ปรับ position size ตาม volatility
#    - ลด position เมื่อ VIX สูง
#    - เพิ่ม position เมื่อ VIX ต่ำ
#
# 4. Basket Carry Trade
#    - กระจายความเสี่ยงหลายคู่สกุลเงิน
#    - Long basket: NZD, AUD, MXN
#    - Short basket: JPY, CHF
#    - ลด single currency risk

วิเคราะห์ Interest Rate Differentials ด้วย Python

คำนวณ carry yield และ swap rates สำหรับคู่สกุลเงินต่างๆ

#!/usr/bin/env python3
# carry_analyzer.py — Carry Trade Analysis Tool
import pandas as pd
import numpy as np
from datetime import datetime

INTEREST_RATES = {
    "JPY": 0.10, "CHF": 1.50, "EUR": 4.50, "GBP": 5.25,
    "USD": 5.50, "AUD": 4.35, "NZD": 5.50, "CAD": 5.00,
    "MXN": 11.25, "BRL": 10.50, "TRY": 50.00, "ZAR": 8.25,
    "NOK": 4.50, "SEK": 4.00, "SGD": 3.50, "HKD": 5.75,
}

def calculate_carry(long_ccy, short_ccy, notional=100000, leverage=1):
    long_rate = INTEREST_RATES.get(long_ccy, 0)
    short_rate = INTEREST_RATES.get(short_ccy, 0)
    carry_pct = long_rate - short_rate
    
    annual_carry = notional * leverage * (carry_pct / 100)
    daily_carry = annual_carry / 365
    monthly_carry = annual_carry / 12
    
    return {
        "pair": f"{long_ccy}/{short_ccy}",
        "long_rate": long_rate,
        "short_rate": short_rate,
        "carry_pct": round(carry_pct, 2),
        "annual_carry": round(annual_carry, 2),
        "monthly_carry": round(monthly_carry, 2),
        "daily_carry": round(daily_carry, 2),
    }

def find_best_carry_pairs(min_carry=3.0):
    pairs = []
    currencies = list(INTEREST_RATES.keys())
    
    for long_ccy in currencies:
        for short_ccy in currencies:
            if long_ccy == short_ccy:
                continue
            result = calculate_carry(long_ccy, short_ccy)
            if result["carry_pct"] >= min_carry:
                pairs.append(result)
    
    pairs.sort(key=lambda x: x["carry_pct"], reverse=True)
    return pairs

def calculate_breakeven_move(long_ccy, short_ccy, holding_days=365):
    carry = calculate_carry(long_ccy, short_ccy)
    carry_pct = carry["carry_pct"]
    daily_carry = carry_pct / 365
    total_carry = daily_carry * holding_days
    
    return {
        "pair": carry["pair"],
        "carry_pct": carry_pct,
        "holding_days": holding_days,
        "total_carry_pct": round(total_carry, 2),
        "breakeven_move_pct": round(-total_carry, 2),
        "explanation": f"{long_ccy} can depreciate up to {total_carry:.2f}% against {short_ccy} before losing money"
    }

if __name__ == "__main__":
    print("=== Best Carry Trade Pairs (min 3%) ===\n")
    best = find_best_carry_pairs(3.0)
    for p in best[:15]:
        print(f"  {p['pair']:10s} | Carry: {p['carry_pct']:6.2f}% | "
              f"Daily:  | Monthly: ")
    
    print("\n=== Breakeven Analysis ===\n")
    for pair in [("USD", "JPY"), ("AUD", "JPY"), ("MXN", "JPY")]:
        be = calculate_breakeven_move(*pair, 180)
        print(f"  {be['pair']}: {be['explanation']}")

สร้างระบบ Carry Trade Scanner อัตโนมัติ

สร้าง scanner ที่รวม carry yield กับ technical signals

#!/usr/bin/env python3
# carry_scanner.py — Enhanced Carry Trade Scanner
import yfinance as yf
import numpy as np
import pandas as pd

FOREX_TICKERS = {
    "USD/JPY": "USDJPY=X", "AUD/JPY": "AUDJPY=X",
    "NZD/JPY": "NZDJPY=X", "GBP/JPY": "GBPJPY=X",
    "EUR/JPY": "EURJPY=X", "MXN/JPY": "MXNJPY=X",
    "USD/CHF": "USDCHF=X", "GBP/CHF": "GBPCHF=X",
    "AUD/CHF": "AUDCHF=X", "NZD/CHF": "NZDCHF=X",
}

CARRY_RATES = {
    "USD/JPY": 5.40, "AUD/JPY": 4.25, "NZD/JPY": 5.40,
    "GBP/JPY": 5.15, "EUR/JPY": 4.40, "MXN/JPY": 11.15,
    "USD/CHF": 4.00, "GBP/CHF": 3.75, "AUD/CHF": 2.85,
    "NZD/CHF": 4.00,
}

def get_price_data(ticker, period="6mo"):
    try:
        df = yf.download(ticker, period=period, progress=False)
        return df
    except Exception:
        return None

def calculate_trend_score(df):
    if df is None or len(df) < 50:
        return 0
    
    close = df["Close"].values
    sma_20 = pd.Series(close).rolling(20).mean().values
    sma_50 = pd.Series(close).rolling(50).mean().values
    
    score = 0
    if close[-1] > sma_20[-1]: score += 1
    if close[-1] > sma_50[-1]: score += 1
    if sma_20[-1] > sma_50[-1]: score += 1
    
    # Momentum
    returns_20d = (close[-1] - close[-20]) / close[-20] * 100
    if returns_20d > 0: score += 1
    if returns_20d > 2: score += 1
    
    return score  # 0-5

def calculate_volatility(df, window=20):
    if df is None or len(df) < window:
        return None
    returns = df["Close"].pct_change().dropna()
    vol = returns.rolling(window).std().iloc[-1] * np.sqrt(252) * 100
    return round(vol, 2)

def scan_carry_trades():
    results = []
    
    for pair, ticker in FOREX_TICKERS.items():
        df = get_price_data(ticker)
        carry = CARRY_RATES.get(pair, 0)
        trend = calculate_trend_score(df)
        vol = calculate_volatility(df) or 0
        
        # Volatility-adjusted carry
        vol_adj_carry = carry / max(vol, 1) * 10
        
        # Combined score (carry + trend)
        combined = (carry * 0.4) + (trend * 2 * 0.3) + (vol_adj_carry * 0.3)
        
        results.append({
            "pair": pair,
            "carry_pct": carry,
            "trend_score": trend,
            "volatility": vol,
            "vol_adj_carry": round(vol_adj_carry, 2),
            "combined_score": round(combined, 2),
            "signal": "STRONG BUY" if combined > 5 else ("BUY" if combined > 3.5 else "HOLD"),
        })
    
    results.sort(key=lambda x: x["combined_score"], reverse=True)
    return results

if __name__ == "__main__":
    print(f"=== Carry Trade Scanner — {pd.Timestamp.now().strftime('%Y-%m-%d')} ===\n")
    results = scan_carry_trades()
    
    print(f"{'Pair':10s} | {'Carry':6s} | {'Trend':5s} | {'Vol':6s} | {'Score':6s} | Signal")
    print("-" * 60)
    for r in results:
        print(f"{r['pair']:10s} | {r['carry_pct']:5.2f}% | {r['trend_score']}/5  | "
              f"{r['volatility']:5.1f}% | {r['combined_score']:5.2f} | {r['signal']}")

Risk Management สำหรับ Carry Trade

จัดการความเสี่ยงสำหรับ Carry Trade positions

# Risk Management Framework สำหรับ Carry Trade
#
# === Position Sizing ===
# กฎ: Risk ไม่เกิน 1-2% ต่อ position
# 
# Position Size = (Account * Risk%) / (Entry - StopLoss)
# ตัวอย่าง: Account $100,000, Risk 1%
# USD/JPY Entry: 150.00, Stop: 147.00 (300 pips)
# Risk Amount: $100,000 * 1% = $1,000
# Position Size: $1,000 / (300 pips * $6.67/pip) = 0.5 lots
#
# === Stop Loss Strategies ===
# 1. ATR-based Stop:
#    Stop = Entry - (2.5 * ATR)
#    ใช้ 14-period ATR
#
# 2. Support/Resistance Stop:
#    วาง stop ใต้ support level สำคัญ
#
# 3. Trailing Stop:
#    เลื่อน stop ตาม profit
#    เช่น trail ด้วย 2x ATR
#
# === Risk Indicators ===
# ตรวจสอบก่อนเข้า Carry Trade:
#
# VIX (Fear Index):
#   VIX < 15: Low risk, carry trade เหมาะ
#   VIX 15-25: Normal, ระวัง position size
#   VIX > 25: High risk, ลด exposure
#   VIX > 35: Extreme, ปิด carry positions
#
# USD/JPY Volatility:
#   ถ้า 1M implied vol > 10%: ระวัง JPY carry trades
#
# EM Currency Index:
#   ถ้า MSCI EM Currency Index ลดลง > 2%/สัปดาห์: ลด EM carry
#
# === Hedging ===
# 1. Options Hedge:
#    ซื้อ put option บน carry pair
#    Cost: ~1-3% ต่อปี (ลด net carry)
#
# 2. Correlation Hedge:
#    ถ้า long AUD/JPY → short NZD/USD เป็น partial hedge
#    ลด directional risk แต่ยังได้ carry
#
# 3. Volatility Hedge:
#    Long VIX futures เมื่อ VIX ต่ำ
#    ได้กำไรเมื่อ market panic (carry unwind)

Backtesting Carry Trade Strategy

ทดสอบกลยุทธ์ Carry Trade ด้วยข้อมูลในอดีต

#!/usr/bin/env python3
# carry_backtest.py — Backtest Carry Trade Strategy
import yfinance as yf
import numpy as np
import pandas as pd

def backtest_carry(pair_ticker, carry_annual_pct, period="5y",
                   sma_filter=True, vol_filter=True):
    df = yf.download(pair_ticker, period=period)
    if df is None or len(df) < 200:
        return None
    
    df["returns"] = df["Close"].pct_change()
    df["sma_50"] = df["Close"].rolling(50).mean()
    df["sma_200"] = df["Close"].rolling(200).mean()
    df["volatility"] = df["returns"].rolling(20).std() * np.sqrt(252)
    
    daily_carry = carry_annual_pct / 100 / 365
    capital = 100000
    position = 0
    equity = [capital]
    trades = []
    
    for i in range(200, len(df)):
        in_position = position > 0
        price = df["Close"].iloc[i]
        
        # Entry conditions
        enter = True
        if sma_filter:
            enter = enter and (df["Close"].iloc[i] > df["sma_50"].iloc[i])
            enter = enter and (df["sma_50"].iloc[i] > df["sma_200"].iloc[i])
        if vol_filter:
            enter = enter and (df["volatility"].iloc[i] < 0.15)
        
        # Exit conditions
        exit_signal = False
        if sma_filter:
            exit_signal = df["Close"].iloc[i] < df["sma_200"].iloc[i]
        
        if enter and not in_position:
            position = equity[-1] / price
            entry_price = price
            trades.append({"date": df.index[i], "action": "BUY", "price": price})
        
        elif exit_signal and in_position:
            pnl = (price - entry_price) / entry_price * equity[-1]
            equity.append(equity[-1] + pnl)
            trades.append({"date": df.index[i], "action": "SELL", "price": price, "pnl": pnl})
            position = 0
            continue
        
        # Daily P&L
        if in_position:
            daily_pnl = equity[-1] * df["returns"].iloc[i]
            carry_income = equity[-1] * daily_carry
            equity.append(equity[-1] + daily_pnl + carry_income)
        else:
            equity.append(equity[-1])
    
    # Stats
    equity_series = pd.Series(equity)
    total_return = (equity[-1] - capital) / capital * 100
    max_dd = ((equity_series.cummax() - equity_series) / equity_series.cummax()).max() * 100
    sharpe = (equity_series.pct_change().mean() / equity_series.pct_change().std()) * np.sqrt(252)
    
    return {
        "total_return_pct": round(total_return, 2),
        "annualized_return_pct": round(total_return / (len(df) / 252), 2),
        "max_drawdown_pct": round(max_dd, 2),
        "sharpe_ratio": round(sharpe, 2),
        "total_trades": len([t for t in trades if t["action"] == "SELL"]),
        "final_equity": round(equity[-1], 2),
    }

if __name__ == "__main__":
    pairs = [
        ("USDJPY=X", 5.4, "USD/JPY"),
        ("AUDJPY=X", 4.25, "AUD/JPY"),
        ("NZDJPY=X", 5.4, "NZD/JPY"),
    ]
    
    print("=== Carry Trade Backtest (5Y) ===\n")
    for ticker, carry, name in pairs:
        result = backtest_carry(ticker, carry, "5y")
        if result:
            print(f"{name}:")
            print(f"  Return: {result['total_return_pct']}% | "
                  f"Ann: {result['annualized_return_pct']}%/yr")
            print(f"  MaxDD: {result['max_drawdown_pct']}% | "
                  f"Sharpe: {result['sharpe_ratio']}")
            print(f"  Trades: {result['total_trades']} | "
                  f"Final: \n")

FAQ คำถามที่พบบ่อย

Q: Carry Trade เหมาะกับนักลงทุนแบบไหน?

A: เหมาะกับนักลงทุนที่มี time horizon ยาว (หลายเดือนถึงหลายปี) สามารถรับความเสี่ยงจากอัตราแลกเปลี่ยนได้ และมี capital เพียงพอที่จะรับ drawdown ไม่เหมาะกับ day traders หรือผู้ที่ต้องการ quick returns เพราะกำไรหลักมาจาก swap ที่สะสมทุกวัน

Q: Carry Trade unwind คืออะไรและอันตรายแค่ไหน?

A: Carry trade unwind เกิดเมื่อนักลงทุนจำนวนมากปิด carry positions พร้อมกัน มักเกิดในช่วง risk-off events เช่น วิกฤตการเงิน ตัวอย่างเช่น August 2024 ที่ JPY แข็งค่าขึ้น 10% ภายในสัปดาห์เดียวเมื่อ BOJ ขึ้นดอกเบี้ย ทำให้ carry traders ขาดทุนมหาศาล สิ่งสำคัญคือต้องมี stop loss เสมอ

Q: Swap rate กับ interest rate differential เหมือนกันไหม?

A: ไม่เท่ากันพอดี swap rate ที่ broker ให้มักต่ำกว่า theoretical interest rate differential เพราะ broker บวก spread ส่วนต่างอาจ 0.5-1.5% ขึ้นอยู่กับ broker ควรเปรียบเทียบ swap rates ระหว่าง brokers และเลือกที่ให้ swap ดีที่สุด

Q: ใช้ leverage เท่าไหร่สำหรับ Carry Trade?

A: แนะนำ leverage ไม่เกิน 3:1 ถึง 5:1 สำหรับ carry trade แม้ broker อาจให้ leverage สูงถึง 50:1 หรือ 100:1 แต่ carry trade มี holding period ยาวทำให้ต้องรับ drawdown มากกว่า day trading leverage สูงเกินไปอาจทำให้ margin call ก่อนที่ carry จะชดเชยขาดทุนได้

📖 บทความที่เกี่ยวข้อง

herschel trade carry onอ่านบทความ → carry trade meaningอ่านบทความ → carry trade forexอ่านบทความ → สอนเล่นหุ้น day tradeอ่านบทความ → learn how to forex tradeอ่านบทความ →

📚 ดูบทความทั้งหมด →