🚀 AI 一键生成 ptrade 策略代码
立即体验
👉 AI 生成代码 👈

ptrade 模拟交易与实盘交易资金持仓无法隔离怎么办?

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

问题描述

账户共享问题

模拟交易和实盘交易的资金、持仓无法隔离怎么办?

解决方案

问题分析

在 ptrade 量化平台中,如果您发现模拟交易和实盘交易的资金、持仓数据发生了混淆或无法隔离,通常是因为以下原因导致的:

  1. 持久化文件冲突:策略中使用了 pickle 等方式将自定义的持仓、资金或状态变量保存到本地文件中,但模拟盘和实盘使用了相同的文件名和路径,导致数据互相覆盖和读取。
  2. 全局变量污染:在某些特殊部署环境下,如果模拟和实盘共用同一个策略实例(较少见),全局变量 g 可能会发生混淆。

解决方案

为了彻底隔离模拟交易和实盘交易的数据,最有效的方法是利用 ptrade 提供的 get_user_name() 接口获取当前登录的资金账号,并根据资金账号来区分逻辑和持久化文件。

1. 动态生成持久化文件路径

在保存和读取 pickle 文件时,将资金账号作为文件名的一部分,确保模拟账户和实盘账户读写不同的文件。

import pickle
from collections import defaultdict

def initialize(context):
    g.security = '600570.SS'
    set_universe(g.security)
    
    # 获取当前登录的资金账号
    g.user_name = get_user_name()
    if g.user_name is None:
        g.user_name = "default_account"
        
    # 根据资金账号动态生成持久化文件路径
    g.file_path = get_research_path() + f'hold_days_{g.user_name}.pkl'
    
    # 尝试加载对应账户的持久化数据
    try:
        with open(g.file_path, 'rb') as f:
            g.hold_days = pickle.load(f)
        log.info(f"成功加载账户 {g.user_name} 的持久化数据")
    except:
        g.hold_days = defaultdict(list)
        log.info(f"初始化账户 {g.user_name} 的空持久化数据")

def handle_data(context, data):
    # 交易逻辑...
    
    # 每天将存储状态的字典对象进行 pickle 保存,隔离到对应账户的文件中
    with open(g.file_path, 'wb') as f:
        pickle.dump(g.hold_days, f, -1)

2. 根据账户执行不同逻辑

如果您希望在同一个策略代码中,针对模拟盘和实盘设置不同的参数(例如交易数量、风控阈值),同样可以使用 get_user_name() 进行分支判断。

def initialize(context):
    g.security = "600570.SS"
    set_universe(g.security)
    g.user_name = get_user_name()
    
    # 假设 '123456789' 是实盘账号,'987654321' 是模拟账号
    if g.user_name == "123456789":
        g.trade_amount = 1000  # 实盘交易量
        log.info("当前为实盘环境")
    else:
        g.trade_amount = 100   # 模拟盘交易量
        log.info("当前为模拟盘环境")

def handle_data(context, data):
    # 使用区分后的参数进行交易
    order(g.security, g.trade_amount)

注意事项

  1. get_user_name() 的返回值:该接口在查询失败时会返回 None。在编写代码时,务必做好 None 值的异常处理,避免拼接字符串时报错。
  2. 框架自带的 Context 对象:ptrade 框架底层的 context.portfolio(账户资金和持仓信息)本身就是与登录的资金账号强绑定的,框架层面已经做好了隔离。您只需要确保您自己编写的持久化逻辑自定义状态变量不发生冲突即可。
  3. 回测环境兼容:在回测环境中,get_user_name() 可能返回特定的回测标识或 None,请确保您的路径生成逻辑在回测中也能正常运行。