bt - Python的灵活回测工具¶
什么是bt?¶
bt 是一个灵活的Python回测框架,用于测试量化交易策略。回测是在给定数据集上测试策略的过程。该框架允许您轻松创建混合和匹配不同Algos
的策略。它旨在促进创建易于测试、可重用和灵活的策略逻辑块,以促进复杂交易策略的快速开发。
目标:让量化分析师避免重复造轮子,使他们能够专注于工作中重要的部分——策略开发。
bt 是用 Python 编写的,并加入了一个充满活力和丰富的数据分析生态系统。 有许多用于机器学习、信号处理和统计的库,可以利用这些库来避免重复造轮子——在使用其他没有如此丰富的高质量开源项目的语言时,这种情况经常发生。
bt 构建在 ffn 之上 - 一个用于 Python 的金融函数库。查看它!
一个快速示例¶
以下是bt的快速体验:
import bt
%matplotlib inline
一个简单的策略回测¶
让我们创建一个简单的策略。我们将创建一个每月重新平衡的仅做多策略,其中我们在资产组合中的每个资产上放置相等的权重。
首先,我们将下载一些数据。默认情况下,bt.get (alias for ffn.get)
从Yahoo! Finance下载调整后的收盘价。为了本次演示的目的,我们将下载从2010年1月1日开始的一些数据。
# fetch some data
data = bt.get('spy,agg', start='2010-01-01')
print(data.head())
spy agg
Date
2010-01-04 89.225410 74.942825
2010-01-05 89.461586 75.283791
2010-01-06 89.524574 75.240227
2010-01-07 89.902473 75.153221
2010-01-08 90.201691 75.196724
一旦我们有了数据,我们将创建我们的策略。Strategy
对象通过组合各种 Algos
来包含策略逻辑。
# create the strategy
s = bt.Strategy('s1', [bt.algos.RunMonthly(),
bt.algos.SelectAll(),
bt.algos.WeighEqually(),
bt.algos.Rebalance()])
最后,我们将创建一个Backtest
,这是策略与数据集的逻辑组合。
一旦完成,我们就可以运行回测并分析结果。
# create a backtest and run it
test = bt.Backtest(s, data)
res = bt.run(test)
现在我们可以分析回测的结果了。Result
对象是对 ffn.GroupStats 的一个轻量级封装,增加了一些辅助方法。
# first let's see an equity curve
res.plot();
# ok and what about some stats?
res.display()
Stat s1
------------------- ----------
Start 2010-01-03
End 2022-07-01
Risk-free rate 0.00%
Total Return 150.73%
Daily Sharpe 0.90
Daily Sortino 1.35
CAGR 7.64%
Max Drawdown -18.42%
Calmar Ratio 0.41
MTD 0.18%
3m -10.33%
6m -14.84%
YTD -14.84%
1Y -10.15%
3Y (ann.) 5.12%
5Y (ann.) 6.44%
10Y (ann.) 7.36%
Since Incep. (ann.) 7.64%
Daily Sharpe 0.90
Daily Sortino 1.35
Daily Mean (ann.) 7.74%
Daily Vol (ann.) 8.62%
Daily Skew -0.98
Daily Kurt 16.56
Best Day 4.77%
Worst Day -6.63%
Monthly Sharpe 1.06
Monthly Sortino 1.91
Monthly Mean (ann.) 7.81%
Monthly Vol (ann.) 7.36%
Monthly Skew -0.39
Monthly Kurt 1.59
Best Month 7.57%
Worst Month -6.44%
Yearly Sharpe 0.81
Yearly Sortino 1.75
Yearly Mean 7.48%
Yearly Vol 9.17%
Yearly Skew -1.34
Yearly Kurt 2.28
Best Year 19.64%
Worst Year -14.84%
Avg. Drawdown -0.84%
Avg. Drawdown Days 13.23
Avg. Up Month 1.70%
Avg. Down Month -1.80%
Win Year % 83.33%
Win 12m % 93.57%
# ok and how does the return distribution look like?
res.plot_histogram()
# and just to make sure everything went along as planned, let's plot the security weights over time
res.plot_security_weights()
修改策略¶
如果我们每周运行这个策略,并且使用一些风险平价风格的方法,通过使用与每个资产波动率的倒数成比例的权重会怎样?那么,我们只需要插入一些不同的算法。见下文:
# create our new strategy
s2 = bt.Strategy('s2', [bt.algos.RunWeekly(),
bt.algos.SelectAll(),
bt.algos.WeighInvVol(),
bt.algos.Rebalance()])
# now let's test it with the same data set. We will also compare it with our first backtest.
test2 = bt.Backtest(s2, data)
# we include test here to see the results side-by-side
res2 = bt.run(test, test2)
res2.plot();
res2.display()
Stat s1 s2
------------------- ---------- ----------
Start 2010-01-03 2010-01-03
End 2022-07-01 2022-07-01
Risk-free rate 0.00% 0.00%
Total Return 150.73% 69.58%
Daily Sharpe 0.90 0.96
Daily Sortino 1.35 1.41
CAGR 7.64% 4.32%
Max Drawdown -18.42% -14.62%
Calmar Ratio 0.41 0.30
MTD 0.18% 0.38%
3m -10.33% -6.88%
6m -14.84% -12.00%
YTD -14.84% -12.00%
1Y -10.15% -10.03%
3Y (ann.) 5.12% 1.84%
5Y (ann.) 6.44% 3.35%
10Y (ann.) 7.36% 3.76%
Since Incep. (ann.) 7.64% 4.32%
Daily Sharpe 0.90 0.96
Daily Sortino 1.35 1.41
Daily Mean (ann.) 7.74% 4.33%
Daily Vol (ann.) 8.62% 4.50%
Daily Skew -0.98 -2.21
Daily Kurt 16.56 46.12
Best Day 4.77% 2.84%
Worst Day -6.63% -4.66%
Monthly Sharpe 1.06 1.13
Monthly Sortino 1.91 1.87
Monthly Mean (ann.) 7.81% 4.40%
Monthly Vol (ann.) 7.36% 3.89%
Monthly Skew -0.39 -1.06
Monthly Kurt 1.59 3.92
Best Month 7.57% 4.05%
Worst Month -6.44% -5.04%
Yearly Sharpe 0.81 0.65
Yearly Sortino 1.75 1.19
Yearly Mean 7.48% 4.13%
Yearly Vol 9.17% 6.31%
Yearly Skew -1.34 -1.48
Yearly Kurt 2.28 3.37
Best Year 19.64% 11.71%
Worst Year -14.84% -12.00%
Avg. Drawdown -0.84% -0.48%
Avg. Drawdown Days 13.23 13.68
Avg. Up Month 1.70% 0.90%
Avg. Down Month -1.80% -0.93%
Win Year % 83.33% 83.33%
Win 12m % 93.57% 91.43%
正如你所见,策略逻辑易于理解,更重要的是,易于修改。使用简单、可组合的Algos来创建策略的想法是bt的核心构建块之一。
功能¶
- Tree Structure
树结构 有助于构建和组合模块化且可重复使用的复杂算法交易策略。此外,每个树
Node
都有自己的price index
,可以被算法用来确定节点的分配。
- Algorithm Stacks
Algos
和AlgoStacks
是 另一个核心功能,有助于创建模块化和可重用的策略 逻辑。由于其模块化,这些逻辑块也更容易测试 - 这是构建稳健金融解决方案的重要步骤。
- Transaction Cost Modeling
通过使用佣金函数和传递给
Backtest
的特定于工具的、随时间变化的买卖价差。
- Fixed Income
策略可以包括支付息票的工具,如债券,无资金支持的工具,如互换,持有成本,以及名义加权的选项。这些是树结构的扩展。
- Charting and Reporting
bt 还提供了许多有用的图表功能,帮助可视化回测结果。我们还计划在未来添加更多图表、表格和报告格式,例如自动生成的 PDF 报告。
- Detailed Statistics
此外,bt 计算了一堆与回测相关的统计数据,并提供了通过
Results'
显示方法快速比较这些不同回测的各种统计数据的方式。
路线图¶
未来的开发工作将集中在:
- Speed
由于bt的灵活性,必须在可用性和性能之间做出权衡。可用性始终是优先考虑的因素,但我们确实希望尽可能提高性能。
- Algos
随着时间的推移,我们还将开发更多的算法。我们也鼓励任何人贡献他们自己的算法。
- Charting and Reporting
这是我们希望不断改进的另一个领域,因为报告是工作中的一个重要方面。图表和报告也有助于发现策略逻辑中的错误。