3. 动态调整仓位权重

任务目标

在分散做市策略中,各板块仓位权重需随市场波动率变化动态调整,使组合整体风险维持在目标水平。本案例实现一个最小可运行的波动率目标仓位调整器:输入各板块当前波动率与目标组合波动率,输出调整后的仓位权重。

核心逻辑

采用波动率倒数加权方法:高波动板块自动降低权重,低波动板块自动提高权重,同时将组合预期波动率拉回目标值。权重计算公式为:

w_i = (target_vol / vol_i) / Σ(target_vol / vol_j)

该公式保证权重之和为1,且当所有板块波动率等于目标波动率时,权重均匀分布。

完整实现


import numpy as np

def adjust_weights(vols, target_vol):
    """
    基于波动率倒数加权动态调整仓位权重。
    
    参数:
        vols: list[float],各板块当前年化波动率(如 0.15 表示 15%)
        target_vol: float,目标组合年化波动率
    
    返回:
        np.ndarray,归一化后的权重向量,和为1
    """
    vols = np.array(vols)
    if np.any(vols <= 0):
        raise ValueError("波动率必须为正数")
    if target_vol <= 0:
        raise ValueError("目标波动率必须为正数")
    
    # 波动率倒数加权(含目标缩放,但归一化后缩放因子抵消)
    inv_vol = target_vol / vols
    weights = inv_vol / inv_vol.sum()
    return weights

if __name__ == "__main__":
    # 示例:三个板块当前波动率分别为 12%、20%、30%
    current_vols = [0.12, 0.20, 0.30]
    target = 0.15
    
    w = adjust_weights(current_vols, target)
    
    print("调整后权重:", np.round(w, 4))
    print("权重和:", round(w.sum(), 6))
    
    # 验证:组合波动率(假设相关性为0的近似估算)
    port_vol = np.sqrt((w**2 * np.array(current_vols)**2).sum())
    print("估算组合波动率:", round(port_vol, 4))

运行方式

python vol_target_weights.py

验证方法

  • 权重归一化:输出权重之和必须为1.0(允许浮点误差)。
  • 单调性:波动率最高的板块(30%)应获得最低权重;波动率最低的板块(12%)应获得最高权重。
  • 风险收敛:按输出权重重新计算的组合波动率应接近目标值15%。本例预期输出权重约为 [0.4839, 0.2903, 0.1935],估算组合波动率约0.15。

若实际市场波动率变化,只需将最新波动率数组传入函数即可获得新权重,实现动态调整。