For code/output blocks: Use ``` (aka backtick or grave accent) in a single line before and after the block. See: http://commonmark.org/help/

Create Indicator Line from DataFrame (not from data in Cerebros)



  • Hi everyone,
    I have tried finding an answer to this in the community, but never found the exact solution unfortunately. I have seen and understood that backtrader does not intend to rely on any other modules / libraries and I fully understand that decision.

    I am however struggling with the thought of having to port all indicators that are already out there using Pandas and wanted to work around that by (a) using PandasData to feed Cerebros (works perfectly fine, great job!) and (b) by using the same dataframe that is fed to Cerebros in "runstrat" to perform calculations from existing indicators using pandas.

    I have therefore made the dataframe a global variable to be accessed in "runstrat" as well as in my indicator class.

    # Get a pandas dataframe
    datapath = ('pandas-data.txt')
    # Simulate the header row isn't there if noheaders requested
    skiprows = 1 if _ARGS.noheaders else 0
    header = None if _ARGS.noheaders else 0
    
    _DATAFRAME = pandas.read_csv(datapath,
                                skiprows=skiprows,
                                header=header,
                                parse_dates=True,
                                index_col=0)
    

    feeding Cerebros:

    data = bt.feeds.PandasData(dataname=_DATAFRAME)
    

    and pulling it into the indicator:

    df = _DATAFRAME
    
    # Existing indicator logic using "df" 
    df['H-L']=abs(df['High']-df['Low'])
    df['H-PC']=abs(df['High']-df['Close'].shift(1))
    ...
    

    However at the end of the calculation using Pandas, I end up needing to assign the result (which is a column in the Pandas dataframe, so a "Series" (?) ) to my "self.lines.custom_indicator" if I am not mistaken?

    Is there a way to transfor this particular column into the line that I want the indicator to spit out? The functions in "backtrader" (e.g. bt.All()) were not documented and I'm not quite sure if I may have missed a very easy way to do this?

    Let me know if you need more code examples. I'm really excited to use this library and would assume someone else has had this issue / question?

    Thanks!

    (I have tried porting some of the more complicated indicators, buut would really save a lot of time if I could fall back onto the existing Pandas implementations)



  • You may want to try to extend data feed. In the data feed you can have additional columns with the indicator values pre-calculated using Pandas. Then based on this values bt can generate buy/sell signals. Check out Docs - Extebding a Data Feed.



  • If you wish to use the power of pandas, then you need to do it before feeding it into Backtrader.

    So let’s say you have this indicator you show above. First this is put it into a function, then when you are adding your data, if you wish to use this pandas indicator, send your dataframe to the function, and return it with an additional line(s).

    When the dataframe comes back, you will then add it into Backtrader with a custom data loader that includes the additional lines. Your example could look something like this:

    from backtrader import feeds as btfeeds
    
    class CustomDataLoader(btfeeds.PandasData):
    
        lines = (
            "H-L",
            "H-PC",
        )
    
        params = (
            ("H-L", 5),
            ("H-PC", 6),
        )
    
        datafields = btfeeds.PandasData.datafields + (
            [
                "H-L",
                "H-PC",
            ]
        )
    
    # Then create a function: 
    
    def HLPC(df):
        # Existing indicator logic using "df" 
        df['H-L']=abs(df['High']-df['Low'])
        df['H-PC']=abs(df['High']-df['Close'].shift(1))
        
        return df 
    
    
    # Then you apply these to your existing dataframe before sending it to Cerebro.
    dataframe = pd.read_csv("AAPL.csv", more stuff)
    dataframe = HLPC(dataframe)
    
    # Pass it to the backtrader datafeed and add it to the cerebro
    data = CustomDataLoader(dataname=dataframe, plot=True)
    
    cerebro.adddata(data, name="AAPL")
    


  • In fact, you could move the

    data = CustomDataLoader(dataname=dataframe, plot=True)
    

    Into the function HLPC() and return data which has the great benefit of not having to remember which customdataloader goes with which pandas function indicator.



  • thanks for the feedback. very helpful!


Log in to reply
 

});