想快速上手量化投资,亲手跑通第一个策略回测吗?本文将通过一个极其简单的K线策略示例,带你快速入门AKQuant,一个基于Python的开源量化框架。我们从安装开始,到编写策略、运行回测,并详细解读各项核心绩效指标。
1. 安装
打开终端,只需一行命令即可安装:
pip install akquant
2. 极简策略示例
我们将实现一个最简单的K线策略逻辑:
- 当收盘价 > 开盘价(阳线)-> 买入100股
- 当收盘价 < 开盘价(阴线)且持有仓位 -> 卖出全部持仓
下面是用Python实现的完整代码:
import akshare as ak
from akquant import Strategy, run_backtest
# 1. 准备数据 (这里利用 AKShare 来获取数据,需要通过 pip install akshare 来进行安装)
df = ak.stock_zh_a_daily(symbol="sh600000", start_date="20250101", end_date="20260212")
# 2. 策略定义
class MyStrategy(Strategy):
# 3. 策略逻辑
def on_bar(self, bar):
# 获取当前持仓
current_pos = self.get_position(bar.symbol)
# 1. 当收盘价 > 开盘价 (阳线) -> 买入
if current_pos == 0 and bar.close > bar.open:
self.buy(bar.symbol, 100) # 买入 100 股
# 2. 当收盘价 < 开盘价 (阴线) -> 卖出
elif current_pos > 0 and bar.close < bar.open:
self.close_position(bar.symbol) # 卖出所有持仓
# 3. 运行回测
print("开始回测...")
result = run_backtest(
data=df, # 输入数据
strategy=MyStrategy, # 输入策略
cash=100000.0, # 初始资金
symbol="sh600000" # 交易的股票代码
)
# 4. 查看结果
print(result) # 跟 print(result.metrics_df) 等效
运行上述代码,你将看到该策略完整的绩效评价指标汇总:
开始回测...
2026-02-12 00:58:53 | INFO | Running backtest via run_backtest()...
BacktestResult:
Value
name
start_time 2025-01-02 00:00:00+08:00
end_time 2026-02-11 00:00:00+08:00
duration 405 days, 0:00:00
total_bars 271
trade_count 67.0
initial_market_value 100000.0
end_market_value 99100.68204
total_pnl -188.0
unrealized_pnl 0.0
total_return_pct -0.899318
annualized_return -0.008109
volatility 0.002453
total_profit 584.0
total_loss -772.0
total_commission 711.31796
max_drawdown 913.30785
max_drawdown_pct 0.91318
win_rate 26.865672
loss_rate 73.134328
winning_trades 18.0
losing_trades 49.0
avg_pnl -2.80597
avg_return_pct -0.172318
avg_trade_bars 2.014925
avg_profit 32.444444
avg_profit_pct 2.818291
avg_winning_trade_bars 4.055556
avg_loss -15.755102
avg_loss_pct -1.270909
avg_losing_trade_bars 1.265306
largest_win 120.0
largest_win_pct 10.178117
largest_win_bars 7.0
largest_loss -70.0
largest_loss_pct -5.380477
largest_loss_bars 1.0
max_wins 2.0
max_losses 9.0
sharpe_ratio -3.305093
sortino_ratio -3.92213
profit_factor 0.756477
ulcer_index 0.004666
upi -1.737695
equity_r2 0.932224
std_error 70.552942
calmar_ratio -0.887949
exposure_time_pct 49.815498
var_95 -0.000281
var_99 -0.000625
cvar_95 -0.000434
cvar_99 -0.00071
sqn -0.708177
kelly_criterion -0.086485
3. 如何查看详细记录?
除了汇总指标,AKQuant还提供了详细的持仓、订单和成交记录,方便你进行深度分析。
- 查看持仓记录:使用
print(result.positions_df) 可以查看每日的持仓快照。
- 查看订单记录:使用
print(result.orders_df) 可以查看所有历史订单的详细信息。
- 查看成交记录:使用
print(result.trades_df) 可以查看每一笔已平仓交易的详情。
这些DataFrame包含了丰富的字段,下文会详细解释。
4. 核心绩效指标详解
AKQuant计算了数十种绩效指标,下表是它们的简要说明:
| 指标名称 (Name) |
含义 (Description) |
单位/类型 |
计算说明 |
start_time |
回测开始时间 |
Datetime |
对应回测数据的第一个 Bar 的时间。 |
end_time |
回测结束时间 |
Datetime |
对应回测数据的最后一个 Bar 的时间。 |
duration |
回测总时长 |
Timedelta |
end_time - start_time。 |
total_bars |
总 Bar 数量 |
Int |
回测经历的 K 线总数。 |
trade_count |
交易笔数 |
Int |
完成平仓的交易总数 (Round-trip)。 |
initial_market_value |
初始市值 |
Float |
初始资金 (通常为 Cash)。 |
end_market_value |
结束市值 |
Float |
回测结束时的总资产 (Cash + 持仓市值)。 |
total_pnl |
总盈亏 |
Float |
end_market_value - initial_market_value。 |
unrealized_pnl |
未实现盈亏 |
Float |
结束时持仓的浮动盈亏。 |
total_return_pct |
总收益率 |
% (百分比) |
(结束市值 - 初始市值) / 初始市值 * 100。 |
annualized_return |
年化收益率 |
Ratio (小数) |
(1 + 总收益率)^(1/年数) - 1。注意这里是小数,如 0.2 表示 20%。 |
volatility |
年化波动率 |
Ratio (小数) |
收益率标准差 * sqrt(252)。 |
total_profit |
总盈利 |
Float |
所有盈利交易的盈利之和。 |
total_loss |
总亏损 |
Float |
所有亏损交易的亏损之和。 |
total_commission |
总手续费 |
Float |
交易产生的总佣金。 |
max_drawdown |
最大回撤比率 |
Ratio (小数) |
历史最大回撤幅度(如 0.1 表示 10%)。 |
max_drawdown_pct |
最大回撤百分比 |
% (百分比) |
max_drawdown * 100。 |
win_rate |
胜率 |
% (百分比) |
盈利次数 / 总交易次数 * 100。 |
loss_rate |
败率 |
% (百分比) |
亏损次数 / 总交易次数 * 100。 |
winning_trades |
盈利次数 |
Int |
盈利大于 0 的交易次数。 |
losing_trades |
亏损次数 |
Int |
盈利小于 0 的交易次数。 |
avg_pnl |
平均盈亏 |
Float |
每笔交易的平均净盈亏。 |
avg_return_pct |
平均收益率 |
% (百分比) |
每笔交易收益率的平均值。 |
avg_trade_bars |
平均持仓 K 线数 |
Float |
平均每笔交易持有的 Bar 数量。 |
avg_profit |
平均盈利 |
Float |
盈利交易的平均金额。 |
avg_profit_pct |
平均盈利比例 |
% (百分比) |
盈利交易的平均收益率。 |
avg_winning_trade_bars |
平均盈利持仓时长 |
Float |
盈利交易的平均持仓 Bar 数。 |
avg_loss |
平均亏损 |
Float |
亏损交易的平均金额。 |
avg_loss_pct |
平均亏损比例 |
% (百分比) |
亏损交易的平均收益率。 |
avg_losing_trade_bars |
平均亏损持仓时长 |
Float |
亏损交易的平均持仓 Bar 数。 |
largest_win |
最大单笔盈利 |
Float |
单笔交易的最大盈利金额。 |
largest_win_pct |
最大单笔盈利比例 |
% (百分比) |
单笔交易的最大收益率。 |
largest_win_bars |
最大盈利持仓时长 |
Float |
产生最大盈利那笔交易的持仓 Bar 数。 |
largest_loss |
最大单笔亏损 |
Float |
单笔交易的最大亏损金额。 |
largest_loss_pct |
最大单笔亏损比例 |
% (百分比) |
单笔交易的最大亏损率。 |
largest_loss_bars |
最大亏损持仓时长 |
Float |
产生最大亏损那笔交易的持仓 Bar 数。 |
max_wins |
最大连续盈利次数 |
Int |
连续盈利的最多次数。 |
max_losses |
最大连续亏损次数 |
Int |
连续亏损的最多次数。 |
sharpe_ratio |
夏普比率 |
Ratio |
(年化收益率 - 无风险利率) / 年化波动率。无风险利率默认 0。 |
sortino_ratio |
索提诺比率 |
Ratio |
(年化收益率 - 无风险利率) / 下行波动率。只考虑下行风险。 |
profit_factor |
盈亏比 |
Ratio |
总盈利 / abs(总亏损)。 |
ulcer_index |
溃疡指数 |
Ratio |
衡量回撤深度和持续时间的指标。 |
upi |
溃疡绩效指数 |
Ratio |
(年化收益率 - 无风险利率) / 溃疡指数。 |
equity_r2 |
权益曲线 R² |
Ratio |
权益曲线相对于时间的线性回归拟合度 (0-1),越接近 1 表示收益越稳定。 |
std_error |
标准误差 |
Float |
权益曲线回归的标准误差。 |
calmar_ratio |
卡尔玛比率 |
Ratio |
年化收益率 / 最大回撤比率。 |
exposure_time_pct |
市场暴露时间百分比 |
% (百分比) |
持有仓位(非空仓)的时间占比。 |
var_95 |
95% 风险价值 |
Ratio (小数) |
95% 置信度下的每日最大亏损比例。 |
var_99 |
99% 风险价值 |
Ratio (小数) |
99% 置信度下的每日最大亏损比例。 |
cvar_95 |
95% 条件风险价值 |
Ratio (小数) |
超过 95% VaR 阈值后的平均亏损比例(预期亏损)。 |
cvar_99 |
99% 条件风险价值 |
Ratio (小数) |
超过 99% VaR 阈值后的平均亏损比例(预期亏损)。 |
sqn |
系统质量指数 (SQN) |
Float |
(平均盈亏 / 盈亏标准差) * sqrt(交易次数)。 |
kelly_criterion |
凯利公式比例 |
Ratio (小数) |
胜率 - (败率 / 盈亏比)。 |
重点指标解读
风险类指标
- 最大回撤 (Max Drawdown): 衡量策略历史最差表现。例如30%的最大回撤意味着你可能在最高点买入后,最大面临30%的亏损。
- 波动率 (Volatility): 衡量收益的波动程度,越高说明收益越不稳定。
- 风险价值 (VaR) 与条件风险价值 (CVaR):
- VaR: 在特定置信度(如95%)下,一天内可能的最大损失。
- CVaR: 当损失超过VaR阈值时的平均损失,更能反映极端尾部风险。
- 市场暴露时间 (Exposure Time): 策略持有仓位的时间占比。低暴露时间资金更安全,但也可能错过机会。
收益风险比类指标
- 夏普比率 (Sharpe Ratio): 衡量每承担一单位总风险所获得的超额收益。通常>1可接受,>2优秀。
- 索提诺比率 (Sortino Ratio): 类似夏普比率,但只考虑下行风险,对经常暴涨的策略评价更公允。
- 卡尔玛比率 (Calmar Ratio): 年化收益与最大回撤之比,是衡量“收益回撤比”的重要指标。
- 系统质量指数 (SQN): 衡量交易系统稳定性。>2.0合格,>3.0优秀,>7.0极佳。
- 凯利公式 (Kelly Criterion): 基于胜率和盈亏比计算的理论最佳仓位。实战中常使用“半凯利”以降低风险。
5. 交易明细、订单与持仓记录详解
交易明细 (result.trades_df)
包含每一笔已平仓交易的详细信息。
| 指标名称 (Name) |
含义 (Description) |
单位/类型 |
计算说明 |
symbol |
标的代码 |
String |
交易标的。 |
entry_time |
开仓时间 |
Datetime |
开仓成交时间。 |
exit_time |
平仓时间 |
Datetime |
平仓成交时间。 |
entry_price |
开仓均价 |
Float |
开仓成交均价。 |
exit_price |
平仓均价 |
Float |
平仓成交均价。 |
quantity |
交易数量 |
Float |
成交数量。 |
side |
交易方向 |
String |
long (做多) 或 short (做空)。 |
pnl |
毛盈亏 |
Float |
不包含手续费的盈亏。 |
net_pnl |
净盈亏 |
Float |
pnl - commission。 |
return_pct |
收益率 |
Float |
交易收益率 (小数)。 |
commission |
手续费 |
Float |
交易产生的佣金。 |
duration_bars |
持仓 K 线数 |
Int |
持仓期间经历的 Bar 数量。 |
duration |
持仓时长 |
Timedelta |
exit_time - entry_time。 |
订单记录 (result.orders_df)
包含所有历史订单记录(包括已成交、取消、拒绝等)。
| 指标名称 (Name) |
含义 (Description) |
单位/类型 |
计算说明 |
id |
订单 ID |
String |
唯一标识符。 |
symbol |
标的代码 |
String |
交易标的。 |
side |
订单方向 |
String |
buy (买入) 或 sell (卖出)。 |
order_type |
订单类型 |
String |
market (市价), limit (限价), stop (止损)。 |
quantity |
订单数量 |
Float |
下单数量。 |
filled_quantity |
成交数量 |
Float |
实际成交数量。 |
limit_price |
限价 |
Float |
限价单的价格 (Market 单为 NaN)。 |
stop_price |
触发价 |
Float |
止损单的触发价格。 |
avg_price |
成交均价 |
Float |
实际成交的平均价格。 |
commission |
手续费 |
Float |
订单产生的手续费。 |
status |
订单状态 |
String |
filled, cancelled, rejected 等。 |
time_in_force |
有效期 |
String |
gtc, day, ioc 等。 |
created_at |
创建时间 |
Datetime |
订单创建时间。 |
持仓记录 (result.positions_df)
包含每日(或每 Bar)的持仓快照。
| 指标名称 (Name) |
含义 (Description) |
单位/类型 |
计算说明 |
date |
日期 |
Datetime |
持仓快照时间。 |
symbol |
标的代码 |
String |
交易标的。 |
long_shares |
多头持仓 |
Float |
多头方向的持仓数量。 |
short_shares |
空头持仓 |
Float |
空头方向的持仓数量。 |
close |
收盘价 |
Float |
当时的收盘价。 |
equity |
账户权益 |
Float |
包含持仓盈亏的账户总权益。 |
market_value |
持仓市值 |
Float |
当前持仓的市场价值。 |
margin |
占用保证金 |
Float |
当前持仓占用的保证金。 |
unrealized_pnl |
未实现盈亏 |
Float |
持仓浮动盈亏。 |
下一步:编写真正的策略
这个“阳线买阴线卖”的策略只是个开始。想要学习如何编写更实用的量化策略吗?比如双均线策略、MACD策略,并加入止盈止损逻辑?
建议你继续阅读AKQuant的官方文档和更深入的中文教程,那里会详细讲解如何使用get_history获取历史数据、计算各种技术指标(如MA, RSI),以及实现完整的策略逻辑。
希望这个快速入门指南能帮你顺利开启Python量化投研之路。如果在探索过程中有更多想法或问题,欢迎到云栈社区与更多开发者交流讨论。
|