🚀 AI 一键生成 ptrade 策略代码

PTrade 回测技巧:如何使用 convert_position_from_csv 从文件加载底仓?

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

问题描述

我有一个CSV文件,里面是我的股票持仓,怎么把它加载到回测里作为初始资金和持仓?

解决方案

在PTrade回测中,要通过CSV文件加载初始持仓,主要使用 convert_position_from_csvset_yesterday_position 这两个API接口。

以下是详细的步骤说明和代码示例。

1. 准备CSV文件

首先,你需要确保你的CSV文件格式符合PTrade的要求。文件必须包含表头,且列名必须严格对应以下字段:

  • sid: 标的代码(如 600570.SS
  • amount: 总持仓数量
  • enable_amount: 可用持仓数量(通常与总持仓相等,除非有冻结)
  • cost_basis: 持仓成本价

CSV文件内容示例 (initial_positions.csv):

sid,enable_amount,amount,cost_basis
600570.SS,1000,1000,45.50
000001.SZ,2000,2000,12.30

注意:

  1. 请将该CSV文件上传至PTrade的研究(Notebook)根目录或指定文件夹下。
  2. 文件名不要包含特殊字符。

2. 策略代码实现

在策略的 initialize 函数中,读取该文件并设置底仓。

def initialize(context):
    """
    初始化函数,设置回测参数和初始持仓
    """
    # 1. 设置回测频率等基础配置
    # 注意:set_yesterday_position 仅在回测模块可用
    
    # 2. 定义CSV文件的路径
    # 如果文件在研究根目录下,直接写文件名
    # 如果在子文件夹下,例如 data 文件夹,则写 'data/initial_positions.csv'
    csv_file_path = 'initial_positions.csv'
    
    try:
        # 3. 使用 convert_position_from_csv 读取CSV文件
        # 该函数会自动解析CSV并返回符合 set_yesterday_position 要求的列表格式
        pos_list = convert_position_from_csv(csv_file_path)
        
        # 4. 打印读取到的持仓信息,方便调试查看
        log.info("读取到的初始持仓列表: %s" % pos_list)
        
        # 5. 设置底仓
        # 注意:这会初始化策略的持仓对象
        if pos_list:
            set_yesterday_position(pos_list)
            log.info("初始底仓设置成功")
        else:
            log.warning("CSV文件为空或读取失败,未设置底仓")
            
    except Exception as e:
        log.error("设置底仓时发生错误: %s" % e)

    # 6. 设置基准(可选)
    set_benchmark('000300.SS')

def handle_data(context, data):
    """
    盘中运行函数
    """
    # 示例:打印当前持仓以验证是否加载成功
    # 仅在第一天打印一次
    if context.blotter.current_dt.hour == 9 and context.blotter.current_dt.minute == 31:
        positions = context.portfolio.positions
        for code, pos in positions.items():
            log.info("当前持仓: %s, 数量: %s, 成本: %s" % (code, pos.amount, pos.cost_basis))

3. 关键点解析

  1. convert_position_from_csv(path):

    • 这个函数是专门为了简化从文件读取持仓而设计的。
    • 它会读取CSV文件并将其转换为 set_yesterday_position 所需的 list[dict] 格式,即 [{'sid': '...', 'amount': '...', ...}, ...]
    • 路径问题: path 参数是相对于“研究”环境根目录的相对路径。
  2. set_yesterday_position(poslist):

    • 该函数接受一个列表,列表中的每个元素是一个字典,包含股票代码、数量和成本。
    • 资金影响: 该函数设置的是股票持仓。回测的初始现金(Cash)通常是在回测界面的配置参数中设置的(例如“初始资金 1,000,000”)。set_yesterday_position 创建的持仓价值会加在你的总资产(Portfolio Value)中,或者根据具体回测引擎的逻辑,它代表你“昨天”已经持有的股票。
  3. 适用范围:

    • 这两个函数仅在回测模块(Backtest)中有效。在实盘交易模式下,持仓通常直接从柜台同步,无需手动通过CSV设置。

Q&A

Q1: 如果我的CSV文件里包含不在股票池(set_universe)里的股票,会报错吗?
A: set_yesterday_position 会建立持仓对象,即使这些股票没有显式地通过 set_universe 加入股票池,它们也会出现在 context.portfolio.positions 中。但是,为了确保后续 handle_data 能获取到这些股票的行情数据(如 data[security]),建议在 initialize 中将这些股票加入 set_universe,或者使用 set_universe(list(context.portfolio.positions.keys())) 动态添加。

Q2: convert_position_from_csv 支持 Excel (.xlsx) 文件吗?
A: 不支持。该API仅支持 CSV 格式。如果你有 Excel 文件,请先在 Excel 中将其“另存为” CSV (逗号分隔) 格式,并上传到 PTrade 研究环境中。

Q3: 设置的底仓会扣除我的初始资金吗?
A: 在 PTrade 回测中,set_yesterday_position 主要是为了模拟“继承”之前的持仓。通常情况下,它构建的是持仓部分,而回测设置里的“初始资金”指的是可用现金(Cash)。因此,你的账户总资产(Total Value) = 初始现金 + 底仓市值。它不会从初始现金中扣除购买底仓的钱,而是视为额外的资产或已存在的资产状态。

Q4: 为什么我运行代码后报错 "File not found"?
A: 这通常是因为文件路径不正确。

  1. 确认文件已上传到“研究”环境。
  2. 确认文件名大小写完全匹配。
  3. 如果文件在文件夹内,路径需要包含文件夹名,例如 'my_folder/position.csv'。可以使用 get_research_path() 查看根目录路径辅助调试。