Files
qmt_bridge/docs/迭代记录/持仓查询接口.md
T

4.1 KiB
Raw Blame History

持仓查询接口(GET /trade/positions 增强)

版本: 1.0 (2026-08-26) 状态: 已完成 关联: docs/设计/整体设计方案_v3.md 第四节(trade 命名空间)、docs/桥接口清单与sfgrid满足度对照.md 本次迭代: 持仓查询接口返回全部持仓信息(语义化字段 + 汇总),不做过滤筛选,不兼容旧调用模式

一、已确认的设计决策

  1. 接口: GET /trade/positions(复用现有路由,不改 URI
  2. 返回全部持仓信息: 每一行 = 语义化字段(xt 风格,供 sfgrid 等消费方直接使用)+ 完整原始 m_* 字段(透传,不丢弃)
  3. 不做过滤筛选: 不加 code/status 等过滤参数;客户端需要单票时自行从全量中取(sfgrid 的 getStockPosition 本就以全部持仓为缓存)
  4. 不兼容旧调用模式: 不再承诺只返回 m_* 原始字段;新返回为超集(m_* 仍在,新增语义字段),旧调用方读 m_* 不受影响,但返回结构/示例以本设计为准
  5. 增加汇总 summary: count(持仓只数)、total_market_value(总市值)、total_profit(总浮动盈亏)
  6. 字段映射QMT POSITION 行 → 语义字段,字段缺失时安全降级):
语义字段 来源(m_* 候选,按序探测) 说明
stock_code m_strInstrumentID 完整代码(带交易所后缀,如 600519.SH)
stock_name m_strInstrumentName 股票名称
volume m_nVolume 总持仓量
available m_nCanUseVolume 可用持仓量
frozen_volume m_nFrozenVolume 冻结数量
on_road_volume m_nOnRoadVolume 在途数量
yesterday_volume m_nYesterdayVolume 昨仓数量
avg_price m_dOpenPrice / m_dCostPrice 持仓成本价
price m_dLastPrice / m_dSettlementPrice / m_dOpenPrice 最新价(缺失时兜底成本价)
market_value m_dMarketValue / m_dInstrumentValue / volume*price 计算 持仓市值
open_price m_dOpenPrice 开仓价(与 avg_price 同源)
profit m_dFloatProfit / 计算 (price-avg_price)*volume 浮动盈亏
profit_pct 计算 盈亏比例 %
direction m_nDirection 方向(默认 48=多)
  1. JSON 安全: 所有值经 _json_safe 处理(QMT 可能返回 numpy 类型)

二、实现记录(已完成)

  • src/bridge_data_adapter.py 新增 get_positions():
    • bridge_util.get_trade_cache("position") 读缓存(策略线程 300ms 刷新,HTTP 线程只读)
    • 每行先 _obj_to_dict 得到 m_* 字段,再补充语义字段(含缺失字段探测与计算兜底)
    • 计算 summary: count / total_market_value / total_profit
    • 返回 {"positions": [...], "summary": {...}}
  • src/bridge_http_server.py _api_trade: dtype == "position" 时调用新 get_positions(),返回 {"ok":true,"data":{...}}
  • tests/test_trade.py: 更新持仓断言(语义字段 + summary)
  • docs/api_spec/openapi.yaml: /trade/positions 响应示例更新为语义字段 + summary
  • 重新生成 docs/api_spec/openapi.json

三、返回结构(示例)

{
  "ok": true,
  "data": {
    "positions": [
      {
        "stock_code": "600519.SH",
        "stock_name": "贵州茅台",
        "volume": 100,
        "available": 100,
        "frozen_volume": 0,
        "on_road_volume": 0,
        "yesterday_volume": 0,
        "avg_price": 1500.0,
        "price": 1510.0,
        "market_value": 151000.0,
        "open_price": 1500.0,
        "profit": 1000.0,
        "profit_pct": 0.67,
        "direction": 48,
        "m_strInstrumentID": "600519.SH",
        "m_nVolume": 100,
        "m_nCanUseVolume": 100,
        "m_dOpenPrice": 1500.0,
        "m_dFloatProfit": 1000.0
      }
    ],
    "summary": {
      "count": 1,
      "total_market_value": 151000.0,
      "total_profit": 1000.0
    }
  }
}

说明: 语义字段名以 xtquant 风格为准(sfgrid qmt_real.py/data_store.py 消费的 volume/avg_price/stock_code/instrument_name 等);原始 m_* 字段作为超集保留在同一行,避免旧调用方(如已部署脚本)因删字段而失效。