VectorBT量化入门系列:第五章 VectorBT性能评估与分析
本教程专为中高级开发者设计,系统讲解VectorBT技术在量化交易中的应用。通过结合Tushare数据源和TA-Lib技术指标,深度探索策略开发、回测优化与风险评估的核心方法。从数据获取到策略部署,全面提升量化交易能力,助力开发者构建高效、稳健的交易系统。
文中内容仅限技术学习与代码实践参考,市场存在不确定性,技术分析需谨慎验证,不构成任何投资建议。适合量化新手建立系统认知,为策略开发打下基础。

学习对象
- 中高级水平的开发者和数据分析师
- 具备 Python 编程基础和一定的数据分析能力
- 对量化交易和金融数据处理有一定了解
- 熟悉 A 股市场,了解 Tushare 数据源和 TA-Lib 技术指标
教程目标
- 系统学习 VectorBT 技术,掌握其在量化交易中的应用
- 熟练使用 Tushare 数据源获取 A 股市场数据,并使用 Parquet 文件存储
- 掌握基于 VectorBT 的策略开发、回测和性能评估流程
- 学会使用 TA-Lib 计算技术指标,并将其应用于交易策略
- 理解并实现多因子策略、机器学习策略等高级策略
- 掌握策略优化、风险管理以及策略组合的方法
- 能够独立构建和评估量化交易策略,并部署到生产环境
教程目录
1.1 VectorBT简介与应用场景
1.2 环境搭建与依赖安装
1.3 数据源与Tushare集成
1.4 数据存储与Parquet文件格式
2.1 数据加载与预处理
2.2 时间序列数据处理
2.3 技术指标计算与TA-Lib集成
2.4 数据可视化与探索性分析
3.1 策略定义与实现
3.2 回测流程与关键参数
3.3 性能评估指标与解读
3.4 策略优化与参数调整
4.1 多因子策略开发
4.2 机器学习策略集成
4.3 风险管理与交易成本模拟
4.4 策略组合与资产配置
5.1 性能评估框架
5.2 统计指标与回测报告
5.3 敏感性分析与压力测试
5.4 策略对比与选择标准
6.1 策略逻辑
6.2 实现步骤
6.3 代码执行
6.4 结果分析
第五章 VectorBT性能评估与分析
本章将深入探讨如何使用VectorBT进行策略性能评估和分析。我们将介绍性能评估框架、统计指标、敏感性分析以及策略对比等内容。
python
# 示例:运行多因子策略
data = load_data_from_parquet("./data/600519.SH.parquet") # 贵州茅台
data = generate_multi_factor_signals(data)
portfolio = vbt.Portfolio.from_signals(
close=data["close"],
entries=data["signal"] == 1,
exits=data["signal"] == -1,
freq="D",
init_cash=100000,
fees=0.0015,
slippage=0.0015,
sl_stop=0.05,
tp_stop=0.10,
)
5.1 性能评估框架
性能评估是策略开发的重要环节,VectorBT提供了丰富的工具来评估策略表现。
5.2 统计指标与回测报告
5.2.1 Portfolio.stats
python
# 计算关键指标
stats = portfolio.stats()
# 绘制图表
portfolio.plot().show()
# 打印报告
print(portfolio.stats())
输出:
text
Start 2020-01-02 00:00:00
End 2024-12-31 00:00:00
Period 1212 days 00:00:00
Start Value 100000.0
End Value 108968.031684
Total Return [%] 8.968032
Benchmark Return [%] 34.867257
Max Gross Exposure [%] 100.0
Total Fees Paid 20944.833953
Max Drawdown [%] 52.462141
Max Drawdown Duration 941 days 00:00:00
Total Trades 49
Total Closed Trades 48
Total Open Trades 1
Open Trade PnL 1496.588556
Win Rate [%] 39.583333
Best Trade [%] 14.097797
Worst Trade [%] -8.991079
Avg Winning Trade [%] 10.817294
Avg Losing Trade [%] -6.266302
Avg Winning Trade Duration 23 days 22:44:12.631578947
Avg Losing Trade Duration 20 days 01:39:18.620689655
Profit Factor 1.027352
Expectancy 155.655065
Sharpe Ratio 0.238863
Calmar Ratio 0.049944
Omega Ratio 1.038227
Sortino Ratio 0.35283
dtype: object
5.2.2 Portfolio.orders
python
# 计算关键指标
orders = portfolio.orders
# 绘制图表
orders.plots().show()
# 打印报告
print(orders.stats())
输出:

