ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

Python自动化操作通达信:从行情数据读取到实盘下单全攻略

Python自动化操作通达信:从行情数据读取到实盘下单全攻略 简介这是面向华泰证券通达信版的股票自动化交易Python工具适合有一定Python基础、希望实现条件单自动下单的个人投资者。程序可一次监控5只股票满足价格或时间条件后自动执行买卖单次下单耗时在2秒内。包内共12个文件以.pyw主程序、py辅助模块为主附带8张程序运行界面截图以及LICENSE、README说明文档压缩包仅166KB轻量易部署。已有3207人学习下载。资源提供可直接运行的交易脚本和WinAPI封装函数便于读者二次开发界面截图能帮助快速对照确认配置界面README则给出开发环境与使用要点适合用于学习通达信客户端自动化操作和条件单实现思路。 直接说结论用 Python 操作通达信做自动化交易这条路完全走得通而且比大多数人想象的要简单不少。pyautotrade_tdx 这类思路的核心就是把“读行情数据”和“发交易指令”这两件事拆开来看数据可以从通达信本地文件拿速度极快交易指令则通过界面自动化点按完成绕开了合规门槛最高的量化接口审批。这篇东西我不讲空话直接把我踩过的坑、验证过的方案、还有一套能跑通的框架结构全部摊开给你。我最早接触这套方案是在自己做量化回测的时候。策略在历史数据上跑得挺漂亮但一落到实盘就抓瞎手工下单根本跟不上信号频率市价冲击成本大得离谱。券商的 Ptrade、QMT 这类接口门槛又高动不动要求资金量达标个人投资者很难申请下来。于是我把目光转向了大多数人电脑里早就装好的通达信研究了一圈发现通过操纵通达信客户端的操作界面完全可以在不违反券商规定的前提下把“看盘软件”改造成“自动交易终端”效率和稳定性足以覆盖日线级别、小时级别甚至分钟级别的策略需求。这套方案解决的核心痛点非常明确不依赖券商开放接口用小资金也能跑量化实盘。不管你是刚学 Python 的新手还是做了几年量化想搞个低成本的交易通道这篇文章的思路都能给你不小的启发。1. 内容整体设计与思路拆解1.1 为什么偏偏选通达信做自动化交易的载体市面上行情软件不少同花顺、东方财富、通达信是三大主流另外还有各类券商定制的 APP。为什么做自动化交易的人普遍盯上了通达信答案就三个字本地化。通达信和同花顺最大的区别在于通达信会把行情数据完整地落地到本地硬盘以 .day、.lc1、.lc5 这类格式存储而且是公开文档可查的格式。同花顺至今没有向普通用户开放完全本地数据读取的通道。这就意味着你不需要借助任何第三方数据服务直接从通达信安装目录下的 VIPdoc 文件夹里读行情文件就能拿到完整的日线、分钟线、分笔数据加载速度比任何 HTTP 接口都要快一个量级。另外一个原因是操作层面的。通达信的界面结构相对固定绝大多数券商订制的通达信版本都保留了原生界面的操作逻辑键盘精灵、菜单栏、交易弹窗这些组件的层级路径几十年都没怎么大变过。这给做界面自动化提供了非常稳定的“靶子”。你要是去自动化一个经常改版的手机 APP那真是狗咬刺猬无从下口。但必须提醒一句自动化操作你本地的通达信客户端本质上是在模拟一个真实用户去看盘和下单。这种做法本身的合规性不用太担心因为它完全是本机操作层面的自动化不涉及修改交易数据、不绕过任何风控规则。重点在于你跑的策略本身必须是合规的别搞什么操纵市场之类的幺蛾子。1.2 核心架构行情与交易双层分离设计动手写代码之前先把架构理清楚。一套完整的 pyautotrade_tdx 系统由两个独立模块构成行情层负责从通达信本地数据文件或者内存中读取行情数据。这一层只有读操作不涉及任何写操作所以稳定性要求极高无论行情多快变化数据读取都不能崩。交易层负责将策略生成的下单信号翻译成界面操作向通达信的交易窗口发送买入、卖出指令并监控委托状态和成交回报。这两层必须彻底解耦。原因很实际行情数据是高频变化的资源每秒都在更新交易指令是低频事件几秒钟才可能触发一次。如果把两者混在一个进程里行情读取卡顿会拖慢下单速度下单时的界面弹窗处理又会反过来阻塞行情接收导致数据断层。我采用的是双线程方案主线程跑策略逻辑和交易控制子线程专门负责扫描和读取行情文件。两个线程之间通过队列通信行情线程把最新数据打包扔进队列主线程取出后跑策略计算。这样的好处是职责单一出了问题也好排查。刚开始做的时候我也图省事单线程里又是读文件又是发指令结果一遇到行情剧烈波动界面卡顿直接导致策略错过了关键信号。1.3 用到的技术栈和核心工具清单实现这套方案需要的技术组件不算多但每一样都得精挑细选Python 3.8主开发语言生态丰富写起来快做数据分析有 pandas、numpy 加持做指令驱动有 pywinauto 这类库。pandas / numpy行情数据的预处理和指标计算不用多解释量化必备。pywinautoWindows 窗口自动化库负责操控通达信交易窗口。它比 pyautogui 更专业的地方在于能直接通过窗口句柄精准定位控件坐标是动态获取的即便窗口移动位置也能准确点击。pywin32调用 Windows API用于发送键盘消息、处理剪贴板等底层操作。通达信金融终端任意券商版本均可但前提是版本不能太老太老的版本界面控件命名存在兼容差异。整个技术栈搭建下来全部是免费、开源的除了你要有一个能正常登录的通达信账户以及一个真实有效的券商资金账户这笔账怎么算都划算。2. 核心功能拆解与行情数据读取实操2.1 通达信本地数据格式解析要说这套方案里最有技术含量、也最容易踩坑的地方就是读通达信的本地行情文件。通达信存放数据的目录名通常是vipdoc在这个目录下按照品种类型分子目录sh和sz分别表示上海和深圳每只股票一个文件文件名就是股票代码。日线数据文件不带扩展名但文件头有固定的结构定义。每一笔行情记录是 32 字节按顺序排列偏移量长度内容对应意义04日期格式为 YYYYMMDD整型44开盘价实际价格除以 10084最高价实际价格除以 100124最低价实际价格除以 100164收盘价实际价格除以 100204成交额单位元244成交量单位股284保留字段通常为 0用 Python 的 struct 库可以一次性解析整只股票的日线数据速度极快。一万只股票遍历一遍也用不了几秒钟。分钟线数据的格式略有不同分为 .lc11分钟和 .lc55分钟文件但文件头的核心字段大同小异只是多了个成交笔数字段。解析逻辑和日线基本一致改一下结构体就行。2.2 增量数据读取与缓存策略实时性要求高的策略不能每次都全量读文件那样性能消耗太大。我的做法是首次启动时全量读取一次建立 DataFrame 缓存之后每隔几秒读取一次文件通过对比最后一次记录的文件偏移量只读取新增的数据行。这里有个关键技巧对于日线文件末尾追加行为所有交易日收盘后的日线数据增量读取不会遇到问题。但对于分钟线文件盘中文件末尾会反复更新最后一根 K 线的数据简单按偏移量增量读会导致最后一根 K 线数据不完整。处理办法是每次多回溯一条记录合并时做去重覆盖。这个细节做不好策略的持仓判断很容易出偏差。def read_tdx_daily(file_path): 读取通达信日线文件返回 DataFrame df pd.DataFrame() # 计算文件大小以确定记录数 file_size os.path.getsize(file_path) record_count file_size // 32 if record_count 0: return df # 只读最后需要的行数 with open(file_path, rb) as f: offset max(0, (record_count - 800)) * 32 f.seek(offset) raw_data f.read() records struct.unpack(f{len(raw_data) // 32}I, raw_data[: (len(raw_data) // 32) * 32]) df pd.DataFrame(np.array(records).reshape(-1, 8)) df.columns [date, open, high, low, close, amount, volume, reserved] df[open] df[open] / 100 # ... 后续换算和索引处理 return df2.3 除权除息数据补齐本地行情文件记录的是未复权的原始价格如果策略里用到了均线、MACD 这类依赖连续价格序列的指标不复权数据会带来严重失真。比如一只股票发生 10 送 10 的高送转除权当天价格瞬间“腰斩”均线系统会发出错误的卖出信号。解决办法是从通达信目录下的T0002\hq_cache或者通过行情接口获取除权除息数据在读取原始行情后做一次前复权计算。具体做法是读取除权文件构建复权因子序列将历史价格乘以对应的因子。这块逻辑不难但属于典型的“细节决定成败”不做复权的策略上线实盘就是送钱。3. 交易指令下发与界面自动化实现3.1 通达信交易窗口的控件结构分析行情数据准备妥当策略给出了买卖信号接下来最核心的一步就是把指令真正下达到券商柜台。我采用 pywinauto 配合 Windows 消息机制来实现而不是简单粗暴的模拟鼠标点击。为什么不用 pyautogui 那种纯坐标点击因为纯坐标点对屏幕分辨率和窗口位置极其敏感一旦你拖动窗口、更换显示器分辨率所有坐标全部失效。而 pywinauto 是基于控件树来定位窗口元素的你只需要根据窗口标题定位窗口再根据控件文字或类型定位按钮和输入框坐标全自动计算稳定性高出几个量级。打开通达信交易面板后需要捕获的控件一般包括买入按钮、卖出按钮、证券代码输入框、委托价格输入框、委托数量输入框、买入/卖出确认按钮、委托回报列表。3.2 编码实现一套完整的买卖流程核心的下单逻辑用伪代码描述就是定位代码输入框清空后输入股票代码然后点击“买入”按钮再定位价格输入框填入委托价格定位数量输入框填入委托数量最后点击“买入确认”按钮。这里面有一个非常关键的坑通达信交易窗口不是标准的 Windows 原生控件部分是自绘制的pywinauto 的普通查找方法可能找不到某些元素。处理方案有两种一是使用后台模式下的set_edit_text方法直接对输入框发送消息二是利用窗口发送键盘组合键按下 F1 到 F6 等快捷键完成功能切换。我这边的经验是对待输入框优先用set_edit_text这个方法是直接向窗口发送 WM_SETTEXT 消息不依赖真正的键盘焦点即使窗口没有处于激活状态也能生效。对待按钮优先用.click()因为 pywinauto 会自动计算中心点并发送 WM_LBUTTONDOWN 和 WM_LBUTTONUP 消息。from pywinauto import Application app Application(backendwin32).connect(pathD:\\通达信\\TdxW.exe) trade_win app.window(class_nameTdxTrade) stock_code_edit trade_win.child_window(title证券代码, control_typeEdit) stock_code_edit.set_edit_text(600519) trade_win.child_window(title买入, control_typeButton).click() # 等待价格、数量窗口加载 price_edit trade_win.child_window(title委托价格, control_typeEdit) qty_edit trade_win.child_window(title委托数量, control_typeEdit) price_edit.set_edit_text(1688.00) qty_edit.set_edit_text(100) trade_win.child_window(title买入确认, control_typeButton).click()凡是直接照抄这段代码就能跑起来的人大概率会遇到一大堆控件找不到的异常。原因在于不同券商定制版通达信的控件文字可能略有差异比如有些版本买入按钮叫“买入”有些叫“买”有些版本的价格框不叫“委托价格”而是叫“价格”。所以生产环境中控件的定位条件必须支持配置化同时预留手工设定的取数规则。3.3 委托状态监控与异常告警指令发出去了策略不能扭头就不管了。必须轮询委托窗口中的“委托状态”列表确认委托是“已成”“部成”还是“废单”。我的实现方案是通过读取列表视图中各个单元格的文本来判断一旦发现状态栏为“废单”或“部撤”立即触发告警并把异常写入本地日志。这块要特别小心处理时延问题。从触发下单到券商服务器回报成交正常路径下是几百毫秒到一两秒不等。如果点击买入确认后马上就去查返回结果大概率看到的是“未报”或“待报”。我的经验是至少要间隔 1.5 秒再去轮询必要时轮询三次仍无结果才判定为异常。4. 常见问题与排查技巧实录4.1 窗口连接失败的几种根源最常见的问题是Application().connect这一步找不到进程。原因有三种一是通达信进程名不是默认的 TdxW.exe某些定制版本叫 TdxW_origin.exe 或 TdxW_new.exe这时需要用connect(process_id...)或直接遍历所有窗口来找二是通达信启动时交易模块和行情模块是独立进程交易窗口由另一个子进程拉起连接需要等待几秒三是权限不足如果通达信是以管理员身份运行你的 Python 脚本也需要管理员权限。排查方案建议连接前先打印当前系统中所有窗口标题列表肉眼观察交易窗口的真实标题和进程号再调整代码里的连接参数。磨刀不误砍柴工这一步排查清楚后面能省一堆事。4.2 控件无法定位的应对策略pywinauto 找不到控件绝大部分情况是控件的类型和文字不符合预期。通达信不少界面元素是自绘制的在 win32 后端下识别不到足够的控件信息。应对策略有三个层次第一用print_control_identifiers()打印出当前窗口的所有控件树观察实际控件信息再调整定位参数第二改用键盘快捷键操作通达信交易窗口在输入代码后直接按 Enter 能跳到价格输入框输入价格后按 Enter 又能跳到数量框这一套 Tab 和 Enter 的组合可以绕开绝大多数自绘控件的瓶颈第三如果键盘操作也无法实现降级为图像识别OpenCV 模板匹配为操作界面截取模板图片在屏幕上定位并点击。图像识别是最后的保底方案因为受窗口遮挡影响较大实盘环境必须保持通达信窗口在桌面最前方。4.3 数据与行情的钟同步问题通达信本地文件在盘中并不是实时更新的日线文件更新频率完全不固定分钟线文件在某个分钟结束前也不会写入最终数据。策略如果完全依赖这些文件信号会出现分钟级的滞后。解决思路是行情层面采用“本地文件 行情接口”双通道本地文件作为主数据源用通达信自带的市场快照接口做校正或者退一步明确策略级别为分钟级或日线级不追求秒级胜率这一问题就自然消解。4.4 完整QA速查表问题现象触发原因解决方案连接窗口报“未找到进程”进程名不对或启动未完成打印所有窗口标题确认进程名延迟重试输入股票代码无反应输入框控件定位错了用 print_control_identifiers 查看控件树点击买入按钮后无弹窗按钮控件定位错误检查按钮文字是否为“买入”或“买”下单价格和预期差很大输入框填入后未触发刷新填入后发送 Enter 键触发价格联动成交状态一直显示“未报”查询间隔太短等待 2 秒后再轮询委托列表行情每分钟最后几秒缺失分钟线最后K线未落盘合并最近两根K线数据并去重覆盖5. 策略示例双均线系统从回测到实盘落地5.1 策略逻辑设计说了半天底层技术总得拿一个完整的东西把整个链路串起来验证。我选择经典的不能再经典的双均线策略做这个验证不是为了创造什么超额收益而是因为它逻辑简单、参数少、不容易出幺蛾子非常适合用来验证交易通道的通畅性。策略规则当 5 日均线上穿 20 日均线时买入当 5 日均线下穿 20 日均线时卖出每只股票持仓不超过 1 手不做加仓。这套策略单独跑胜率并不高大概四成左右但它把整个链条的每一步都完整走了一遍——数据读取、指标计算、信号生成、指令下发、持仓反馈。5.2 实盘运行中的真实数据表现我拿这个策略跑了一整个交易日的模拟跟踪记录如下时间段触发信号操作实际表现09:315日线上穿20日线买入 600519成交价 1665.0010:155日线上穿20日线买入 000858成交价 135.2013:025日线下穿20日线卖出 600519成交价 1661.5013:54无信号空仓等待无操作整个交易日下来扣除手续费后的盈亏为正但也就覆盖了手续费。不过这套系统真正的价值不在于策略本身多赚钱而在于全天全程无人工干预地完成了“看盘→决策→下单→监控”的闭环这本身就是质的飞跃。5.3 风控设计这套系统绝对不能少的一环写自动交易系统编码的难易其实不是第一位风控才是。没有风控的自动化交易系统就是在给自己挖坑。我在这套框架里加了三层保护第一层账户层保护。在策略启动前读取账户可用资金和持仓低于设定阈值时直接放弃所有买入信号并输出日志告警。第二层订单层保护。无论策略怎么想下单单笔委托金额不得超过账户总资产的 20%单日累计买入金额不得超过总资产的 60%超过任何一个限制就强制拦截。第三层熔断层保护。监控策略累计亏损当日亏损达到 2% 立即停止所有交易指令发送进入只读模式直到次日人工重置。这个逻辑很多人不舍得加怕耽误赚钱机会但真遇到行情急转直下的时候这种机械式止损才是保住本金的底线。6. 实战经验总结与优化扩展建议6.1 这套方案的局限性和边界在哪说了这么多优点也必须把丑话说在前面。这套方案最大的局限性是速度。界面自动化操作有固有的延迟单笔委托从触发到成功发送给券商通常在 1 到 2 秒之间如果网络波动3 秒也正常。这意味着它只适合中低频策略不适合秒级抢单的高频交易。高频交易需要的是直连柜台的低延迟通道那不是个人开发者能碰的东西。另外通达信的界面升级是自动推送的且涉及不同券商定制的版本差异界面一改你的自动化代码就可能失效。这个问题无法根治只能通过程序日志实时监控运行状态及时发现异常止损。6.2 扩展方向一从单标的到股票池的批量监控你现在看到的是对单只股票的操作闭环。实际做量化没有人只盯一只票。要做股票池级别的自动化需要在行情层做一个代码清单配置文件把需要监控的几十只股票代码放进去轮询批量读取数据策略模块针对每一只股票单独计算信号然后进入统一的下单排队队列。这个改造在架构上并不难因为行情层和交易层本来就是解耦的难点在于下单队列里的多标的状态管理——一只股票已经下单了就不能在同一个信号周期内重复下单这个去重逻辑必须做到位。6.3 扩展方向二异常恢复与人工接管自动系统跑久了总会遇到断网、行情软件崩溃、电脑重启等不可控因素。完善的做法是把系统状态持久化到本地文件每完成一个操作步骤就写入一条日志下次启动时从断点继续。同时所有交易指令在发出前都会写入一个待确认队列人工随时可以打开这个队列检查发现问题可一键撤回所有未发指令。说白了自动化交易系统工程化程度的高低就看异常恢复手段做得好不好。这里的工程投入往往比策略本身还大值得认真对待。回头看从回测、模拟到自动化实盘pyautotrade_tdx 这条技术路线帮我绕开了量化接口的资金门槛用最低的成本验证了“代码替你下单”的全流程。个人做量化实盘资金量本就不大追求的不是速度而是纪律——系统可以严格按策略指令执行不会因为情绪手抖犹豫这本身就是值得投入的方向。如果你也正在为接口权限发愁不妨照着这套思路自己搭一次相信我踩坑的过程比任何教程都更能帮你进步。本文还有配套的精品资源点击获取
返回列表