尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

用Python+uiautomator2驱动同花顺模拟炒股:量化策略自动下单实战

用Python+uiautomator2驱动同花顺模拟炒股:量化策略自动下单实战 简介面向希望用Python实现移动端自动交易的人群此资源提供了一个基于同花顺手机版模拟炒股环境的量化交易工具核心代码通过uiautomator2驱动Android界面并辅以图色方法识别元素从而在不易获取控件树的环境下也能稳定完成点击、滑动与输入操作有效降低自动化门槛。压缩包内容紧凑共9个文件涵盖Python源码、依赖清单、README说明、许可证及示例图片等既包含可运行的主程序也提供了便于二次开发的工程结构和环境配置指引整体大小仅1.33MB适合快速下载阅读。目前已有203人学习下载适合具有一定Python基础并想尝试量化策略自动执行的开发者。借助项目内的脚本与文档使用者可以完整了解模拟炒股环境下的策略自动下单流程并通过修改参数或扩展接口来调整选股与风控逻辑同时代码保留了对接真实交易系统的扩展点为后续接入券商API、实现模拟转实盘提供了可参考的起点。 做量化交易的人应该都懂那种感觉策略回测跑得再漂亮一说到“怎么真正下单”就卡住了。券商API要资金门槛、要写申请、还只开放给部分客户普通个人玩家根本摸不到门。这个项目标题一出来我就看明白了——直接用Python驱动同花顺手机版模拟炒股绕开官方接口借助uiautomator2做UI自动化再配合图色识别判断行情和买卖点把“策略信号到实际下单”这条最后一公里自己接上了。而且标题最后那句“可自行扩展到实盘”是关键说明这套框架的扩展性被刻意保留了下来。这篇我就把这个工具的完整设计思路、核心实现和我在实际折腾中踩过的坑全部拆开讲适合想做程序化交易但又被券商接口挡在门外的人参考。1. 项目整体设计与技术选型思路1.1 为什么偏偏选同花顺模拟炒股当落地载体先想清楚一个问题做量化交易最烦的不是写策略而是“执行层”。我在早期调研时列过三条路各有各的麻烦。第一条路是券商官方API比如华泰的MATIC、中泰的XTP、券商的Ptrade/QMT。这些接口功能强、速度快但开通条件普遍有资金门槛通常50万以上还要走营业部审核个人小资金玩家基本被挡在门外。第二条路是用easytrader这类开源库直接对接券商的客户端但它在较新版本券商App上经常失效维护成本也不低。第三条路就是这种“UI自动化模拟炒股”路线。同花顺手机版的模拟炒股板块是个优势极大的试验田行情数据是真实的交易撮合规则接近实盘初始模拟资金可以让你放心跑策略不用怕亏光。它本质上是个公开的Android应用任何人装个App就能注册使用不存在接口权限问题。拿它来验证策略的有效性、练手自动化下单流程真的是再合适不过。1.2 uiautomator2加图色识别这套组合拳怎么理解uiautomator2是Android平台上的UI自动化框架通过ADB和手机通信可以用Python获取当前界面的控件树、点击按钮、输入文本。它解决的是“我知道按钮在哪怎么点下去”的问题。但同花顺这类金融App有个很讨厌的地方K线图、分时图、价格涨跌颜色这类信息根本不在Android控件树里你拿不到它们的resourceId或者text因为人家是自绘的。这时候就需要第二招图色识别。思路很原始但有效——截屏然后用OpenCV做模板匹配或者直接做像素颜色判断识别出你关心的视觉信息。所以这套方案的组合逻辑是uiautomator2负责“操作”图色识别负责“感知”两者互补。纯用uiautomator2做不了视觉判断纯用图色识别又点不了按钮。1.3 这套方案解决什么问题适合谁来用一句话概括它把量化策略从“纸上谈兵”变成“真刀真枪在模拟盘上跑起来”。适合这几类人想入门程序化交易但够不着券商API的个人投资者做爬虫或自动化出身的Python工程师想快速验证一个交易想法以及想研究交易策略实盘可行性但不想承担真金白银风险的人。有几点要提前说清楚。这个方案是低频交易路线适合日线、分钟级别的策略不适合做高频。UI自动化的操作延迟动辄几百毫秒甚至几秒这是物理限制。另外它更适合用作策略验证和流程演练如果在实盘中使用必须做好异常处理。2. 动手前的环境准备2.1 硬件和依赖清单跑这套工具你不需要什么高性能服务器但手机或模拟器是必须的。我实测下来一台闲置的Android手机比模拟器更稳定因为模拟器在ADB连接、控件渲染上偶尔会有兼容问题。系统版本建议Android 8以上太低的话uiautomator2的兼容性会受影响。电脑端需要装好Python 3.8以上版本然后安装核心依赖pip install uiautomator2 opencv-python pandas同花顺App直接用应用商店下载安装注册登录后在首页找到“模拟炒股”入口开一个模拟账户。这一步别跳因为工具运行的前提就是你已经有一个可用的模拟账户。2.2 设备连接与最小可用验证手机开启开发者模式打开USB调试用数据线连接电脑。在终端执行adb devices确认设备被识别。然后安装uiautomator2的配套服务python -m uiautomator2 init这个命令会在手机上安装ATX Agent应用它是uiautomator2运行时的服务端。接下来写一段最简代码验证链路是否通畅import uiautomator2 as u2 d u2.connect() # 连接USB调试中的设备 print(d.app_current()) d.app_start(com.hexin.plat.android) # 同花顺包名如果能看到同花顺的包名输出并且手机自动打开了App说明基础链路已经打通。到这里你的“量化交易工具”地基算打好了。3. 核心实操用uiautomator2驱动同花顺下单3.1 学会元素定位先啃下同花顺的控件树uiautomator2的精髓在于元素定位。同花顺的Android端虽然有很多自绘控件但像“买入”“卖出”“持仓”这些核心功能按钮走的还是原生控件路线可以拿到ID或者文本。最常用的两种定位方式# 按resourceId定位 d(resourceIdcom.hexin.plat.android:id/trade_buy).click() # 按文本定位 d(text买入).click()实际使用中同花顺的resourceId经常因为版本更新而变化反倒是text定位稳定性更好。不过text定位有个问题如果页面上有多个“买入”文本比如买入按钮、买入标签它会默认匹配第一个。这时候可以加个instance参数指定第几个或者结合父控件层级缩小范围。我建议你在跑脚本时先用这个命令把当前的控件布局导出来看d.dump_hierarchy()把它保存成XML用文本编辑器打开就能看到同花顺当前页面到底有哪些控件、哪些带ID、哪些只有文本。这是排查“定位不到元素”这类问题最直接的手段。3.2 一次完整买入下单的代码拆解我来还原一次完整的模拟买入操作流程打开个股页面、点击买入、输入价格和数量、点击买入按钮、处理确认弹窗。import time import uiautomator2 as u2 d u2.connect() d.app_start(com.hexin.plat.android) time.sleep(3) # 1. 假设已经进入个股页面点击“买入”按钮 d(text买入).click() time.sleep(1) # 2. 输入股票代码这里以平安银行为例000001 # 同花顺的输入框内部结构各不相同有的需要先点击再输入 d(resourceIdcom.hexin.plat.android:id/stock_code).clear_text() d(resourceIdcom.hexin.plat.android:id/stock_code).set_text(000001) time.sleep(0.5) # 3. 输入买入价格价格默认带出当前价一般不用自己填 d(resourceIdcom.hexin.plat.android:id/trade_price).clear_text() d(resourceIdcom.hexin.plat.android:id/trade_price).set_text(10.50) # 4. 输入买入数量 d(resourceIdcom.hexin.plat.android:id/trade_num).clear_text() d(resourceIdcom.hexin.plat.android:id/trade_num).set_text(100) time.sleep(0.5) # 5. 点击“买入”按钮 d(text买入).click() time.sleep(1) # 6. 处理确认弹窗一般会有“确认买入”或“确定”按钮 if d(text确认).exists: d(text确认).click() print(下单指令已发送)这段代码看着简单但在实际跑的时候有几个细节会让你头疼。第一clear_text()在同花顺部分输入框上不生效因为它是自定义数字键盘不是系统输入法。这种情况还得靠另一种方式先点击输入框唤醒数字键盘然后用d.send_keys()模拟按键。第二按钮的“买入”和页签的“买入”会冲突我习惯在初始化时先打印当前控件树确认当前页面上到底有几个“买入”再做精确点击。3.3 图色识别从截图到买卖信号uiautomator2能拿到控件信息但拿不到K线、分时图、涨跌颜色这些视觉数据。这里轮到图色识别登场。核心思路就三步截屏、匹配、判断。最常用的场景是识别当前股价的红绿颜色。A股市场红涨绿跌同花顺个股页面的现价数字颜色直接用像素点判断就行import cv2 import numpy as np # 截图 d.screenshot(screen.png) img cv2.imread(screen.png) # 取现价数字区域的BGR平均值判断颜色 # 区域坐标需要根据你的手机分辨率提前标定 crop img[650:690, 320:520] avg_color crop.mean(axis(0, 1)) # [B, G, R] b, g, r avg_color if r 150 and g 100 and b 100: print(当前为红色股价上涨) elif b 150 and g 100 and r 100: print(当前为蓝色股价下跌)这块区域坐标怎么标定用Windows自带画图打开截图鼠标移到价格数字处看左下角的坐标值就行。但要注意不同分辨率手机坐标完全不同。所以我后来做了个改进——先用模板匹配定位到“现价”标签附近的区域再在那个区域内取像素颜色这样换手机也能自适应。模板匹配的代码也不复杂import cv2 screen cv2.imread(screen.png) template cv2.imread(template_price_label.png) # 提前截取“现价”二字做模板 res cv2.matchTemplate(screen, template, cv2.TM_CCOEFF_NORMED) min_val, max_val, min_loc, max_loc cv2.minMaxLoc(res) if max_val 0.8: print(找到现价标签位置, max_loc)这里阈值0.8是经验值。设高了容易漏匹配设低了容易误匹配。实际使用中我建议先打印一下max_val的实际分布再确定一个合适的阈值。图色识别这玩意说白了就是不断调参调出来的一次到位不太现实。4. 把量化策略真正接进来4.1 行情数据从哪里来量化策略的前提是有行情数据。在这个工具里行情有两个来源。一是直接从同花顺界面上读取用uiautomator2拿文本控件然后用正则把数字提取出来。二是自己对接免费的HTTP行情接口比如新浪、腾讯的公开行情接口代码简单还有实时价格。我的做法是两条腿走路用免费HTTP接口获取行情数据用来计算指标用同花顺的UI读取用来确认当前界面状态避免两个数据源打架。这里不展开讲接口细节但建议你在做的时候把获取行情封装成一个独立函数比如get_price(stock_code)后续无论是切数据源还是切交易标的都只要改这一个函数。4.2 我实测能跑通的双均线策略示例策略不用搞太高深先跑通链路比追求复杂更重要。我自己用轮询方式收集分钟级价格存到pandas的DataFrame里然后算两条均线短期上穿长期就买下穿就卖。核心逻辑大概是这样的import pandas as pd import time prices [] # 维护最近一段时间的价格列表 def update_price(): price get_price(000001) # 获取当前价 prices.append((time.time(), price)) # 只保留最近2小时数据 while prices and time.time() - prices[-1][0] 7200: prices.pop(0) def get_ma(window): if len(prices) window: return None df pd.DataFrame(prices[-window:], columns[ts, price]) return df[price].mean() # 策略主循环 while True: price get_price(000001) ma5 get_ma(5) ma20 get_ma(20) if ma5 and ma20: if ma5 ma20 and not holding: trade_buy(000001, price, 100) holding True elif ma5 ma20 and holding: trade_sell(000001, price, 100) holding False time.sleep(30) # 每30秒轮询一次这套逻辑跑在模拟盘上我记得有一天下来触发过三四次交易整体稳定就是慢了点。要说策略本身能不能赚钱那得看行情但至少它验证了整套“信号→下单”的链路是通的。这里再多说一句如果有人想升级策略可以往离散时间的马尔可夫决策过程MDP那个方向做那套框架很适合把交易抽象成状态、动作、奖励三个要素用强化学习来做决策。不过那是另一个大坑建议先把基础链路跑顺了再碰。4.3 交易循环设计别把手机点到“爆”交易循环是策略的大脑但设计不好就会变成“刷单机器”。我踩过这个坑用while True不加限制地轮询结果短期均线频繁金叉死叉每次交叉都触发买卖手续费吃掉一大截收益不说同花顺那边直接弹了风控提示。我的改进方案是三层控制。第一层是轮询间隔最少隔30秒才重新取一次行情避免对UI造成频繁压力。第二层是冷却时间一次交易后至少等两分钟再接受下一次信号防止反复操作。第三层是仓位控制不管策略信号多强烈单笔模拟买入数量不超过账户总资金的三成。另外一定要加日志。每次下单之后把时间、股票、价格、数量、操作类型写入CSV文件后续复盘的时候才知道钱是怎么亏的。别嫌麻烦这一步能省掉你大量的排查时间。5. 稳定运行的细节全是踩坑换来的5.1 常见问题速查表运行这套工具过程中我基本把能踩的坑都踩了一遍。整理成表格方便你直接对照问题现象根本原因解决方案uiautomator2连接超时ADB服务异常或手机锁屏执行adb kill-server adb start-server解锁手机屏幕找不到text买入控件页面加载慢或处于其他Tab增大等待时间先打印dump_hierarchy()确认当前页面clear_text()无效同花顺使用自绘数字键盘改用点击输入框 d.send_keys()方式输入模板匹配大量误匹配阈值设太低或模板不具区分度提高匹配阈值至0.8截取更小的独特区域做模板手机息屏后脚本中断系统休眠断开ADB连接关闭自动锁屏用d.screen_on()保活运行一段时间越跑越慢同花顺内存占用攀升每隔2小时重启一次同花顺App模拟盘提示操作频繁轮询和下单间隔太短加大轮询间隔增加交易冷却时间5.2 设备状态维护的三个细节第一个细节是屏幕常亮。Android手机默认几十秒无操作就锁屏锁屏后ADB连接可能还在但uiautomator2执行点击时会直接失败。我建议把自动锁屏时间改成10分钟以上或者干脆开“保持唤醒”模式。如果你用的是旧手机闲置跑脚本最好插着电别让电量耗尽关机。第二个细节是通知干扰。跑脚本期间如果微信、短信弹个通知可能会把同花顺的界面挤到后台元素定位马上就乱套。我在测试手机会专门开一个“勿扰模式”并卸载不需要的App让手机变成一个纯粹的交易执行终端。这一步越干净越好。第三个细节是配合uiautomator2的watch。它可以在后台监控弹窗发现指定文本出现时自动点击。比如同花顺偶尔会弹“升级提示”或“活动弹窗”会让你的脚本卡死。用d.watch_context设置一个自动关闭弹窗的规则整个工具的稳定性会上一大截。6. 从模拟盘到实盘路线图与风险提示6.1 标题里的“可自行扩展到实盘”到底怎么理解这句话我琢磨了很久其实它是这套设计最关键的地方。它不是让你直接用这套UI自动化去操作同花顺的实盘账户——那太危险了UI自动化实盘下单的失败率你根本承受不起。它的真正含义是你在这套模拟工具中写好的策略逻辑、行情处理、信号判断代码是可以无缝平移到正规实盘通道的。真正的实盘路线应该走券商提供的量化接口。比如中泰XTP、华鑫奇点、Ptrade、QMT这些它们提供Python API支持实盘和仿真交易。迁移的时候你只需要把“执行层”替换掉把原来调用uiautomator2点按钮的trade_buy()函数换成调用券商API的order_shares()函数上面那套均线策略、轮询框架、日志记录一行都不用改。这就是“可自行扩展到实盘”的正解——投资逻辑复用执行通道替换。6.2 我在实际使用中的体会与提醒这套工具我从头到尾在模拟盘跑了几个星期最大的体会是它真的能帮你把注意力从“怎么下单”解放出来放到“策略对不对”上。但它不是万能钥匙UI自动化的天花板很明显——速度慢、依赖界面稳定、无法处理极端行情下的拥堵和卡顿。所以我最后的建议是模拟盘阶段大胆跑实盘阶段务必换正规API。如果你决定往实盘走还有两件事要提前做。一是把回测做得再细一点模拟盘的成交滑点和手续费跟实盘有差距策略在模拟盘表现好不代表实盘也能复制。二是务必把异常处理加强断网重连、服务器超时、交易所熔断这些极端情况都要在代码里考虑进去。最后提一句不算忠告的提醒量化交易本质是概率游戏任何策略都有亏损周期用自己能承受的风险参与最重要。这套工具的价值在于让你低成本、低风险地把整个流程跑通至于后续能走多远就看你自己怎么用了。本文还有配套的精品资源点击获取
返回列表