BTCFXの自動売買BOTで売買の状況をLINEに通知させる方法

外出時や仕事中でもBOTの稼働状況を監視して把握する方法の2つ目です。
前回の記事ではコマンドラインへの出力結果と同じ内容をメールで送信する方法を解説しました。

今回はもう1つの定番のLINE通知の方法について解説します! やる前は難しそうに感じるかもしれませんが、15分もかからないほど簡単なので安心してください。

BOTの状況をLINEに通知する方法

今回の記事では、PythonでLINEに通知する関数を作ります。
そしてprint文と同じように要所要所に1行入れるだけで、そのテキスト内容をLINEに飛ばす方法を解説します。

手順

(1)LINE公式ページで開発者向けのアクセストークンを発行する
(2)Pythonで自由なメッセージをLINEに飛ばす関数を作る
(3)エントリーや決済・損切りなどの箇所に1行追加して通知する

では、やっていきましょう!

1.LINE公式でアクセストークンを取得する

(1)まず最初に以下の「LINE Notify」のページにアクセスします。
https://notify-bot.line.me/ja/

右上の「ログイン」をクリックして、ご利用のLINEアカウントでログインしてください。

登録したメールアドレスを忘れた方は、LINEのスマホ端末側で、「設定 -> アカウント -> メールアドレス」で確認できます。

ログインが完了したら、右上のメニューから「マイページ」を選択してください。

マイページをクリックして画面をスクロールすると、下の方に「アクセストークンの発行(開発者向け)」という箇所があるので、そこで「トークンを発行する」をクリックしてください。

▽ アクセストークンの発行(開発者向け)

すると、以下のようなトークン発行画面になります。

▽ トークン発行画面

設定する箇所は、「トークン名」と「トークルーム」の2つです。

トークン名は何でも構いませんが、この名前で通知が来るので、通知が来たときにわかる名前を付けておきましょう。ここでは「自動売買BOT(チャネルブレイクアウト)」としています。トークルームの方は、「1:1でLINE Notifyから通知を受け取る」を選択します。

できたら「発行する」をクリックします。
すると以下のようにトークンが表示されます。

▽ 発行されたトークン番号

このトークン画面は再表示できないので、コピーをしてメモ帳などに保存しておきましょう。

ただしもし間違えて閉じてしまっても、もう1度、新しいトークンを作ればいいだけなので大した問題ではありません。

2.LINE通知する関数を作る

次はBOTのPythonコードの方です。
以下のようなLINE通知をする関数を作ります。


import requests

# 設定項目
line_token = "************"    # さっき保存したLINEトークン

# LINEに通知する関数
def line_notify( text ):
	url = "https://notify-api.line.me/api/notify"
	data = {"message" : text}
	headers = {"Authorization": "Bearer " + line_token} 
	requests.post(url, data=data, headers=headers)

はい、LINE通知する関数はこれで完成です!

これでLINEに通知を送りたい箇所に、 line_notify(“テキスト”) のかたちでコードを1行追加すれば、LINE通知を実装することができます。

LINE通知の実装例

例えば、前回の第4回「BOT作成編」の章で作成したBOTでは、エントリーするたびに以下のような出力をしていましたよね。


# 売買の決済をする箇所
if data["close_price"] < last_data["close_price"]:
	print("前回の終値を下回ったので" + str(data["close_price"]) + "あたりで成行で決済します")

ここに以下のように行を追加すれば、LINEにも同じ通知を送ることができます。


# 売買の決済をする箇所
if data["close_price"] < last_data["close_price"]:
	print("前回の終値を下回ったので" + str(data["close_price"]) + "あたりで成行で決済します")
	line_notify("前回の終値を下回ったので" + str(data["close_price"]) + "あたりで成行で決済します")

同じことを2回書かないといけませんが、エントリー・決済・損切りなどの重要な箇所だけLINEに通知させたいのであれば、この方法が一番いいと思います。

