backtesting.pyを使って、ビットコインをゴールデンクロスで買って、デッドクロスで売ったら、儲かるか?のバックテスト
公式HP
https://kernc.github.io/backtesting.py/
1 |
pip3 install backtesting |
ビットコインをゴールデンクロスで買って、デッドクロスで売ったら、儲かるか?のバックテスト
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
# ライブラリ from backtesting import Backtest, Strategy from backtesting.lib import crossover from backtesting.test import SMA, GOOG import requests from datetime import datetime import pandas as pd # Cryptowatchから価格データ取得。1分足(60秒)で過去1000分(16時間40分)がもらえる response = requests.get("https://api.cryptowat.ch/markets/bitflyer/btcfxjpy/ohlc",params = { "periods" : 60 }).json() # データフレームの列名は"Time"、"Open"、"High"、"Low"、"Close"である必要がある。 df_columns = [ "Time", "Open", "High", "Low", "Close", "Volume", "QuoteVolume" ] # ベクトル化(pandasのデータフレーム化)して、for文を使わなくても、SQLのUPDATE文みたいに一気に更新できるのが便利! df = pd.DataFrame(response['result']['60'], columns=df_columns) # Time列は文字列だとうまくいかないので、日付型にして投入する df['Time'] = pd.to_datetime(df['Time'].astype(int), unit='s') # 変換したら、インデックスである事を明示する必要がある df.set_index("Time", inplace=True) # 売買アルゴリズム(SMA = Simple Moving Average = 単純移動平均線) class SmaCross(Strategy): n1 = 25 # 短期 n2 = 75 # 長期 # 初期化 def init(self): close = self.data.Close # 基準は終値 self.sma1 = self.I(SMA, close, self.n1) # 短期の移動平均線を生成 self.sma2 = self.I(SMA, close, self.n2) # 長期の移動平均線を生成 # 各レコードでの売買判定 def next(self): # ゴールデンクロスなら買い if crossover(self.sma1, self.sma2): self.buy() # デッドクロスなら売り elif crossover(self.sma2, self.sma1): self.sell() # バックテストの設定 bt = Backtest(df, # 検証データ SmaCross, #売買アルゴリズム cash=123456789, #投資金額(USドル) commission=.002, #手数料 exclusive_orders=False) #自動でポジションをクローズ(オープン) # バックテスト実行 output = bt.run() # 結果 print(output) # グラフ出力(HTMLファイル) # bt.plot() |
結果は、マイナス1%やな…。
Buy & Hold Return [%] 1.89312
だから、ガチホしてたらプラス2%弱…。
Start 2023-01-16 15:11:00 開始日時
End 2023-01-17 08:01:00 終了日時
Duration 0 days 16:50:00 取引にかかった時間
Exposure Time [%] 90.2 保有していた期間パーセンテージ
Equity Final [$] 1.22173e+08 最終的に売った金額
Equity Peak [$] 1.23459e+08 保有期間中の最高額
Return [%] -1.03992 プラスなら儲け、マイナスなら損したパーセンテージ
Buy & Hold Return [%] 1.89312 最初に買って最後に売るガチホ時のリターン
Return (Ann.) [%] 2.49521 年リターン?
Volatility (Ann.) [%] NaN 年の振れ幅?
Sharpe Ratio NaN
Sortino Ratio inf
Calmar Ratio 1.10447
Max. Drawdown [%] -2.2592 一番下った時のパーセンテージ
Avg. Drawdown [%] -1.21748 下落時の平均
Max. Drawdown Duration 0 days 15:10:00 一番長かった下落期間
Avg. Drawdown Duration 0 days 07:37:00 下落期間の平均
# Trades 1 売買回数
Win Rate [%] 0 勝率(勝ち回数/取引回数)、損なら0
Best Trade [%] -1.06017 一番良かった売買
Worst Trade [%] -1.06017 一番悪かった売買
Avg. Trade [%] -1.06017 売買の平均
Max. Trade Duration 0 days 15:12:00 最長保有期間
Avg. Trade Duration 0 days 15:12:00 保有期間の平均
Profit Factor 0 総利益/総損失
Expectancy [%] -1.06017 損益期待値
SQN NaN #SQN(SystemQualityNumber)
_strategy SmaCross #手法の関数名とパラメータ
_equity_curve …
_trades Size EntryBa…
dtype: object
独自の売買アルゴリズムが必要。結果が分かった状態なら楽だけどね~。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
# Strategyクラスを継承して、売買アルゴリズムのクラスを作る class myCustomStrategy(Strategy): def init(self): pass #初期化は何もしない # データフレーム毎にコールされる def next(self): # print(self.data) # 最安値近くで買う if self.data.Close < 380*10000: # 終値が380万円以上になったら買い! self.buy() # 最高値近くで買う if self.data.Close > 430*10000: # 終値が430万円以上になったら売り! # self.sell() # 空売りになる self.position.close() # これなら必ず、買い→売りになる # バックテストの設定 bt = Backtest(df, # 検証データ myCustomStrategy, #売買アルゴリズム cash=400*10000, #投資金額 commission=.002, #手数料 exclusive_orders=False) #自動でポジションをクローズ(オープン) |