🚀 AI 一键生成 joinquant 策略代码

如何在 JoinQuant 回测过程中模拟真实的资金转入转出?

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

问题描述

在回测的时候,我能模拟中途往账户里加钱或者取钱吗?

解决方案

是的,在聚宽(JoinQuant)的回测和模拟交易中,您可以模拟中途出入金(加钱或取钱)。

这是通过 inout_cash 函数实现的。

核心函数说明

inout_cash(cash, pindex=0)

  • 功能:账户转入或转出资金。
  • 参数
    • cash:资金金额。正数表示入金(加钱),负数表示出金(取钱)。
    • pindex:仓位索引。默认只有 subportfolios[0] 一个仓位,通常保持默认值 0 即可。如果使用了 set_subportfolios 设置了多个子账户,则需要指定对应的索引。
  • 注意:当日的出入金从当日开始记入成本,用于计算收益。即当日结束计算收益时的本金是包含当日出入金金额的。

策略代码示例

以下是一个完整的策略示例。该策略在初始化时设定基准,并在指定的日期模拟入金和出金操作,同时打印账户可用资金的变化以供验证。

# -*- coding: utf-8 -*-
import datetime

def initialize(context):
    # 设定沪深300作为基准
    set_benchmark('000300.XSHG')
    # 开启动态复权模式(真实价格)
    set_option('use_real_price', True)
    # 过滤掉order系列API产生的比error级别低的log
    log.set_level('order', 'error')
    
    # 每天开盘前运行,检查是否需要出入金
    run_daily(check_and_adjust_cash, time='09:00')

def check_and_adjust_cash(context):
    # 获取当前日期
    current_date = context.current_dt.date()
    
    # 示例:在 2020年6月1日 入金 100,000 元
    if current_date == datetime.date(2020, 6, 1):
        log.info("=== 执行入金操作前 ===")
        log.info("当前可用资金: %.2f" % context.portfolio.available_cash)
        log.info("当前总资产: %.2f" % context.portfolio.total_value)
        
        # 执行入金
        inout_cash(100000, pindex=0)
        
        log.info("=== 执行入金操作后 ===")
        log.info("当前可用资金: %.2f" % context.portfolio.available_cash)
        log.info("当前总资产: %.2f" % context.portfolio.total_value)

    # 示例:在 2020年12月1日 出金 50,000 元
    elif current_date == datetime.date(2020, 12, 1):
        log.info("=== 执行出金操作前 ===")
        log.info("当前可用资金: %.2f" % context.portfolio.available_cash)
        
        # 执行出金 (负数)
        inout_cash(-50000, pindex=0)
        
        log.info("=== 执行出金操作后 ===")
        log.info("当前可用资金: %.2f" % context.portfolio.available_cash)

def handle_data(context, data):
    # 这里可以编写您的交易逻辑
    pass

常见问题 (Q&A)

Q: 使用 inout_cash 后,收益率是如何计算的?
A: 当日的出入金会立即反映在账户的总资产(Total Value)和可用资金中。在计算当日收益率时,系统会调整分母(本金),以确保收益率反映的是投资能力的表现,而不是单纯因为加钱导致的资产增加。具体来说,当日结束计算收益时的本金是包含当日出入金金额的。

Q: 如果出金金额大于当前账户的可用资金会怎样?
A: 如果尝试取出的金额大于 available_cash(可用资金),系统通常不会报错,但可用资金可能会变成负数(取决于具体的账户类型和保证金设置),这会导致后续无法开仓或导致强平风险。建议在调用 inout_cash 进行出金前,先判断 context.portfolio.available_cash 是否充足。

Q: 这个函数在模拟交易(实盘模拟)中有效吗?
A: 有效。在聚宽官网的模拟交易中,使用 inout_cash 可以调整模拟账户的资金,常用于同步实际账户的资金变化。

Q: 我有多个子账户(SubPortfolios),如何指定给哪个账户加钱?
A: 通过 pindex 参数指定。例如,如果您在 initialize 中通过 set_subportfolios 设置了两个子账户(索引为0和1),您可以使用 inout_cash(10000, pindex=1) 给第二个子账户加钱。如果不指定,默认是 pindex=0