Skip to content

聚宽转 PTrade:后缀、持仓、财务对不上

聚宽策略回测能跑,整段贴进 PTrade 两天就歪,多半不是信号写错,是底层口径不一样。下面按优先级对。不构成投资建议,不代操盘。

手册:get_price · get_history · get_fundamentals · .SS / .SH

1. 后缀不是全局替换

聚宽和 PTrade 至少三套写法在混:

场景聚宽PTrade
上交所518880.XSHG518880.SS 或仍写 .XSHG
深交所159915.XSHE159915.SZ 或仍写 .XSHE
指数成分399101.XSHE399101.SZ(不是 .XSHE
行业指数部分券商 .XBHS

同一个文件里,get_price 一种后缀、order 一种、get_positions 返回的 key 又一种,就会出现:选到了、买不进、卖了还显示有仓。

所有取价、下单、持仓比对走同一层规范化,ETF 池整表替换。

python
def normalize_stock_code(code):
    if not code:
        return code
    return (code.replace('.XSHG', '.SS')
                 .replace('.XSHE', '.SZ')
                 .replace('.SH', '.SS'))

QMT 和 PTrade 之间的沪市尾缀见 .SS / .SH。不要和聚宽那套混在一个文件里。

2. 当天卖掉的票还在持仓列表里

PTrade get_positions() 两个坑:

  1. 当天卖出后 amount=0,对象仍在返回结果里
  2. 返回的代码后缀和其他 API 不一定一致

不要用 if stock in get_positions()len(get_positions()) 当持仓数。先过滤 amount > 0,再规范化代码。

python
def get_position_dict():
    out = {}
    for code, pos in (get_positions() or {}).items():
        qty = getattr(pos, 'amount', 0) or 0
        if qty > 0:
            out[normalize_stock_code(code)] = pos
    return out

聚宽回测里很少出现「以为还有仓 → 再买一次」。字段对照见 查持仓和资金

3. get_price 拿不到「现在」

PTrade 的 get_price 只能稳定拿到昨天及以前。聚宽在 handle_dataget_price(..., count=1, end_date=context.current_dt) 当现价,同样写法在 PTrade 往往是上一交易日收盘。

盘中现价用 get_history 拉分钟线,并带上当前未完成 K 线:

python
def get_current_price(security):
    df = get_history(
        count=1,
        frequency='1m',
        field='close',
        security_list=[security],
        fq=None,
        include=True,
    )
    return float(df['close'].iloc[-1])

include=True / False 差一个参数,均线、MACD 窗口会整体错位。

4. 财务:聚宽单季,PTrade 累计

小市值、多因子迁移,先对齐这个。

  • 聚宽 income_statement:Q2 营收是 4–6 月这一季
  • PTrade:Q2 营收是 1–6 月累计

直接拿 PTrade 的 operating_revenue 和聚宽比,同比环比会全错。累计转单季按报告期做差:

python
q1_single = q1_ytd
q2_single = q2_ytd - q1_ytd   # 0630 累计减 0331 累计
q3_single = q3_ytd - q2_ytd
q4_single = q4_ytd - q3_ytd

还要注意:

  • 看返回的 end_date 判断是哪一季,4 月查可能仍是 Q1 的 0331
  • 查上期累计时校验 end_date,不对就换 date 重查
  • valuationturnover_ratepe_dynamic 常带 % 字符串,要自己转 float
  • get_fundamentals 不传 date 容易踩未来函数,文档建议传上一交易日

5. 没有 get_factor_values

聚宽一行 get_factor_values(stocks, 'SGAI', end_date=date)。PTrade 没有等价 API,每个因子要用行情和财报自己算。

对不齐的常见原因:

类型聚宽侧PTrade 自算容易偏
量价 ARBR、VOL120前复权、固定窗口fq='pre' 还是 None;是否含当日 bar
财务 SGAI 等TTM 或单季用了累计没转单季
成长 sales_growth公告日 + 报告期publ_date / end_date 规则不同
估值 PE / PB按日更新字符串带 %;不传 date 未来函数

因子策略不要指望改函数名一周上线。先固定一小撮股票、十个交易日,逐个因子和聚宽 diff。

其他硬规则

  • 涨停价:日线才能稳定取到;分钟线 check_limit 可能不一致
  • 指数成分:get_index_stocks('399101.XSHE') 改成 '399101.SZ'
  • 定时:run_daily(time='09:31') 触发秒数和聚宽差 1 分钟,轮动结果就会不同
  • 研究 / 回测 / 交易三套环境,同一 API 规则不一样

建议顺序

  1. 统一后缀 + 持仓过滤
  2. get_price 做历史,get_history 做现价
  3. 财务累计转单季,几只股票手工验算
  4. 因子逐个重写再 diff
  5. 最后才动下单和对账

跳过财务口径直接调参,是在错误因子上拟合。

相关:API 查询 · 热门问题 · 关注