简介面向高频交易与量化投资者的同花顺Level-2全推行情Python API操作手册聚焦沪深市场深度行情获取与涨停板策略等实战场景适合具备Python基础、希望接入逐笔成交与委托数据的中高级证券开发者。压缩包共1个文件为PDF格式约850KB集中呈现SDK版本迭代记录与接口使用说明。手册梳理了从V2.0.0多连接模式改造、上证逐笔委托支持到V2.1.9逐笔委托序号字段的完整演进涵盖级联功能、离线调试、异步订阅接口及快照字段精度优化等细节同时说明TDS系统的C/S架构、运行环境要求与初始化流程并给出指数快照、证券快照、委托队列、逐笔委托、逐笔成交、极速盘口六类回调函数的注册方式与参数含义。已有2833人学习可帮助读者快速理解行情订阅机制、字段变更影响与低延迟数据接入要点为量化策略开发提供参考。1. 装 Level-2 行情 SDK 前先把版本和运行环境对齐去年帮一个做涨停板策略的团队排查问题对方在 Windows 上跑得好好的 Python 脚本挪到一台 CentOS 7 的机器上import datafeed直接报 ImportError折腾了一下午才发现装的是 32 位 Python。这类翻车在 Level-2 全推行情 SDK 的部署里太常见了——行情数据本身对延迟敏感环境差一点回调里堵一次包策略信号就慢半拍。同花顺这套 TDS 的 Python API 走 C/S 结构SDK 直连行情网关用回调把沪深 Level-1、Level-2 的十档快照、逐笔成交、逐笔委托、委托队列和极速盘口推上来做量化、盯涨停板、算盘口失衡的开发者基本绕不开它。这篇笔记按我实际装过的顺序把版本选择、依赖、安装、回调配置、级联和离线调试、排错验证一路写下来新手能照着走通熟手能对着版本差异和参数取舍少踩几个坑。2. 版本选择与运行环境Python 3.5 起步64 位是硬门槛2.1 从修订记录里挑一个能用的版本这套 SDK 从 V2.0.0 到 V2.1.9 迭代了两年多每个版本改的东西不一样装之前先想清楚自己要用哪些能力再倒推版本。下面这张表是我从修订说明里摘出来的关键节点装的时候对着看版本关键变化什么时候必须升到它V2.0.0单连接改多连接支持上证逐笔委托快照加买卖委托笔数、证券名称需要逐笔委托或十档委托笔数V2.0.1支持级联逐笔加业务序号支持 Level-1提供 Linux 支持要跑 Linux 或做局域网分发V2.0.4新增极速盘口查询与订阅策略依赖极速盘口V2.0.6withdraw_buyturnover、withdraw_sellturnover由 int 改 float算撤单金额精度不能丢V2.1.0增加离线调试环境设置加m_connectmarket、m_timeout无行情时想本地回放调试V2.1.3登录返回 -1018 版本过低通知回调参数由 int 改 dict老代码升级要改回调签名V2.1.4异步订阅async_sub加m_connectsubscribe快照加匹配成交相关字段要断线重连后自动重发订阅V2.1.9逐笔委托增加委托序号逐笔委托要排序去重我一般会直接上 V2.1.9除非对接方明确要求某个旧版本。要注意 V2.1.3 是个分水岭消息通知回调函数的入参从 int 变成了 dict如果你从 V2.1.2 及以前升上来fncnotify里取参数的方式必须改否则运行时报类型错误。另外 V2.0.6 把两个撤单金额字段从 int 改成 float历史代码里如果拿它做整数运算升级后结果会变这点在涨停板撤单率统计里尤其容易翻车。2.2 硬件、系统和 Python 版本对照官方给的运行环境不算苛刻但每一条都有实际意义别当摆设项目要求实际含义CPU64 位双核及以上32 位 Python 装不上这是最常见的 ImportError 来源内存8G 及以上全市场订阅时回调数据量大内存小容易堆积带宽下行 100Mb 及以上全推行情是持续流带宽不够会堵包操作系统Windows 7 及以上、CentOS 7 等常用 LinuxLinux 下安装需要 root 权限PythonPython 3.564 位及以上低于 3.5 或 32 位一律不行这里有个反直觉的点很多人以为 Python 版本越高越好实际上这套 SDK 的 tar.gz 包是按特定 Python 版本编译的装之前先确认包名里的版本标识和本机 Python 对得上。我见过在 Python 3.11 上硬装 3.5 编译的包import datafeed报的是符号未定义不是简单的版本不匹配。稳妥做法是先用python -c import platform; print(platform.architecture())确认是 64 位再看python --version是否 ≥ 3.5两个条件都满足再往下走。2.3 装之前先确认的三件事第一确认你有可用的行情账号和密码SDK 登录走的是账号认证没有账号装完也连不上。第二确认网络能到行情网关这套系统是 C/S 结构SDK 要连服务端公司内网如果有出站限制提前找网络同事放行。第三Linux 下准备好 root 权限安装步骤里明确写了需要 root。这三件事任何一件没落实后面装得再顺也是白装。3. 安装 SDKtar.gz 包两种装法Linux 要 root3.1 用 pip 装 tar.gz 包拿到手的安装包长这样L2-tdsapi-python-X.X.X-XXXXXXXX.tar.gzX 是版本号后面是编译标识。最省事的方式是 pip 直接装本地包# 进入安装包所在目录确认 Python 是 64 位且 3.5 python -c import platform; print(platform.architecture()) python --version # 用 pip 安装本地 tar.gz 包Linux 下前面加 sudo pip install ./L2-tdsapi-python-X.X.X-XXXXXXXX.tar.gzpip install ./xxx.tar.gz会把包解压、编译、装进当前 Python 环境的 site-packages。这里的关键是「当前 Python 环境」——如果你机器上有多个 Python一定要用which python和which pip确认两者指向同一个解释器否则会出现 pip 装到了 A 环境、脚本跑在 B 环境、import 找不到的经典问题。Linux 下不加 sudo 通常会因为写 site-packages 权限不足失败报 Permission denied加上 sudo 即可。3.2 用 setup.py 装有些分发包不带 pip 元数据或者你想指定安装参数就走 setup.py# 解压安装包 tar -zxvf L2-tdsapi-python-X.X.X-XXXXXXXX.tar.gz cd L2-tdsapi-python-X.X.X-XXXXXXXX # Linux 下需要 root 权限 sudo python setup.py installsetup.py install和 pip 装的是同一个东西区别在于前者不经过 pip 的依赖解析和缓存适合离线环境或需要看安装日志的场景。装完会在输出里看到Finished processing dependencies如果中途报编译错误多半是 Python 版本或位数不对回到 2.2 节重新核对。3.3 验证导入是否成功装完别急着写业务代码先验证包能不能导入python -c import datafeed; print(datafeed import ok)没有异常输出datafeed import ok就说明安装成功。如果报ModuleNotFoundError: No module named datafeed先查pip show能不能看到包看不到就是装错环境能看到但导入失败多半是位数或版本不匹配卸载重装对应版本的包。这一步是整个部署的地基地基不稳后面全是玄学问题。4. 初始化与回调配置set_env 的参数决定后面顺不顺4.1 创建实例并注册行情回调SDK 的工作方式是回调驱动你注册函数行情来了 SDK 调你的函数。最小可用骨架是这样from datafeed.tds_api import TDS # 创建实例 tds TDS() # 行情推送回调三个参数固定数据列表、条数、链路时间戳 def callback_stock(data_list: list, count: int, stats: dict): # 不要在回调里做耗时操作否则会堵包 print(receive count:, count) # 注册回调并设置环境参数 tds.set_env(fnctickstockcallback_stock)set_env必须在创建实例之后、登录之前调用而且必须先调它才能调后续的注册和登录。fnctickstock对应证券快照另外还有fnctickindex指数快照、fncorderqueue委托队列、fncorderdata逐笔委托、fnctransaction逐笔成交、fncsuperstock极速盘口五个数据回调以及fncnotify断线通知和fucsubscribe异步订阅回调。每个数据回调都必须接受(data, count, stats)三个参数stats里是produce_time、send_time、recv_time三个微秒级时间戳做延迟分析时直接拿它算链路耗时。4.2 set_env 里值得改的几个参数set_env的参数大多有默认值但有几个我建议显式设置tds.set_env( fnctickstockcallback_stock, m_heartbeat_interval5, # 心跳间隔秒最小 1 m_reconn_count10, # 断线重试次数1 不重连 m_reconn_interval3, # 重连间隔秒 m_timeout5000, # 同步请求超时毫秒 m_connectmarketUSH;USZ, # 连接市场可只填 USH 或 USZ m_connectsubscribe1, # 重连成功后自动重发订阅 m_logpath/var/log/tds, # 日志路径默认在包安装目录 m_loglevelwarn # 日志级别 )m_connectmarket是 V2.1.0 加的只做单市场时填USH或USZ能少连一条链路m_connectsubscribe是 V2.1.4 加的设成 1 后断线重连成功会自动重发订阅请求不设的话重连后订阅全丢行情静默这个坑我在实盘环境里踩过一次排查了半天才发现是订阅没恢复。m_logpath建议指到一个有写权限的独立目录默认装在包目录下升级或重装时日志容易被覆盖。4.3 登录与返回值判读登录接口很简单但返回值必须判ret tds.login(your_account, your_password) if ret ! 0: print(login failed, code:, ret)成功返回 0失败返回负数。常见的几个-1004 用户名密码错误、-1005 无法连接服务器、-1016 重复登录、-1018 版本太低需要更新程序。V2.1.3 起专门加了 -1018意思是客户端版本低于服务端要求遇到它别怀疑账号直接换新包。另外 -1014 是级联模式下主 IP 连接异常-1015 是级联模式要求同一局域网这两个只在级联场景出现普通模式不用管。5. 订阅、查询与级联模式把数据真正拉起来5.1 同步订阅与查询接口登录成功后用sub订阅、unsub取消、add_sub加代码、del_sub删代码都是同步接口返回 0 表示成功# 订阅 USHA 全市场证券快照[] 表示全市场 tds.sub(stock, USHA, []) # 增加 USHA 全市场逐笔成交订阅 tds.add_sub(trans, USHA, []) # 取消 USHA 快照订阅 tds.unsub(stock, USHA)data_type支持index、stock、queue、order、trans、superstock六种。查询接口是同步拉取适合补数据或做快照校验get_code_list(USHI)拿代码表get_tick_index(USHI, [])拿指数快照get_tick_stock(USHA, [600000])拿指定证券快照get_super_stock拿极速盘口。市场代码要记准上交所 A 股是USHA深交所 A 股是USZA上证风险警示板是USHT填错市场返回空列表不报错很容易误以为没数据。5.2 异步订阅与订阅回调V2.1.4 加了async_sub订阅结果通过fucsubscribe回调通知适合订阅量大、不想阻塞主线程的场景def on_subscribe(data_type, op_type, market, code_list, statuscode, callback_type): # statuscode 为 0 表示成功其余为失败 print(data_type, market, statuscode) tds.set_env(fucsubscribeon_subscribe) tds.async_sub(stock, 1, USHA, []) # op_type1 全新订阅op_type的取值1 全新订阅、2 取消订阅、3 增加订阅代码、4 取消订阅代码。callback_type为 1 表示异步订阅触发为 2 表示断线重连或手动登录后自动重发订阅触发。注意 V2.1.6 调整过订阅回调的参数如果你对接的是旧版本文档回调签名可能对不上以实际包的接口为准。5.3 级联模式主从 SDK 的配置与注册级联模式用于局域网内多个 SDK 实例共享一份行情主 SDK 连行情服务器从 SDK 连主 SDK。开启分两步先建tool.iniPython 版本放在程序文件同级目录# 主 SDK 的 tool.ini mastertrue socket_port9999# 从 SDK 的 tool.ini masterfalse socket_port9998socket_port后必须带换行符否则配置读取失败这是文档里专门提醒的细节。主从在同一台机器上时端口必须不同。然后从 SDK 在登录前注册主 SDK 地址tds.register_addr(master, 192.168.1.10, 9999) tds.login(your_account, your_password)register_addr是级联模式下从 SDK 专用主 SDK 不用调必须在主 SDK 登录成功后从 SDK 才能连而且它位于登录前顺序错了连不上。从 SDK 的账号密码要和主 SDK 保持一致。5.4 离线调试没有行情也能把流程跑通V2.1.0 加的离线调试对开发阶段特别有用没有实时行情时读本地 CSV 驱动回调tds.start_offline_debug( pathD:\\datafeed, subtype[stock, index, order, queue, trans, superstock], push_space3000, # 推送间隔毫秒 push_count5000, # 单次推送条数 playback_times1 # 遍历次数 ) tds.login(test1, 123456) # 不连线上网关直接返回成功数据文件命名必须是stock.csv、index.csv、order.csv、queue.csv、trans.csv、superstock.csv、codelist.ini之一SDK 靠文件名判断数据类型命名不规范直接不读。这个函数要在实例创建之后、登录之前调用已经登录了再调不生效。级联模式下只有父节点支持离线调试子节点调了无效。6. 避坑与排查这几条都是实打实踩出来的6.1 导入报 ModuleNotFoundError现象import datafeed报找不到模块。原因pip 装到了另一个 Python 环境或者装的是 32 位包。解决用which python和which pip确认指向同一解释器python -c import platform; print(platform.architecture())确认 64 位不匹配就卸载重装对应版本。6.2 登录返回 -1018现象账号密码确认无误登录返回 -1018。原因客户端版本低于服务端要求V2.1.3 起专门用这个码提示版本过低。解决换最新版安装包重装别在旧包上改配置。6.3 断线重连后行情静默现象网络抖动后 SDK 重连成功但回调不再触发。原因没设m_connectsubscribe1重连后订阅没重发。解决set_env里显式设m_connectsubscribe1或者用async_sub配合订阅回调自己重发。6.4 回调里做耗时操作导致堵包现象行情延迟越来越大stats里recv_time和produce_time差距持续拉大。原因回调函数里做了数据库写入、复杂计算等耗时操作SDK 推送被阻塞。解决回调里只做入队把处理逻辑放到独立线程或进程回调保持轻量。6.5 级联从节点连不上主节点现象从 SDKregister_addr后登录失败。原因主 SDK 没先登录成功、端口配错、tool.ini的socket_port后缺换行符或者主从不在同一局域网。解决按顺序确认主 SDK 已登录、端口一致、ini 文件末尾有换行、网络同网段。7. 装完怎么验证跑通用离线回放做一次端到端自检装完 SDK、配好回调最怕的是「以为通了其实没通」。我的习惯是不管多急都先用离线调试做一次端到端自检因为它不依赖实时行情和网络能把「实例创建 → set_env → 回调注册 → 数据推送 → 回调触发」整条链路走一遍。准备一个最小数据集stock.csv放几行证券快照表头按文档字段来market、code、new_price、bidorder_price这些列名别写错顺序不限但名字要对。然后跑下面这段from datafeed.tds_api import TDS received [] def callback_stock(data_list, count, stats): # 只记录不做耗时处理 received.append(count) print(count:, count, first code:, data_list[0].get(code)) tds TDS() tds.set_env(fnctickstockcallback_stock) tds.start_offline_debug( path/data/offline, subtype[stock], push_space1000, push_count100, playback_times1 ) ret tds.login(test1, 123456) print(login ret:, ret)判断标准有三条login ret为 0callback_stock被触发且count大于 0data_list里能取到code字段。三条都满足说明安装、回调注册、数据解析这条主链路是通的再切到实时行情只需要换掉start_offline_debug和账号。如果回调没触发先查 CSV 文件名是不是stock.csv、表头字段名是否和文档一致、subtype里有没有写stock如果login ret非 0回到第 4 章对返回码。实时环境下的验证再加一步订阅一个你熟悉的代码比如tds.sub(stock, USHA, [600000])观察回调里stats的recv_time减produce_time正常应该在毫秒级如果持续在几百毫秒以上多半是回调堵包或带宽不够。我一般会把这个延迟值打到日志里跑一天看分布比单次观察靠谱。从那以后我每次部署这套 SDK都强制先跑一遍离线回放再连实时哪怕对接方催得再急也不跳过——有一次省了这一步上线后发现回调签名和文档对不上白白多排查两个小时。希望这套流程能帮到你少走几个我踩过的坑。本文还有配套的精品资源点击获取