text
Start 2020-01-02 00:00:00
End 2024-12-31 00:00:00
Period 1212 days 00:00:00
Total Records 97
Total Buy Orders 49
Total Sell Orders 48
Min Size 69.028927
Max Size 91.758362
Avg Size 83.302056
Avg Buy Size 83.18164
Avg Sell Size 83.42498
Avg Buy Price 1722.519706
Avg Sell Price 1733.594622
Total Fees 20944.833953
Min Fees 133.163145
Max Fees 320.478898
Avg Fees 215.926123
Avg Buy Fees 214.932823
Avg Sell Fees 216.940117
dtype: object
5.2.3 Portfolio.trades
python
# 计算关键指标
trades = portfolio.trades
# 绘制图表
trades.plots().show()
# 打印报告
print(trades.stats())
输出:

text
Start 2020-01-02 00:00:00
End 2024-12-31 00:00:00
Period 1212 days 00:00:00
First Trade Start 2020-03-05 00:00:00
Last Trade End 2024-12-31 00:00:00
Coverage 1064 days 00:00:00
Overlap Coverage 0 days 00:00:00
Total Records 49
Total Long Trades 49
Total Short Trades 0
Total Closed Trades 48
Total Open Trades 1
Open Trade PnL 1496.588556
Win Rate [%] 39.583333
Max Win Streak 5
Max Loss Streak 7
Best Trade [%] 14.097797
Worst Trade [%] -8.991079
Avg Winning Trade [%] 10.817294
Avg Losing Trade [%] -6.266302
Avg Winning Trade Duration 23 days 22:44:12.631578947
Avg Losing Trade Duration 20 days 01:39:18.620689655
Profit Factor 1.027352
Expectancy 155.655065
SQN 0.087304
dtype: object
5.3 敏感性分析与压力测试
敏感性分析和压力测试是评估策略鲁棒性的重要方法。
5.3.1 敏感性分析
python
def perform_sensitivity_analysis(
strategy_func, param_ranges: dict, **kwargs
) -> pd.DataFrame:
"""进行敏感性分析。
:param strategy_func: 策略函数,接受参数并返回vbt.Portfolio对象
:param param_ranges: 参数范围
:param kwargs: 传递给策略函数的其他参数
:return: 敏感性分析结果
"""
results = []
# 获取所有参数的组合
from itertools import product
params_list = list(product(*param_ranges.values()))
for params in params_list:
param_dict = dict(zip(param_ranges.keys(), params))
# 运行策略
portfolio = strategy_func(**param_dict, **kwargs)
# 计算关键指标
sharpe_ratio = portfolio.sharpe_ratio()
total_return = portfolio.total_return()
results.append(
{
"params": param_dict,
"sharpe_ratio": sharpe_ratio,
"total_return": total_return,
}
)
return pd.DataFrame(results)
# 示例:敏感性分析
def example_strategy(fast_window, slow_window):
# 示例策略:简单移动平均交叉策略
fast_ma = vbt.MA.run(close, window=fast_window)
slow_ma = vbt.MA.run(close, window=slow_window)
entries = fast_ma.ma_crossed_above(slow_ma)
exits = fast_ma.ma_crossed_below(slow_ma)
pf = vbt.Portfolio.from_signals(
close,
entries,
exits,
freq="D",
init_cash=100000,
fees=0.0015,
slippage=0.0015,
sl_stop=0.05,
tp_stop=0.10,
)
return pf
# 收盘价数据
close = data["close"]
param_ranges = {"fast_window": [5, 10, 15], "slow_window": [20, 30, 40]}
sensitivity_results = perform_sensitivity_analysis(example_strategy, param_ranges)
print(sensitivity_results)
输出:
text
params sharpe_ratio total_return
0 {'fast_window': 5, 'slow_window': 20} -0.294548 -0.217831
1 {'fast_window': 5, 'slow_window': 30} 0.078081 -0.007422
2 {'fast_window': 5, 'slow_window': 40} 0.139590 0.032914
3 {'fast_window': 10, 'slow_window': 20} -0.000603 -0.057222
4 {'fast_window': 10, 'slow_window': 30} -0.006332 -0.041972
5 {'fast_window': 10, 'slow_window': 40} -0.132529 -0.093364
6 {'fast_window': 15, 'slow_window': 20} -0.039138 -0.077459
7 {'fast_window': 15, 'slow_window': 30} 0.037290 -0.022990
8 {'fast_window': 15, 'slow_window': 40} 0.000408 -0.033410
5.3.2 压力测试
python
def perform_stress_test(
portfolio: vbt.Portfolio, market_crash_dates: list
) -> pd.DataFrame:
"""进行压力测试。
:param portfolio: 回测结果
:param market_crash_dates: 市场大跌日期列表
:return: 压力测试结果
"""
results = []
# 获取投资组合的价值
portfolio_value = portfolio.value()
for crash_date in market_crash_dates:
# 提取压力测试期间的数据
crash_period = portfolio_value.loc[crash_date[0] : crash_date[1]]
# 计算关键指标
crash_return = (crash_period.iloc[-1] / crash_period.iloc[0]) - 1
crash_drawdown = (crash_period / crash_period.cummax() - 1).min()
results.append(
{
"crash_period": f"{crash_date[0]}至{crash_date[1]}",
"return": crash_return,
"max_drawdown": crash_drawdown,
}
)
return pd.DataFrame(results)
# 示例:压力测试
market_crash_dates = [("2020-02-01", "2020-03-31"), ("2022-01-01", "2022-03-31")]
stress_test_results = perform_stress_test(portfolio, market_crash_dates)
print(stress_test_results)
输出:
text
crash_period return max_drawdown
0 2020-02-01至2020-03-31 -0.012710 -0.113575
1 2022-01-01至2022-03-31 -0.278241 -0.302678
5.4 策略对比与选择标准
通过对比不同策略的性能,选择最优策略。
5.4.1 策略对比
python
def compare_strategies(portfolios: list, strategy_names: list) -> pd.DataFrame:
"""对比多个策略。
:param portfolios: 包含多个策略的回测结果列表
:param strategy_names: 策略名称列表
:return: 对比结果
"""
# 计算每个策略的关键指标
metrics = {"总回报率": [], "夏普比率": [], "最大回撤": [], "胜率": []}
for portfolio in portfolios:
metrics["总回报率"].append(portfolio.total_return())
metrics["夏普比率"].append(portfolio.sharpe_ratio())
metrics["最大回撤"].append(portfolio.max_drawdown())
metrics["胜率"].append(portfolio.trades.win_rate())
# 创建对比表格
comparison_df = pd.DataFrame(metrics, index=strategy_names)
return comparison_df
# 示例:对比策略
data1 = generate_signals(data)
strategy1 = run_backtest(data1)
data2 = generate_multi_factor_signals(data)
strategy2 = run_multi_factor_strategy(data2)
comparison_df = compare_strategies([strategy1, strategy2], ["Strategy 1", "Strategy 2"])
print(comparison_df)
输出:
text
总回报率 夏普比率 最大回撤 胜率
Strategy 1 0.175969 0.325138 -0.396185 0.250
Strategy 2 0.316914 0.417877 -0.467244 0.375
5.4.2 选择标准
python
def select_best_strategy(comparison_df: pd.DataFrame, weights: dict) -> str:
"""选择最优策略。
:param comparison_df: 策略对比结果
:param weights: 各指标权重
:return: 最优策略名称
"""
# 计算加权得分
comparison_df["score"] = (
comparison_df["总回报率"] * weights["return"]
+ comparison_df["夏普比率"] * weights["sharpe"]
+ (1 - comparison_df["最大回撤"]) * weights["drawdown"]
+ comparison_df["胜率"] * weights["win_rate"]
)
# 找到得分最高的策略
best_strategy = comparison_df["score"].idxmax()
return best_strategy
# 示例:选择最优策略
weights = {"return": 0.3, "sharpe": 0.3, "drawdown": 0.2, "win_rate": 0.2}
best_strategy = select_best_strategy(comparison_df, weights)
print(f"最优策略: {best_strategy}")
输出:
text
最优策略: Strategy 2
总结
通过本章,你已经掌握了以下内容:
- 性能评估框架:如何计算关键性能指标并生成性能报告。
- 统计指标:如何评估策略的统计表现。
- 敏感性分析与压力测试:如何验证策略的鲁棒性。
- 策略对比与选择:如何对比多个策略并选择最优策略。
风险提示与免责声明
本文内容基于公开信息研究整理,不构成任何形式的投资建议。历史表现不应作为未来收益保证,市场存在不可预见的波动风险。投资者需结合自身财务状况及风险承受能力独立决策,并自行承担交易结果。作者及发布方不对任何依据本文操作导致的损失承担法律责任。市场有风险,投资须谨慎。