功能
多策略投资组合
将策略堆叠为同一投资组合、配置权重,并比较定期投资计划
如何组合交易策略并在它们之间分配资金?在 VBT 中,每个策略的投资组合都可以视为一项资产:将策略堆叠为多列,再使用等权或优化器分配权重,最后通过另一次回测,按计划再平衡并计入手续费。
spy = vbt.YFData.pull("SPY", start="2010-01-01", end="2025-01-01")
fast = spy.close.vbt.rolling_mean(50)
slow = spy.close.vbt.rolling_mean(200)
trend = vbt.PF.from_signals(spy, fast > slow, fast < slow, fees=0.001)
rsi = vbt.RSI.run(spy.close, window=2).rsi
reversion = vbt.PF.from_signals(spy, rsi < 10, rsi > 70, fees=0.001)
strategies = pd.concat(
{"trend": trend.value, "reversion": reversion.value}, axis=1
)
returns = vbt.RepEval(
"strategies.pct_change().iloc[index_slice]", context=dict(strategies=strategies)
)
def inverse_vol(returns):
inv = 1 / returns.std()
return inv / inv.sum()
wrapper = vbt.ArrayWrapper.from_obj(strategies)
fifty = vbt.PFO.from_uniform(wrapper, every="M")
inv_vol = vbt.PFO.from_optimize_func(
wrapper, inverse_vol, returns, every="M", lookback_period="63D"
)
period = slice("2010-05", None)
pfs = {
"Trend": trend,
"Mean reversion": reversion,
"50/50 monthly": fifty.simulate(strategies, fees=0.001),
"Inverse volatility": inv_vol.simulate(strategies, fees=0.001),
}
metrics = ["total_return", "sharpe_ratio", "max_dd"]
stats = {k: pf.loc[period].stats(metrics) for k, pf in pfs.items()}
pd.DataFrame(stats).astype(float).round(2) Trend Mean reversion 50/50 monthly Inverse volatility
Total Return [%] 285.49 51.41 145.83 86.76
Sharpe Ratio 0.89 0.39 0.74 0.57
Max Drawdown [%] 33.72 31.79 27.95 28.11将两个策略组合后,回撤低于任一单独策略,但收益和夏普比率均未超过趋势策略,因为两者的相关性为 62%,且都持有 SPY。波动率倒数配置不如等权:均值回归策略多数时间持有现金,表面波动更低,因此尽管收益更少,却获得了更多资金。策略交易不同市场或行为差异更大时,组合通常更有帮助。
选择策略之间的协作方式
您可以组合不同入场规则、参数集或市场。需要决定的是,它们的资金如何交互:
| 您想测试什么 | 如何组合策略 |
|---|---|
| 为各策略分配固定初始资金,让它们自行增长 | 堆叠已完成的投资组合,并应用静态权重。 |
| 按计划在策略之间调配资金 | 将策略投资组合的净值视为价格,对配置方案进行回测。 |
| 让策略在交易时竞争同一笔现金 | 在同一现金共享组中,一起模拟它们的订单。 |
将策略作为列
具有相同索引的策略可以组成一个投资组合的不同列。即使一个策略使用信号,另一个使用显式订单等不同模拟方法,也能一起分析。vbt.PF.column_stack
合并已完成的投资组合,group_by=True 将它们视为一个永不再平衡的账户,因此各策略保留各自的初始资金,并随自身结果增长或缩减。apply_weights
可按固定权重缩放每个策略的资金、订单和现金流,无须重新模拟:
combined = vbt.PF.column_stack(
[trend, reversion], wrapper_kwargs=dict(group_by=True)
)
static = {
"50/50 static": combined,
"70/30 static": combined.apply_weights([0.7, 0.3], rescale=True),
}
stats.update({k: pf.loc[period].stats(metrics) for k, pf in static.items()})
pd.DataFrame(stats).iloc[:, 2:].astype(float).round(2) 50/50 monthly Inverse volatility 50/50 static 70/30 static
Total Return [%] 145.83 86.76 166.90 213.95
Sharpe Ratio 0.74 0.57 0.77 0.83
Max Drawdown [%] 27.95 28.11 29.88 31.70不进行调整时,50/50 组合会随着趋势策略增长更快而逐渐偏向它。与每月恢复各占一半相比,这种做法收益更高,但回撤略深。权重按策略应用于整个时期,并非逐根 K 线设置。若要在策略间再平衡,可像首个示例一样,将它们的净值作为投资组合优化器的价格。投资组合优化页的所有配置方法都适用,从固定权重到 PyPortfolioOpt 和 Riskfolio-Lib,再平衡手续费在策略层面收取。
策略交易时共享现金
若策略必须使用同一现金余额,可通过 group_by=True 和
cash_sharing=True,将它们的策略列与资产列放入同一模拟组。分开的组各自持有独立现金。投资组合记账页说明如何跟踪现金、持仓和净值。
这样,一个策略可以使用另一策略释放的现金。多个信号同时出现时,仓位大小和订单顺序决定如何分配资金。若规则依赖当前持仓,例如限制未平仓头寸总数,可使用事件驱动回测中介绍的回调。
检查组合及其组成部分
堆叠会保留原始订单记录,因此可以同时检查单个策略的交易以及组合收益和回撤。为堆叠后的投资组合添加策略名称,便于之后选择,即使多个策略交易同一品种也不受影响。比较收益序列与相关性,判断新增策略是否带来不同行为,还是主要重复现有策略。
再平衡示例有两层结果:原始趋势和均值回归投资组合包含各自的 SPY 交易,组合投资组合则记录策略之间的资金配置。同时保留两者,就能将组合表现追溯到底层交易。交易分析页介绍盈利交易、亏损交易和持有期分析。
在多个时期比较候选权重和再平衡计划,包括未参与配置拟合的留出时期。前向滚动优化将这一过程应用于滚动训练和测试窗口。
定期投资与定额投资
现金入金可以模拟定期储蓄。下面比较每月初存入并买入 100 美元,与一次性投入相同总额:
close = spy.close.loc["2015":"2024"]
month = pd.Series(close.index.month, index=close.index)
first_days = month != month.shift(1)
deposits = pd.Series(np.where(first_days, 100.0, 0.0), index=close.index)
dca = vbt.PF.from_orders(
close,
size=np.where(first_days, np.inf, np.nan),
init_cash=0,
cash_deposits=deposits,
)
lump = vbt.PF.from_orders(
close,
size=np.where(np.arange(len(close)) == 0, np.inf, np.nan),
init_cash=deposits.sum(),
)
print(deposits.sum(), round(dca.final_value, 2), round(lump.final_value, 2))12000.0 25724.02 40748.85在这十年大部分时间上涨的市场中,一次性投入的最终净值高出 58%。每月投入会在不同价格买入,使入场价格更平滑,但也使大部分资金多年处于未投资状态。同一入金计划适用于任何策略,因此可以将回撤后加大买入等规则与普通月度买入比较。入金也可为投资组合优化器的定期配置提供资金,从而一同测试定期投入和再平衡。
比较策略表现时,除最终账户净值外,也应使用投资组合收益率。VBT 的收益率计算考虑入金和出金,不会将新增资金当作交易收益。投资组合记账介绍这种比较中的现金流处理。
教程
会员专享的投资组合优化(英文)教程介绍配置和优化函数的构建,包括根据模拟投资组合状态调整的配置方法。
版权所有 © 2021–2026 Oleg Polakow。保留所有权利。
本站内容与文档供使用和评估 VectorBT PRO 以及教育用途。任何其他用途,包括开发或支持竞争产品或服务,均须事先取得书面同意。