前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >组合优化神器:Riskfolio-Lib(附代码)

组合优化神器:Riskfolio-Lib(附代码)

作者头像
量化投资与机器学习微信公众号
发布2022-02-28 11:39:09
4.1K1
发布2022-02-28 11:39:09
举报

前言

组合优化是量化投资策略实施过程中非常重要的步骤,组合优化的过程是结合不同的投资目标及风险约束给出最优组合权重的过程。在数学上,它是一个凸优化的求解问题。业界常用的凸优化的求解工具包有CVXPY及CVXOPT。但这两款工具包并不是专门针对投资组合优化的,在求解过程中还需要将组合优化的问题转化为对应的优化问题。

今天我们介绍的Riskfolio-Lib是专门针对投资组合优化的工具包,其构建于CVXPY之上(其实CVXPY也用到了CVXOPT的求解器),并于Pandas紧密结合。Riskfolio-Lib内嵌了多个开箱即用的组合优化工具,致力于帮助学生、学者和实践者以最少的精力建立基于复杂数学模型的投资组合。

该项目在github上已经超过900个star,项目的地址如下:

https://github.com/dcajasn/Riskfolio-Lib

安装

安装方法非常简单:

代码语言:javascript
复制
pip install riskfolio-lib

但需要注意的是,在安装riskfolio-lib前,需要安装cvxpy。如果需要跑通项目中的example,还需要安装yfinance,这是一个从雅虎获取财经数据的工具库。部分example还需要MOSEK求解器,推荐使用conda进行安装:

代码语言:javascript
复制
conda install -c mosek mosek

介绍

Riskfolio-Lib支持多种组合优化模型,从最基础的均值方差模型(Mean-Variance)、风险平价模型(Risk Parity)、Black-Litterman模型到基于机器学习的层次化聚类模型(Hierarchical Clustering)都有完整的支持。

在Riskfolio-Lib中,将以上组合优化模型分为两大类,其中Portfolio类针对传统的组合优化,主要支持以下模型:

  • Mean Risk Portfolio Optimization,该类模型的优化方法又支持以下几类:
    • MinRisk:风险最小优化
    • MaxRet:收益最大优化
    • Sharp:夏普最大优化,其中夏普比率中的风险指标可以切换为其他13个支持的风险指标
    • Utility:效用函数最大优化。
  • Risk Parity Portfolio Optimization
  • Relaxed Risk Parity Portfolio Optimization
  • Worst Case Mean-Variance Portfolio Optimization

还有一类是层次聚类模型,由HCPortfolio类负责,层次聚类的优化方法主要有:

  • Hierarchical Risk Parity (HRP)
  • Hierarchical Equal Risk Contribution (HERC)
  • Nested Clustered Optimization (NCO)

具体的使用方式遵循以下四个步骤:

1、准备相关数据;

2、实例化组合类;

代码语言:javascript
复制
import riskfolio as rp
# 如果是传统模型
port = rp.Portfolio()
# 如果是层次化聚类模型
hcport = rp.HCPortfolio()

3、参数及限制条件配置;

4、求解;

代码语言:javascript
复制
# 如果是Mean Risk Portfolio Optimization,使用optimization方法
port.optimization()
# 如果是Risk Parity,使用rp_optimization方法
port.rp_optimization

下面我们以两个实例学习下工具的使用。

均值方差组合优化

我们以最简单的均值-方差组合优化介绍Riskfolio的使用方法,首先使用是准备数据,我们用yfinance获取数据:

代码语言:javascript
复制
import numpy as np
import pandas as pd
import yfinance as yf
# 起止时间
start = '2016-01-01'
end = '2019-12-30'
# 股票代码
assets = ['JCI', 'TGT', 'CMCSA', 'CPB', 'MO', 'APA', 'MMC', 'JPM',
          'ZION', 'PSA', 'BAX', 'BMY', 'LUV', 'PCAR', 'TXT', 'TMO',
          'DE', 'MSFT', 'HPQ', 'SEE', 'VZ', 'CNP', 'NI', 'T', 'BA']
