mootdx 通达信数据接入实战手册:七步吃透行情、财务与离线数据三大能力

mootdx 通达信数据接入实战手册:七步吃透行情、财务与离线数据三大能力

mootdx 通达信数据接入实战手册:七步吃透行情、财务与离线数据三大能力

【免费下载链接】mootdx通达信数据读取的一个简便使用封装项目地址: https://gitcode.com/GitHub_Trending/mo/mootdx

你是否遇到过这样的困境:写量化回测时,历史 K 线要用通达信本地数据;盯盘时又需要毫秒级的实时行情;做基本面分析时还差一套顺手的历史财报数据——三个需求,三套对接方案,光是协议解析就能耗掉一个周末。mootdx正是为终结这种"数据三线作战"而生的通达信数据封装库:它把通达信的离线文件读取、线上行情请求、财务数据下载解析收敛成三个统一入口,几行代码即可拿到干净的 pandas DataFrame,让你把时间留给策略本身,而不是协议本身。

第一步:十分钟搭好可直接运行的环境

先明确一件事:mootdx 支持 Windows / macOS / Linux,Python 3.8 及以上,唯一硬依赖是 pandas 和 numpy。安装没有任何魔法,建议直接安装全量扩展,省得后面用到命令行工具或复权功能时再补依赖:

# 推荐:不清楚依赖关系就装全量 pip install -U 'mootdx[all]'

装完验证一下,能看到版本号就说明环境已通:

import pandas as pd import numpy as np from mootdx import __version__ print(f"mootdx 版本: {__version__}") # 例如 0.11.7 print(f"pandas 版本: {pd.__version__}")

小提示:若你是从源码参与开发,也可以通过git clone https://gitcode.com/GitHub_Trending/mo/mootdx拉取仓库后用pip install -e .安装开发模式。

第二步:从"为什么日线少了一段"说起——离线数据读取的正确姿势

很多本地化策略失败的起点,其实是数据文件本身:通达信安装目录下的.day.lc1.lc5二进制文件有一套自定义协议,手写解析极易踩坑(字节序、字段偏移、复权标记一错全错)。mootdx 的Reader帮你把这条链路彻底封装好了。

Reader.factory()是一个典型的工厂方法:传入market='std'读沪深股票,传入'ext'则面向扩展市场。你只需告诉它通达信安装目录tdxdir

from mootdx.reader import Reader # tdxdir 指向通达信安装目录(即包含 vipdoc 子目录的那一层) reader = Reader.factory(market='std', tdxdir='C:/new_tdx') # 日线:返回包含 open/high/low/close/vol 等字段的 DataFrame df_daily = reader.daily(symbol='600036') # 1 分钟线 / 5 分钟线(fzline 是 5 分钟的别名) df_min = reader.minute(symbol='600036', suffix=1) # 1 分钟 df_fz = reader.fzline(symbol='600036') # 5 分钟

你不需要关心600036到底落在sh还是sz目录——Reader内部通过get_stock_market()自动判定市场并拼接前缀;连通达信特有的88开头板块指数存放在sh目录这种"潜规则",它也已替你处理。

把离线读取封装成一个可复用类,批量拉取时还会更省心:

from mootdx.reader import Reader from pathlib import Path class LocalDataHub: def __init__(self, tdxdir: str): if not Path(tdxdir).is_dir(): raise ValueError("通达信数据目录不存在,请检查路径") self.reader = Reader.factory(market='std', tdxdir=tdxdir) def daily_since(self, symbol: str, start: str = '2023-01-01'): """读取指定日期之后的日线""" df = self.reader.daily(symbol=symbol) if df is not None and 'date' in df.columns: return df[df['date'] >= start] return df

这里刻意做了一个目录存在性校验——Reader构造时同样会校验,尽早暴露路径错误比数据读到一半再报错要友好得多。

第三步:实时行情不卡壳——Quotes 的三种高频用法

离线数据解决"历史",实时数据解决"当下"。Quotes走的是通达信行情服务器协议,同样用工厂方法创建,但多了一组生产级参数值得留意:

from mootdx.quotes import Quotes # multithread 开启多线程,heartbeat 保持心跳防断连 client = Quotes.factory(market='std', multithread=True, heartbeat=True, timeout=10)

