Navigation

    Backtrader Community

    • Register
    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    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)

    General Code/Help
    3
    5
    804
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • SVetter
      SVetter last edited by

      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)

      1 Reply Last reply Reply Quote 2
      • A
        ab_trader last edited by

        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 my answer helped, hit reputation up arrow at lower right corner of the post.
        • Python Debugging With Pdb
        • New to python and bt - check this out
        1 Reply Last reply Reply Quote 1
        • run-out
          run-out last edited by

          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")
          

          RunBacktest.com

          1 Reply Last reply Reply Quote 1
          • run-out
            run-out last edited by

            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.

            RunBacktest.com

            1 Reply Last reply Reply Quote 0
            • SVetter
              SVetter last edited by

              thanks for the feedback. very helpful!

              1 Reply Last reply Reply Quote 1
              • 1 / 1
              • First post
                Last post
              Copyright © 2016, 2017, 2018, 2019, 2020, 2021 NodeBB Forums | Contributors