ビットコインのトレードbotを書いてみた
どうもみなさん、ガチホしていますか?
最近クリプト界隈で話題となっているビットコインのトレードbotを書いてみましたので、
備忘録として書き残しておきます。
botの作り方などはQiitaや有料noteなんかにもいくつか投稿がありますが、
テーマ別となっており局所的にソースコードが載っていたりと、全体像が分かりにくく、
プログラムを少しかじったことがある人でもモチベーションを維持しながら
最後まで作りきることが難しいのでは感じていました。
そこで、私の尊敬するbotトレーダーAKAGAMIさんとは真逆の路線で、
読者の皆様に"釣り竿"ではなく、"魚"そのものを与え、
まずはbotトレードに興味を持っていただこうというスタンスで記事の公開を始めました。
AKAGAMIさんがいなければ自分自身ここまで来ることはできなかったので、敬意を表します。
目次
1.本記事の対象読者
- プログラミングの基礎知識がある(言語問わず、簡単な機能を実装できる)
- pythonの環境構築ができる(anacondaやpipが分かる、eclipseなどのIDEが使える)
- bitFlyerに口座を開設している
2.概要と技術テーマ
概要
1分ごとにRSIを取得し、設定した基準を割った場合(売られすぎor買われすぎ)にエントリーし、
RSIがニュートラルになったらポジションをクローズする平均回帰型のスキャルbotです。
公開したソースコードはbitFlyerのBTC-FXで取引するための実装にしてあります。
技術テーマ
- ccxt
→暗号通貨取引所のAPIをall-in-oneで使えるライブラリ - TA-Lib
→インディケーターの算出を自動でできるライブラリ
pythonで利用するには、ラッパーのインストールが必要。 - CryptowatchAPI
→bitFlyerの価格を取得するために利用しています
3.パッケージの構成とソースコード
パッケージの構成
TradingController.py (メインクラス)
import ccxt import time from config import Apiconfig as api from config import Tradeconfig as tra from ExecLogic import EXEC_LOGIC from ExecTicker import EXEC_TICKER # ロード処理 # 取引ペア symbol=tra.symbol # APIキー bitflyer = ccxt.bitflyer({ 'apiKey': api.bf_api_key, 'secret': api.bf_api_secret, }) # 実行クラス ticker = EXEC_TICKER() logic = EXEC_LOGIC() while 1==1: print('sleep') time.sleep(tra.crawling_time) # 初期ポジション position=None try: # 終値の取得 close_price=ticker.get_ticker() # ロジッククラスの判定 position_flg=logic.exec_rsi(close_price) print(position_flg) except: print('価格の取得に失敗しました。APIエラーのため再実行します。') # ノーポジションからエントリー if position_flg == 1 or position_flg == -1 : try: # 注文指定 if position_flg == 1: position='buy' elif position_flg == -1: position='sell' # 発注 order = bitflyer.create_order(symbol, type='market',side=position, amount=tra.lot) # 注文id position=order['id'] print('ポジションを取ります') print(order) except: # APIエラー print('ポジションの取得に失敗しました。APIエラーのため再実行します') position=None while position: print('sleep') time.sleep(tra.crawling_time) try: # 終値の取得 close_price=ticker.get_ticker() # ロジッククラスの判定 exit_position_flg=logic.exec_exit_rsi(close_price,position_flg) print(exit_position_flg) except: # APIエラー print('価格の取得に失敗しました。APIエラーのため再実行します') if exit_position_flg + position_flg == 0: try: # 注文指定 if exit_position_flg == 1: position='buy' elif exit_position_flg == -1: position='sell' # 発注 order = bitflyer.create_order(symbol, type='market', side=position, amount=tra.lot) print('ポジションをクローズします') print(order) position=None position_flg=0 exit_position_flg=0 except: # APIエラー print('ポジションのクローズに失敗しました。APIエラーのため再実行します') else : exit_position_flg=0
ExecLogic.py (売買ロジックの判定クラス)
import talib as ta class EXEC_LOGIC: def exec_rsi(self,close_price): entryflg=0 #ta-lib data=ta.RSI(close_price, timeperiod=14) print(data) RSI=data[120] print(RSI) if RSI <= 35.0: print("成行買い") entryflg=1 elif RSI >= 65.0: print("成行売り") entryflg=-1 else: print("ノーポジション") return entryflg def exec_exit_rsi(self,close_price,position_flg): exitflg=0 #ta-lib data=ta.RSI(close_price, timeperiod=14) print(data) RSI=data[120] print(RSI) if RSI <= 53.0 and position_flg == -1: print("手仕舞い_成行買い") exitflg=1 elif RSI >= 47.0 and position_flg == 1: print("手仕舞い_成行売り") exitflg=-1 else: print("HOLD") return exitflg
ExecTicker.py (価格データ取得クラス)
import requests import json import datetime as dt from datetime import timedelta as td import numpy as np from config import Tradeconfig as tra class EXEC_TICKER: def get_ticker(self): # 現在時刻から指定した時間間隔の時刻を取得 endDate = dt.datetime.now() startDate = endDate + td(hours=tra.span) # 時刻データのフォーマット変換 startTimestamp = startDate.timestamp() endTimestamp = endDate.timestamp() # 価格データのAPIリクエスト@cryptowatch # 1分足を取得 query = {"periods": "60", "after": str(int(startTimestamp)), "before": str(int(endTimestamp))} res = json.loads(requests.get("https://api.cryptowat.ch/markets/bitflyer/btcfxjpy/ohlc", params=query).text)["result"]["60"] res = np.array(res) #ta-libに渡す形式 close_price = res[:, 4] return close_price
Tradingconfig.py(トレードに関するパラメータファイル)
# 取引ペア symbol='FX_BTC_JPY' # データを取得する期間 span=-2 # 2hours # ロット数(BTC) lot=0.01 # クローリングTime crawling_time=60 # 60sec
Apiconfig.py(アクセス情報をハードコーディングしたファイル)
# APIのアクセスキーをここに書く bf_api_key= # APIのシークレットキーをここに書く bf_api_secret=
4.考察
バックテストをせずに即本番運用しましたが、パフォーマンスとしては"トントン"でした。
①→➁や①'→➁'のようなレンジ相場ではRSIと価格がほぼ連動してくれているので問題ないですが、
➂→④のようなトレンドが継続する場合になるとエントリーポイントからずるずると含み損になります。
※ちなみに➂→④の時は、再び➂と④の間でRSIのラインを割ったときに
botが持っているポジションよりも多く、私が直接ナンピンしてエントリーして、
RSIがニュートラルに戻った時に利確します。
追加機能として上記のナンピンエントリーが実装できれば、
勝率がかなり高めのbotになるのではないかと考えています。
5.備考
Win10の64bit環境でTA-Libのラッパーをインストールするまでに
C#のコンパイルツールがデフォルトで入っていなかったり、
64bit専用のVisual Studioコマンドプロンプトでコンパイルしないといけないなど
地雷除去に2日かかりましたorz
※Gitの説明を見ればなんとか解決できますが、そもそもlinuxやmac環境であれば瞬殺です。
本記事を最後まで読んでいただきありがとうございました。
botトレードをこれから始めたい人の何かきっかけになれたら幸いです。