Skip to content

15.5 跨资产宏观策略

名词解释:跨资产宏观策略(Cross-Asset Macro Strategy)

跨资产宏观策略是基于宏观经济分析,在股票、债券、外汇、商品等多个资产类别中同时进行方向性押注的投资策略。全球宏观对冲基金(如 Bridgewater、Tudor)是这类策略的典型实践者,其核心方法论包括 Carry、Momentum 和 Value 三大风格。

一、全球宏观对冲基金策略

1.1 三大宏观交易风格

全球宏观策略通常可归纳为三种系统性风格:

风格逻辑典型交易风险
Carry(套息)持有高收益资产、融低收益资产做多高息货币/做空低息货币(Carry Trade)崩盘风险(Crash Risk)
Momentum(动量)趋势会延续做多过去6-12个月表现最强的资产趋势反转
Value(价值)价格会回归公允价值做多低估货币/债券,做空高估货币/债券价值陷阱

1.2 外汇 Carry Trade 的量化实现

PYTHON49 行 · 1.6 KB
📄此处有展示代码49 行 · 1.6 KB展开 ▼
python
import numpy as np
import pandas as pd
from typing import Tuple

def fx_carry_strategy(spot_rates: pd.DataFrame,
                       interest_rates: pd.DataFrame,
                       lookback_days: int = 21) -> pd.DataFrame:
    """
    系统性外汇套息策略。

    每月做多利率最高的3种货币,做空利率最低的3种货币。

    参数:
        spot_rates: 外汇即期汇率(每列为一种货币对)
        interest_rates: 对应货币的短期利率(年化%)
        lookback_days: 调仓周期
    返回:
        策略收益率序列
    """
    n_currencies = len(interest_rates.columns)

    returns = spot_rates.pct_change().fillna(0)
    strategy_returns = []

    for t in range(lookback_days, len(interest_rates), lookback_days):
        # 当前利率排名
        current_rates = interest_rates.iloc[t]
        ranked = current_rates.sort_values()

        # 高利率货币做多,低利率货币做空
        long_currencies = ranked.index[-3:]  # 最高利率的3种
        short_currencies = ranked.index[:3]   # 最低利率的3种

        # 下一持仓期的收益
        end_idx = min(t + lookback_days, len(returns))
        period_returns = returns.iloc[t:end_idx]

        # 组合收益(等权多空)
        long_return = period_returns[long_currencies].mean(axis=1)
        short_return = period_returns[short_currencies].mean(axis=1)
        portfolio_return = long_return - short_return

        strategy_returns.append(portfolio_return)

    # 拼接
    strategy_returns = pd.concat(strategy_returns)
    strategy_returns = strategy_returns[~strategy_returns.index.duplicated()]

    return strategy_returns
点击展开可浏览运行结果
📘 本段代码定义了 1 个函数/类:函数 `fx_carry_strategy`(系统性外汇套息策略)。该片段为教学展示(未包含独立运行的输入数据),可在实战练习中结合真实数据调用。

1.3 宏观动量策略

PYTHON40 行 · 1.4 KB
📄此处有展示代码40 行 · 1.4 KB展开 ▼
python
def global_macro_momentum(asset_prices: pd.DataFrame,
                           n_assets: int = 10,
                           momentum_months: int = 6,
                           rebalance_freq: str = 'M') -> pd.DataFrame:
    """
    全球宏观动量策略:做多过去N个月表现最好的资产。

    参数:
        asset_prices: 全球资产价格矩阵
            (含股票指数、债券指数、商品、外汇)
        n_assets: 做多资产数量
        momentum_months: 动量回看月数
        rebalance_freq: 调仓频率 ('M'=每月)
    返回:
        策略权重和收益
    """
    # 计算动量信号
    momentum_signal = asset_prices.pct_change(momentum_months * 21)

    # 每月调仓
    weights = pd.DataFrame(0.0, index=asset_prices.index,
                           columns=asset_prices.columns)

    if rebalance_freq == 'M':
        rebalance_dates = asset_prices.resample('M').last().index

        for date in rebalance_dates:
            if date in momentum_signal.index:
                mom = momentum_signal.loc[date]
                top_assets = mom.nlargest(n_assets).index

                # 等权配置
                weight_value = 1.0 / n_assets
                weights.loc[date:, top_assets] = weight_value

    # 策略收益
    asset_returns = asset_prices.pct_change()
    strategy_returns = (weights.shift(1) * asset_returns).sum(axis=1)

    return strategy_returns
点击展开可浏览运行结果
📘 本段代码定义了 1 个函数/类:函数 `global_macro_momentum`(全球宏观动量策略:做多过去N个月表现最好的资产)。该片段为教学展示(未包含独立运行的输入数据),可在实战练习中结合真实数据调用。

二、跨资产相关性的危机特征

2.1 相关性在危机期间的结构性变化

市场在正常时期和危机时期的相关性结构截然不同:

