问题描述
解决方案
是的,在聚宽(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。