投资组合优化,需要一定背景知识,否则不清楚整篇文章干嘛的,达到什么目的。
“马科维茨”投资组合模型实践——第三章 投资组合优化:最小方差与最大夏普比率:https://www.jianshu.com/p/400758e58768
随机搜索最优权重
构造随机权重
1 | np.random.seed(42) |
数据准备
1 | # Build column hierarchy such that one weight corresponds to one price series |
tile用法样例
1 | price.vbt.tile(3, keys=pd.Index(list('abc'), name='symbol_group')) |
stack_index用法样例
1 | num_tests= 3 |
生成订单
1 | # Run simulation |
波动率收益回报率,可视化
1 | annualized_return = pf.annualized_return() |
取得最优组合信息
1 | # Get index of the best group according to the target metric |
月再平衡(重置回初始权重)
收益计算
按照月重新平衡,虽然再平衡权重没变,但由于标的价格变化,购买时的size对应的targetpercent,其实是现金比例,所以实际仓位也会变化。等于在原始持续持有的基础上,卖出了上涨幅度大的(由于上涨,导致reset时,实际targetpercent高于初始取值,所以会卖出部分,维持资金占比)。
1 | # Select the first index of each month |
这部分如何理解?
1 | _price.index.to_period('m') |
再平衡日,重新设置权重
1 | rb_size = np.full_like(_price, np.nan) |
重新计算再平衡收益
1 | # Run simulation, with rebalancing monthly |
权值可视化
1 | def plot_allocation(rb_pf): |
搜索和30日再平衡
1 | srb_sharpe = np.full(price.shape[0], np.nan) |
from_order_func(有点复杂,暂跳过)
先搞清楚from_order_func,参考:https://vectorbt.dev/api/portfolio/base/#vectorbt.portfolio.base.Portfolio.from_order_func
1 | # Run simulation using a custom order function |
关于from_order_func,几个比较容易混淆的重要的函数
1 | order_func_nb: callable |
执行官方提供最简单demo
1 | import numpy as np |
有效边界法(PyPortfolioOpt)
1 | # Calculate expected returns and sample covariance amtrix |
1 | # Get weights maximizing the Sharpe ratio |
填充初始权值
1 | pyopt_size = np.full_like(price, np.nan) |
只进行一次初始化时的交易回测
1 | # Run simulation with weights from PyPortfolioOpt |
有效边界的按月再平衡
原文中有这么一段描述
1 | You can't use third-party optimization packages within Numba (yet). #不确定为啥 |
重写了weight方法
1 | def pyopt_find_weights(sc, price, num_tests): # no @njit decorator = it's a pure Python function |
计算组合收益
1 | pyopt_srb_sharpe = np.full(price.shape[0], np.nan) |
夏普值的可视化
1 | pd.Series(pyopt_srb_sharpe, index=price.index).vbt.scatterplot(trace_kwargs=dict(mode='markers')).show_svg() |
绩效评估
1 | print(pyopt_srb_pf.stats()) |
权值可视化
1 | plot_allocation(pyopt_srb_pf) |
附录
Portfolio.from_orders
参考:https://vectorbt.dev/api/portfolio/base/#from-orders
样例
需要注意的是size:1,-1,1,-1需要结合不同direction会生成不同的sell,buy信号,shortonly时的size=1表示卖出。