🚀 AI 一键生成 joinquant 策略代码

如何在 JoinQuant 策略回测或模拟结束时执行最终的汇总分析?

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

问题描述

我希望在策略运行结束后进行一些数据总结工作,应该怎么做?

解决方案

在 JoinQuant 聚宽平台中,如果您希望在回测或模拟交易结束时进行数据总结、统计分析或日志输出,可以使用 on_strategy_end(context) 函数。

该函数是策略框架的可选回调函数,仅在回测或模拟交易正常结束时被调用一次。

核心实现方法

您需要在策略代码中定义 on_strategy_end(context) 函数。在该函数内部,您可以访问 context 对象来获取最终的账户状态、持仓信息或回测期间记录的全局变量。

以下是一个完整的代码示例,展示了如何在策略结束时打印最终的总资产和收益率:

# -*- coding: utf-8 -*-
# 导入函数库
from jqdata import *

def initialize(context):
    # 初始化设置
    set_benchmark('000300.XSHG')
    set_option('use_real_price', True)
    log.info('策略开始运行')
    
    # 每天运行一次
    run_daily(market_open, time='every_bar')

def market_open(context):
    # 简单的买入示例:如果空仓则买入平安银行
    if len(context.portfolio.positions) == 0:
        order_value('000001.XSHE', context.portfolio.available_cash)

# ------------------------------------------------------------------
# 策略结束回调函数
# ------------------------------------------------------------------
def on_strategy_end(context):
    """
    策略运行结束时调用
    """
    print('=' * 50)
    print('策略运行结束,开始进行数据总结:')
    
    # 1. 获取最终账户信息
    final_value = context.portfolio.total_value
    starting_cash = context.portfolio.starting_cash
    returns = context.portfolio.returns
    
    # 2. 打印总结信息
    log.info('初始资金: %.2f' % starting_cash)
    log.info('最终资产: %.2f' % final_value)
    log.info('累计收益率: %.2f%%' % (returns * 100))
    
    # 3. 打印最终持仓
    positions = context.portfolio.positions
    if len(positions) > 0:
        log.info('最终持仓详情:')
        for security, position in positions.items():
            log.info('标的: %s, 持仓数量: %d, 市值: %.2f' % 
                     (security, position.total_amount, position.value))
    else:
        log.info('最终无持仓')
        
    print('数据总结完成。')
    print('=' * 50)

on_strategy_end 的主要用途

  1. 统计分析:计算策略特有的指标(如特定因子的平均暴露度、交易胜率等,前提是您在 g 全局变量中记录了过程数据)。
  2. 日志输出:输出最终的资金曲线摘要或持仓快照。
  3. 文件持久化:结合 write_file 函数,将回测过程中的自定义数据(如每日的信号值)保存为 CSV 或 JSON 文件,以便在“研究”模块中进一步分析。

注意事项

  1. 触发条件:该函数仅在回测时间结束(到达 end_date)或模拟交易到期结束时调用。如果策略因报错而终止,或用户手动停止策略,该函数不会被调用。
  2. Context 对象:此时的 context 对象包含了策略结束那一刻的所有状态信息。
  3. API 限制:在该函数中不能调用下单函数(如 order),因为交易已经结束。

Q&A

Q: on_strategy_end 函数中可以使用 write_file 保存数据吗?
A: 可以。这是非常常见的用法。您可以在回测过程中将数据保存在全局变量(如 g.my_data_list)中,然后在 on_strategy_end 中将其转换为 DataFrame 并使用 write_file 保存到研究目录,方便后续分析。

Q: 如果我在回测中途手动点击“停止”,on_strategy_end 会运行吗?
A: 不会。根据 API 文档,手动在到期前关闭策略或回测发生异常错误时,该函数不会被调用。它仅在流程正常走完时间轴后触发。

Q: 这个函数能用来平掉所有仓位吗?
A: 不能。on_strategy_end 运行时回测/交易已经结束,此时调用 order 等交易函数是无效的。如果您需要在最后一天平仓,需要在 handle_data 或定时函数中判断当前日期是否为回测结束日期来实现。