3.出力を全て1行にまとめたい場合

逆にすべての print文の出力結果をLINEにも通知したい場合は、全部の箇所で同じことを2回書くよりも、1つの関数にまとめてしまった方が管理が楽です。

例えば、前回の記事の内容とあわせて、コマンドラインへの標準出力・ログファイルへの書き出し・LINEへの通知をすべて1つの関数にまとめておけば、コードはもっとすっきりします。


import requests
from logging import getLogger,Formatter,StreamHandler,FileHandler,INFO

# ログの設定
logger = getLogger(__name__)
handlerSh = StreamHandler()
handlerFile = FileHandler("c:/Pydoc/helloBot.log")
handlerSh.setLevel(INFO)
handlerFile.setLevel(INFO)
logger.setLevel(INFO)
logger.addHandler(handlerSh)
logger.addHandler(handlerFile)

# LINEの設定
line_token = "************"

# print文のかわりに使用
def print_log( text ):
	
	# コマンドラインへの出力とファイル保存
	logger.info( text )
	
	# LINEへの通知
	url = "https://notify-api.line.me/api/notify"
	data = {"message" : text}
	headers = {"Authorization": "Bearer " + line_token} 
	requests.post(url, data=data, headers=headers)

これで、全てのprint("")文の箇所を上記の print_log("") に置き換えれば、同じことを2回書かなくても済みます。

例えば、以下の1行だけで、コマンドラインへの出力・ファイルへのログ保存・LINEへの通知がすべて実行できます。


print_log("前回の終値を下回ったので" + str(data["close_price"]) + "あたりで成行で決済します")

ただし全ての出力内容をいちいちLINEに通知させるのは、少し鬱陶しいかもしれませんね。

BOTの稼働状況の監視(1)定期的にコマンドラインの標準出力をメールで受け取ろう!

自宅やクラウド、WindowsVPSなどでBOTを稼働したまま外出していると、今のBOTの稼働状況が気になることがあります。

売買のタイミングでLINE通知する方法もありますが、私はできればコマンドラインの内容を全部確認したいです。そこで、この記事では、コマンドラインに出力されるログの内容をそのまま6時間おきにメールで転送してBOTの稼働状況を把握する方法を解説します!

▽ コマンドラインの内容を外でも把握したい

▽ メールで定期的に通知する方法

それではやっていきましょう!

全体の流れ

これはあくまで私のやり方ですが、上記のことを実現するために以下の2つの手順を実行しています。

(1)ログをファイルに書き出す

今まではコマンドラインへの出力はすべてprint()文を使っていましたが、pythonには標準のログ用モジュール(logging)が存在します。これを使って、全てのprint文を logger.info(“”)に置き換えると、コマンドラインに出力する内容をリアルタイムで同時にログファイルに書き出すことができます。

(2)ログファイルの中身をメールする

トレードBOT本体とは別のpythonファイル(例:mail.py)を作って、その別BOTに定期的にログファイルの内容を指定のメールアドレスに送信させます。実行は、Windowsタスクスケジューラを使って6時間おきに自動実行します。

1.標準出力の内容をログファイルに書き出す

pythonには標準で logging というログ用のモジュールが用意されています。

このログ用モジュールを使って、いままでprint文で出力していた箇所を、すべてlogging.info に置き換えます。すると、コマンドラインに出力した文を同時にログファイルにも書き出すことができます。

説明だけではピンと来ないと思うので、実際にやってみましょう! 例えば、以下のように1秒おきにprint(“Hello!”)と出力するようなコードを作ってみてください。


import time
while True:

	print("Hello!")
	time.sleep(1)


これを実行すると、以下のように1秒おきにコマンドラインに「Hello!」と出力されます。

ログ用モジュールを使う場合

では全く同じことを、ログ用モジュールを使って書いてみましょう。ログ用モジュールで書き直すと以下のようになります。


