很多小韭菜以为投资就是埋头选股,但其实啊,资产怎么分配比选个股更重要!乱分配容易翻车,系统化配置才能让投资组合更稳当~今天花姐就带大家解锁一个超实用的策略:风险平价!
和简单粗暴的等权重分配、或者教科书式的均值方差优化不同,风险平价的核心思路是:按每个资产的波动风险来分筹码,让每个资产对整体组合的风险贡献度差不多~说白了就是:谁也别想一个人带偏整个团队!
花姐还专门用Python跑了回测,选了5个A股做了对比实验
✅ 关键结果亮出来:
- 风险平价策略年化收益11.07% vs 等权重8.01%
- 波动率更低:30.27% vs 32.33%
- 夏普比率更高:0.37 vs 0.25
- 最大回撤更小:-37.59% vs -40.35%

不过花姐也要说句实话:这策略靠的是历史波动率估风险,得经常调仓,而且市场风格一变也可能歇菜~
入门小贴士
开始之前,花姐建议宝宝们最好具备一些 Python 基础------不是只会打印"Hello World"那种哦!要会写基本的代码,还要熟悉数据分析常用的库(比如 pandas、numpy)。如果你想系统打基础,可以看看这篇👉
【Python编程入门指南】
另外,也需要对金融数据有一定的了解,比如什么是股票,股票包含了open/high/low/close等价格,如何获取股票行情数据等......
掌握这些之后,你就能更轻松跟上后续内容,自己动手实践也会更有信心哒!💪
写在前面
你是不是也想过:你投资组合的风险,到底是从哪儿来的?🤔
大多数投资者都专注于埋头选股、选基金,但万一 「怎么分配钱」比「买什么」更重要呢?研究一遍遍告诉我们:资产配置,才是长期投资表现的关键!比如先锋集团(Vanguard)就发过好多报告,实锤资产配置才是决定你投资成绩的"大头"。
今天花姐要带大家仔细瞅瞅一个聪明又系统的配置方法------风险平价。它不只平衡你的"本金",更平衡你的"风险"!不让任何一个资产类别"绑架"你整个组合的风险,而是让风险更均匀地分摊------这样不管市场怎么变,你的账户都可能更稳当。📊
其实呀,量化管理一个组合,通常就分三步:
-
1.选资产
-
2.分配资产
-
3.调仓 & 跟踪
现代组合理论研究发现,"资产分配"这一步对绩效影响最大!今天我们不光要搞懂资产分配,还要慢慢引出其中一种超实用的分配方法------分层风险平价。
什么是资产配置
想象一下:有个投资新手小白,拿着10万块钱,买了5只股票。咋买的呢?基本上是看心情、凭感觉,或者看手头有多少钱就买多少......结果买出来一看,组合长这样👇
(注:以下数据仅为举例,非真实情况)
股票 | 股价 | 股数 | 金额 | 占比 |
---|---|---|---|---|
兆易创新 | 116 | 400 | 1,944 | 46.40% |
用友网络 | 14.94 | 400 | 4,366 | 5.98% |
中航沈飞 | 62.68 | 200 | 3,610 | 12.54% |
汇川技术 | 64.51 | 100 | 8,340 | 6.45% |
浪潮信息 | 53.69 | 500 | 11,742 | 26.85% |
总计 | 98208 | 98.21% |
一眼就能看出来------问题大啦!😥
兆易创新一支独大,占了46.40%,而汇川技术却只占6.45%。这已经不是"偏科"了,这是直接把整个组合押注在几只股票上!
➡️ 情况一:万一兆易创新表现不好,你整个账户都会跟着"抖三抖",回撤吓死人------这叫个股风险集中!
➡️ 情况二:就算汇川技术涨得再好,因为它只占你仓位的6.45%,你也吃不到多少肉......
所以花姐常说:
你买什么固然重要,但你给每个资产分配多少比例,更是门大学问!
如何解决"资金分配不均"的问题?
很多"小韭菜"在做投资组合时,常常会凭感觉来分配资金。🙃 但在量化投资的世界里,基金经理可不会靠"拍脑袋"做决定,而是用一些逻辑清晰、经过验证的有效方法来进行资金配置。
如果资金分配不均,很容易导致某些股票占比过高,从而让整个组合暴露在集中风险里。为了解决这个问题,量化圈里发展出了几种系统化的资产配置方法。今天我先带大家看看最常见的几种:
方法一:等权分配
思路: 很简单,给每只股票分配相同的资金。比如说我有10万要投 5 只股票,那就每只都投2万。
来看个例子👇
股票 | 股价 | 股数 | 金额 | 占比 |
---|---|---|---|---|
兆易创新 | 116 | 200 | 23200 | 23.20% |
用友网络 | 14.94 | 1300 | 19422 | 19.42% |
中航沈飞 | 62.68 | 300 | 18804 | 18.80% |
汇川技术 | 64.51 | 300 | 19353 | 19.35% |
浪潮信息 | 53.69 | 300 | 16107 | 16.11% |
总计 | 96886 | 96.89% |
优点:
- 简单直观,谁都能看懂。
- 能有效避免"某一只股票占比过大"的集中风险。
缺点:
- 完全忽略了不同股票的波动性和相关性。
- 有些风险更高的股票,可能会被分配到和低风险股票一样的资金,从而导致风险放大。
好的,我来帮你把这段英文翻译并改写成适合 Python小白用户 看的风格,用花姐的口吻来讲👇
方法二:均值-方差优化(MVO)
在量化投资里,另一个经典的配置方法就是 均值-方差优化 ,它基于现代投资组合理论(MPT)。核心思路是:在给定的风险水平下,让投资组合的 预期收益最大化。
听起来是不是有点抽象?其实很多基金经理都在用,只不过在实操中需要不断地定期再平衡,因为市场会变,风险和收益的估计也会变化。
MVO 主要依赖三类输入数据:
- 各个资产的 预期收益
- 各个资产的 波动率(风险大小)
- 各个资产之间的 相关性/协方差
举个例子:
假设我们还是有 10 万要投资,这次不是简单的等权,而是用算法算出一个更"聪明"的分配👇
股票 | 预期收益(%) | 波动率(%) | 优化后权重(%) | 金额(¥) | 股数 |
---|---|---|---|---|---|
兆易创新 | 9 | 22 | 12% | 12000 | 103.4 |
用友网络 | 10 | 18 | 18% | 18000 | 1205.6 |
中航沈飞 | 11 | 25 | 25% | 25000 | 398.6 |
汇川技术 | 8 | 20 | 15% | 15000 | 232.6 |
浪潮信息 | 13 | 35 | 30% | 30000 | 558.9 |
合计 | - | - | 100% | 100000 | - |
⚠️ 注意:
-
预期收益和波动率依旧是假设的,不是真实市场数据。
-
股数为近似计算结果(金额 ÷ 股价),实际交易时只能买整数股。
Monte Carlo 模拟
为了测试投资组合在不同市场场景下的稳健性,常常会用到 蒙特卡罗模拟(Monte Carlo Simulation) 。 简单来说,就是用电脑随机生成成千上万种不同的权重组合,计算每种组合的 收益与波动率,然后画在图上。

