実現したいこと
ここに実現したいことを箇条書きで書いてください。
- > backtrader(バックテスト)に、注文を反映させたい。
前提
エントリーロジックには、以下のように単純なものしか記載していないのですが、
バックテストを行うと、一切エントリーがされていない状態となっています。
self.buy() elif self.position: self.sell()
実行後: Final Portfolio Value: 100000.0 Sharpe Ratio: None Max Drawdown: 0.0 Annual Return: OrderedDict([(datetime.datetime(2020, 2, 26, 23, 25), 0.0)]) Sharpe Ratio Analysis: OrderedDict([('sharperatio', None)]) Drawdown Analysis: AutoOrderedDict([('len', 0), ('drawdown', 0.0), ('moneydown', 0.0), ('max', AutoOrderedDict([('len', 0.0), ('drawdown', 0.0), ('moneydown', 0.0)]))]) Annual Return Analysis: OrderedDict([(datetime.datetime(2020, 2, 26, 23, 25), 0.0)])
該当のソースコード
python
1 2class PandasDataFeed(btfeeds.PandasData): 3 4 params = ( 5 ('datetime', -1), 6 ('high', 'high'), 7 ('low', 'low'), 8 ('close', 'close'), 9 ) 10 11 # 既存のデータフレーム 'df' に対して、NaNを含む行を削除 12 df = df.dropna() 13 14 def __init__(self): 15 super(PandasDataFeed, self).__init__() 16 17class BollingerStrategy(btStrategy): 18 params = { 19 'time_period_to_close': 1, 20 } 21 22 def __init__(self): 23 self.first_bar = True 24 25 self.datetime = self.datas[0].datetime 26 self.high = self.datas[0].high 27 self.low = self.datas[0].low 28 self.close = self.datas[0].close 29 self.bar_executed = 0 30 31 def next(self): 32 33 if self.first_bar: 34 self.first_bar = False 35 return 36 37 self.buy() 38 39 if self.position:g 40 self.sell() 41 42 def log(self, txt, dt=None): 43 """ Logging function for this strategy""" 44 dt = dt or self.datas[0].datetime.datetime(0) 45 print('%s, %s' % (dt.isoformat(), txt)) 46 47class SafeAnnualReturn(btanalyzers.AnnualReturn): 48 def start(self): 49 super().start() 50 self._value_start = self.strategy.broker.getvalue() 51 52 def stop(self): 53 value_start = self._value_start 54 value_end = self.strategy.broker.getvalue() 55 56 if value_start != 0.0 and len(self.strategy.datetime.array) > 0: 57 annualret = (value_end / value_start) - 1.0 58 if len(self.rets) > 0: 59 self.rets[self.strategy.datetime.datetime(-1)] = annualret 60 else: 61 self.rets[self.strategy.datetime.datetime(-1)] = annualret 62 else: 63 if len(self.strategy.datetime.array) > 0: 64 self.rets[self.strategy.datetime.datetime(-1)] = 0.0 65 else: 66 self.rets[self.strategy.datetime.datetime(-1)] = 0.0 67 68 def get_analysis(self): 69 return self.rets 70 71# バックテストの実行と評価 72# Cerebroエンジンの初期化 73cerebro = bt.Cerebro() 74 75# データフィードの追加 76data_feed = PandasDataFeed(dataname=df) 77cerebro.adddata(data_feed) 78 79# 戦略の追加 80cerebro.addstrategy(BollingerStrategy) 81 82# 分析機能の追加 83cerebro.addanalyzer(btanalyzers.SharpeRatio, _name='sharpe_ratio') 84cerebro.addanalyzer(btanalyzers.DrawDown, _name='drawdown') 85cerebro.addanalyzer(SafeAnnualReturn, _name='annual_return') 86cerebro.addanalyzer(btanalyzers.SharpeRatio, _name='mySharpeRatio') 87 88# 初期資本の設定 89cerebro.broker.setcash(100000.0) 90cerebro.addsizer(bt.sizers.FixedSize, stake=1) 91 92# バックテストの実行 93results = cerebro.run() 94 95# 分析結果の取得 96sharpe_ratio = results[0].analyzers.sharpe_ratio.get_analysis()['sharperatio'] 97drawdown = results[0].analyzers.drawdown.get_analysis() 98annual_return = results[0].analyzers.annual_return.get_analysis() 99 100# 最終資産額と分析結果の表示 101print('Final Portfolio Value:', cerebro.broker.getvalue()) 102print('Sharpe Ratio:', sharpe_ratio) 103print('Max Drawdown:', drawdown['max']['drawdown']) 104print('Annual Return:', annual_return) 105 106#results変数を確認し、異常な値が含まれているかどうかをチェック 107print("Sharpe Ratio Analysis:", results[0].analyzers.sharpe_ratio.get_analysis()) 108print("Drawdown Analysis:", results[0].analyzers.drawdown.get_analysis()) 109print("Annual Return Analysis:", results[0].analyzers.annual_return.get_analysis()) 110 111# プロットの設定 112plt.style.use('seaborn-whitegrid') 113matplotlib.rcParams.update({'font.size': 8}) 114fig, ax1 = plt.subplots(figsize=(12, 6)) 115 116# バックテストの結果をプロット 117cerebro.plot(iplot=False, ax=ax1) 118 119# プロットの保存 120plt.savefig("backtest_results.png", dpi=300, bbox_inches='tight') 121 122# 結果をファイルに保存 123with open("backtest_results.txt", "w") as f: 124 f.write("Final Portfolio Value: {}\n".format(cerebro.broker.getvalue())) 125 f.write("Sharpe Ratio: {}\n".format(sharpe_ratio)) 126 f.write("Max Drawdown: {}\n".format(drawdown['max']['drawdown'])) 127 f.write("Annual Return: {}\n".format(annual_return)) 128 f.write("\n") 129 f.write("Sharpe Ratio Analysis: {}\n".format(results[0].analyzers.sharpe_ratio.get_analysis())) 130 f.write("Drawdown Analysis: {}\n".format(results[0].analyzers.drawdown.get_analysis())) 131 f.write("Annual Return Analysis: {}\n".format(results[0].analyzers.annual_return.get_analysis())) 132 133# バックテスト結果の詳細を表示 134print("Strategy analysis:") 135for k, v in results[0].analyzers.items(): 136 print(" {}: {}".format(k, v.get_analysis())) 137 138print("Backtest completed successfully.")
試したこと
データに欠損値がないことは確認し、欠損値があれば行ごと削除するという前処理は実行しています。
df上のデータ、計算後のデータもprintで確認し問題はありませんでした。
補足情報(FW/ツールのバージョンなど)
windows11

回答2件
あなたの回答
tips
プレビュー