问题描述
解决方案
是的,您完全可以在回测图表中画出自定义的每日持仓数量(或其他任何数值变量)。
在 JoinQuant 聚宽平台中,实现这一功能的核心函数是 record()。
核心函数说明
record(key=value, ...)
- 功能:在回测结果页面的图表中绘制自定义曲线。
- 参数:
key:曲线的名称(图例名)。value:当前时间点的值(必须是数字,不能是列表或对象)。
- 显示位置:回测结束后,在收益曲线图下方会生成新的图表区域显示这些自定义曲线。
代码实现示例
以下是一个完整的策略示例。该策略会买入平安银行,并每天使用 record() 函数记录当前的持仓数量。
# -*- coding: utf-8 -*-
# 导入聚宽函数库
import jqdata
def initialize(context):
# 设定要操作的股票:平安银行
g.security = '000001.XSHE'
# 设定基准
set_benchmark('000300.XSHG')
# 开启动态复权模式(真实价格)
set_option('use_real_price', True)
# 每天开盘时运行
run_daily(market_open, time='09:30')
def market_open(context):
security = g.security
# 获取当前持仓数量
# context.portfolio.positions[security].total_amount 获取该标的总持仓
current_amount = context.portfolio.positions[security].total_amount
# 简单的交易逻辑:如果没持仓就买入 1000 股,如果有持仓且价格上涨则卖出部分(仅演示用)
if current_amount == 0:
order(security, 1000)
log.info("买入 1000 股")
# --- 关键步骤:记录持仓数量 ---
# 获取交易后的最新持仓
new_amount = context.portfolio.positions[security].total_amount
# 使用 record 函数绘制曲线
# 'Position_Count' 是图表中显示的曲线名称
# new_amount 是要记录的数值
record(Position_Count=new_amount)
# 您也可以同时记录多个变量,例如记录股价
# current_price = get_current_data()[security].last_price
# record(Stock_Price=current_price)
注意事项
- 调用频率:
record函数通常在handle_data或run_daily调用的函数中使用。 - 数据展示:
- 如果是按天回测,图表上的点代表当天的值。
- 如果是按分钟回测,虽然每分钟都可以调用,但图表通常以“天”为单位进行展示(取当天最后一次调用的值),或者在详细视图中展示。
- 参数限制:
record的参数值必须是数值类型(整数或浮点数),不能直接传入对象或列表。 - 查看结果:回测运行结束后,在收益率曲线图的下方,您会看到一个额外的坐标轴或独立的图表区域,上面画着您定义的
Position_Count曲线。
Q&A
Q: record 函数可以画多条线吗?
A: 可以。您可以在一次 record() 调用中传入多个参数,例如 record(line1=value1, line2=value2),或者在代码的不同位置多次调用 record()。它们会显示在回测结果的图表中。
Q: 如果我在分钟回测中每分钟都调用 record,图表会怎么显示?
A: 聚宽的回测图表主要展示日级别的变化。如果您在分钟级别策略中调用 record,系统通常会记录该交易日最后一次调用 record 时的数值作为当天的数值绘制在图上。
Q: 为什么我的 record 曲线是一条直线?
A: 请检查您传入的变量值是否发生了变化。例如,如果您记录的是 g.security(股票代码字符串)而不是持仓数量,或者逻辑导致持仓从未改变,曲线就会是一条直线。确保传入的是动态变化的数值(如 context.portfolio.total_value 或 positions.total_amount)。