问题描述
我对此很陌生。
backTrader有一个addwriter可以写一些数据, cerebro.addwriter(bt.WriterFile,csv=True,out='outputfiles3\{}cerebro.csv'.format(ticker))
但买入和卖出价格总是与执行价格不匹配。
或者:
我在cerebro.addanalyzer(WritingAnalyzer)
之前做了cerebro.run()
所以我试图用“日期时间”、“打开”、“关闭”、“现金”、“价值”、“仓位大小”来构建 csv 文件
但我不知道如何访问这些数据。我只能用 self.data[0]
我不知道怎么做才对。我希望有人能给我一些指导。
import backTrader as bt
from backTrader import Analyzer
import csv
class WritingAnalyzer(Analyzer):
def __init__(self):
def create_analysis(self):
self.counter = 0
print(self.counter)
with open('demo1.csv',mode='w') as csv_file:
fieldnames=['datetime','open','close','cash','value','position size']
writer = csv.DictWriter(csv_file,fieldnames=fieldnames)
writer.writeheader()
def next(self):
self.counter += 1
print('close price:',self.data[0],"counter:",self.counter,)
# the following line suppose to write into csv file but i dont kNow how to get most of the data.
bt.writer.writerow({'datetime': '??','open': '??','close': self.data[0],'cash':'??','value':'??','position size':'??'})
def stop(self):
print("SSSSSSSSSSSsstTTTTTOOOOOOOOOOOOPPPPPPPPPP")
self.rets._close()
解决方法
您需要以不同的方式处理分析器。您可以从字面上获取每个酒吧的数据,然后在最后提供给您。
创建一个新的分析器,在我的例子中我做了:
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(),]
)
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)