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

# 自動売買ロジックの実装
実装の流れとしては
1. BTCの価格取得
1. 移動平均を計算
1. クロスで取引実行

https://github.com/SohMitian/btc_trade

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

```python
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 }
    # ローソク足取得期間が初期値０以外の時の処理
	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
```

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

```python
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)
```

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


```python
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でトリガーを設定

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

![スクリーンショット 2022-04-11 0.16.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1135021/3467aadd-1b36-ffc4-df59-16b0106daf44.png)

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

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

![スクリーンショット 2022-04-11 0.18.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1135021/db19cd00-79ec-7248-94a4-e019d2cff93e.png)

# で、儲かるの？
## 儲からない
こんなアルゴリズムで儲かるわけがない

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

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

## 詐欺には使える
一応動くものを作ったので「仮想通貨自動売買Bot買いませんか？儲かりますよ？６０万円で売りますよ？」とか適当ぶっこいて売りさばけば別の意味で儲かりそうですね。

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