简体   繁体   中英

extract dataframe from pandas datafeed in backtrader

I have my pandas backtrader datafeed created and passed in via:

data = bt.feeds.PandasData(dataname= **my_data.candles_to_backtrader(pandas))
cerebro.adddata(data)

I'm creating a new indicator that needs to get back out the dataframe from the data feed

or actually just perform operations like min , max on the data.

in my indicator I have:

def next(self):
    ...
    minr = datas[0].min()
    ...

this is not working, mentioning:

AttributeError: 'Lines_LineSeries_DataSeries_OHLC_OHLCDateTime_Abst' object has no attribute 'min'

any clues?

backtrader is not pandas and it is not conceived to be used as a Dataframe .

From your example:

def next(self):
    ...
    minr = datas[0].min()
    ...

It should actually be self.datas[0] or even better self.data0 or self.data , which simplifies things, but that's not the point.

The key point is here

    minr = datas[0].min()

First:

  • When you are referring to self.datas[0] and doing something with it, you are referring to the close price. Why? Because the industry settled on that a long time ago and it also enables the development of generic indicators that do not have to reference a specific field (when you have Indicators on Indicators on Indicators it becomes obvious that being generic is the way to go)

Second:

  • You are apparently asking for the minimum of the entire, already gone through, series.

    Indicators as conceived have a lookback period and don't (usually, but you may) look at the entire series back.

Third:

  • Even if you have used a Dataframe as your input, backtrader doesn't work with this structure internally (it is conscious design decision) and each of the elements which make a price bar or the output of an indicator are individual arrays.

No. backtrader is not a Dataframe and it is not meant to be used as one. You can always slice the desired lines and create a Dataframe or Series from them.

See: Backtrader Documentation - Platform Concepts and the Section: Slicing

I got from several sources that backtrader is not (and not going to) support calculations with pandas dataframe.

Here's the method to convert self.datas[0] to a pandas dataframe, passing len(self) in too, to support proper backtesting.

here's the code:

def __bt_to_pandas__(self, btdata, len):
    get = lambda mydata: mydata.get(ago=0, size=len)

    fields = {
        'open': get(btdata.open),
        'high': get(btdata.high),
        'low': get(btdata.low),
        'close': get(btdata.close),
        'volume': get(btdata.volume)
    }
    time = [btdata.num2date(x) for x in get(btdata.datetime)]

    return pd.DataFrame(data=fields, index=time)

Where btdata can be simply self.datas[0] and len can be len(self)

hope this helps

AttributeError: 'Lines_LineSeries_DataSeries_OHLC_OHLCDateTime_Abst' object has no attribute 'min'

this means you are trying to get the min of a Abst object or objects

the reason of this issue maybe

You probably have a 2.0 account and the code is failing to receive the contractdetails from the server. You need a legacy account.

qutoe from : backtrader link

so solution is find the correct series to get min

minr = datas["something different"].min()

if you can provide the data sample, i can help detail

or if you really wanna sort datetime , u can always try convert it to unix timestamp first

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM