背景
朋友炒股,闲聊时说到“自己有交易策略,但是不知道怎么自动下单。要是有工具可以自动输入股票代码、价格、数量,并点击确实按钮
就好了”。当时我想到可以自己摸索着实现一下。
自动下单,即量化交易,券商提供该功能给机构。个人投资者有资金门槛才能获取此功能,比如300w资金。
除此之外,自动消除连连看
也是同样的目的。
于是,就开始实现了。该文简略记录一下。
调研
可选择的
- c语言和win32
- 使用autoIt
- python的pypiwin32
- java的jna (ava-native-access,github地址在这里)
因为熟悉java,所以选择jna。
思路
- 判断windows应用在运行着,若是没有运行可以主动启动它。
- 找到程序窗口。
- 找到程序中的控件
- 给指定的控件发送
- 点击按钮
- 读取输入框的内容
- 往输入框中写入内容
- 点击窗口中的某个位置
- 等等
辅助工具
spy++
因为是处理win32窗口,该工具必不可少- 会有20%的时间应该花费在该工具上,主要目标是找到窗口、对话框、控件ID,查看它们收到了什么消息并模拟
ApiViewer
win32中有大量的常量如类似WM_LBUTTONDOWN的WM_*,找到这些常量比较麻烦,可考虑使用该工具。- 若是本地安装
visual studio
(注意不是vscode)的话,可以直接找对应的头文件(如windows.h,windef.h,commctrl.h),里面有对应的常量定义。
- 若是本地安装
error错误说明
调用Win32的函数后,若不正常需要调用GetLastError得到一个数字,但得查文档才知道是什么错误,可以在此处看到。msdn / 微软官方文档
,直接在搜索引擎中输入常量如WM_LBUTTONDOWN (结果中会有https://learn.microsoft.com/zh-cn/windows/win32/inputdev/wm-lbuttondown)即可看到对应的文档。
问题记录
- SysTreeView32树形控件较难获取数据,但可以通过发送快捷键来解决。
- 窗口中的点击问题,优先给控件发送点击消息,实在不行的话再给父窗口发送x/y坐标的点击事件。
- Toolbar32控件的点击事件,需要使用spy++监控消息,再手工点击,把消息和参数整理出来,再通过程序发送消息。
- 该控件看起来就是几个按钮,但实际调用起来却完全获取不到任何按钮,只能通过点击窗口的x/y坐标来实现。
- 控件ID问题,因为控件ID是不变化的,所有尽量使用该值来获取对话框中的控件(即
HWND GetDlgItem(HWND hDlg, int nIDDlgItem);
函数)。 - 窗口的子窗口的子窗口问题,这个需要耐心整理出窗口之间的关系。
- CVirtualGridCtrl控件是同花顺自己写的控件和网上的不同,难处理,可以通过模拟输入ctrl+c,然后从clipboard提取内容。
- 但是ctrl+c会出现验证码,还好图片比较简单,使用tess4j和tesseract-ocr可以轻易识别。
感想
- 微软的官方文档是很详细的。要多看看。
- 自动化操作就是方便 ^_^ 。
- 使用java的好处是可以优化代码,如使用继承,目前实现了华泰证券的自动化操作,进一步可以考虑实现其它券商软件,并把核心逻辑提取到父类中。
- 下一步可以考虑自动化消除
连连看
小游戏了。 - 编写代码时会有很多小问题,慢慢调试,不要急。