bot開発9.自動売買botで何度も使いそうな処理を関数にまとめてみよう

私も苦手な関数の登場です。今回は、自作関数をとして、「自動売買botで何度も使いそうな処理」をまとめていきます。
関数については「【Python】関数(メソッド)を作れるようになろう」で説明しているので参考になれば幸いです。

関数のおさらいですが、関数とは、一定の処理をまとめたメソッドになります。

ソースコードdef 関数名:
	処理

戻り値が必要であればreturnを記述するというものです。

Contents

関数を作る

Bitflyerから最新の1分足の価格データを取得して、日時に更新があった場合のみ表示するコードを分解し、関数を作っていましょう。

import requests
from datetime import datetime
import time

while True:
	response = requests.get("https://api.cryptowat.ch/markets/bitflyer/btcfxjpy/ohlc?periods=60")
	response = response.json()

	data = response["result"]["60"][-2]
	
	close_time = datetime.fromtimestamp(data[0]).strftime('%Y/%m/%d %H:%M')
	open_price = data[1]
	close_price = data[4]

	if close_time != last_time:
		print( "時間: " + close_time
			+ " 始値: " + str(open_price)
			+ " 終値: " + str(close_price) )
		last_time = close_time

	time.sleep(15)

上記処理は、大きく分けると「Cryptowatchから最新価格を取得する」「ローソク足の日時・始値・終値を表示する部分」の2つの処理があります。ですので、この2つを関数化します。

「Cryptowatchから最新価格を取得する」を関数にする

def get_price(min):

	# APIで価格を取得する
	response = requests.get("https://api.cryptowat.ch/markets/bitflyer/btcfxjpy/ohlc",params = { "periods" : min })
	response = response.json()
	data = response["result"][str(min)][-2]
	
	close_time = data[0]
	open_price = data[1]
	close_price = data[4]

	# 日時・終値・始値の3つを返す
	return close_time, open_price, close_price

「ローソク足の日時・始値・終値を表示する部分」を関数にする

# 日時・終値・始値を表示する関数を作成
def print_price( close_time, open_price, close_price ):
	print( "時間: " + datetime.fromtimestamp(close_time).strftime('%Y/%m/%d %H:%M')
		+ " 始値: " + str(open_price)
		+ " 終値: " + str(close_price) )

完成

関数を組み込んんだプログラムが以下になります。

import requests
from datetime import datetime
import time


# Cryptowatchから 〇分足のデータを取得する関数を作成
def get_price(min):
	# APIで価格を取得する
	response = requests.get("https://api.cryptowat.ch/markets/bitflyer/btcfxjpy/ohlc",params = { "periods" : min })
	response = response.json()
	data = response["result"][str(min)][-2]
	
	close_time = data[0]
	open_price = data[1]
	close_price = data[4]

	# 日時・終値・始値の3つを返す
	return close_time, open_price, close_price


# 日時・終値・始値を表示する関数を作成
def print_price( close_time, open_price, close_price ):
	print( "時間: " + datetime.fromtimestamp(close_time).strftime('%Y/%m/%d %H:%M')
		+ " 始値: " + str(open_price)
		+ " 終値: " + str(close_price) )


# ここからがメイン処理
last_time = 0
while True:
	# get_price()関数を使って最新のローソク足の日時・始値・終値を取得する
	close_time , open_price , close_price = get_price(60)
	
	if close_time != last_time:
		last_time = close_time
		
		# print_price()関数を使って価格データを表示する
		print_price( close_time,open_price,close_price )
	
	time.sleep(15)

プログラム(自作関数)を読み解く

importの部分は割愛します。

def get_price(min):

Cryptowatchから 〇分足のデータを取得する関数です。
元のプログラムで該当する箇所は以下の通りです。

response = requests.get("https://api.cryptowat.ch/markets/bitflyer/btcfxjpy/ohlc?periods=60")
response = response.json()

data = response["result"]["60"][-2]
	
close_time = datetime.fromtimestamp(data[0]).strftime('%Y/%m/%d %H:%M')
open_price = data[1]
close_price = data[4]

1.def get_price(min):ではminという引数を指定しています。1分足、5分足、60分足など複数の観察観点があるためです。関数化されているので、minを変更するだけで、後続処理は同じです。

プログラムにperiods=60と指定してしまうと60秒のみですが、params = { “periods” : min }とすることで、引数minに渡された値で分足を作成することができます。
1分足、5分足、60分足の結果を取得したい場合は、以下のような記述ができます。

get_price(60) #1分足
get_price(300) #5分足
get_price(3600) #60分足

スッキリしますね。

def print_price( close_time, open_price, close_price ):

日時・終値・始値を表示する関数です。
元のプログラムで該当する箇所は以下の通りです。

print( "時間: " + close_time
		+ " 始値: " + str(open_price)
		+ " 終値: " + str(close_price) )

def get_price(min):の戻り値(return)でclose_time, open_price, close_priceを渡しています。その値をdef print_price()の引数で受け取り、後続処理を行っています。

複数引数を使う場合は、引数を渡さないとエラーなることです。

メイン処理

get_price(min):でCryptowatchから 〇分足のデータを取得
print_price( close_time, open_price, close_price ):で日時・終値・始値を表示
その結果を繰り返しています。

関数化する意味ってあるの?

完成したプログラムをみてふと思うことありませんか?

「むしろプログラム長くなっているじゃないか」

私は関数を勉強しはじめたときと常々おもっていました。極端なことを言えば、処理が複数回行われないのであれば関数化しなくても十分だと思っています。しかし「可読性」を考えると関数化したほうが良いと思えるようになってきています。

ややこしい処理は外出しにしてしまい、メイン処理で「今プログラムでは何がしたいのか」が見えるはずです。

botの流れ

Bitflyerから最新の1分足の価格データを取得して、日時に更新があった場合のみ表示するコードであれば、そんなに難しい処理でないことが確認できます。しかし、実際に自動売買botとなると複数の処理、いくつかの条件分岐があります。

  • Cryptowatchから最新価格を取得する
  • エントリー条件を判定する
  • Bitflyerにエントリー注文を出す
  • 指値注文が約定したかを確認する
  • 約定しなければキャンセルする
  • 約定したら手仕舞いの条件を満たしたか判定する
  • 手仕舞いの条件を満たしたら決済注文を出す
  • ループさせる

利益を出すことにエンジニアが力を入れているとすれば「エントリー条件を判定する」部分です。ここには、さまざまな分析手法が組み込まれます。分析手法ごとに関数にすればプログラムが楽になりますね。

※注意:本bot開発は「文系でもわかる!BitcoinのBOT自動売買トレードの始め方」をもとに開発・自分なりの解釈用備忘録としています。


Python勉強したいのであればこれ一択


AIの技術、データ分析を身につけるにはPythonが取り組みやすいです。専門コースもあるので、まずは、気軽に問い合わせしてみてください!
技術者も多くなってきていますが、世界と戦うにはまだまだ人材不足です。高い年収を狙うなら今がチャンス!


フリーランスエンジニアが登録して欲しいエージェント


長くお世話になっているengineer-route。
単価、稼働日数、稼働時間相談も親身にのってくれます。しっかりしたサポート・コミュニケーションを交わすことで「はいってみた違った」というエンジニアあるあるを極力回避できると思います。私は当たりしかないです。