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 thinkhere 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:
- For the Strategy script: "Too many positional arguments for constructor call" in the crossover line (line22). And the compiler underlines the "bt."
- 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?? ^^
-
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