import time
from logging import getLogger,Formatter,StreamHandler,FileHandler,INFO

logger = getLogger(__name__)
handlerSh = StreamHandler()
handlerFile = FileHandler("c:/Pydoc/helloBot.log") # ログファイルの出力先とファイル名を指定
handlerSh.setLevel(INFO)
handlerFile.setLevel(INFO)
logger.setLevel(INFO)
logger.addHandler(handlerSh)
logger.addHandler(handlerFile)

while True:

	logger.info("Hello!")
	time.sleep(1)


2行目~10行目までは、ただの「おまじない」だと思ってコピーしていただいても構いません。ログファイルの出力先とファイル名の箇所だけご自身で必要に応じて変更してください。

そして先ほど、print(“Hello!”) と書いた箇所を、logger.info(“Hello!”) に書き換えます。これを実行すると以下のようになります。

先ほどのprint文と同じように、コマンドラインに「Hello!」が出力されています。しかし同時に指定したフォルダに「helloBot.log」というログファイルが出力されている点に注目してください。

このログファイルを開いてみましょう。「Hello!」BOTは実行中のまま開いても構いません。すると以下のように、メモ帳にコマンドラインと同じ内容が出力されているのがわかります。

このファイルを同時にリアルタイムで、別のpythonファイルから読み込んでメールするようなコードを書けば、コマンドラインの出力結果を定期的にメールで受け取ることができるわけです!

▽ (例)Bitflyerの自動売買BOTのログファイル

ログ機能の説明の補足

なお、ここでは「コマンドラインへの標準出力を同時にファイルに書き出す」ということだけがやりたかったので、ログ機能(logging)の説明は最低限にとどめました。Python標準のログ機能についてもっと詳しく知りたい方は、以下の外部記事が参考になると思います。

[Quitta]Pythonのログ出力のまとめ
Pythonでのロギング機能を実装してみる

2.出力したファイルの内容をメールで転送する

次に別のpythonファイルを作って、さきほどのログファイルの内容を定期的に指定のメールアドレスに転送するスクリプトを作ります。

監視用のpythonコードは、本体BOTとは全く関係のない機能なので、切り離して別プロセスで実行します。こうしておけば、複数BOTを運用するときでも複数のログを同時に監視できますし、万が一、トラブルで止まったりしても、本体BOTに影響を与えないので安心です。

Gメールを送信するpythonコード

Pythonでメールを送るのは、GmailのようなWebメールを送信元として使うのであれば、全く難しくありません。
以下のようなコードを作るだけです。


import smtplib
from email.message import EmailMessage
from datetime import datetime

with open( "helloBot.log" ) as file:   # さっきのログファイルを指定して読み込み
	msg = EmailMessage()
	msg.set_content(file.read())

msg["Subject"] = "BOT稼働状況の通知:{}".format(datetime.now().strftime("%Y-%m-%d-%H-%M"))
msg["From"] = "xxxxxxxxxxxx@gmail.com"         # 送信元のアドレス
msg["To"] = "xxxxxxxxxxxx@gmail.com"           # 受け取りたいアドレス

server = smtplib.SMTP("smtp.gmail.com",587)    # これはGmailのSMTPなら共通
server.starttls()
server.login("Account", "PassWord")            # Gmailのアカウント名とパスワード
server.sendmail( msg["From"],msg["To"],msg.as_string() )
server.close()


メールの送信には、SMTPというプロトコルを使います。

GmailのようなWebメールであれば、メール送信サーバーは「smtp.gmail.com」、TLS/STARTTLSのポートは「587」と決まっているので、上記のようなコードを書いて、アカウント名とパスワードを入れれば、どこからでもpythonでメールの送信を実行できます。

なお、以下のページを参考にさせていただきました。
ありがとうございます。

Python3公式ドキュメント(smtplib)
Python3公式ドキュメント(email使用例)
[Quitta]Pythonでメール送信~Gmail編~

