您需要以不同的方式处理您的分析仪。您可以从字面上抓取每个栏的数据,然后在最后将其提供给您。
创建一个新的分析器,在我的例子中,我做了:
class BarAnalysis(bt.analyzers.Analyzer):
在您的分析器中,您将创建一个新列表。
def start(self):
self.rets = list()
然后在下一步中,您将为每个条添加一个数据列表。我使用 try 语句以防万一出现任何数据问题,但可能没有必要。Strategy
作为子类包含在内,您可以通过调用self.strategy.getvalue()
作为示例来使用它的方法。
def next(self):
try:
self.rets.append(
[
self.datas[0].datetime.datetime(),
self.datas[0].open[0],
self.datas[0].high[0],
self.datas[0].low[0],
self.datas[0].close[0],
self.datas[0].volume[0],
self.strategy.getposition().size,
self.strategy.broker.getvalue(),
self.strategy.broker.getcash(),
]
)
except:
pass
最后创建一个get_analysis
方法,你可以用它来得到你的结果。
def get_analysis(self):
return self.rets
在运行 cerebro 之前添加您的分析仪。您可以随意命名,我们需要名称来调用结果。
cerebro.addanalyzer(BarAnalysis, _name="bar_data")
确保为 cerebro.run() 方法的结果提供一个变量,以便收集回测的结果。
strat = cerebro.run()
最后,从strat 中取出数据并按照您的意愿进行操作。在这种情况下,我正在创建一个数据框并打印。
bar_data_res = strat[0].analyzers.bar_data.get_analysis()
df = pd.DataFrame(bar_data_res)
print(df)
打印输出如下:
/home/runout/projects/rb_master/venv/bin/python /home/runout/projects/scratch/20210424_analyzer.py
0 1 2 ... 6 7 8
0 2020-01-02 23:59:59.999989 212.70 213.36 ... 0 10000.00 10000.00
1 2020-01-03 23:59:59.999989 210.81 213.28 ... 0 10000.00 10000.00
2 2020-01-06 23:59:59.999989 210.18 213.59 ... 0 10000.00 10000.00
3 2020-01-07 23:59:59.999989 213.11 214.13 ... 0 10000.00 10000.00
4 2020-01-08 23:59:59.999989 212.43 216.47 ... 0 10000.00 10000.00
.. ... ... ... ... .. ... ...
247 2020-12-23 23:59:59.999989 268.38 269.31 ... 1 10015.38 9747.25
248 2020-12-24 23:59:59.999989 267.76 269.67 ... 1 10016.48 9747.25
249 2020-12-28 23:59:59.999989 270.48 270.55 ... 1 10014.82 9747.25
250 2020-12-29 23:59:59.999989 268.30 268.78 ... 1 10011.78 9747.25
251 2020-12-30 23:59:59.999989 264.45 265.64 ... 1 10010.86 9747.25
[252 rows x 9 columns]
Process finished with exit code 0
整个代码如下所示:
import datetime
import backtrader as bt
import pandas as pd
class BarAnalysis(bt.analyzers.Analyzer):
def start(self):
self.rets = list()
def next(self):
try:
self.rets.append(
[
self.datas[0].datetime.datetime(),
self.datas[0].open[0],
self.datas[0].high[0],
self.datas[0].low[0],
self.datas[0].close[0],
self.datas[0].volume[0],
self.strategy.getposition().size,
self.strategy.broker.getvalue(),
self.strategy.broker.getcash(),
]
)
except:
pass
def get_analysis(self):
return self.rets
class Strategy(bt.Strategy):
params = (
("lowerband", 30),
("upperband", 70),
)
def __init__(self):
self.rsi = bt.ind.RSI(period=10)
def next(self):
if not self.position:
if self.rsi <= self.p.lowerband:
self.buy()
elif self.rsi >= self.p.upperband:
self.close()
if __name__ == "__main__":
cerebro = bt.Cerebro()
ticker = "HD"
data = bt.feeds.YahooFinanceData(
dataname=ticker,
timeframe=bt.TimeFrame.Days,
fromdate=datetime.datetime(2020, 1, 1),
todate=datetime.datetime(2020, 12, 31),
reverse=False,
)
cerebro.adddata(data, name=ticker)
cerebro.addanalyzer(BarAnalysis, _name="bar_data")
cerebro.addstrategy(Strategy)
# Execute
strat = cerebro.run()
bar_data_res = strat[0].analyzers.bar_data.get_analysis()
df = pd.DataFrame(bar_data_res)
print(df)