🚀 AI 一键生成 joinquant 策略代码

JoinQuant 文件操作:利用 read_file 读取 JSON 策略配置

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

问题描述

如何从json文件中读取策略的参数配置?

解决方案

在 JoinQuant(聚宽)平台中,从 JSON 文件读取策略配置主要涉及两个步骤:使用平台提供的 read_file API 读取文件内容,然后使用 Python 标准库 json 将其解析为字典。

这种方法非常适合将策略逻辑与参数分离,便于在不修改代码的情况下调整参数。

以下是具体的实现方案和代码示例。

核心步骤说明

  1. 准备 JSON 文件:文件通常存储在聚宽的“研究”环境中(根目录)。
  2. 读取文件:在策略的 initialize 函数中使用 read_file('文件名') 读取二进制或文本内容。
  3. 解析 JSON:使用 json.loads() 将读取的内容转换为 Python 字典。
  4. 赋值变量:将解析后的参数赋值给全局变量 g 或用于策略逻辑。

策略代码示例

为了演示完整流程,下面的代码包含两个部分:

  1. 辅助函数:用于在回测开始时自动创建一个测试用的 JSON 配置文件(实际使用时,您通常是在“研究”模块手动创建这个文件)。
  2. 核心逻辑:在 initialize 中读取并应用配置。
# -*- coding: utf-8 -*-
import json
import jqdata

def initialize(context):
    """
    策略初始化函数
    """
    set_benchmark('000300.XSHG')
    set_option('use_real_price', True)
    log.set_level('order', 'error')
    
    # ---------------------------------------------------------
    # 第一步:创建一个模拟的配置文件(实际场景中,该文件通常已存在于您的研究根目录)
    # ---------------------------------------------------------
    create_dummy_config_file()
    
    # ---------------------------------------------------------
    # 第二步:读取并解析 JSON 配置文件
    # ---------------------------------------------------------
    file_path = 'my_strategy_config.json'
    
    try:
        # read_file 是聚宽专用API,用于读取研究目录下的文件
        # 注意:在 Python 3 环境下,read_file 返回的是 bytes 类型
        file_content = read_file(file_path)
        
        if file_content is None:
            log.error(f"未找到配置文件: {file_path},将使用默认参数。")
            load_default_params()
        else:
            # 将 bytes 解码为字符串 (utf-8) 并解析 JSON
            config = json.loads(file_content)
            log.info(f"成功加载配置文件: {config}")
            
            # 将配置应用到全局变量 g 中
            g.security = config.get('security', '000001.XSHE')
            g.short_window = config.get('short_window', 5)
            g.long_window = config.get('long_window', 20)
            
    except Exception as e:
        log.error(f"读取或解析配置文件失败: {e},将使用默认参数。")
        load_default_params()

    # 设置要操作的股票
    g.security_list = [g.security]
    
    # 按天运行
    run_daily(market_open, time='every_bar')

def create_dummy_config_file():
    """
    辅助函数:在回测开始前创建一个测试用的 json 文件。
    在实际使用中,您应该在【研究】模块中上传或创建此文件,不需要在策略里写这部分。
    """
    dummy_config = {
        "security": "000001.XSHE",
        "short_window": 10,
        "long_window": 60,
        "comment": "这是一个双均线策略的配置文件"
    }
    # write_file 也是聚宽专用API
    write_file('my_strategy_config.json', json.dumps(dummy_config), append=False)

def load_default_params():
    """
    加载默认参数,防止文件读取失败导致策略崩溃
    """
    g.security = '000001.XSHE'
    g.short_window = 5
    g.long_window = 20
    log.warn("已加载默认参数。")

def market_open(context):
    """
    每日交易逻辑
    """
    sec = g.security
    
    # 获取历史收盘价
    # 获取长度为长均线窗口的数据
    hist_data = attribute_history(sec, g.long_window + 1, '1d', ['close'])
    close_prices = hist_data['close']
    
    if len(close_prices) < g.long_window:
        return
        
    # 计算均线
    # 短均线
    ma_short = close_prices[-g.short_window:].mean()
    # 长均线
    ma_long = close_prices[-g.long_window:].mean()
    
    # 获取当前持仓
    current_position = context.portfolio.positions[sec].total_amount
    
    # 交易信号:金叉买入
    if ma_short > ma_long and current_position == 0:
        order_target_value(sec, context.portfolio.available_cash)
        log.info(f"金叉买入 {sec},短均线: {ma_short}, 长均线: {ma_long}")
        
    # 交易信号:死叉卖出
    elif ma_short < ma_long and current_position > 0:
        order_target(sec, 0)
        log.info(f"死叉卖出 {sec},短均线: {ma_short}, 长均线: {ma_long}")

关键点解析

  1. read_file(path):

    • 这是聚宽特有的 API,用于读取“研究”环境根目录下的文件。
    • 注意:在 Python 3 回测环境中,read_file 返回的数据类型通常是 bytes(字节流)。
  2. json.loads():

    • Python 标准库函数。
    • 如果 read_file 返回的是 bytes,json.loads 在较新的 Python 版本中可以直接处理 bytes,但为了兼容性和稳健性,建议先解码:json.loads(file_content.decode('utf-8'))(如果文件包含中文)。
  3. 异常处理 (try...except):

    • 文件读取涉及 I/O 操作,可能会因为文件不存在、格式错误等原因失败。强烈建议使用 try...except 块包裹读取逻辑,并提供默认参数(load_default_params),确保策略在配置文件缺失时也能运行。
  4. 文件位置:

    • 代码中引用的 'my_strategy_config.json' 必须位于您的聚宽研究模块的根目录下。您可以在研究界面点击“新建” -> “文本文件”,输入 JSON 内容并重命名为 .json 后缀。

Q&A

Q: 为什么使用 read_file 而不是 Python 原生的 open()
A: 在聚宽的回测和模拟交易容器中,文件系统路径与本地不同。read_file 是平台封装好的接口,专门用于安全地访问用户在“研究”模块中存储的私有文件,路径处理更简便且权限受控。

Q: 如果 JSON 文件中有中文,读取时乱码怎么办?
A: read_file 读取的是二进制数据。在进行 json.loads 之前,请显式进行解码:content_str = file_content.decode('utf-8'),然后再传入 json.loads(content_str)

Q: 能否在回测过程中修改 JSON 文件来动态调整参数?
A: 在回测模式下,文件是在回测开始时读取的,中途修改文件通常不会影响正在运行的回测(除非你在 handle_data 中反复读取,但这会极大地降低回测速度,不推荐)。在模拟交易中,如果策略重启(每天盘前),会重新读取文件;如果需要在盘中动态调整,可以在 handle_data 中设置定时读取逻辑,但需注意性能消耗。