実行手順

ではこのコードを、「mail.py」などの別ファイルで保存して実行してみましょう!

より実践っぽく試したい方は、さきほどの「helloBot.py」を動かしたまま、Anacondaプロンプトをもう1画面立ち上げて、同時に「mail.py」を実行してみるとわかりやすいと思います。

▽ 左画面「helloBot.py」実行中、右画面「mail.py」実行

このように並行して複数のpythonプログラムを別のコマンドラインから実行することを、「別プロセス」といいます。

「別プロセスってよく聞くけどどういう意味だろうな?」と思っっていた方は、このようにコマンドプロンプトの画面を複数立ち上がる状況をイメージすればわかりやすいと思います。

実行結果

以下のように受信したいアドレス宛にメールが届いていれば成功です!
ちゃんとコマンドラインに標準出力されているのと同じ内容が届いていることを確認してください。

もしログインがブロックされた場合

なお、アカウントによってはPython経由でのGmailアカウントへのログインがブロックされることがあります。

間違って不審なアプリからのログインだと判断された場合、「ブロックされたログインについてご確認ください」という警告メールが届きます。

この場合、ログインを許可させるためには、同じメールの下の方の文章にある「安全性の低いアプリへのアクセスを許可」をクリックして、アプリからのログインを許可する必要があります。

しかし、これをするとGmailのセキュリティレベルが下がってしまいます。

そのため、個人的には「普段使いのメールアドレスを送信元アドレスに指定しない方がいい」と思います。つまりBOT稼働状況の通知用に新しい専用のメールアドレスを作った方がいいです。私はそうしました。

3.Windowsタスクスケジューラで自動実行する

さて、最後のステップです!
さきほど作成した「mail.py」をWindowsのタスクスケジューラに登録して、定期的に自動で実行して貰いましょう! 私は1日に4回ほど状況を教えて欲しいので、6時間おきに設定しています。

なお、これはWindowsの場合の手順です。一般のサーバーを使っている場合はcronの設定で同様のことができます。

1)タスクスケジューラを探す

WindowsVPSの方は、まず左下のメニューを右クリックして「検索」をクリックします。すると右上に検索窓が出ますので、「タスクスケジューラ」を検索します。普通のWindowsOSの方はスタートメニューから検索するだけです。

2)タスクスケジューラの設定

あとは基本的な流れは、別の記事「Windowsのタスクスケジューラを使ってpythonを定期的に自動実行しよう!」で解説したのと同じ内容なので、そちらを参考にしてください。

そちらを読んでいただく前提で、少し違うところだけ解説しておきます。

6時間おきの実行方法

Windowsタスクスケジューラーには、トリガーは「毎日」「毎週」「毎月」の選択肢しかなく、「6時間おき」というのは存在しません。そこで、このトリガーの画面では「1回限り」を選択します。時間は6時間後くらいを指定しておけばいいでしょう。

そして全てのタスクの登録作業が終わったら、左メニューの「タスク スケジューラライブラリ」から先ほど作成したタスクを探します。見つけたら選択してダブルクリックしてください。

すると以下のようなウィンドウが立ち上がると思うので、「トリガー」タブを選択して「編集」をクリックします。

そして詳細設定の箇所で、「繰り返し間隔」を6時間にし、「継続時間」を「無期限」に設定します。これで1回限りのトリガーのタスクを、6時間おきにずっと繰り返し実行することが可能になります。

まとめ

さて、これでWindowsVPSなどの外部サーバーでBOTを稼働したまま、外出していても、定期的に実行状況をメールで配信して貰うことができるようになりました。出先でもスマホで確認できるので便利です。

次回は、自動売買BOTがエントリーしたり決済をしたタイミング、またはBOT側で把握してるポジション情報と実際のポジション情報が一致しなくなった場合などのトラブル発生時にLINEでそれを通知する方法を解説します!