5
Help us understand the problem. What are the problem?

posted at

【Python】ビットコイン自動売買BotをAWS Lambdaで動かす

自動売買ロジックの実装

実装の流れとしては

  1. BTCの価格取得
  2. 移動平均を計算
  3. クロスで取引実行

CryptowatchからBTCFXの価格データを取得

CryptowatchのAPIを叩いて、BTCFXの価格データを引っ張ります。

def get_price(min, before=0, after=0):
    # Cryptowatchのparamはbefore, after, period
    # before: int Unix timstamp
    # after:  int Unix timstamp
    # period: array Example: 60,180,108000

	price = []
    # 何分単位かを設定
	params = {"periods" : min }
    # ローソク足取得期間が初期値0以外の時の処理
	if before != 0:
		params["before"] = before
	if after != 0:
		params["after"] = after
    
    # OHLCを取得
	response = requests.get("https://api.cryptowat.ch/markets/bitflyer/btcfxjpy/ohlc",params)
	data = response.json()
	
    # dataがNoneでなければデータをdict型に整形してPriceに入れる
	if data["result"][str(min)] is not None:
		for i in data["result"][str(min)]:
			price.append({ "close_time" : i[0],
				"close_time_dt" : datetime.fromtimestamp(i[0]).strftime('%Y/%m/%d %H:%M'),
				"open_price" : i[1],
				"high_price" : i[2],
				"low_price" : i[3],
				"close_price": i[4] })
	return price

単純移動平均を計算

ここでは単純移動平均としていますが、より精度の高い取引をするなら他の移動平均(加重や指数など)にすると良いと思います。
そこら辺は関数作って切り替えてもいいかも。

def calculate_MA(price, value, before=None):
	"""単純移動平均計算

	単純移動平均を計算する

	Args:
		price(Any) : 価格
		value(Int) : MAの期間
		before(Int) : n足前の指定
	Returns:
		小数を丸めたMA
	"""
	if before is not None:
		MA = sum(i["close_price"] for i in price[-1*value + before: before]) / value
	else:
		MA = sum(i["close_price"] for i in price[-1*value:]) / value
	return round(MA)

クロスで取引実行

ここでゴールデンクロスとデッドクロスを判定して取引を実行します。
今回は単純なアルゴリズムで、ゴールデンクロスなら買い、デッドクロスなら売りという処理にしています。

def cross_MA(event=None, context=None):
	load_dotenv('.env') # 環境変数読み込み
	bitflyer = ccxt.bitflyer()
	bitflyer.apiKey = os.environ.get("APIKEY")
	bitflyer.secret = os.environ.get("SECRETKEY")

	# 使用する時間足
	chart_min = 60 # 60分

	# 価格チャートを取得
	price = get_price(chart_min)

	# 一つ前
	MA10_BEFORE1 = calculate_MA(price, 10, -1)     # 現在の10期間移動平均の数値
	MA21_BEFORE1 = calculate_MA(price, 21, -1)     # 現在の21期間移動平均の数値

	# 現在
	MA10 = calculate_MA(price, 10)     # 現在の10期間移動平均の数値
	MA21 = calculate_MA(price, 21)     # 現在の21期間移動平均の数値

	# 一つ前の移動平均線の状態を設定
	state_line_before1 = 0 # 初期値
	if MA10_BEFORE1 > MA21_BEFORE1:
		state_line_before1 = 1 # プラス傾向
	elif MA10_BEFORE1 < MA21_BEFORE1:
		state_line_before1 = -1 # マイナス傾向

	# 現在の移動平均線の状態を設定
	state_line = 0 # 初期値
	if MA10 > MA21:
		state_line = 1 # プラス傾向
	elif MA10 < MA21:
		state_line = -1 # マイナス傾向

	# 移動平均線を最新と一つ前で比較してクロスしているかを判定
	if state_line_before1 > state_line: #プラスクロス
		order = bitflyer.create_order(
		symbol = 'BTC/JPY',
		type='market',
		side='buy',
		amount='0.01',
		params = { "product_code" : "FX_BTC_JPY" })
		pprint( order )
	elif state_line_before1 < state_line: #マイナスクロス
		order = bitflyer.create_order(
		symbol = 'BTC/JPY',
		type='market',
		side='sell',
		amount='0.01',
		params = { "product_code" : "FX_BTC_JPY" })
		pprint( order )
	else:
		print("クロスしてないから何もしない")

AWS Lambdaで実行

Cloud watchでトリガーを設定

実行感覚は1時間ごととかにします。

スクリーンショット 2022-04-11 0.16.06.png

関数をZipしてアップロード

ランタイム設定を開発環境と合わせます。
ハンドラはメインの実行関数であるcross_MA

スクリーンショット 2022-04-11 0.18.43.png

で、儲かるの?

儲からない

こんなアルゴリズムで儲かるわけがない

ただ今回実装したことで、自動売買Botの便利さは体感しました。
いちいちチャートとにらめっこしなくても勝手に取引してくれるので機会損失は防げそうです。

指標を単純移動平均ではなく、加重や指数を使うとまた変わってくるでしょうし、ゴールデンクロスの平均線もどの期間の線を使うかによっても変わってくるでしょう。

詐欺には使える

一応動くものを作ったので「仮想通貨自動売買Bot買いませんか?儲かりますよ?60万円で売りますよ?」とか適当ぶっこいて売りさばけば別の意味で儲かりそうですね。

まあ詐欺で捕まりますけど。

Register as a new user and use Qiita more conveniently

  1. You can follow users and tags
  2. you can stock useful information
  3. You can make editorial suggestions for articles
What you can do with signing up
5
Help us understand the problem. What are the problem?