三个最常用的能力,覆盖绝大多数盘中场景:

1. 批量实时报价

# 传入列表即可一次请求多只股票 df = client.quotes(symbol=['000001', '600000', '000858'])

2. 任意周期的 K 线

# frequency 与通达信约定一致:9=日线,0=5分钟,7=1分钟,5=周线,6=月线 df_k = client.bars(symbol='600036', frequency=9, offset=800) df_i = client.index(symbol='000001', frequency=9) # 指数

3. 分时与逐笔

df_today = client.minute(symbol='000001') # 当日分时 df_trans = client.transactions(symbol='000001', date='20240115') # 历史分笔成交

值得一提的还有client.k(symbol, begin, end)这个"日期区间友好"接口:它内部会自动按 800 条分页翻取、剔除节假日占比,直接返回按日期排序的完整区间数据,做回测取数时比手动拼 offset 优雅得多。

第四步:财报数据一键同步——Affair 与 Financial 的分工

基本面数据是很多人的痛点:通达信财务文件是gpcwYYYYMMDD.zip这种历史归档,手动下载、解压、解析二进制字段,步骤繁琐且容易漏季度。mootdx 把这套流程拆成两个角色:

  • Affair:负责"清单 + 下载",解决数据从哪来的问题
  • Financial:负责"解压 + 解析",解决二进制怎么读的问题
from mootdx.affair import Affair # 1. 拉取远程财务文件清单(含文件名、hash、大小) files = Affair.files() # 2. 按需下载单个文件到本地目录 Affair.fetch(downdir='./fin_data', filename='gpcw20231231.zip') # 3. 解析为 DataFrame(zip / dat 自动识别) df = Affair.parse(downdir='./fin_data', filename='gpcw20231231.zip')

Affair.fetch在下载时会自动校验文件是否已存在且 hash 一致,避免重复下载;解析后拿到的是带标准化列名的财务宽表,配合mootdx.financial.columns中的字段定义即可对齐报表口径。

一个实用的增量同步思路:用files()的清单与本地目录比对,只下载缺失季度,天然形成"增量更新"机制:

import os from mootdx.affair import Affair def sync_finance(download_dir: str = './fin_data'): os.makedirs(download_dir, exist_ok=True) local = set(os.listdir(download_dir)) for item in Affair.files(): if item['filename'] not in local: print(f"增量下载: {item['filename']}") Affair.fetch(downdir=download_dir, filename=item['filename'])

第五步:生产级健壮性——缓存、重试与服务器选择的组合拳

数据接口跑在真实环境里,要面对三个现实问题:慢、断、不稳。对应三个解法:

5.1 慢 → 用 pd_cache 做磁盘缓存

mootdx 内置了pd_cache装饰器,把函数的计算结果序列化到.pkl文件,并按函数源码 + 参数生成缓存键,天然支持"改了代码自动失效":

from mootdx.utils.pandas_cache import pd_cache @pd_cache(cache_dir='./cache', expired=600) # 600 秒过期 def load_daily(symbol: str): client = Quotes.factory(market='std') return client.bars(symbol=symbol, frequency=9)

盘中反复取同一批股票的日线时,命中缓存后直接从磁盘读 pickle,耗时从秒级降到毫秒级。

5.2 断 → 学会利用内置重试

Quotes底层基于tenacity实现了自动重连与重试:返回空数据时会reconnect()重连服务器,auto_retry=True默认开启。因此你的业务代码里,普通的临时性失败大多已被吞掉;只有业务级错误才需要自己兜底。如果你要更强的控制力,可以在自己函数上叠加tenacity装饰器:

from tenacity import retry, stop_after_attempt, wait_random @retry(stop=stop_after_attempt(3), wait=wait_random(min=1, max=3)) def fetch_quotes_safe(symbol: str): client = Quotes.factory(market='std') df = client.quotes(symbol=symbol) if df is None or df.empty: raise ValueError("返回空数据") return df

5.3 不稳 → 用 bestip 挑选最优服务器

行情服务器有好坏之分。mootdx 的server模块提供了测速选优能力,启动时花几秒探测,后续全程享用低延迟连接:

from mootdx.server import bestip servers = bestip(limit=5, timeout=5) # 测速,返回最优服务器列表 client = Quotes.factory(market='std', server=servers[0], timeout=10)

