Skip to main content

quotekit — A股/北交所/场内ETF 统一行情工具箱

一个出口拉取 A 股个股(含北交所)、场内 ETF 与指数的实时行情和 K 线,统一返回 pandas DataFrame。

  • 标的覆盖:沪深 A 股 + 北交所(43/83/87/92 开头)+ 场内 ETF(沪 50/51/52/56/58、深 15/16 开头)+ 股指指数
  • 默认源 mootdx(通达信协议,32 线程并发,快、带五档盘口)
  • 自动回退:mootdx 失败/缺失的代码(含北交所、休市场景)自动用 easyquotation 新浪源补,仍缺失再用腾讯源
  • 休市可用:休市时返回最后交易日收盘快照(自动落到 eq 源,属设计行为)

安装

pip install -e .                          # 开发安装
pip install build && python -m build      # 打包: dist/quotekit-0.6.0-py3-none-any.whl
pip install dist/quotekit-0.6.0-py3-none-any.whl

依赖:pandas、mootdx、easyquotation、pypinyin(见 pyproject.toml)。

快速上手

from quotekit import get_quotes, get_index_quotes, configure

# 个股: 三种代码写法混用均可
df = get_quotes(['600519', '000001.SZ', 'sh600000', '920099'])
print(df[['symbol', 'price', 'open', 'high', 'low', 'volume', 'amount', 'time']])

# 指数: 000001上证 399001深成 399006创业板指 000300沪深300
idx = get_index_quotes(['000001', '399001', '000300'])

# 场内ETF: 与个股同一接口, 支持实时快照(含五档)和K线
etf = get_quotes(['510300', '510050', '588000', '159915', '511990'])
etf_bars = get_bars('510300', freq='day', sd='2026-01-01')          # ETF日K

# 交易所 A 股列表(symbol 格式 000001.SZ): 'all' | 'SH' | 'SZ' | 'BJ'
lst = get_stock_list()            # 全市场 5400+ 只, 含名称
lst = get_stock_list('BJ')        # 仅北交所
lst = get_stock_list(refresh=True)  # 强制绕过缓存重拉

# K线: 单只或多只, 频度 1m/5m/15m/30m/60m/day/week/month, 支持复权与日期区间
bars = get_bars('600519', freq='day', limit=120)                    # 最近120根
bars = get_bars(['600519', '000001.SZ'], freq='30m', limit=100)     # 多只30分钟K
bars = get_bars('600519', freq='day', limit=800, adjust='qfq')      # 前复权
bars = get_bars('600519', freq='day', sd='2024-01-01')              # 日期区间(优先于limit)
bars = get_bars('600519', freq='day', sd='2026-01-01', ed='2026-03-31')
bars = get_bars('000001.SZ', freq='day', ed='2025-12-31')           # ed之前全部历史
bars = get_bars('920099', freq='week', limit=52)                    # 北交所周K

# 搜索: 股票/ETF/指数, 支持代码/中文名/拼音首字母/全拼
search('茅台')            # 中文名 -> 600519
search('mt')              # 拼音首字母
search('maotai')          # 全拼
search('000001')          # 同时命中 上证指数 + 平安银行
search('hs300', kind='etf')   # kind: 'all'|'stock'|'etf'|'index'

# 强制指定源 / 临时改线程数
df = get_quotes(['600519'], source='tencent')
df = get_quotes(all_codes, workers=16)

# 全局配置(线程数/超时/批量, 批量上限60)
configure(workers=32, timeout=10, batch=60)

返回 schema

个股/ETF 29 列 / 指数 9 列,symbol 格式 600519.SH / 000001.SZ / 920099.BJ / 510300.SH。

列 类型 说明
code str 6 位纯代码
symbol str 带市场后缀
price float 现价
open / high / low float 今开 / 最高 / 最低
volume int64 成交量(股票=股、ETF=份;mootdx 源手×100)
amount float 成交额(元)
time str YYYY-MM-DD HH:MM:SS
bid1..5 / ask1..5 float 五档价(个股与 ETF)
bid_vol1..5 / ask_vol1..5 int64 五档量(个股与 ETF)

