TencentFetcher:科创板(688/689)成交量单位与其它板不同,入库后偏大 100 倍

Author: rsm-yizhaCreated Sep 22, 2026Updated Sep 22, 2026

问题

TencentFetcher 的 _lots_to_shares() 对所有股票一律 volume × 100(手 → 股)。

但腾讯日线接口 对科创板返回的就是「股」,只有其它板返回「手」。 于是所有 688/689 开头的股票,stock_daily.volume 一直偏大 100 倍。

证据

同一交易日(2026-09-21),腾讯日线原始 volume 字段 ÷ ak.stock_zh_a_daily() 的股数:

代码 板块 腾讯 raw akshare(股) 比值 结论
688111 科创板 4,421,640 4,421,640 1.0000 腾讯给「股」
688012 科创板 11,983,910 11,983,910 1.0000 腾讯给「股」
603501 主板 107,450 10,744,999 0.0100 腾讯给「手」
002230 深主板 147,895 14,789,469 0.0100 腾讯给「手」
600227 主板 1,558,464 155,846,414 0.0100 腾讯给「手」

比值精确到 1.0000 / 0.0100,不是近似误差,是两种单位。

复现

python
import requests, akshare as ak

def tx_raw(sym, date):
    u = f"https://web.ifzq.gtimg.cn/appstock/app/fqkline/get?param={sym},day,{date},{date},10,qfq"
    d = requests.get(u, timeout=15).json()["data"][sym]
    rows = d.get("qfqday") or d.get("day")
    return float(rows[-1][5])          # 字段 5 = volume

for sym, code in [("sh688111", "688111"), ("sh603501", "603501")]:
    raw = tx_raw(sym, "2026-09-21")
    ref = float(ak.stock_zh_a_daily(symbol=sym, start_date="20260921",
                                    end_date="20260921", adjust="qfq").iloc[0]["volume"])
    print(f"{code}  tencent={raw:,.0f}  akshare={ref:,.0f}  ratio={raw/ref:.4f}")

输出:

688111  tencent=4,421,640  akshare=4,421,640  ratio=1.0000
603501  tencent=107,450    akshare=10,744,999 ratio=0.0100

影响

  • 自选股里含科创板时,该股的成交量、均量、放量判断全部失真 100 倍
  • 不易被发现:常见的单位自检是 volume × close / amount ≈ 1, 而腾讯日线不返回 amount,这些行 amount 为空,正好落在自检的盲区里。 我这边是 84% 的行没有 amount,自检只覆盖 16%,问题存在半年才暴露。
  • volume_ratio(量比)因为是比值,100 倍会自行抵消,所以也不会报警—— 除非同一只票在数据源之间切换过,交界处会出现约 100 倍的跳变。

建议修法

data_provider/tencent_fetcher.py:

python
def _is_star_market(symbol: str) -> bool:
    """科创板:688 为主号段,689 为科创板 CDR。"""
    code = symbol[2:] if symbol[:2].lower() in ("sh", "sz", "bj") else symbol
    return code.startswith(("688", "689"))


def _lots_to_shares(volume, symbol: str = ""):
    try:
        v = float(volume)
    except (TypeError, ValueError):
        return volume
    return v if _is_star_market(symbol) else v * 100

调用点(_extract_kline_rows 里已有 symbol 参数):

python
-                "volume": _lots_to_shares(row[5]),
+                "volume": _lots_to_shares(row[5], symbol),

已在本地验证:修复后 TencentFetcher 取到的 volume 对科创板和非科创板都与 ak.stock_zh_a_daily() 一致(比值 1.0000,5 只样本)。

另外

已有数据需要迁移修正:

sql
update stock_daily
   set volume = volume / 100.0
 where (code like '688%' or code like '689%')
   and data_source = 'TencentFetcher'
   and volume > 0;

(限定 data_source 很重要——同一批科创板数据里来自 EfinanceFetcher / AkshareFetcher 的行单位本来就是对的,不能一起除。)

环境

  • 版本:v3.32.0(f9e7b77)
  • Python 3.12 / macOS

Source: ZhuLinsen/daily_stock_analysis