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

AttributeError: 'DataFrame' object has no attribute 'setenvironment'"



  • I am new to backtrader, and I have a big problem. I want to start my strategy (just a simple GoldenCross strategy). This GoldenCross.py Script looks like this:

    import math
    import backtrader as bt
    
    class GoldenCross(bt.Strategy):
        params = (("fast", 50), 
                    ("slow", 200), 
                    ("order percentage", 0.95), 
                    ("ticker", "AAPL"))
    
    
        def __init__(self):
            self.fast_moving_average = self.bt.indicators.SmoothedMovingAverage(
               self.data.close, 
               period=self.p.fast,
               plotname="50 day moving average")
            self.slow_moving_average = self.bt.indicators.SmoothedMovingAverage(
               self.data.close, 
               period=self.p.slow,
               plotname="200 day moving average")
            self.crossover = self.bt.indicators.crossover(self.fast_moving_average, self.slow_moving_average)
    
        def next(self):
            pass
    

    Now I want to run the strategy with my run.py script. In this script the code looks like this:

    import os, sys, argparse
    import pandas as pd 
    import backtrader as bt 
    from Strategien.GoldenCross import GoldenCross
    import datetime
    
    
    
    cerebro = bt.Cerebro()
    cerebro.broker.setcash(100000)
    
    symbol = "AAPL"
    path = "/Users/me/Desktop/allgemein/Visual Studio/Stock Data/S&P500 Aktien 1H/" + symbol + ".csv"
    stock_prices = pd.read_csv(path)
    
    
    feed = bt.feeds.PandasData(dataname=stock_prices)
    #(dataname=stock_prices)
    cerebro.adddata(stock_prices)
    
    cerebro.addstrategy(GoldenCross)
    cerebro.run()
    cerebro.plot()
    

    Now the visual studio compiler gives me back an error called: "AttributeError: 'DataFrame' object has no attribute 'setenvironment'".

    I don't know what's the problem. Maby the problem is in my csv data.. My Date column looks like this:

         Unnamed: 0                      date    close     high      low     open
    0              0  2017-01-03T15:00:00.000Z  115.450  115.815  115.400  115.600
    1              1  2017-01-03T16:00:00.000Z  115.370  115.670  115.135  115.450
    2              2  2017-01-03T17:00:00.000Z  115.470  115.525  115.270  115.365
    3              3  2017-01-03T18:00:00.000Z  115.235  115.495  115.235  115.475
    4              4  2017-01-03T19:00:00.000Z  115.435  115.445  115.160  115.235
    ...          ...                       ...      ...      ...      ...      ...
    

    But I already tried to convert this date to date time with using :

    stock_prices['date'] = pd.to_datetime(stock_prices['date']) #object to datetime
    

    But this doesn't change the problem either..

    Does anyone have a good tip for me?

    best regards Christian

    PS. Maby it is also important to know, that the compiler also gives me back a "problem" called: "Unexpected keyword argument 'dataname' in constructor call"



  • You have some issues in your code:
    -you provide the pandas df to backtrader instead of the data feed
    -in your strategy, you have self.bt. ... which is wrong
    -dates in pandas df should be datetime objects, I think

    here is a corrected version of your code above:

    import backtrader as bt
    import math
    import datetime
    import pandas as pd
    
    
    class GoldenCross(bt.Strategy):
        params = (("fast", 50),
                  ("slow", 200),
                  ("order percentage", 0.95),
                  ("ticker", "AAPL"))
    
        def __init__(self):
            self.fast_moving_average = bt.indicators.SmoothedMovingAverage(
                self.data.close,
                period=self.p.fast,
                plotname="50 day moving average")
            self.slow_moving_average = bt.indicators.SmoothedMovingAverage(
                self.data.close,
                period=self.p.slow,
                plotname="200 day moving average")
            self.crossover = bt.indicators.CrossOver(
                self.fast_moving_average, self.slow_moving_average)
    
        def next(self):
            pass
    
    
    cerebro = bt.Cerebro()
    cerebro.broker.setcash(100000)
    
    symbol = "AAPL"
    path = "/Users/me/Desktop/allgemein/Visual Studio/Stock Data/S&P500 Aktien 1H/" + symbol + ".csv"
    # read csv, parse date, use dates col as index
    stock_prices = pd.read_csv(path, index_col=[0], parse_dates=[0])
    # create data feed pandas df
    feed = bt.feeds.PandasData(dataname=stock_prices)
    # add feed
    cerebro.adddata(feed)
    
    cerebro.addstrategy(GoldenCross)
    cerebro.run()
    cerebro.plot()
    


  • Hey @dasch Thank you for your help! And sorry for the late answer (I thought nobody would give me an answer :D )

    I copied your code into my run.py script. And to your the strategy code, I changed my crossover line to bt.indicators...

    the actual strategy.py script:

    import math
    import backtrader as bt
    
    
    
    
    class GoldenCross(bt.Strategy):
        params = (("fast", 50), 
                    ("slow", 200), 
                    ("order percentage", 0.95), 
                    ("ticker", "AAPL"))
        
        def __init__(self):
            self.fast_moving_average = self.bt.indicators.SmoothedMovingAverage(
               self.data.close, 
               period=self.p.fast,
               plotname="50 day moving average")
            self.slow_moving_average = self.bt.indicators.SmoothedMovingAverage(
               self.data.close, 
               period=self.p.slow,
               plotname="200 day moving average")
            self.crossover = bt.indicators.CrossOver(self.fast_moving_average, self.slow_moving_average)
    
        def next(self):
            pass
    

    the actual run.py script.:

    import os, sys, argparse
    import pandas as pd 
    import backtrader as bt 
    from Strategien.GoldenCross import GoldenCross
    import datetime
    
    
    cerebro = bt.Cerebro()
    cerebro.broker.setcash(100000)
    
    symbol = "AAPL"
    path = "/Users/christianbrendel/Desktop/allgemein/Visual Studio/Stock Data/S&P500 Aktien 1H/" + symbol + ".csv"
    # read csv, parse date, use dates col as index
    stock_prices = pd.read_csv(path, index_col=[0], parse_dates=[0])
    # create data feed pandas df
    feed = bt.feeds.PandasData(dataname=stock_prices)
    # add feed
    cerebro.adddata(feed)
    
    cerebro.addstrategy(GoldenCross)
    cerebro.run()
    cerebro.plot()
    
    

    But than my compiler gives me back these errors:

    1. For the Strategy script: "Too many positional arguments for constructor call" in the crossover line (line22). And the compiler underlines the "bt."
    2. For the run script: "Unexpected keyword argument 'dataname' in constructor call" for the bt.feeds.PandasData... Line (line16) and the compiler also underlines the "bt."

    Is it possible, that I imported my backtrader module wrong?



  • Yes, remove self. in the lines:

           self.fast_moving_average = self.bt.indicators.SmoothedMovingAverage(
    

    and

           self.slow_moving_average = self.bt.indicators.SmoothedMovingAverage(
    

    since you use the module bt, not an attribute of your strategy



  • they should read:

          self.fast_moving_average = bt.indicators.SmoothedMovingAverage(
    

    and

          self.slow_moving_average = bt.indicators.SmoothedMovingAverage(
          
    


  • Hey @dasch,
    thank you. If I write it like you did, than I get a lot of other problems from the compiler.. Like you can see on the screenshot.. Why does it works by everybody only not in my case?? ^^
    Bildschirmfoto 2020-06-17 um 14.28.56.png



  • Hey @dasch I tried an other way. I wrote:

    self.fast_moving_average = bt.indicators.SMA(
    

    in cases of

    self.fast_moving_average = bt.indicators.SmoothedMovingAverage(
    

    and now there is only one error left. This error is called "Too many positional arguments for constructor call" when I write this code:

            self.crossover = bt.indicators.CrossOver(self.fast_moving_average, self.slow_moving_average)
    
    

    and if I write this code:

            self.crossover = bt.indicators.crossover(self.fast_moving_average, self.slow_moving_average)
    
    

    The error is called again "Too many positional arguments for constructor call"



  • @chhrissi2909 in this line:

      self.crossover = bt.indicators.crossover(self.fast_moving_average, self.slow_moving_average)
    

    The error is: ***"bt.indicators.crossover is not callable"***. sorry..



  • @dasch Okay now I got it. Thank you for your help and sorry for these much replies... the fully code looks now like this:

    import os, sys, argparse
    import pandas as pd 
    import backtrader as bt 
    from Strategien.GoldenCross import GoldenCross
    import datetime
    
    
    cerebro = bt.Cerebro()
    cerebro.broker.setcash(100000)
    
    symbol = "AAPL"
    path = "/Users/christianbrendel/Desktop/allgemein/Visual Studio/Stock Data/S&P500 Aktien 1H/" + symbol + ".csv"
    # read csv, parse date, use dates col as index
    stock_prices = pd.read_csv(path, index_col=[0], parse_dates=[0])
    # create data feed pandas df
    feed = bt.feeds.PandasData(dataname=stock_prices)
    # add feed
    cerebro.adddata(feed)
    
    cerebro.addstrategy(GoldenCross)
    cerebro.run()
    cerebro.plot()
    
    
    


  • strategy.p script:

    import math
    import backtrader as bt
    
    
    class GoldenCross(bt.Strategy):
        params = (("fast", 50), 
                    ("slow", 200), 
                    ("order percentage", 0.95), 
                    ("ticker", "AAPL"))
    
        def __init__(self):
            self.fast_moving_average = bt.indicators.SMA(
               self.data.close, 
               period=self.p.fast,
               plotname="50 day moving average")
            self.slow_moving_average = bt.indicators.SMA(
               self.data.close, 
               period=self.p.slow,
               plotname="200 day moving average")
            self.crossover = self.bt.indicators.crossover(self.fast_moving_average, self.slow_moving_average)
    
        def next(self):
            pass
    

Log in to reply
 

});