场内 ETF 实测说明(2026-09-30 快照验证):实时与 K 线与个股完全同接口;成交量口径为份, 经"金额÷量≈现价"自检通过(510300/510050/588000/159915/511990 五只全部吻合);日K收盘与量 和实时快照精确一致;mootdx 主路径交易日生效(TDX 协议 ETF 与股票同接口)。

get_stock_list(market) 返回 4 列:code(6 位)、symbol(000001.SZ 格式)、name、market(SH/SZ/BJ)。 SH/SZ 来自 mootdx 实时列表(含名称,休市可用),A 股口径前缀:SH 60/68、SZ 00/30;BJ 来自 easyquotation 内置代码表(静态文件,名称经 eq 补齐,新上市股票可能滞后)。进程内缓存,refresh=True 重拉。 注意:列表仅含 A 股,不含 ETF/指数(get_quotes/get_bars 支持场内 ETF,代码需自行传入)。

search(keyword, kind, limit) 返回 5 列:code / symbol / name / market / type(type 为 stock/etf/index,etf 含 LOF 等场内基金)。证券池覆盖全部 A 股 + 北交所 + 场内基金 + 沪深指数, 来自 mootdx 全列表(与 get_stock_list 共享缓存)+ 北交所清单。

匹配排序两级:先按匹配层级(代码精确 > 代码前缀 > 名称前缀 > 名称包含 > 拼音首字母前缀 > 首字母包含 > 全拼包含 > 模糊兜底),同层内按相似度降序(difflib SequenceMatcher 的字母重合度, 如 mt 会把"煤炭"排在"煤炭指数"前);拼写有误差时(如 maotia)由模糊层兜底召回(阈值 0.55, 结合最长公共子串比率)。

全量列表获取:8 线程分页并行拉取(每页 1000 条,绕过 mootdx 自带 stocks() 的串行翻页, 直接调底层 tdxpy 协议接口),三级缓存——进程内 → 磁盘(TTL 8 小时,~/.quotekit/market_list.csv, 环境变量 QUOTEKIT_CACHE_DIR 可改路径,跨进程复用)→ 网络。refresh=True 强制重拉并刷新磁盘缓存。

get_bars(codes, freq, limit, adjust, sd, ed) 返回 9 列:code / symbol / datetime / open / high / low / close / volume(股) / amount(元)。datetime:分钟线 YYYY-MM-DD HH:MM:SS,日线及以上 YYYY-MM-DD。

取数方式两种(给了 sd/ed 时优先,忽略 limit):

  • limit 模式:最近 N 根。mootdx 逐只自动翻页凑足;tencent/sina 按源上限截断(日K 800、分钟 320/1970)。
  • 日期区间模式:sd/ed('YYYY-MM-DD',分钟线可带时分秒;均可单独给,ed 缺省=至今)。 tencent 日线原生支持日期段并按年分段回拉(可取全部历史,实测 1991 年起);mootdx 回翻过滤; 分钟线的日期区间受源保留窗口限制(mootdx 近期、tencent 最近 320 根、sina 最近 1970 根)。 日期模式下区间无数据返回空 DataFrame(不报错)。

频度与源能力:

频度 mootdx(主源) tencent(回退) sina(回退,仅分钟)
1m/5m/15m/30m/60m 近期滚动窗口,复权支持 320 根,无复权 1970 根,无复权
day/week/month 回溯到上市,复权支持 800 根/段(自动分段翻全部历史),复权支持 ✗

分钟频率的复权仅 mootdx 支持;腾讯源无成交额字段(amount 为 NaN);休市时 mootdx 返回空自动回退。

数据源与实现

数据 主路径 回退路径 说明
个股/ETF 实时快照 mootdx → tdxpy(通达信 TCP 7709,32 线程 × 60 只/批) 新浪 → 腾讯(easyquotation) 休市时 mootdx 空,自动回退拿最后快照
指数实时快照 mootdx 底层 tdxpy(显式 market+code,绕过 mootdx 的市场误判) 新浪 → 腾讯 sina 沪市指数量单位为手已 ×100 归一
K线 分钟 mootdx(近期窗口,支持复权) 腾讯 mkline(320 根)→ 新浪(1970 根) 回退源分钟无复权
K线 日/周/月 mootdx(回溯到上市,支持复权) 腾讯 fqkline(800 根/段,自动按年分段回拉全部历史,支持复权) —
股票列表 mootdx → tdxpy get_security_list(8 线程分页) — 北交所来自 easyquotation 静态代码表,名称经腾讯补齐
搜索池 同上(与股票列表共享缓存)+ pypinyin 拼音 — 沪深指数取自 mootdx 全列表