PYTHON70 行 · 2.5 KB
📄此处有展示代码70 行 · 2.5 KB展开 ▼
python
def crisis_correlation_analysis(asset_returns: pd.DataFrame,
                                 crisis_dates: list = None) -> dict:
    """
    分析正常时期 vs 危机时期的跨资产相关性变化。

    参数:
        asset_returns: 各资产的日收益率
        crisis_dates: 危机期间的日期列表
    返回:
        包含正常和危机时期相关性矩阵的字典
    """
    if crisis_dates is None:
        # 示例:2008金融危机和2020新冠
        crisis_dates = [
            ('2008-09-01', '2009-03-31'),
            ('2020-02-19', '2020-03-23')
        ]

    # 正常时期(排除危机)
    crisis_mask = pd.Series(False, index=asset_returns.index)
    for start, end in crisis_dates:
        crisis_mask |= (asset_returns.index >= start) & \
                        (asset_returns.index <= end)

    normal_returns = asset_returns[~crisis_mask]
    crisis_returns = asset_returns[crisis_mask]

    # 计算相关性
    normal_corr = normal_returns.corr()
    crisis_corr = crisis_returns.corr()

    # 相关性差异
    corr_diff = crisis_corr - normal_corr

    # 可视化
    fig, axes = plt.subplots(1, 3, figsize=(18, 5))

    titles = ['正常时期', '危机时期', '差异 (危机 - 正常)']
    matrices = [normal_corr, crisis_corr, corr_diff]

    for i, (title, mat) in enumerate(zip(titles, matrices)):
        im = axes[i].imshow(mat.values, cmap='RdBu_r',
                            vmin=-1, vmax=1, aspect='auto')
        axes[i].set_xticks(range(len(mat.columns)))
        axes[i].set_yticks(range(len(mat.columns)))
        axes[i].set_xticklabels(mat.columns, rotation=45, ha='right',
                                 fontsize=8)
        axes[i].set_yticklabels(mat.columns, fontsize=8)
        axes[i].set_title(title)
        plt.colorbar(im, ax=axes[i], shrink=0.8)

    plt.tight_layout()
    plt.show()

    # 相关性分散度:危机期间各资产间相关性趋于1
    normal_dispersion = np.std(normal_corr.values[np.triu_indices_from(
        normal_corr.values, k=1)])
    crisis_dispersion = np.std(crisis_corr.values[np.triu_indices_from(
        crisis_corr.values, k=1)])

    return {
        'normal_correlation': normal_corr,
        'crisis_correlation': crisis_corr,
        'correlation_diff': corr_diff,
        'dispersion_normal': normal_dispersion,
        'dispersion_crisis': crisis_dispersion,
        'diversification_benefit_deterioration': (
            normal_dispersion - crisis_dispersion
        ) / normal_dispersion * 100
    }
点击展开可浏览运行结果
📘 本段代码定义了 1 个函数/类:函数 `crisis_correlation_analysis`(分析正常时期 vs 危机时期的跨资产相关性变化)。该片段为教学展示(未包含独立运行的输入数据),可在实战练习中结合真实数据调用。

2.2 动态条件相关模型(DCC-GARCH)

DCC-GARCH 可以刻画时变的相关性,并捕捉相关性在危机期间的突然上升:

PYTHON35 行 · 1.1 KB
📄此处有展示代码35 行 · 1.1 KB展开 ▼
python
def simple_dcc_estimate(returns_1: np.ndarray,
                         returns_2: np.ndarray,
                         half_life: int = 20) -> np.ndarray:
    """
    简化的动态条件相关性估计(指数加权移动平均)。

    DCC_t = q12_t / sqrt(q11_t * q22_t)

    参数:
        returns_1, returns_2: 两个资产的收益率
        half_life: EWMA半衰期(天)
    返回:
        时变相关性序列
    """
    alpha = 2.0 / (half_life + 1)  # EWMA衰减因子

    T = len(returns_1)
    q11 = np.zeros(T)
    q22 = np.zeros(T)
    q12 = np.zeros(T)
    dcc = np.zeros(T)

    # 初始化:无条件方差/协方差
    q11[0] = np.var(returns_1)
    q22[0] = np.var(returns_2)
    q12[0] = np.cov(returns_1, returns_2)[0, 1]

    for t in range(1, T):
        q11[t] = (1 - alpha) * q11[t-1] + alpha * returns_1[t-1] ** 2
        q22[t] = (1 - alpha) * q22[t-1] + alpha * returns_2[t-1] ** 2
        q12[t] = (1 - alpha) * q12[t-1] + alpha * returns_1[t-1] * returns_2[t-1]

        dcc[t] = q12[t] / (np.sqrt(q11[t]) * np.sqrt(q22[t]) + 1e-10)

    return dcc
点击展开可浏览运行结果
📘 本段代码定义了 1 个函数/类:函数 `simple_dcc_estimate`(简化的动态条件相关性估计(指数加权移动平均))。该片段为教学展示(未包含独立运行的输入数据),可在实战练习中结合真实数据调用。

