我正在尝试使用backtrader对策略进行反向测试。我看到的大多数例子都只是使用csv文件。我想知道是否可以从交易所获取数据,将其转换为熊猫数据帧,然后使用backtrader?当我运行它时,我得到一个错误AttributeError: 'numpy.int64' object has no attribute 'lower'
,它指的是pandafeed.py
import ccxt,os
from dotenv import load_dotenv
import backtrader
class Trader:
def __init__(self) -> None:
load_dotenv()
self.connect()
""" Creates Binance client """
def connect(self):
self.exchange = ccxt.binance({
'apiKey': os.getenv('BINANCE_API_KEY'),
'secret': os.getenv('BINANCE_API_SECRET')
})
klines = Trader().exchange.fetch_ohlcv(symbol=trading_pair,timeframe=interval)
dataFrame = pd.DataFrame(klines)
dataFrame[0] = [datetime.fromtimestamp(t/1000) for t in dataFrame[0]]
data = backtrader.feeds.PandasData(dataname=dataFrame)
cerebro = backtrader.Cerebro()
cerebro.broker.set_cash(10000)
cerebro.adddata(data)
cerebro.run()
如果我使用列名并将代码更改为以下
colums = ['datetime', 'open','high', 'low', 'close', 'volume']
dataFrame = pd.DataFrame(klines, columns=colums)
dataFrame["datetime"] = [datetime.fromtimestamp(t/1000) for t in dataFrame["datetime"]]
data = backtrader.feeds.PandasData(dataname=dataFrame)
我收到这个错误
属性错误:"int"对象没有属性"to_pydatetime"pandafeed.py
我的问题是:我如何将列表变成可以用来运行backtrader的东西?非常感谢。
附言:klines
返回的示例数据结构类似
[[1621152000000,49375.28,49795.89,48656.0,49014.99,10956.006583],[16211640000,49014.99,49249.06,47566.01,47727.26,14166.961995],[1621118000000、47727.26、48097.59、44444.44、45549.26、36819.653456],[162119520000,45553.24,46480,43825.39,4643.15,28724.055984],[16212960000,46426.83,46686.0,42777.0,42915.46,28171.858447],[16212240000,42915.46,45400.0,42196.97,45149.18,40557.45817],[16212388400000,45143.28,45800.0,44291.84,45773.39,23851.50751],[1621528000,45733.55,45791.04,43156.0,43362.75,23137.989315],[16216720000、43357.0、44400.0、42001.0、44197.73、30883.162039],[16212860000,44197.73,44939.2,42500.0,43538.04,20055.197255],[16212960000,43538.02,45281.34,43150.79,44779.83,19252.919453],[16211040000044774.7845799.2944738.2645172184.30549],[162132480000045172.6945420.044607.0845225.718427.020047]]
我认为backtrader试图读取没有标头的标头。试着告诉PandasData没有标题。参见文档
data = backtrader.feeds.PandasData(dataname=dataFrame, header=None)
我遇到了同样的问题,调试后我发现它是附加的,因为backtrader希望你的数据帧按日期时间索引(为了简单起见(。然后要解决它,只需添加到您的代码中:
...
dataFrame = dataFrame.set_index('datetime')
...
在我的情况下,我还必须更改"日期时间"字段的类型,我这样做了:
...
dataFrame["datetime"] = dataFrame["datetime"].values.astype(dtype='datetime64[ms]')
dataFrame = dataFrame.set_index('datetime')
...
我希望这将对你有所帮助,即使你在两个月前问过这个问题。
添加到@alainivars回复,您需要
- 首先,将
datetime
转换为datetime64[ms]
- 可以将
datetime
设置为索引,也可以指定datetime = -1
在后台交易文档中:
# Possible values for datetime (must always be present)
# None : datetime is the "index" in the Pandas Dataframe
# -1 : autodetect position or case-wise equal name
# >= 0 : numeric index to the colum in the pandas dataframe
# string : column name (as index) in the pandas dataframe
('datetime', None),
因此,另一种解决方案:
dataFrame["datetime"] = pd.to_datetime(dataFrame["datetime"])
data = backtrader.feeds.PandasData(dataname=dataFrame, datetime=-1)