注:腾讯 K 线接口为 ifzq.gtimg.cn 的公开端点(fqkline/mkline),直接 HTTP 调用,不经 easyquotation。

性能实测(2026-10,休市环境)

操作 耗时
全市场列表冷拉取(51861 条,8 线程) 1.8~5.7s(受 mootdx 服务器波动,慢轮曾 20s)
线程数对比(2/4/8/16 各 3 轮均值) 4.8s / 2.4s / 1.9s / 5.9s(负优化)——8 为甜点
新进程命中磁盘缓存建池 ~0.8s
同进程搜索(缓存后) ~50ms
全市场实时快照(mootdx 32 线程,交易日) ~0.3s(休市计时为协议往返上界)

口径与已知行为(实测)

  • 单位统一:量=股(ETF 为份)、额=元;已修正各源字段错位(sina volume 实为成交额、tencent 成交额(万) 实为元、sina 沪市指数量单位为手需 ×100)。
  • mootdx 单连接独占、批量上限 60 只/次;并发靠"每线程一条连接"。
  • 北交所(43/83/87/92 开头)mootdx 不支持,auto 模式自动由 eq 补齐;老北交码(83/43)sina 数据残缺(有价无开高低),需要完整数据请强制 source='tencent'。
  • mootdx 的 servertime 不含日期,按调用当日拼时间;交易日调用即正确。
  • 全部源失败抛 QuoteSourceError(含各源失败原因)。
  • 休市期间:mootdx 快照为空 → 自动回退 eq 拿最后快照。

运行测试

python -m unittest discover -s tests -v     # 离线单元测试
python tests/test_live_smoke.py             # 在线冒烟(需网络, 交易日效果最佳)

目录结构

quotekit/
├── pyproject.toml
├── src/quotekit/
│   ├── __init__.py     # 出口: get_quotes / get_index_quotes / get_bars / get_stock_list / configure
│   ├── api.py          # 实时行情编排与回退链
│   ├── bars.py         # K线接口(8频度, 复权, 多源回退)
│   ├── lists.py        # 交易所 A 股列表(8线程分页+三级缓存)
│   ├── search.py       # 证券搜索(拼音/相似度/模糊兜底)
│   ├── sources.py      # mootdx / easyquotation 实时行情适配器
│   ├── codes.py        # 代码归一(sh600519 / 600519.SH / 600519)
│   ├── schema.py       # 统一列定义
│   └── config.py       # 全局配置
├── tests/              # 离线单测 + 在线冒烟
└── examples/basic_usage.py

Metadata

Release files for quotekit 0.6.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for quotekit 0.6.0
File Size Uploaded
quotekit-0.6.0.tar.gz 28.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for quotekit 0.6.0
File Interpreter ABI Platform
quotekit-0.6.0-py3-none-any.whl Python 3 none any Details

Total release size: 52.1 kB

Release files / quotekit-0.6.0.tar.gz

Download URL quotekit-0.6.0.tar.gz
Size 28.5 kB
Tags Source
SHA-256 checksum
How to use checksums
5c7ef97d176ff43441e2d4ff74804fff58c2ea91b468c935e9e0d2c3821a592d
BLAKE2b-256 checksum
How to use checksums
f2b09acdf68c943ffdc73b3764959bc5475cc34709d05ae455b062ff816c54bd
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.12

Release files / quotekit-0.6.0-py3-none-any.whl

Download URL quotekit-0.6.0-py3-none-any.whl
Size 23.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
57968861e442052b45e706537731156fc4060c4cb14d4fbbb6226a0920e43127
BLAKE2b-256 checksum
How to use checksums
605ccde6922de4cf28b7c4b82f1c95d094ffda8da7c482701f04ec3922d3499b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.12

Release history Release notifications | RSS feed

0.6.1

2 release files

This release

0.6.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page