chore: init qmt_bridge repo (HTTP+WS bridge, MCP endpoint, docs, references)
This commit is contained in:
@@ -0,0 +1,86 @@
|
||||
# 持仓查询接口(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=多) |
|
||||
|
||||
7. **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`
|
||||
|
||||
## 三、返回结构(示例)
|
||||
|
||||
```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_*` 字段作为超集保留在同一行,避免旧调用方(如已部署脚本)因删字段而失效。
|
||||
Reference in New Issue
Block a user