![]() |
Photo by Andrea De Santis on Unsplash |
Windows 上の操作で自動化したいことがあり、いろいろなシェアウェアを試してみたが、どれもいまひとつであった。
ネットで調べてみたところ RPA のようなことが Python でもできるようなので自作することにした。
Table of Contents [Disable]
開発にいたる背景
au カブコム証券 FX のシステムトレードを使っている。
通信が瞬断すると自動売買が停止し、リトライを手動でしなければならない。(Fig.1
参照)
頻繁に起きるので自動売買の意味がない。
通信設定の調整もやり尽くしたが、インターネット側の問題であれば手詰まりである。
同証券会社にリトライを自動化してくれと要求したとしても、すぐには対応してくれないだろう。
取り急ぎ Python で自動でリトライボタンをクリックするプログラムを作成することにした。
![]() |
Fig.1 通信エラー |
プログラムの概要
このプログラムで実現したいのは、システムトレードに通信エラーが表示されたらリトライボタンをクリックするということ。
通信エラーの表示が検知できればよいのだが、それを実現しようとすると途端にハードルが高くなる。
幸いリトライボタンの座標にはそれ以外のイベントを起こすものがない。
そこで無条件にリトライボタンを定期的にクリックするという仕様にした。
処理手順
-
現在のウインドウを取得する
これは自動売買中に PC で別の作業を行っていることもあり、リトライボタンをクリックした後、元の画面に戻れるようにするため。
[ソースコード:12行目~13行目]
-
対象のウインドウを見つけて、アクティブ化する
システムトレードのウインドウがアクティブになっていないこともあるので、一旦システムトレードのウインドウを見つけてからアクティブ化する。
[ソースコード:15行目~20行目]
-
指定の座標でクリックする
予めリトライボタンの座標を調べておき、その位置で左クリックするようにする。
[ソースコード:22行目~23行目]
-
元の画面に戻る。
1で取得していたウインドウに戻す。
[ソースコード:25行目~27行目]
ちょっとした工夫
ちょいプロだが、繰り返し回数と実行間隔は可変にしておいた。
[ソースコード:46行目~53行目]
このプログラムはコマンド起動するが、その際繰り返し回数と実行間隔を指定することにより状況に応じた運用ができる。
また、プログラムを走らせたまま外出することもある。
ログを出力し、プログラムの稼働確認ができるようにしておく。
[ソースコード:32行目~42行目]
ログは Google Drive
に出力するにすればスマホでも確認できる。
プログラムが停止していたら、リモートアクセスで再起動などの対応を取る。
リモートアクセスは Chrome リモート デスクトップ を使用している。
ソースコード
from sys import argv | |
import time | |
import datetime | |
import pyautogui as pyag | |
import win32gui | |
def auto_retry(): | |
# 処理を実行するたびに1秒待機させる | |
pyag.PAUSE = 1.0 | |
# 現在のウインドウを取得する | |
current_window = win32gui.GetForegroundWindow() | |
# 対象のウインドウを見つける | |
target_window = win32gui.FindWindow(None, 'auKabucom FX') | |
# 対象のウインドウをアクティブ化する | |
pyag.press('alt') | |
win32gui.SetForegroundWindow(target_window) | |
# 指定の座標でクリックする | |
pyag.click(1000, 700, button="left") | |
# ウインドウを元に戻す | |
pyag.press('alt') | |
win32gui.SetForegroundWindow(current_window) | |
return () | |
def auto_retry_log(): | |
# ログファイルオープン | |
f = open('auto_retry_log.txt', 'a') | |
# 現在時刻を取得 | |
dt_now = datetime.datetime.now() | |
loglist = [str(num), '-', dt_now.isoformat(), '\n'] | |
f.writelines(loglist) | |
# ログファイルクローズ | |
f.close() | |
if __name__ == '__main__': | |
# コマンドラインから引数を取得する | |
args = argv | |
# 引数1:繰り返し回数 | |
repeat = int(args[1]) | |
# 引数2:間隔時間(秒) | |
interval = int(args[2]) | |
# 実行 | |
for num in range(repeat): | |
# リトライ処理 | |
auto_retry() | |
auto_retry_log() | |
time.sleep(interval) |
メモ
win32gui は pywin32 をインストールすること。
pip install pywin32
座標の求め方
まず、画面全体の大きさはディスプレイの解像度で確認する。
設定 > システム > ディスプレイ > ディスプレイの解像度
次に該当位置にマウスのカーソルを置き、コンソールで下記のコマンドを実行する。
>>> pyautogui.position()
Point(x=987, y=695)
解像度は1920 × 1080 であり、横は真ん中あたり、縦は真ん中より少し下なので、だいたいこんなものだろう。
コードに書くときは切りよく x=1000、y=700 にしておいた。
実行方法
プログラムは実行可能ファイル(exe ファイル)にビルドしておく。(参考:Python ファイルをビルドしてEXE ファイルを作る方法)
コンソールに直接コマンドを打ち込んでもよいがバッチファイルにしておけばコンソールを開かなくても実行できる。
次のバッチファイルの例では、60秒間隔で 1440回(24時間)繰り返す設定になっている。
auto_retry.exe 1440 60
使用感
手動でリトライする必要がなくなったので夜中も安心して眠れるようになった。
ただ、PC
で作業している場合は一瞬ではあるものの、作業が定期的に止まってしまうところが難点。
ネットサーフィンなどのお楽しみ中なら我慢できる範囲。
専用のマシンを導入すべきだろうか?