最后会出现一个"有效前沿",而夏普比率最高的那个点(上图标"+"的点),就是被认为最优的组合。🎯
优点:
- 理论上最优,只要输入数据准确,就能找到风险收益比最划算的组合。
缺点:
- 对输入假设特别敏感,尤其是 预期收益 ------ 但未来收益往往很难预测,这也是它在实操中的最大挑战。
这样一对比,你会发现:
- 等权分配像是"大家一碗水端平",简单粗暴;
- MVO 优化则更像是"聪明分配",考虑风险与收益,但对数据要求很高。
方法三:基于风险的资产配置:风险平价
接下来是我们今天要重点讲的------风险平价。
很多朋友一开始学资产配置时,都会想着「要么平均分配资金,要么按照收益来分配」。但风险平价的思路有点不一样:它关注的不是资金投入多少,而是每个资产对整个组合风险的贡献。目标就是------让每个资产对组合的波动性贡献都差不多。💡
实现的步骤大致是这样的:

- 估计每个资产的波动率(通常用历史收益的标准差来衡量)。
- 计算波动率的倒数(简单理解就是:波动小 → 权重高;波动大 → 权重低)。
- 对这些倒数进行归一化,让所有资产的权重加起来等于 1。
这样一来,你的组合里,不是某个高风险资产说了算,而是大家"均衡发声",组合的稳定性自然就会更好一些。🎯
什么是波动率?
波动率,其实就是价格"晃动"的幅度有多大。简单说,就是价格涨涨跌跌的速度和幅度有多大。它通常被用来衡量风险。
打个比方:价格动得越厉害(波动大),风险可能就越高,但同时机会也可能更多。😂
📊 波动率的计算公式(标准差)
公式长得有点吓人,但别慌,我给你拆开讲:
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> σ = 1 N − 1 ∑ i = 1 N ( r i − r ˉ ) 2 \sigma = \sqrt{\frac{1}{N-1} \sum_{i=1}^{N} (r_i - \bar{r})^2} </math>σ=N−11i=1∑N(ri−rˉ)2
公式里的每个符号是什么意思呢?
- <math xmlns="http://www.w3.org/1998/Math/MathML"> σ = 标准差(也就是波动率) \sigma = 标准差(也就是波动率) </math>σ=标准差(也就是波动率)
- <math xmlns="http://www.w3.org/1998/Math/MathML"> r i = 第 i 个时间点的收益 r_i = 第 i 个时间点的收益 </math>ri=第i个时间点的收益
- <math xmlns="http://www.w3.org/1998/Math/MathML"> r ˉ = 平均收益 \bar{r} = 平均收益 </math>rˉ=平均收益
- <math xmlns="http://www.w3.org/1998/Math/MathML"> N = 时间段的数量 N = 时间段的数量 </math>N=时间段的数量
简单理解就是:先算出每个时间点收益跟平均收益的差,然后平方,求平均,再开平方,就得到波动率啦!
通俗点说,就是看价格离"平均水平"有多远,越远波动率越高。🎉
📊 波动率的倒数
波动率的倒数,其实就是把波动率拿来"取反",数学上就是 1 除以波动率。
为什么要用它呢?
- 它常用来衡量风险调整后的仓位,也就是把钱投到风险低的资产上多一点,风险高的资产上少一点。
- 在组合投资里,我们可以用它来按风险反向分配权重,风险越高,分得的钱越少;风险低的,分得的钱就多。
公式很简单:
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> σ = 波动率 \sigma = \text{波动率} </math>σ=波动率
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> 波动率倒数 = 1 σ \text{波动率倒数} = \frac{1}{\sigma} </math>波动率倒数=σ1
通俗点说,就是波动越大,倒数越小,投资比例就低;波动越小,倒数越大,投资比例就高。😂
📊 用波动率倒数算最终权重
想要做组合投资,我们希望低波动的资产多投点,高波动的资产少投点,但总资金还要分配完。这个时候就用"波动率倒数归一化"啦。
步骤很简单:
- 先算每个资产的波动率倒数(1/σ)
- 再把这些倒数"归一化",也就是让它们加起来等于 1
公式长这样:
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> w i = 1 / σ i ∑ j = 1 N 1 / σ j w_i = \frac{1/\sigma_i}{\sum_{j=1}^{N} 1/\sigma_j} </math>wi=∑j=1N1/σj1/σi
公式里的意思:
- <math xmlns="http://www.w3.org/1998/Math/MathML"> w i w_i </math>wi = 第 i 个资产在组合里的权重
- <math xmlns="http://www.w3.org/1998/Math/MathML"> σ i \sigma_i </math>σi = 第 i 个资产的波动率(收益的标准差)
- <math xmlns="http://www.w3.org/1998/Math/MathML"> N N </math>N = 组合里资产的总数
- <math xmlns="http://www.w3.org/1998/Math/MathML"> ∑ j = 1 N 1 / σ j {\sum_{j=1}^{N} 1/\sigma_j} </math>∑j=1N1/σj = 所有资产波动率倒数的总和
通俗理解就是:
- 每个资产的权重 = 它的"波动率倒数" / 所有资产的"波动率倒数之和"
- 这样波动小的资产权重就高,波动大的权重就低,而且总资金刚好分配完。🎉
用Python计算风险平价VS等权分配
步骤1:导入相关库
在做风险平价组合前,我们先导入需要用到的Python库:
python
import pandas as pd # 用于数据处理
import numpy as np # 用于数学计算
from xtquant import xtdata # 用于下载股票历史数据
import matplotlib.pyplot as plt # 用于绘图展示
步骤2:获取股票数据
-
这里依然用上面的5个股票来做演示
-
时间范围 : 从 2023年12月 (也就是2024年前一个月)开始到 2024年12月 为什么从前一个月开始?因为我们要用 20天滚动窗口 来计算波动率,并且每月调整一次组合(20个交易日大约就是一个月)
-
只取收盘价(Close): 收盘价最能反映当天股票的实际市场走势,数据会整理成平铺的表格形式,方便后续做计算
通俗点理解就是:
- 我们抓取了整整一年的收盘价数据
- 每列是股票,每行是日期
- 后面就可以直接算收益率、波动率,最后做风险平价组合啦🎉
python
stocks = [
"603986.SH", # 兆易创新
"600588.SH", # 用友网络
"600760.SH", # 中航沈飞
"300124.SZ", # 汇川技术
"000977.SZ" # 浪潮信息
]
start_date='20221201'
end_date ='20241230'
xtdata.download_history_data2(stock_list=stocks,period='1d',start_time="",end_time="")
data = xtdata.get_market_data_ex(stock_list=stocks,period='1d', start_time=start_date, end_time=end_date,dividend_type="front_ratio")
close_prices = pd.DataFrame()
for stock in stocks:
close_prices[stock] = data[stock]['close']
close_prices.index = pd.to_datetime(close_prices.index.astype(str), format='%Y%m%d')
# 查看结果
print(close_prices.head())
运行结果
txt
603986.SH 600588.SH 600760.SH 300124.SZ 000977.SZ
20221201 100.853181 23.312022 43.699074 68.500066 22.701428
20221202 97.887786 22.514348 43.113818 69.185949 22.741064
20221205 99.167171 23.092662 42.403151 70.841865 23.038333
20221206 101.289560 22.773592 42.744550 70.009008 22.909516
20221207 99.276265 22.624028 43.336773 69.479898 22.760882
步骤3:创建计算组合收益的函数
目标:计算组合的累计净值,组合可以是 等权 或 风险平价(Risk Parity),并按固定周期(如每 20 个交易日)再平衡。
函数参数
-
price_df
:DataFrame,包含多只股票的历史价格,行索引是日期 -
rebalance_period=20
:每多少天重新调整一次组合权重 -
method='equal'
:组合权重方式'equal'
→ 每只股票权重相等'risk_parity'
→ 根据波动率倒数分配权重
函数逻辑步骤
-
计算日收益率
pythonreturns = price_df.pct_change().dropna()
- 用
pct_change()
计算每天的涨跌幅 - 第一行会是 NaN,要去掉
- 用
-
计算滚动波动率(Rolling Volatility)
pythonvol = returns.rolling(window=rebalance_period).std().shift(1)
- 用
rolling().std()
计算每只股票的波动率 .shift(1)
防止未来数据泄露
- 用
-
对齐起始日期
- 找出所有股票都能计算出滚动波动率的最早日期
- 截取
returns
和vol
,保证时间对齐
-
初始化组合净值(NAV)
pythonnav = pd.Series(index=returns.index, dtype=float) nav.iloc[0] = 1.0
-
再平衡循环(Rebalance Loop)
-
按
rebalance_period
天划分窗口 -
每个窗口第一天重新计算权重:
权重计算方式:
-
equal
→ 所有股票权重相等 -
risk_parity
→ 波动率倒数归一化:pythonw = 1 / vol.iloc[rebalance_day] w /= w.sum()
-
-
-
计算窗口内累计收益 & 更新 NAV
- 计算窗口期间每只股票的累计收益
- 用权重加权得到组合累计收益
- 将 NAV 归一化,使每个窗口连续衔接
-
输出最终 NAV
- 返回组合累计净值序列
dropna()
去掉缺失值
步骤4:投资组合构建
接下来,我们使用历史价格数据来构建两个投资组合。这需要调用之前定义的投资组合构建函数。具体来说,我们生成:
- 等权重投资组合:在每个再平衡周期中,每个资产分配相同的权重。
- 风险平价投资组合:资产权重根据波动率的倒数确定,旨在使所有持仓的风险贡献相等。
两个投资组合都会根据指定的再平衡频率进行周期性调整。
python
# 等权重投资组合
eq_pf = compute_rebalanced_portfolio_returns(close_prices,20,method='equal')
# 风险平价投资组合
rp_pf = compute_rebalanced_portfolio_returns(close_prices,20,method='risk_parity')
步骤5:投资组合绩效评估
在这一步,我们对前面构建的两个投资组合------等权重和风险平价------进行绩效评估,通过计算关键指标来衡量表现:
- 日收益率:通过累计净值序列计算,用于观察每日的收益波动情况。
- 年化收益率:基于整个投资期的复合收益计算,并换算为年度表现。
- 年化波动率:由日收益率的标准差估算,并乘以交易日平方根(252天)进行年化。
- 夏普比率:衡量风险调整后的收益,计算方式为年化收益率与年化波动率的比值,这里假设无风险利率为0。
- 最大回撤:投资组合净值从峰值到谷值的最大跌幅,反映历史上的最坏情况损失。
这些指标可以全面展示每个投资组合在收益和风险上的表现。同时,我们也会可视化两个投资组合的累计净值,直观观察其随时间的表现趋势。
python
# 计算累计净值的日收益率
eq_returns = eq_pf.pct_change().dropna()
rp_returns = rp_pf.pct_change().dropna()
# 年化收益率
eq_ann_return = (eq_pf.iloc[-1])**(252/len(eq_pf)) - 1
rp_ann_return = (rp_pf.iloc[-1])**(252/len(rp_pf)) - 1
# 年化波动率
eq_ann_vol = eq_returns.std() * np.sqrt(252)
rp_ann_vol = rp_returns.std() * np.sqrt(252)
# 夏普比率(假设无风险利率 = 0)
eq_sharpe = eq_ann_return / eq_ann_vol
rp_sharpe = rp_ann_return / rp_ann_vol
# 最大回撤
def max_drawdown(series):
roll_max = series.cummax()
drawdown = (series - roll_max) / roll_max
return drawdown.min()
eq_max_dd = max_drawdown(eq_pf)
rp_max_dd = max_drawdown(rp_pf)
# 创建汇总表
comparison = pd.DataFrame({
'Annualized Return': [eq_ann_return, rp_ann_return],
'Annualized Volatility': [eq_ann_vol, rp_ann_vol],
'Sharpe Ratio': [eq_sharpe, rp_sharpe],
'Max Drawdown': [eq_max_dd, rp_max_dd]
}, index=['Equal Weighted PF', 'Risk Parity PF'])
print(comparison)
# 格式化输出
comparison['Annualized Return'] = comparison['Annualized Return'].map(lambda x: f"{x*100:.2f}%")
comparison['Annualized Volatility'] = comparison['Annualized Volatility'].map(lambda x: f"{x*100:.2f}%")
comparison['Sharpe Ratio'] = comparison['Sharpe Ratio'].map(lambda x: f"{x:.2f}")
comparison['Max Drawdown'] = comparison['Max Drawdown'].map(lambda x: f"{x*100:.2f}%")
# 打印或显示汇总表
print(comparison.to_string())
# 绘制累计净值对比图
plt.figure(figsize=(10, 7))
plt.plot(eq_pf, label='Equal Weighted PF', linewidth=2)
plt.plot(rp_pf, label='Risk Parity PF', linewidth=2)
plt.title('Portfolio NAV Comparison')
plt.xlabel('Date')
plt.ylabel('Cumulative NAV')
plt.legend(fontsize=12)
plt.grid(True)
plt.tight_layout()
plt.show()
输出结果:
erlang
Annualized Return Annualized Volatility Sharpe Ratio Max Drawdown
Equal Weighted PF 8.01% 32.33% 0.25 -40.35%
Risk Parity PF 11.07% 30.27% 0.37 -37.59%

结论
对比分析清晰地显示出,风险平价策略相较于传统等权组合具有明显优势。虽然两个组合都能带来正向收益,但风险平价组合在以下方面表现更优:
- 更高的年化收益率(11.07% vs 8.01%)
- 更低的波动率(30.27% vs 32.33%)
- 更优的风险调整后表现,夏普比率更高(0.37 vs 0.25)
- 更小的最大回撤(-37.59% vs. -40.35%)
这些结果表明,通过让资产的风险贡献而非资金投入来决定权重,风险平价组合不仅能提升潜在收益,还能提供更好的下行保护,使整体表现更加平滑稳定。
净值曲线进一步强化了这一结论:风险平价策略展现出更一致、更具韧性的增长轨迹。
总的来说,对于优先考虑稳健性而非极致增长的投资者而言,风险平价无疑是一个值得关注的传统配置替代方案。