assets.sort()
# 下载数据
data = yf.download(assets, start = start, end = end)
data = data.loc[:,('Adj Close', slice(None))]
data.columns = assets

# 计算收益率
Y = data[assets].pct_change().dropna()

使用Riskfolio求解最优组合,优化目标为夏普比率最大:

代码语言:javascript
复制
import riskfolio as rp

# 实例化一个投资组合,输入为收益率数据Y
port = rp.Portfolio(returns=Y)

# 组合优化参数配置
model='Classic' # 可以为Classic (historical), BL (Black Litterman)、FM (Factor Model)或BLFM
rm = 'MV' # 风险度量指标,MV表示方差,本工具包共支持13种风险度量指标
obj = 'Sharpe' # 目标函数, 可选有MinRisk, MaxRet, Utility或Sharpe
hist = True # 是否基于历史数据计算风险收益
rf = 0 # 无风险利率
l = 0 # 风险厌恶系数, 只有当目标函数为'Utility'时有用

# 计算期望收益及方差,当模型model选择Classic时,需使用assets_stats计算组合的期望收益及方差
method_mu='hist' # 还支持其他方法,详见文档
method_cov='hist' # 还支持其他方法,详见文档
port.assets_stats(method_mu=method_mu, method_cov=method_cov)

# 传入参数,求解
w = port.optimization(model=model, rm=rm, obj=obj, rf=rf, l=l, hist=hist)

均值方差组合优化-因子暴露约束

因子模型的组合优化中,我们常常会对组合有因子暴露的约束,项目中给的例子是已知因子组合的收益,因子暴露未知,所以首先需要通过因子收益与股票收益的回归,求解每个股票的因子暴露,具体我们看代码:

代码语言:javascript
复制
import numpy as np
import pandas as pd
import yfinance as yf
import warnings
warnings.filterwarnings("ignore")
pd.options.display.float_format = '{:.4%}'.format
# 起止时间
start = '2016-01-01'
end = '2019-12-30'
# 股票代码
assets = ['JCI', 'TGT', 'CMCSA', 'CPB', 'MO', 'APA', 'MMC', 'JPM',
          'ZION', 'PSA', 'BAX', 'BMY', 'LUV', 'PCAR', 'TXT', 'TMO',
          'DE', 'MSFT', 'HPQ', 'SEE', 'VZ', 'CNP', 'NI', 'T', 'BA']
assets.sort()
# 因子ETF代码,主:这是美国市场的因子ETF基金,作者使用基金的收益作为因子收益
factors = ['MTUM', 'QUAL', 'VLUE', 'SIZE', 'USMV']
factors.sort()
tickers = assets + factors
tickers.sort()
# 下载数据
data = yf.download(tickers, start = start, end = end)
data = data.loc[:,('Adj Close', slice(None))]
data.columns = tickers
X = data[factors].pct_change().dropna()
Y = data[assets].pct_change().dropna()

其中因子收益X如下,包含动量(MTUM)、质量(QUAL)、规模(SIZE)、低波动(USMV)、价值(VLUE)五个因子:

计算因子暴露:

代码语言:javascript
复制
step = 'Forward' 
loadings = rp.loadings_matrix(X=X, Y=Y, stepwise=step)

设置因子暴露的限制条件,并求解:

代码语言:javascript
复制
constraints = {'Disabled': [False, False, False, False, False],
               'Factor': ['MTUM', 'QUAL', 'SIZE', 'USMV', 'VLUE'],
               'Sign': ['<=', '<=', '<=', '>=', '<='],
               'Value': [-0.3, 0.8, 0.4, 0.8 , 0.9],
               'Relative Factor': ['', 'USMV', '', '', '']}
               
C, D = rp.factors_constraints(constraints, loadings)
port.ainequality = C
port.binequality = D
w = port.optimization(model=model, rm=rm, obj=obj, rf=rf, l=l, hist=hist)

Riskfolio-Lib是一款完善的组合优化工具,自带丰富的案例供大家学习参考,项目文档中也有丰富的文献供大家学习,

https://riskfolio-lib.readthedocs.io/en/latest/index.html

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-02-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 量化投资与机器学习 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档