作为一名从事期货量化交易近十年的从业者,我深刻体会到绩效分析对于策略评估的重要性。绩效分析就像给策略做全面体检,通过一系列关键指标来诊断策略的健康状况。在实盘交易前,我们需要通过这些指标来判断策略是否值得投入真金白银。
绩效分析的核心价值在于:
我见过太多交易员只关注收益率而忽视风险指标,最终在实盘中遭遇重大损失。一个完整的绩效分析应该包含收益率、风险、风险调整收益和交易质量四个维度的评估。
收益率是最直观的策略评估指标,但需要从多个角度来考量:
python复制def calculate_returns(equity_curve):
"""计算收益率指标"""
import numpy as np
# 总收益率
total_return = (equity_curve[-1] - equity_curve[0]) / equity_curve[0]
# 年化收益率计算
periods = len(equity_curve)
annual_return = (1 + total_return) ** (252 / periods) - 1 # 假设252个交易日
# 日收益率序列
daily_returns = np.diff(equity_curve) / equity_curve[:-1]
return {
'total_return': total_return,
'annual_return': annual_return,
'daily_returns': daily_returns
}
注意:年化收益率计算假设一年有252个交易日,这是金融行业的通用标准。对于不同交易频率的策略,需要调整这个参数。
在实际应用中,我发现还需要关注:
风险指标是很多新手交易员容易忽视的部分:
python复制def calculate_risk_metrics(daily_returns):
"""计算风险指标"""
import numpy as np
# 年化波动率
volatility = np.std(daily_returns) * np.sqrt(252)
# 最大回撤计算
cumulative = np.cumprod(1 + daily_returns)
running_max = np.maximum.accumulate(cumulative)
drawdown = (cumulative - running_max) / running_max
max_drawdown = np.min(drawdown)
return {
'volatility': volatility,
'max_drawdown': max_drawdown
}
最大回撤是我最看重的风险指标之一,它反映了策略在最坏情况下的损失程度。根据我的经验:
夏普比率是最常用的风险调整收益指标:
python复制def calculate_sharpe_ratio(annual_return, volatility, risk_free_rate=0.03):
"""计算夏普比率"""
if volatility > 0:
sharpe = (annual_return - risk_free_rate) / volatility
else:
sharpe = 0
return sharpe
夏普比率的解读:
2:非常优秀的策略
在实际应用中,我发现夏普比率有以下局限性:
因此,我通常会同时计算Sortino比率和Calmar比率作为补充。
胜率和盈亏比是评估交易质量的重要指标:
python复制def calculate_win_rate(trades):
"""计算胜率和盈亏比"""
if len(trades) == 0:
return 0, 0
winning_trades = [t for t in trades if t['pnl'] > 0]
losing_trades = [t for t in trades if t['pnl'] <= 0]
win_rate = len(winning_trades) / len(trades)
avg_win = np.mean([t['pnl'] for t in winning_trades]) if winning_trades else 0
avg_loss = np.abs(np.mean([t['pnl'] for t in losing_trades])) if losing_trades else 0
profit_ratio = avg_win / avg_loss if avg_loss > 0 else float('inf')
return win_rate, profit_ratio
根据我的交易日志统计:
python复制from tqsdk import TqApi, TqAuth, TqBacktest
from datetime import date
import numpy as np
import pandas as pd
def run_backtest(strategy_func, symbol, start_date, end_date):
"""运行回测并获取权益曲线"""
api = TqApi(
backtest=TqBacktest(start_dt=start_date, end_dt=end_date),
auth=TqAuth("your_account", "your_password")
)
klines = api.get_kline_serial(symbol, 300, 200)
account = api.get_account()
equity_curve = []
try:
while True:
api.wait_update()
if api.is_changing(klines):
# 执行策略逻辑
signal = strategy_func(klines)
if signal:
execute_signal(api, symbol, signal)
# 记录权益曲线
equity_curve.append(account.balance)
finally:
api.close()
return equity_curve
实操建议:回测时间跨度至少应包含一个完整的市场周期(牛市和熊市),通常3-5年的数据比较合适。
python复制def full_performance_analysis(equity_curve, trades):
"""完整的绩效分析流程"""
# 计算收益率
returns = calculate_returns(equity_curve)
# 计算风险指标
risk_metrics = calculate_risk_metrics(returns['daily_returns'])
# 计算夏普比率
sharpe = calculate_sharpe_ratio(returns['annual_return'], risk_metrics['volatility'])
# 计算交易质量指标
win_rate, profit_ratio = calculate_win_rate(trades)
# 构建结果字典
results = {
'returns': returns,
'risk_metrics': risk_metrics,
'sharpe_ratio': sharpe,
'win_rate': win_rate,
'profit_ratio': profit_ratio,
'equity_curve': equity_curve,
'daily_returns': returns['daily_returns']
}
return results
python复制import matplotlib.pyplot as plt
def plot_performance(results):
"""绘制绩效图表"""
plt.figure(figsize=(12, 8))
# 权益曲线
plt.subplot(2, 2, 1)
plt.plot(results['equity_curve'])
plt.title('Equity Curve')
plt.xlabel('Day')
plt.ylabel('Balance')
# 收益率分布
plt.subplot(2, 2, 2)
plt.hist(results['daily_returns'], bins=50)
plt.title('Return Distribution')
plt.xlabel('Daily Return')
plt.ylabel('Frequency')
# 滚动夏普比率
plt.subplot(2, 2, 3)
rolling_sharpe = (pd.Series(results['daily_returns']).rolling(63).mean() * 252) / \
(pd.Series(results['daily_returns']).rolling(63).std() * np.sqrt(252))
rolling_sharpe.plot()
plt.title('Rolling 3-Month Sharpe Ratio')
plt.xlabel('Day')
plt.ylabel('Sharpe Ratio')
# 回撤曲线
plt.subplot(2, 2, 4)
cumulative = np.cumprod(1 + np.array(results['daily_returns']))
running_max = np.maximum.accumulate(cumulative)
drawdown = (cumulative - running_max) / running_max
plt.fill_between(range(len(drawdown)), drawdown, color='red', alpha=0.3)
plt.title('Drawdown Curve')
plt.xlabel('Day')
plt.ylabel('Drawdown')
plt.tight_layout()
plt.show()
在实际分析中,我发现这些指标之间存在一些有趣的关系:
一个好的策略应该在各项指标间取得平衡。例如:
我通常会将自己的策略与以下基准比较:
比较时需要注意:
策略绩效通常会随时间衰减,我通过以下方法监测:
过拟合:在样本内表现优异但在实盘表现差
幸存者偏差:只分析成功的策略而忽略失败的
数据窥探:使用未来数据进行回测
风险控制:
参数优化:
交易执行优化:
从回测到实盘是量化交易的关键一步,我的经验是:
当运行多个策略时,需要考虑:
python复制def portfolio_analysis(strategies):
"""策略组合分析"""
# 计算各策略收益率
returns = [s['daily_returns'] for s in strategies]
returns_matrix = np.vstack(returns).T
# 计算相关系数矩阵
corr_matrix = np.corrcoef(returns_matrix, rowvar=False)
# 计算组合收益率和风险
weights = np.array([1/len(strategies)] * len(strategies)) # 等权重
portfolio_return = np.dot(weights, np.mean(returns_matrix, axis=0)) * 252
portfolio_volatility = np.sqrt(np.dot(weights.T, np.dot(np.cov(returns_matrix, rowvar=False), weights))) * np.sqrt(252)
return {
'correlation_matrix': corr_matrix,
'portfolio_return': portfolio_return,
'portfolio_volatility': portfolio_volatility,
'portfolio_sharpe': (portfolio_return - 0.03) / portfolio_volatility
}
好的绩效分析应该包含:
我常用的压力测试方法:
近年来,我开始尝试将机器学习应用于绩效分析:
python复制from sklearn.cluster import KMeans
def strategy_clustering(strategies):
"""策略聚类分析"""
features = []
for s in strategies:
features.append([
s['sharpe_ratio'],
s['win_rate'],
s['max_drawdown'],
np.mean(s['daily_returns']),
np.std(s['daily_returns'])
])
kmeans = KMeans(n_clusters=3)
clusters = kmeans.fit_predict(features)
return clusters
在多年的量化交易实践中,我总结了以下几点深刻体会:
没有完美的策略:每个策略都有其优势和局限性,关键是要了解策略的适用条件。我早期曾追求"圣杯"策略,后来明白适应不同市场环境的策略组合才是更稳健的选择。
风险控制优先:2005年的一次重大回撤让我深刻认识到,保住本金比追求高收益更重要。现在我设计任何策略,首先考虑的是最大可能损失,而非潜在收益。
绩效分析要全面:不能只看夏普比率或收益率,需要综合评估各项指标。我曾有一个夏普2.5的策略,但因为最大回撤超过30%而放弃。
持续改进是关键:市场环境不断变化,策略也需要不断进化。我每周都会review策略绩效,每月做一次全面评估。
心理因素很重要:即使是最好的策略,如果执行者不能承受其波动,也会失败。我建议实盘前先用模拟账户体验策略的波动特性。