
做个自动化交易机器人听起来是个大工程但如果你的下单入口是Python EasyTrader 同花顺那第一个能用的版本完全可能在5分钟内跑起来。这个“5分钟”指的是把最基本的连接、查询、下单这条路走通不包括你之后为了适配客户端版本折腾掉的两小时但至少方向对了后面所有的坑都是可以逐个填平的。我最早是被手动下单搞烦的。盯盘时手里正开着会、回着消息价格到了预设位置手一点慢单子就滑出去了有时候是涨到目标价舍不得卖等回撤了又拍大腿。说实话我的执行纪律并不可靠所以我决定让程序来执行——不是让它替我思考买卖逻辑而是把我已经定好的规则变成自动动作。这篇文章就记录我怎么做通这件事涉及环境准备、核心代码、实跑会遇到的坑以及我后来补上的工程化改造。适合有基础Python语法知识、想把手动操作自动化的朋友如果你完全零基础建议先跑一遍Python入门教程再回来不然遇到环境问题会有点挫败。先说清楚一点这里说的“同花顺编程”和你在网上看到的“同花顺公式系统”“资金博弈指标源码”完全是两回事。公式系统是在同花顺内置环境里写指标而本文是用Python在外部操控同花顺客户端去下单逻辑层级完全不同别混淆。1. 为什么我用EasyTrader同花顺做第一版机器人1.1 手动交易真正的成本手动下单看起来只是“点几下鼠标”实际成本远不止时间。盘中打开交易软件输入代码、看现价、填价格、填数量、点买入再确认一次弹窗顺利的话十秒钟但这十秒钟恰恰是最容易出问题的价格触发时你正在其他软件里切不过来手一抖把100股填成1000股看着分时图犹豫三秒价格已经飘走。这些其实都能用提前挂单解决一部分但挂单只能挂固定价没法做条件单、没法做网格、没法在你临时要开会时继续按纪律执行。自动化机器人的第一价值不是“快”而是“不带情绪、不犯低级错误、能盯住你盯不住的盘”。1.2 为什么不直接接券商API或者上量化平台很多人的第一反应是既然要自动化为什么不直接找券商开量化接口这个想法没错但现实阻力不小。券商量化接口通常有资金门槛、开户时长要求、策略审核流程个人小资金用户很难快速获批第三方量化平台也类似策略部署、数据许可以及订阅费用都是成本。我只想把自己的几个固定规则跑起来为了这个去走一套企业级流程太重了。EasyTrader这类方案的本质是“操控现有客户端”你已经有同花顺有券商的网上交易功能程序做的只是代替你操作那些按钮、输入框和确认键。它没有黑进交易所也没有破解什么协议就像是给软件请了一个不知疲倦的“隐形操作员”。好处是门槛低、实现快、账户逻辑和券商通道完全由官方客户端兜底代价是它依赖界面元素的稳定客户端一升级可能就识别失效这是后面最大的维护成本。1.3 EasyTrader的价值和局限EasyTrader是GitHub上的开源Python库它封装了同花顺客户端、部分券商客户端的底层自动化操作屏蔽了窗口句柄查找、控件点击、输入框定位这些枯燥细节对外暴露的是一套接近交易语义的API比如查询资金、查询持仓、买入、卖出、撤单。我第一次看到它的README时第一反应是“这么简单”但实际跑起来之后才发现简单的是API不简单的是环境匹配。做个表格对比一下市面上几条技术路径方便你判断自己的场景方案接入门槛资金成本稳定性适合场景券商官方量化API高需开户审核、资历门槛通常免费但条件严高中高频、策略复杂、资金量较大第三方量化平台中需注册认证订阅或数据费用高想专注策略研究不想管运维EasyTrader操控同花顺低会Python就行免费中依赖客户端升级个人低频自动化、学习验证、小资金所以这个方案的定位很明确低门槛、能落地的个人交易自动化工具而不是机构级交易系统。别指望用它去做毫秒级高频交易那个场景下客户端UI自动化本身就不可行。2. 环境准备Python、同花顺、依赖这三件套2.1 Python版本和操作系统的选择EasyTrader依赖pywinauto、pywin32这类Windows下的GUI自动化库所以强烈建议在Windows环境跑我在Linux下用Wine试过窗口句柄识别和控件映射一团糟纯属给自己找麻烦。Python版本我建议用3.8或3.9这个库本身维护节奏不快太新的Python版本容易出现依赖编译问题。如果习惯用VSCode配置好Python环境之后记得用虚拟环境隔离项目不要一股脑装进全局。我个人的习惯是conda create -n trader python3.9 -y conda activate trader pip install easytrader pywinauto pywin32 pandas这里有个特别容易踩的坑PyPI上的easytrader版本可能很老甚至不兼容你现在下载的同花顺客户端。如果pip安装后import正常但connect失败去GitHub把最新源码clone下来用pip install -e .装到本地或者直接看仓库里最新的示例代码。我用的是社区维护的一个修复分支不同发行版的API细节有差异下面的代码示例是基于常见用法实际操作时以你clone到的仓库README为准。2.2 同花顺客户端怎么准备不要直接双击图标就完事有几个地方要提前处理登录方式建议先手动打开同花顺客户端把交易账户登录一遍确认能正常看到资金和持仓。同时把“保存账号密码”和“自动登录”选项看情况打开。自动登录确实方便程序启动但也会降低一点账户安全性需要在便利和安全之间做取舍。关闭弹窗客户端经常有“系统升级”“资讯推荐”“风险评估”这类弹出窗口如果不提前关掉程序操作时主窗口后面突然跳出一个弹窗可能把焦点抢走导致后续点击全部错位。在设置里尽量关掉消息推送、自动更新提醒。固定安装路径自动化程序需要定位客户端进程和窗口安装路径不要有中文和空格最好虽然技术上能处理但没必要给自己加难度。验证码和动态口令新版同花顺经常有短信验证码或者动态口令登录这类安全机制不要试图去绕过。不要找什么“自动输入验证码”的歪门邪道——安全验证存在是有原因的。正确做法是程序不负责登录而是你先手动登录好客户端再让脚本附加已登录的窗口。2.3 一个常被忽视的环节先验证窗口识别环境准备阶段别急着写业务逻辑先跑一个最简单的测试脚本确认EasyTrader能不能看到你的同花顺窗口import easytrader user easytrader.use(ths) # 方式A连接已经打开并登录好的客户端窗口 user.connect() print(user.balance)如果连接成功并能打印出账户资金信息恭喜最难的环境问题已经过了一半。如果报错说找不到窗口先确认客户端是否已经登录到交易界面再确认你没有同时开着多窗口——我见过有人开了主窗口和迷你窗口程序连到了错误的那一个结果所有操作都作用在看不见的窗口上特别诡异。3. 写一个能跑起来的最小交易脚本3.1 连接客户端两种方式都有前提条件连接这块EasyTrader常见用法有几种形式。一种是指定客户端的可执行文件路径让库自己启动程序另一种是附加到已经打开的客户端上。我强烈建议用“附加已登录窗口”这种方式因为登录流程交给人工处理最稳验证码、动态口令、滑块这些问题全部绕开了。我自己用的连接模式大致是这样import easytrader user easytrader.use(ths) user.connect()如果是需要指定路径的版本大概是user.connect(rC:\同花顺软件\xiadan.exe)不同分支写法有差异我这里不把话说死但整体的流程是先有客户端实例再连接然后查询账户。连接成功后不要急着下单先打印一下持仓和资金确认程序看到的账目和你手动看到的一致这一步能排除“连到了错误账户”这种低级但后果严重的问题。3.2 查询资金和持仓查询接口是检查自动化状态最常用的手段。运行成功后会得到类似结构的数据balance user.balance position user.position print(balance) # 资金、可用、冻结等 print(position) # 持仓列表代码、名称、股份、成本价等这里有一个非常重要的习惯每次下单前先查一次可用资金和持仓程序里要做校验。比如你想买1000股但可用资金只有一半直接下单会触发券商端报错或者导致部分成交处理起来特别麻烦。更安全的做法是下单前检查“可用资金 预计买入金额”不满足就跳过这一轮并记录日志。这不算复杂逻辑但能避免大量事故。3.3 买入、卖出、撤单的基本用法核心交易操作长这样# 买入证券代码、价格、数量股 user.buy(162411, price0.535, amount100) # 卖出 user.sell(162411, price0.550, amount100) # 查询当日委托拿到委托编号后用编号撤单 # user.cancel_entrust(委托编号)几个细节我吃过亏这里展开说价格是元单位不是分单位数量是股数不是手数。A股交易是100股起但场内基金有些是100份起具体以券商规则为准。买入价格填的是你愿意接受的委托价不是市价。如果直接填现价可能因为行情跳动导致委托失败所以在策略里要设定好“买一价”“卖一价”或者你自己算出来的目标价。撤单前一定要先查委托拿到正确的委托编号再去撤。程序不是人不会在界面上用眼睛找到那笔单再点击撤单一切都要靠数据交互。3.4 一个最小但完整的“机器人”骨架我把第一版机器人核心逻辑拆成三部分轮询、条件判断、下单护盾。轮询负责按固定间隔获取行情条件判断决定要不要下单下单护盾负责限制每日委托次数和金额上限防止程序处于异常循环时把自己账户搞穿。下面是一份示意代码注意行情获取部分我留了接口你需要根据自己可用的行情源来填充import time import easytrader user easytrader.use(ths) user.connect() TICK_INTERVAL 5 # 轮询间隔单位秒 MAX_ORDER_PER_DAY 3 # 每日最大委托次数 MAX_AMOUNT_PER_ORDER 5000 # 单笔最大金额就是一层保护 ordered_today 0 def get_price(code): # 这里用你能拿到的行情源数据 # 可以是免费行情接口、数据文件、甚至是同花顺界面OCR抓取 # 示意返回值真实场景需要替换 return 1.235 def main(): global ordered_today while ordered_today MAX_ORDER_PER_DAY: try: price get_price(162411) if price 1.200: amount 100 if price * amount MAX_AMOUNT_PER_ORDER: print(超过单笔金额上限跳过) else: user.buy(162411, price1.200, amountamount) ordered_today 1 print(f已委托第 {ordered_today} 笔) except Exception as e: # 异常要记录不能静默吞掉 print(f执行异常: {e}) time.sleep(TICK_INTERVAL) if __name__ __main__: main()这份代码很简单但它把最重要的几个原则体现出来了有轮询节奏、有策略条件、有防护上限、有异常打印。真实跑之前先把get_price换成可用行情源再在模拟环境跑几天不要直接上实盘。4. 实跑中真正会遇到的几个坑4.1 客户端窗口找不到程序卡在connect这个坑几乎每个人都会撞上。常见原因有三个客户端没打开到交易界面、打开了多个同花顺窗口、客户端窗口最小化到了系统托盘但主窗口被隐藏。排查链路我建议这样做先手动把客户端恢复到正常窗口状态再在脚本里打印一下当前窗口列表确认程序能看到哪个窗口如果还找不到检查客户端版本和EasyTrader分支是否兼容。我一度以为是代码问题折腾了半小时最后发现是客户端在托盘里窗口是隐藏的程序根本捕捉不到。4.2 验证码和二次验证不要试图自动化新版同花顺在交易登录时经常要求短信验证码或者动态口令这里我要说重点不要尝试自动识别验证码也不要尝试绕过二次验证。一方面这涉及账户安全问题另一方面这种对抗纯属无用功——券商的验证机制会不断升级你花时间写出来的识别逻辑过几天就失效。我的方案是让脚本只负责“登录之后”的操作登录这一步保留人工。等到下单的时候程序操作的是已经登录好的界面自然就不会碰到验证码问题。先登录再连接这个顺序不要打乱。4.3 客户端一升级控件识别全部失灵这是EasyTrader方案最大的长期成本。同花顺发布新版本后按钮的位置、大小、控件类型都可能变化程序找不到原来的控件下单就失败。我遇到过最典型的情况一次客户端自动更新后buy函数调用没有任何报错但委托并没有真的提交——程序以为是点了买入按钮实际那个按钮已经改名为别的控件名了。解决思路有三种回退客户端到旧版本等社区发布适配补丁定期手动检查控件树把变化映射更新到脚本里。没有一劳永逸的办法只能把它当作定期维护项写进自己的运维清单。4.4 下单确认弹窗和风险揭示弹窗很多券商端在委托后会弹确认框有些还会在首次交易时弹风险揭示。程序如果没识别到弹窗就去点下一个按钮整个操作序列就错乱了。我的处理办法是在客户端设置里关闭可关闭的二次确认对于不可关闭的风控弹窗只能让脚本增加弹窗检测逻辑先截屏识别弹窗再决定是否点击确认按钮。这一步没什么捷径得对着自己客户端的具体情况调试。4.5 重复下单比漏单更可怕脚本崩溃后重启或者网络超时导致程序以为上次下单失败于是重新下单这些场景都会产生重复委托。手动操作用眼睛能看出来程序可不知道。我的防护手段是记录“已提交委托”的日志文件每次下单前先检查这次要下的单是否已经提交过。更保险的做法是每天开盘前生成一个唯一标识的批次号同一批次同一标的同一价格只允许下一笔。4.6 长时间运行会越来越不稳定GUI自动化本质上是反复操作窗口控件窗口对象、内存句柄、临时文件都会慢慢累积。我跑过一个连续运行三天的脚本到第三天下单响应时间明显变长最后直接卡死。后来养成的习惯是每天收盘后自动重启脚本和客户端开盘前再做一次连通性自检。简单的定时计划任务就能搞定不需要引入太复杂的守护进程。5. 从“能跑的脚本”到“能用的机器人”5.1 日志是你唯一的现场记录脚本跑起来之后你不可能每时每刻盯着屏幕出问题时的排查完全靠日志。我第一版只用了print等真正出问题时悔得肠子都青了——程序崩了控制台也关了什么都查不到。后来把核心操作全部落日志文件至少记录这几类每次轮询的行情快照、每次下单的价格数量金额、委托编号、异常堆栈、每次连接和断开客户端的动作。日志不用复杂格式一行一条能追溯到时间、操作、结果就够了。5.2 参数别写死在代码里第一版脚本我把价格阈值写死在代码里每次想调整都要改源码再重启非常麻烦。后来抽出来一个配置文件用JSON存账户代码、策略阈值、买卖标的、单笔金额上限、每日次数上限程序启动时读一次。这个改动很小但收益巨大——你可以在收盘后修改配置第二天自动生效完全不用碰代码。5.3 行情数据源整个方案里最需要你自己解决的部分EasyTrader解决的是“下单”环节它不提供行情数据。你需要自己找一个可靠的数据源来判断“该不该下单”。这里有几个选择免费行情库的HTTP接口、券商App的推送数据、甚至从同花顺界面里截图识别价格。我的建议是优先用结构化接口别用截图OCR准确率虽然够但处理速度慢还不稳定。行情数据的延时也要有数作为低频策略几秒钟的延时问题不大但如果你想做稍微快一点的策略数据链路就要重新设计了。这一步不要贪快先解决“有数据”再考虑“数据准”。5.4 应急停止能力必须提前做无论你的策略逻辑多完美都要假设最坏情况发生程序在下单循环里疯狂提交委托、或者客户端连不上又重试。我的做法是程序启动时创建一个“停止标志”文件主循环每轮检查一次如果文件存在就暂停所有下单动作只记录日志不操作。这样遇到异常时我只需要在机器上生成一个文件就能让机器人“收手”比去改代码或者杀进程更安全。同时保留“手动撤单”的路径——程序出问题时你还能手动打开客户端一键全撤这个兜底比任何自动化都可靠。5.5 先回测再用模拟盘验证最后小资金实盘自动化交易中最大的风险不是代码写得烂而是策略本身不行。我见过太多人写了一个线上赚钱的策略就急着实盘结果亏到怀疑人生。现在开源的回测框架很多把你的策略逻辑先落地到历史数据上跑出一段时间的结果看最大回撤、胜率、盈亏比这些指标有统计意义了再说下一步。实盘也用最小仓位跑把它当成一次真实环境验收而不是一上来就来大的。6. 该做什么、不该做什么自动化交易的安全边界与心理准备聊完技术说说边界。EasyTrader这套方案适合什么适合个人低频自动化、适合学习量化交易流程、适合把你已经验证过的策略变成自动执行。不适合什么不适合高频抢单、不适合无人值守的全自动滚仓、不适合把它当成一台没有监督的“赚钱机器”——本质是GUI自动化性能和稳定性都够不着这些场景。使用层面有两条底线要守住。第一了解并遵守你的券商和第三方软件的服务条款不要做明显违反账户使用规则的事情。低频合理使用通常不会有什么问题但如果你的账户出现高频登录、频繁下单、异常操作等特征券商风控系统可能会关注到届时配合核实就好别去想办法对抗。第二验证码、动态口令这类安全机制不要尝试绕过那是保护你资金不受损失的最后一道防线。自动化是为了解放你的手不是为了让别人更容易盗走你的钱。投资风险上也要说透自动化不改变交易策略本身的质量垃圾策略自动执行只会亏得更快。机器人做的事情是替你执行纪律不是替你创造奇迹。我第一次让脚本自动下单时盯着客户端里的买单状态手心全是汗比手动下单紧张多了——因为你知道这一次点击不是自己控制的成不成交、什么价成交全部交给了系统和行情。那笔单子最终成交在预期价格但我从那次起意识到自动化交易真正难的不是写代码是敢不敢放手让程序执行以及事后能不能冷静地接受结果。如果你也想做我的建议是从最小成本开始先用模拟环境跑通流程再用最小金额验证实盘观察至少一两周确认它不会在关键时刻掉链子再逐渐加大投入。过程中始终保持手动干预的能力记住它只是一把升级过的工具使用工具的人仍然是你自己。