2022.01.12
Pythonで機械学習を使った暗号資産のシステムトレードに入門する
1. はじめに
こんにちは、次世代システム研究室の新卒のK.Fです。
普段は、主に、スマホアプリのサーバーサイドの開発業務を行っているのですが、金融領域にチャレンジしてみようということで、Pythonで機械学習を使った暗号資産のシステムトレードに入門してみることにしました。(金融初心者ですので、お手柔らかにお願い致します…)
結論
- ccxtでデータ収集、backtesting.pyでバックテストを行うことができる。
- SMAクロスオーバー戦略とSuperTrend戦略について調査した。
- 取引戦略のパラメータ最適化を機械学習(ベイズ最適化、遺伝的アルゴリズム)を用いて行ったところ、取引成績が向上した。
本記事の前半では、ccxtを用いたデータ収集とbacktesting.pyを使ったバックテストの方法を説明し、後半では、機械学習を用いた取引戦略のパラメータ最適化に挑戦してみようと思います。
2. データ収集
ccxtは、BinanceやCoinbase、FTX、Krakenなどの複数の暗号資産取引所のAPI操作をいい感じに使いやすくしてくれるツールです。ccxtを使えば、マーケットの価格取得や注文、残高取得まで行えます。
例えば、下のコードのように数行書くだけで、Binance取引所のBTC/USDT板の「Open(始値)、High(高値)、Low(低値)、Close(終値)、Volume(出来高)」の1分足を取得することができます。
import ccxt exchange = ccxt.binance() data = exchange.fetch_ohlcv(symbol="BTC/USDT", timeframe="1m")
3. 取引戦略
本記事では、以下の2つの取引戦略をバックテストします。ここで、説明のために、Open(始値)、High(高値)、Low(低値)、Close(終値)、Volume(出来高)をそれぞれ
を使って表すこととします。
SMA クロスオーバー 戦略
非常にシンプルで、上記の「長期移動平均(SMA_L)と短期移動平均(SMA_S)を比較し、SMA_L < SMA_S ならば、上昇トレンドとして買いポジション(long)、逆にSMA_L > SMA_Sなら下降トレンドとして売りポジション(short)を取る」という取引戦略です。それぞれの移動平均のサイズ N_L、N_S(ただし、N_L > N_S)がチューニング可能なパラメータとなります。
SuperTrend 戦略
まず、SuperTrend 戦略の理解に必要な要素を説明していきます。TrueRenge(TR)と呼ばれるテクニカル指標は、一つ前のローソク足の終値を
とすると、以下のように計算することができます。
TRの指数平滑移動平均(EMA)をとったものをATRといいます。また、高値Hと低値Lの平均をとったものをHLとします。
上記を踏まえて、やっとSuperTrend 指標について触れることができます。SuperTrend指標とは、tradingviewで最も人気のあるテクニカル指標です。
SuperTrend指標を用いたSuperTrend 戦略は以下の通りです。
- TRのEMA (n = period) をとりATRを求める。
- HLに、ATRを multiplier 倍した数値を上下に足してバンドを作る。
BASIC_UPPERBAND = HL + ATR * multiplier BASIC_LOWERBAND = HL - ATR * multiplier
- 上の2つバンドを、一つ前の終値および、一つ前のバンドと比べて、最終的なバンドを決定する。
if (BASIC_UPPERBAND < PREV_FINAL_UPPERBAND or PREV_FINAL_UPPERBAND < PREV_CLOSE): FINAL_UPPERBAND = BASIC_UPPERBAND else: FINAL_UPPERBAND = PREV_FINAL_UPPERBAND if (PREV_CLOSE < PREV_FINAL_LOWERBAND or PREV_FINAL_LOWERBAND < BASIC_LOWERBAND): FINAL_LOWERBAND = BASIC_LOWERBAND else: FINAL_LOWERBAND = PREV_FINAL_LOWERBAND
- 最終的なバンドと、終値および一つ前の最終バンドとの位置関係で、最終的なバンドのどちらかをSUPERTREND 指標とする。
if PREV_SUPERTREND == PREV_FINAL_UPPERBAND: if CLOSE <= FINAL_UPPERBAND: SUPERTREND = FINAL_UPPERBAND else: SUPERTREND = FINAL_LOWERBAND elif PREV_SUPERTREND == PREV_FINAL_LOWERBAND: if CLOSE >= FINAL_LOWERBAND: SUPERTREND = FINAL_LOWERBAND else: SUPERTREND = FINAL_UPPERBAND
- 終値のEMA (n = ema_period) を求め、その値がSUPERTREND 指標 より上だった場合ロングポジション、下だった場合はショートポジションをとってホールドする。
それぞれ、period, multiplier, ema_periodがチューニング可能なパラメータになります。
4. バックテスト
backtesting.pyは、取引戦略の有効性を過去のデータを使って検証(バックテスト)するときに使うツールです。
以下、SMAクロスオーバー戦略での実装例を紹介します。
戦略はbacktestingのStrategyクラスを継承することで実装します。
from backtesting import Strategy from backtesting.lib import crossover from backtesting.test import SMA class SmaCross(Strategy): n_s = 10 n_l = 20 def init(self): self.sma_s = self.I(SMA, self.data["Close"], self.n_s) self.sma_l = self.I(SMA, self.data["Close"], self.n_l) def next(self): if crossover(self.sma_s, self.sma_l): self.position.close() self.buy() elif crossover(self.sma_l, self.sma_s): self.position.close() self.sell()
初期値とdataを与えることで、簡単にバックテストをすることができます。
簡単に、指定した条件でのパラメータの最適化を試すこともできます。
from backtesting import Backtest # バックテストの初期値設定 bt = BackTest( data, SmaCross, # SMAクロスオーバー戦略 cash=100000, # 初期予算 commission=0.002, # 取引手数料 ) # 取引戦略の最適なパラメータの探索(グリッドサーチ) stats = bt.optimize( n_s=range(5, 26, 5), # n_sの探索パラメータ n_l=range(10, 121, 10), # n_lの探索パラメータ maximize="Equity Final [$]", # 最終残高が最大になるように探索 constraint=lambda param: param.n_s < param.n_l # n_s < n_l を満たすように探索 ) # 結果の表示 stats.plot()
以下は、SMAクロスオーバー取引戦略をバックテストした結果です。
より詳しい使い方は、T.I.さんの過去記事で解説されています。ご参照ください。
5. パラメータの最適化
戦略のパラメータチューニングでは、目的関数を最大化するパラメータの組み合わせを探索する問題を解くことになります。一般的に使われる方法は、はじめに紹介するグリッドサーチです。
- グリッドサーチ(全探索)
指定した全てのパラメータの組み合わせを試して、最も性能がよかったパラメータを求める方法です。パラメータの取りうる値の範囲が広くなる、パラメータ数が多くなるほど、パラメータの組み合わせ数が増大することになります。 - ランダムサーチ
そこで、パラメータの組み合わせをランダムに選択し、上限に設定した回数までテストします。グリッドサーチと比較して、回数を制限している分、計算が高速に終わりますが、最適なパラメータに辿り着けるかは運任せになります。 - ベイズ最適化
ベイズ最適化 (Bayesian Optimization) とは、形状がわからない関数 (ブラックボックス関数) の最大値 (または最小値) を求めるための手法です。考え方はシンプルで、各ステップまでに調べた点をもとに、探索対象の変数から目的関数の形を推定しながら、平均と分散が大きくなる(最大化の場合)ように、次のステップで調べる点を決定することを繰り返します。このようにして、最終的に得られるのが、最適解になります。 - 遺伝的アルゴリズム
遺伝的アルゴリズムも、ベイズ最適化と同様、ブラックボックス最適化の手法の一つです。「選択」、「交叉」、「突然変異」などの生物の進化メカニズムを最適解の探索に応用した手法です。- 選択:世代の中からランダムに個体を選び、その中から適応度(取引では損益)の高い個体を取り出す
- 交叉:ある一定の確率で2個体の遺伝子の一部を交換し、子孫となる2個体を生成する
- 突然変異:個体の各遺伝子をある一定の確率で書き換える
パラメータの最適化問題では、遺伝子→パラメータ、個体→パラメータの組み合わせ、世代→パラメータの組み合わせのセットと読み替えることができます。
より詳しい内容は、過去記事をご確認ください。6. 実験と結果
SuperTrend戦略を用いて、実際のマーケットデータに対してどのくらいの成績を収めることができるのかを確認していきます。
実験条件は以下の通りです。- データ取得条件
- 取引所:Binance
- 板:BTC/USDT
- ローソク足:1分足
- 学習データの期間:2022/01/01 00:00:00 UTC ~ 2021/01/07 23:59:00 UTC
- テストデータの期間: 2022/01/08 00:00:00 UTC ~ 2021/01/08 23:59:00 UTC
- バックテストの設定値
- 予算:100000 USDT
- 手数料:0.002 USDT
- パラメータ探索の範囲
- “period”: range(5, 20, 5), [5, 120), [5, 120)
- “ema_period”: range(100, 200, 10), [100, 500), [100, 500)
- “multiplier”: range(1, 11), [1, 11), [1, 11)
(グリッドサーチ、ベイズ最適化、遺伝的アルゴリズムの順番に記述)
実験では、学習データを用いて取引戦略の最適なパラメータの探索を行い、そのパラメータを用いてテストデータで取引を実施した際の取引成績(最終損益、収益率)を確認します。
実験結果は以下の通りです。
実験結果から分かるように、いずれのパラメータ最適化を行っても、過去のデータを用いて、未来のデータで収益を上げることができました。特に、グリッドサーチ<< 遺伝的アルゴリズム < ベイズ最適化の順番で取引成績が良いことが分かります。
まとめ
今回は、Pythonで機械学習を使った暗号資産のシステムトレードに入門しました。金融初心者でも、ccxtとbacktesting.pyというライブラリを使えば簡単にバックテストを行うことができました。また、取引戦略のパラメータチューニングは、機械学習を用いた組み合わせ最適化問題に落とし込むことができ、最適なパラメータを探索した結果、過去のデータを用いて、未来のデータで収益を上げることができました。実際に、運用する際は定期的に学習し直して、パラメータの更新が必要かもしれませんが、自動取引で利益を上げるのも可能かも知れません。
次世システム研究室では、ビッグデータ解析プラットホームの設計・開発を行うアーキテクトとデータサイエンティストを募集しています。興味を持って頂ける方がいらっしゃいましたら、ぜひ 募集職種一覧からご応募をお願いします。 一緒に勉強しながら楽しく働きたい方のご応募をお待ちしております。
(免責事項:本記事は、収益を保証するものではありません。投資は自己責任です。)
参考
- What is SuperTrend Indicator?, https://www.tradingfuel.com/supertrend-indicator-formula-and-calculation/#Supertrend_Indicator_Formula_and_Calculation
- SuperTrend戦略のpython実装, https://note.com/shinseitaro/n/na18f67431dd4
- 遺伝的アルゴリズムの取引応用, https://note.com/magimagi1223/n/n34181710810e
グループ研究開発本部の最新情報をTwitterで配信中です。ぜひフォローください。
Follow @GMO_RD