第六步:综合实战——把三大能力串成一个"盯盘 + 复盘"工具

到这里,前五步的知识点已经足够拼装一个完整工具了。下面这个MarketAssistant离线日线、实时行情、财务快照三类数据统一收口,并加入了缓存与重试,可以直接跑:

import logging from mootdx.quotes import Quotes from mootdx.reader import Reader from mootdx.affair import Affair from mootdx.utils.pandas_cache import pd_cache logging.basicConfig(level=logging.INFO, format='%(asctime)s %(levelname)s %(message)s') class MarketAssistant: """综合数据助手:离线历史 + 实时行情 + 财务概览""" def __init__(self, tdxdir: str): self.reader = Reader.factory(market='std', tdxdir=tdxdir) self.client = Quotes.factory(market='std', multithread=True, heartbeat=True) self.log = logging.getLogger('assistant') @pd_cache(cache_dir='./cache', expired=300) def history(self, symbol: str): """本地日线优先,缺失时回退到线上行情""" df = self.reader.daily(symbol=symbol) if df is None or df.empty: self.log.warning(f"{symbol} 本地无数据,回退线上拉取") df = self.client.bars(symbol=symbol, frequency=9) return df def realtime(self, symbols): """批量实时报价""" return self.client.quotes(symbol=symbols) def financial_overview(self, filename: str): """解析指定季度的财务快照""" df = Affair.parse(downdir='./fin_data', filename=filename) return df.head() def snapshot(self, symbol: str, symbols, filename: str): """一次调用,输出三种数据的状态""" return { 'history_rows': len(self.history(symbol)), 'realtime': self.realtime(symbols), 'finance_cols': list(self.financial_overview(filename).columns), } if __name__ == '__main__': tool = MarketAssistant(tdxdir='C:/new_tdx') print(tool.snapshot('600036', ['000001', '600000'], 'gpcw20231231.zip'))

这个例子想传达的工程习惯有三点:入口统一(一个类暴露全部能力)、降级策略(本地缺失回退线上)、结果缓存(重复查询不浪费网络)。这也是把库用好与用精的分水岭。

第七步:避坑清单——九个"我当初踩过的坑"

最后按实战频率整理一份避坑清单,每一条背后都是一个真实报错:

现象解法
tdxdir路径写错构造即抛tdxdir 目录不存在指向包含vipdoc的顶层目录,而非vipdoc本身
服务器连不上请求超时 / 连接被重置bestip()重新测速,或换timeout更宽容的配置
批量请求一次太多返回被截断或超时bars/quotes分批请求,单批控制在合理数量内
K 线数量超上限结果莫名缺失offset超过 800 会被钳制到 800,超长历史用k()或自行分页
财务文件 hash 不匹配反复重复下载不要改动下载目录里的 zip 文件名
本地没有某只股票数据daily()返回 None先用线上bars()回退,或检查通达信客户端是否下载过该股日线
扩展市场接口异常market='ext'报错扩展行情接口当前不稳定,生产依赖请以std为主
缓存不生效每次仍重新拉取检查expired参数与缓存目录权限,pd_cached_delete()可清缓存
日志看不到过程排查困难mootdx基于标准logging,设置level=logging.DEBUG即可看到连接细节

收尾:你已经握住了通达信数据的完整链路

回头看看这条学习路径:从离线二进制文件的本地读取,到线上行情的高频请求,再到财报数据的下载解析,最后用缓存、重试、服务器选择把它们打磨成生产可用的形态——这正是"数据工程"在量化场景下的完整闭环。mootdx 的价值在于把这三条链路收敛成三个工厂入口,让你用最少的协议知识拿到最干净的数据。

下一步建议这样走:先用Reader把本地数据全部验证一遍,再跑通Quotes的实时请求,最后加上pd_cachebestip做性能加固。官方文档位于项目docs/目录(API 说明、CLI 用法、FAQ 一应俱全),sample/目录下还有basic_quotes.pybasic_affairs.pyfq.py等可直接运行的示例脚本,配合本文循序渐进,一周内你就能拥有一套自给自足的数据底座。

【免费下载链接】mootdx通达信数据读取的一个简便使用封装项目地址: https://gitcode.com/GitHub_Trending/mo/mootdx

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考