🚀 AI 一键生成 joinquant 策略代码

JoinQuant 回测可视化:如何用 record 函数绘制持仓集中度、波动率等自定义指标?

joinquant | 发布时间: 2025/12/16
以下内容由 EasyQuant 生成。

问题描述

除了收益曲线,我还能在回测图表中画出我自己计算的每日持仓数量吗?

解决方案

是的,您完全可以在回测图表中画出自定义的每日持仓数量(或其他任何数值变量)。

在 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)

注意事项

  1. 调用频率record 函数通常在 handle_datarun_daily 调用的函数中使用。
  2. 数据展示
    • 如果是按天回测,图表上的点代表当天的值。
    • 如果是按分钟回测,虽然每分钟都可以调用,但图表通常以“天”为单位进行展示(取当天最后一次调用的值),或者在详细视图中展示。
  3. 参数限制record 的参数值必须是数值类型(整数或浮点数),不能直接传入对象或列表。
  4. 查看结果:回测运行结束后,在收益率曲线图的下方,您会看到一个额外的坐标轴或独立的图表区域,上面画着您定义的 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_valuepositions.total_amount)。