4. 权重法求解:线性加权法、目标规划法在投资组合中的应用与局限性

说到多目标优化,很多人第一反应就是「给每个目标加个权重,然后求和」。嗯,这确实是最直观的思路。我刚开始做量化的时候,也是这么干的。但后来发现,事情没那么简单。

今天我们就来聊聊两种最经典的权重法:线性加权法目标规划法。它们在实际投资组合中怎么用?坑在哪里?我踩过的雷,你最好别踩。

权重法求解 线性加权法 公式:min Σwᵢfᵢ 权重敏感性高 帕累托前沿 目标规划法 设定目标值 偏差最小化 优先级设定 ⚠ 共同局限性 主观性强 · 非凸问题失效 · 目标冲突

4.1 线性加权法:最朴素的多目标处理方式

线性加权法的思路很简单:给每个目标函数分配一个权重,然后加起来变成一个单目标问题。

数学上长这样:

min  w₁ * f₁(x) + w₂ * f₂(x) + ... + wₙ * fₙ(x)
s.t. x ∈ S

其中 wᵢ ≥ 0,且 Σwᵢ = 1。

在投资组合里,我们通常有两个目标:最大化收益最小化风险。写成加权形式就是:

min  -λ * E(R) + (1-λ) * σ²
s.t. Σwᵢ = 1, wᵢ ≥ 0

这里的 λ 就是权重,从0到1变化。λ=1 时只关注收益,λ=0 时只关注风险。

关键点:改变 λ 值,就能得到一组不同的投资组合。把这些组合画在风险-收益图上,就是那条著名的「有效前沿」。

我个人习惯用 Python 快速扫一遍 λ 从0到1的效果。代码大概长这样:

import numpy as np
from scipy.optimize import minimize

def weighted_portfolio(returns, cov, lambda_):
    n = len(returns)
    def objective(w):
        ret = -lambda_ * np.sum(w * returns)
        risk = (1 - lambda_) * np.sqrt(w @ cov @ w)
        return ret + risk
    constraints = ({'type': 'eq', 'fun': lambda w: np.sum(w) - 1})
    bounds = [(0, 1) for _ in range(n)]
    result = minimize(objective, x0=np.ones(n)/n, 
                      bounds=bounds, constraints=constraints)
    return result.x

# 扫一遍 lambda
lambdas = np.linspace(0, 1, 20)
portfolios = [weighted_portfolio(returns, cov, l) for l in lambdas]

跑完之后,你就能看到一条漂亮的曲线。但这里有个坑——权重怎么定?

⚠ 避坑指南:我曾经在一个项目中,拍脑袋定了 λ=0.6,觉得「收益优先一点」。结果回测出来夏普比率惨不忍睹。后来才发现,不同资产类别的收益和风险量级差太多,同样的 λ 值效果天差地别。

说白了,线性加权法有两个硬伤:

  • 权重主观性太强——你定 λ=0.5 和 λ=0.6,结果可能完全不同
  • 无法处理非凸问题——如果帕累托前沿不是凸的,加权法根本找不到某些最优解

你想想看,如果两个目标之间存在严重的冲突(比如收益和回撤),加权法只能给出一个「折中」,但没法告诉你「哪个折中更好」。

4.2 目标规划法:先定目标,再找方案

目标规划法的思路不太一样。它不搞「加权求和」,而是先给每个目标设定一个「理想值」,然后想办法让实际值尽量靠近这个理想值。

数学形式:

min  Σ (dᵢ⁺ + dᵢ⁻)
s.t. fᵢ(x) - dᵢ⁺ + dᵢ⁻ = targetᵢ
     dᵢ⁺, dᵢ⁻ ≥ 0
     x ∈ S

其中 dᵢ⁺ 是超出目标的部分,dᵢ⁻ 是未达到目标的部分。我们想最小化这些偏差的总和。

在投资组合里,比如你希望年化收益达到 15%,最大回撤不超过 10%。那就可以写成:

min  d₁⁻ + d₂⁺
s.t. E(R) + d₁⁻ ≥ 0.15
     MaxDrawdown - d₂⁺ ≤ 0.10
     d₁⁻, d₂⁺ ≥ 0
     Σwᵢ = 1, wᵢ ≥ 0

这里 d₁⁻ 表示收益没达到 15% 的缺口,d₂⁺ 表示回撤超过 10% 的部分。我们想让这两个「遗憾」尽量小。

💡 实战技巧:我在做 FOF 组合时,经常用目标规划法。因为客户会直接说「我要年化8%以上,最大回撤不超过5%」。这种场景下,目标规划法比加权法更直观——客户能理解「目标没达到,差了多少」。

目标规划法还有一个变种叫分层目标规划。就是给目标排个优先级,先保证最重要的目标,再考虑次要的。

比如:

  1. 第一优先级:风险不能超过某个阈值(这是底线)
  2. 第二优先级:在满足风险约束下,尽量提高收益
  3. 第三优先级:如果还有余地,降低换手率

代码实现也不复杂:

from scipy.optimize import linprog

# 第一优先级:风险约束
c1 = [0] * n + [1]  # 最小化风险偏差
A_ub = [[...]]       # 风险约束矩阵
b_ub = [risk_limit]
res1 = linprog(c1, A_ub=A_ub, b_ub=b_ub)

# 第二优先级:在风险约束下最大化收益
c2 = [-returns]      # 最大化收益
constraints = [...]  # 加上第一优先级的结果作为约束
res2 = linprog(c2, constraints=constraints)

但目标规划法也有自己的问题:

  • 目标值怎么定?定得太高,永远达不到;定得太低,没有挑战性
  • 优先级冲突时怎么办?有时候低优先级的目标会完全被牺牲掉

⚠ 我曾经踩过的坑:有一次做多资产配置,我把「控制回撤」设为第一优先级,「提高收益」设为第二优先级。结果优化出来的组合全是债券,收益低得可怜。后来我加了第三优先级「最低收益要求」,才把权益仓位拉回来。

4.3 两种方法的对比与选择

说了这么多,到底什么时候用加权法,什么时候用目标规划法?

维度 线性加权法 目标规划法
核心思想 折中与权衡 逼近理想值
输入要求 权重 wᵢ 目标值 targetᵢ
输出形式 一个帕累托最优解 偏差最小的可行解
适用场景 目标可量化、权重可协商 有明确目标值、客户有偏好
主要局限 权重敏感、非凸失效 目标值主观、优先级僵化

我个人习惯是:先用加权法扫一遍帕累托前沿,看看有哪些可能的组合;再用目标规划法,根据客户的具体要求做微调。这样既能看到全局,又能满足个性化需求。

核心结论:权重法简单直观,但主观性太强。它们适合做「初步探索」和「快速原型」,但真正要落地到实盘,我建议结合更高级的方法(比如进化算法或贝叶斯优化)。

嗯,关于权重法就聊到这里。记住一点:没有完美的权重,只有合适的权衡。下次你遇到多目标优化问题,不妨先问问自己——我是想「折中」,还是想「逼近目标」?答案会帮你选对方法。


专注资料整理