🚀 AI 一键生成 joinquant 策略代码

JoinQuant 聚宽平台如何实现跨日保存数据与状态持久化?

joinquant | 发布时间: 2026/5/25
以下内容由 EasyQuant 生成。

问题描述

想问一下怎么把今天操作的数据保存至明天?

比如我加仓信号出来后可能会持续几天,我可能在第一天就加仓了,但是不希望第二天或第三天继续加仓,因此需要把今天操作过的记录保存下来,有没有什么函数或者例子可以使用?或者需要怎么做呢?

用全局变量的话,如果系统自动重启,或者自己重启,之前的数据就归零了,所以还是需要有个什么手段把数据保存起来,重启后再读取

解决方案

在 JoinQuant (聚宽) 平台中,要把今天操作的数据保存至明天,并且防止系统重启或手动重启导致数据归零,主要有两种标准的方法:

方法一:正确使用全局变量 g(平台自带持久化)

很多用户误以为系统重启后全局变量 g 会清零,其实在模拟交易中,聚宽平台每天结束时会自动使用 pickleg 对象序列化保存到磁盘。第二天重启时,会恢复 g 的状态,并且不会再次执行 initialize 函数

注意事项:

  1. 只有在模拟盘生命周期内,g 才会持久化。如果是重新创建模拟盘或修改了代码导致某些重置,可能会丢失。
  2. 不能被 pickle 序列化的对象(如数据库连接、网络请求对象)不能保存在 g 中。
  3. 以双下划线 __ 开头的变量(如 g.__test)不会被保存。

方法二:使用 write_fileread_file 进行文件持久化(最稳妥)

如果您希望数据绝对安全,甚至在不同回测、不同模拟盘之间共享,或者防止意外的 g 变量丢失,可以使用聚宽提供的文件读写 API,将操作记录保存为 JSON 文件存放在您的“投资研究”目录下。

核心 API:

  • write_file(path, content, append=False):将内容写入文件。
  • read_file(path):读取文件内容。

具体实现代码示例:

假设我们需要记录某只股票最近一次加仓的日期,以防止连续几天重复加仓:

import jqdata
import json
import datetime

# 定义保存状态的文件路径
STATUS_FILE = 'trade_status.json'

def initialize(context):
    set_benchmark('000300.XSHG')
    set_option('use_real_price', True)
    g.security = '000001.XSHE'
    
    # 每天开盘运行
    run_daily(market_open, time='09:30')

# 辅助函数:读取状态
def load_trade_status():
    try:
        content = read_file(STATUS_FILE)
        return json.loads(content)
    except Exception as e:
        # 如果文件不存在或解析失败,返回空字典
        return {}

# 辅助函数:保存状态
def save_trade_status(status_dict):
    content = json.dumps(status_dict)
    write_file(STATUS_FILE, content, append=False)

def market_open(context):
    security = g.security
    current_date = context.current_dt.strftime('%Y-%m-%d')
    
    # 1. 读取历史操作记录
    trade_status = load_trade_status()
    
    # 获取该股票最后一次加仓的日期
    last_buy_date = trade_status.get(security, None)
    
    # 2. 判断是否需要加仓(这里用伪代码代替您的加仓信号)
    buy_signal = True # 假设今天有加仓信号
    
    if buy_signal:
        # 如果之前没有加仓记录,或者最后一次加仓不是今天(甚至可以限制为不是最近3天)
        if last_buy_date != current_date:
            log.info(f"触发加仓信号,执行加仓: {security}")
            order_value(security, 10000)
            
            # 3. 更新操作记录并持久化保存到文件
            trade_status[security] = current_date
            save_trade_status(trade_status)
            log.info("加仓状态已持久化保存。")
        else:
            log.info(f"{security} 今天已经加过仓了,忽略本次信号。")

总结

  • 常规状态保持:直接挂载在 g 对象上即可,聚宽模拟盘底层会自动帮您 pickle 序列化并在第二天恢复。
  • 高可靠性/跨策略共享:使用 write_fileread_file 结合 json 库,将字典状态写入研究环境的本地文件。每次需要判断时读取,操作完毕后写入。这种方法即使您手动停止并新建模拟盘,只要读取同一个文件,状态依然存在。