背景

朋友炒股,闲聊时说到“自己有交易策略,但是不知道怎么自动下单。要是有工具可以自动输入股票代码、价格、数量,并点击确实按钮就好了”。当时我想到可以自己摸索着实现一下。

自动下单,即量化交易,券商提供该功能给机构。个人投资者有资金门槛才能获取此功能,比如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的好处是可以优化代码,如使用继承,目前实现了华泰证券的自动化操作,进一步可以考虑实现其它券商软件,并把核心逻辑提取到父类中。
  • 下一步可以考虑自动化消除连连看小游戏了。
  • 编写代码时会有很多小问题,慢慢调试,不要急。