三、汇率、利率、大宗商品的联动

3.1 三元悖论与跨资产传导

"三元悖论"(Impossible Trinity)指出:一个经济体不能同时实现固定汇率、资本自由流动和独立货币政策。这一约束驱动了汇率、利率和资本流动之间的紧密联动:

  • 加息 + 资本流入 -> 本币升值 -> 大宗商品(以美元计价)承压
  • 资本外流 -> 本币贬值 -> 出口改善 -> 股市受益(出口导向型)

3.2 联动性的量化

PYTHON40 行 · 1.2 KB
📄此处有展示代码40 行 · 1.2 KB展开 ▼
python
def cross_asset_linkage(fx_changes: np.ndarray,
                         rate_changes: np.ndarray,
                         commodity_changes: np.ndarray,
                         window: int = 60) -> pd.DataFrame:
    """
    量化汇率、利率、大宗商品之间的联动关系。

    使用VAR模型估计相互影响。

    参数:
        fx_changes: 汇率变动率
        rate_changes: 利率变动(收益率变动)
        commodity_changes: 大宗商品价格变动率
        window: 滚动窗口
    返回:
        滚动回归系数DataFrame
    """
    T = len(fx_changes)

    results = []
    for t in range(window, T):
        # 局部数据
        fx = fx_changes[t-window:t]
        rate = rate_changes[t-window:t]
        comm = commodity_changes[t-window:t]

        # 回归: ΔFX = α + β1 * ΔRates + β2 * ΔCommodity + ε
        X = np.column_stack([np.ones(window), rate, comm])
        y = fx

        beta = np.linalg.lstsq(X, y, rcond=None)[0]
        results.append({
            'date': t,
            'constant': beta[0],
            'beta_rate': beta[1],
            'beta_commodity': beta[2],
            'r_squared': 1 - np.sum((y - X @ beta) ** 2) / np.sum((y - np.mean(y)) ** 2)
        })

    return pd.DataFrame(results)
点击展开可浏览运行结果
📘 本段代码定义了 1 个函数/类:函数 `cross_asset_linkage`(量化汇率、利率、大宗商品之间的联动关系)。该片段为教学展示(未包含独立运行的输入数据),可在实战练习中结合真实数据调用。

四、风险平价在全球宏观中的应用

4.1 风险平价原理

风险平价(Risk Parity)使组合中各资产的风险贡献相等,而非资本权重相等。在全球宏观中,风险平价旨在:

  1. 跨资产平衡风险:股票、债券、商品、外汇的风险贡献大致相等
  2. 抗通胀和通缩环境的双重保护:增长环境利好股票/商品,衰退环境利好债券
  3. 适应不同经济周期:不需要预测周期阶段,自然适应环境变化

4.2 实现

PYTHON30 行 · 910 B
📄此处有展示代码30 行 · 910 B展开 ▼
python
def global_macro_risk_parity(asset_returns: pd.DataFrame,
                              lookback: int = 252) -> pd.Series:
    """
    全球宏观风险平价组合权重。

    各资产权重 ∝ 1 / 波动率

    参数:
        asset_returns: 全球资产日收益率
        lookback: 波动率估计窗口
    返回:
        风险平价权重
    """
    # 滚动波动率
    rolling_vol = asset_returns.rolling(lookback).std().iloc[-1]

    # 权重 ∝ 1/vol
    inv_vol = 1.0 / rolling_vol
    weights = inv_vol / inv_vol.sum()

    # 波动率缩放:组合目标波动率 10%
    portfolio_vol_estimate = np.sqrt(
        weights @ asset_returns.rolling(lookback).cov().iloc[-1] @ weights
    )
    target_vol = 0.10 / np.sqrt(252)  # 日度目标波动率
    leverage = target_vol / portfolio_vol_estimate

    weights = weights * min(leverage, 2.0)  # 杠杆上限2倍

    return weights
点击展开可浏览运行结果
📘 本段代码定义了 1 个函数/类:函数 `global_macro_risk_parity`(全球宏观风险平价组合权重)。该片段为教学展示(未包含独立运行的输入数据),可在实战练习中结合真实数据调用。

4.3 全天候策略的宏观逻辑

Bridgewater 的"全天候"(All Weather)策略是风险平价的典型应用。它将经济环境按增长和通胀预期分为四种情况,每种情况配置 25% 的风险预算:

环境增长超预期增长低于预期
通胀超预期商品、TIPS、新兴市场股票通胀挂钩债券、黄金
通胀低于预期股票、公司信用债名义国债、通胀挂钩债券

跨资产宏观策略的精髓在于理解资产之间的联动关系,以及这些关系如何随经济周期变化。构建此类策略需要强大的风险管理体系来应对相关性破裂和市场恶化——这正是下一个模块要深入探讨的主题。