绩效分析模块
betalens.analyst 提供从净值序列出发的指标计算与报告导出功能,适用于回测与实时组合。
PortfolioAnalyzer
import pandas as pd
from betalens.analyst import PortfolioAnalyzer
nav = pd.Series(..., index=pd.date_range("2023-01-01", periods=250))
analyzer = PortfolioAnalyzer(
nav_series=nav,
risk_free_rate=0.02, # 年化无风险利率
annualizer=252, # 年化因子
window=30 # 滚动窗口
)
核心指标
# 累计收益率
print(analyzer.total_return())
# 年化收益率
print(analyzer.annualized_return())
# 年化波动率
print(analyzer.annualized_volatility())
# 夏普比率
print(analyzer.sharpe_ratio())
# 最大回撤
print(analyzer.max_drawdown())
# 卡玛比率(年化收益/最大回撤)
print(analyzer.calmar_ratio())
# 恢复天数
print(analyzer.recovery_days())
滚动指标
# 滚动最大回撤
rolling_mdd = analyzer.rolling_max_drawdown()
# 滚动胜率
rolling_wr = analyzer.rolling_win_rate()
关键属性
nav:净值序列(按日期排序)returns:日度收益(pct_change 后去 NA)risk_free_rate:年化无风险利率annualizer:年化因子(默认252)window:滚动统计窗口
ReportExporter
from betalens.analyst import ReportExporter
exporter = ReportExporter(analyzer)
分年度报告
exporter.generate_annual_report()
exporter.generate_annual_report(excel_path="annual_report.xlsx")
自定义时段报告
exporter.generate_custom_report("2024-01-01", "2024-06-30")
exporter.generate_custom_report("2024-01-01", "2024-06-30", excel_path="custom.xlsx")
基准对比报告
# 创建基准分析器
benchmark_nav = pd.Series(...)
benchmark = PortfolioAnalyzer(benchmark_nav)
# 带基准的报告导出器
exporter = ReportExporter(analyzer, benchmark_analyzer=benchmark)
exporter.generate_benchmark_report()
# 访问超额收益分析器
excess_analyzer = exporter.excess
print(f"超额收益: {excess_analyzer.total_return():.2%}")
指定分析区间
# 在构造函数中裁剪分析区间
exporter = ReportExporter(
analyzer,
benchmark_analyzer=benchmark,
start_date="2023-01-01",
end_date="2024-12-31"
)
输出方式
CLI 表格:基于 PrettyTable,美观易读
Excel:传入
excel_path即可将结果写入多工作表
高级用法
滚动指标绘图
import matplotlib.pyplot as plt
fig, axes = plt.subplots(2, 1, figsize=(12, 8))
# NAV 与滚动最大回撤
axes[0].plot(analyzer.nav, label='NAV')
axes[0].legend()
axes[1].plot(analyzer.rolling_max_drawdown(), label='Rolling MDD', color='red')
axes[1].legend()
plt.tight_layout()
plt.show()
自定义指标
class CustomAnalyzer(PortfolioAnalyzer):
def sortino_ratio(self, target_return=0):
"""索提诺比率"""
excess_returns = self.returns - self.risk_free_rate / self.annualizer
downside_returns = excess_returns[excess_returns < target_return]
downside_std = downside_returns.std() * np.sqrt(self.annualizer)
return excess_returns.mean() * self.annualizer / downside_std
analyzer = CustomAnalyzer(nav)
print(f"Sortino: {analyzer.sortino_ratio():.4f}")
多策略对比
strategies = {
"Strategy A": nav_a,
"Strategy B": nav_b,
"Benchmark": nav_benchmark
}
results = []
for name, nav in strategies.items():
a = PortfolioAnalyzer(nav)
results.append({
"Strategy": name,
"Return": a.total_return(),
"Volatility": a.annualized_volatility(),
"Sharpe": a.sharpe_ratio(),
"MaxDD": a.max_drawdown()
})
comparison = pd.DataFrame(results)
print(comparison)
常见问题
若
generate_custom_report提示「数据不足」,请确认 NAV 序列包含目标日期,并保持频率一致。recovery_days默认寻找首次回到历史高点的日期,若 NAV 从未恢复,将抛出索引错误,可自行捕获。基准序列会自动裁剪到与策略NAV相同的日期范围。
更多 API 细节请参阅 Analyst API。