ImportError: cannot import name MIN_PER_HOUR - when trying to plot
-
I try to use the the example in the QuickStart tutorial however the plotting does not work ...
from __future__ import (absolute_import, division, print_function, unicode_literals) import datetime # For datetime objects import os.path # To manage paths import sys # To find out the script name (in argv[0]) # Import the backtrader platform import backtrader as bt # Create a Stratey class TestStrategy(bt.Strategy): params = ( ('maperiod', 15), ) def log(self, txt, dt=None): ''' Logging function fot this strategy''' dt = dt or self.datas[0].datetime.date(0) print('%s, %s' % (dt.isoformat(), txt)) def __init__(self): # Keep a reference to the "close" line in the data[0] dataseries self.dataclose = self.datas[0].close # To keep track of pending orders and buy price/commission self.order = None self.buyprice = None self.buycomm = None # Add a MovingAverageSimple indicator self.sma = bt.indicators.SimpleMovingAverage( self.datas[0], period=self.params.maperiod) # Indicators for the plotting show bt.indicators.ExponentialMovingAverage(self.datas[0], period=25) bt.indicators.WeightedMovingAverage(self.datas[0], period=25, subplot=True) bt.indicators.StochasticSlow(self.datas[0]) bt.indicators.MACDHisto(self.datas[0]) rsi = bt.indicators.RSI(self.datas[0]) bt.indicators.SmoothedMovingAverage(rsi, period=10) bt.indicators.ATR(self.datas[0], plot=False) def notify_order(self, order): if order.status in [order.Submitted, order.Accepted]: # Buy/Sell order submitted/accepted to/by broker - Nothing to do return # Check if an order has been completed # Attention: broker could reject order if not enough cash if order.status in [order.Completed]: if order.isbuy(): self.log( 'BUY EXECUTED, Price: %.2f, Cost: %.2f, Comm %.2f' % (order.executed.price, order.executed.value, order.executed.comm)) self.buyprice = order.executed.price self.buycomm = order.executed.comm else: # Sell self.log('SELL EXECUTED, Price: %.2f, Cost: %.2f, Comm %.2f' % (order.executed.price, order.executed.value, order.executed.comm)) self.bar_executed = len(self) elif order.status in [order.Canceled, order.Margin, order.Rejected]: self.log('Order Canceled/Margin/Rejected') # Write down: no pending order self.order = None def notify_trade(self, trade): if not trade.isclosed: return self.log('OPERATION PROFIT, GROSS %.2f, NET %.2f' % (trade.pnl, trade.pnlcomm)) def next(self): # Simply log the closing price of the series from the reference self.log('Close, %.2f' % self.dataclose[0]) # Check if an order is pending ... if yes, we cannot send a 2nd one if self.order: return # Check if we are in the market if not self.position: # Not yet ... we MIGHT BUY if ... if self.dataclose[0] > self.sma[0]: # BUY, BUY, BUY!!! (with all possible default parameters) self.log('BUY CREATE, %.2f' % self.dataclose[0]) # Keep track of the created order to avoid a 2nd order self.order = self.buy() else: if self.dataclose[0] < self.sma[0]: # SELL, SELL, SELL!!! (with all possible default parameters) self.log('SELL CREATE, %.2f' % self.dataclose[0]) # Keep track of the created order to avoid a 2nd order self.order = self.sell() if __name__ == '__main__': # Create a cerebro entity cerebro = bt.Cerebro() # Add a strategy cerebro.addstrategy(TestStrategy) # Datas are in a subfolder of the samples. Need to find where the script is # because it could have been called from anywhere modpath = os.path.dirname(os.path.abspath(sys.argv[0])) datapath = os.path.join(modpath, '../../datas/orcl-1995-2014.txt') # Create a Data Feed data = bt.feeds.YahooFinanceCSVData( dataname=datapath, # Do not pass values before this date fromdate=datetime.datetime(2000, 1, 1), # Do not pass values before this date todate=datetime.datetime(2000, 12, 31), # Do not pass values after this date reverse=False) # Add the Data Feed to Cerebro cerebro.adddata(data) # Set our desired cash start cerebro.broker.setcash(1000.0) # Add a FixedSize sizer according to the stake cerebro.addsizer(bt.sizers.FixedSize, stake=10) # Set the commission cerebro.broker.setcommission(commission=0.0) # Print out the starting conditions print('Starting Portfolio Value: %.2f' % cerebro.broker.getvalue()) # Run over everything cerebro.run() # Print out the final result print('Final Portfolio Value: %.2f' % cerebro.broker.getvalue()) # Plot the result cerebro.plot()
2014-12-23, Close, 46.01
2014-12-24, Close, 46.23
2014-12-26, Close, 46.10
2014-12-29, Close, 45.61
2014-12-30, Close, 45.34
Final Portfolio Value: 775.00
Traceback (most recent call last):
File "realstrat1.py", line 184, in <module>
cerebro.plot()
File "/Library/Python/2.7/site-packages/backtrader/cerebro.py", line 974, in plot
from . import plot
File "/Library/Python/2.7/site-packages/backtrader/plot/init.py", line 33, in <module>
from .plot import Plot, Plot_OldSync
File "/Library/Python/2.7/site-packages/backtrader/plot/plot.py", line 44, in <module>
from . import locator as loc
File "/Library/Python/2.7/site-packages/backtrader/plot/locator.py", line 35, in <module>
from matplotlib.dates import (HOURS_PER_DAY, MIN_PER_HOUR, SEC_PER_MIN,
ImportError: cannot import name MIN_PER_HOURany ideas how I can solve this issue?
Thanks
-
It works for everyone else and it is a defined value in the
matplotlib
sources.Either your
matplotlib
installation is corrupted, you have a version which pre-dates anything which was ever used withbacktrader
or something else. -
@thorsten99 I installed matplotlib 3.3.0 just yesterday and started having problems around dates. Different from yours (ImportError: cannot import 'warnings') but it might not be a coincidence. Try installing matplotlib version 3.2.2.
-
@kane said in ImportError: cannot import name MIN_PER_HOUR - when trying to plot:
@thorsten99 I installed matplotlib 3.3.0 just yesterday and started having problems around dates. Different from yours (ImportError: cannot import 'warnings') but it might not be a coincidence. Try installing matplotlib version 3.2.2.
same here.
I used matplotlib 3.3.0 -
@backtrader, I have the same problem. I have originally matplolib 3.2.2 and out of nowhere it stopped printing time labels on the x-axis, then I saw you have suggested installing an earlier version. However out of curiosity, I installed even newer version which is matplotlib 3.3.0, and now I'm getting same error as other guys!(ImportError: cannot import 'warnings')
@kane -
the same errror. Downgraded Matplotlib to 3.2.2 worked.
-
the same errror. Downgraded Matplotlib to 3.2.2 worked.
-
the error is in here
File "/Users/ch4r0n/.pyenv/versions/3.7.5/lib/python3.7/site-packages/backtrader/plot/plot.py", line 44, in <module> from . import locator as loc File "/Users/ch4r0n/.pyenv/versions/3.7.5/lib/python3.7/site-packages/backtrader/plot/locator.py", line 35, in <module> from matplotlib.dates import (HOURS_PER_DAY, MIN_PER_HOUR, SEC_PER_MIN, ImportError: cannot import name 'warnings' from 'matplotlib.dates' (/Users/ch4r0n/.pyenv/versions/3.7.5/lib/python3.7/site-packages/matplotlib/dates.py)
backtrader/plot/locator.py
from matplotlib.dates import (HOURS_PER_DAY, MIN_PER_HOUR, SEC_PER_MIN, MONTHS_PER_YEAR, DAYS_PER_WEEK, SEC_PER_HOUR, SEC_PER_DAY, num2date, rrulewrapper, YearLocator, MicrosecondLocator, warnings)
The 'warnings' modules has been remove in the matplotlib3.3.0
so you should delete it warningsfrom matplotlib.dates import (HOURS_PER_DAY, MIN_PER_HOUR, SEC_PER_MIN, MONTHS_PER_YEAR, DAYS_PER_WEEK, SEC_PER_HOUR, SEC_PER_DAY, num2date, rrulewrapper, YearLocator, MicrosecondLocator)
it worked!
-
@ch4r0n I applied the changes and still showing the same error, any suggestions?
complete code below(you need to change Alpaca keys to run, you can get your own key at https://alpaca.markets/)Complete code below:
from matplotlib.dates import (HOURS_PER_DAY, MIN_PER_HOUR, SEC_PER_MIN,
MONTHS_PER_YEAR, DAYS_PER_WEEK,
SEC_PER_HOUR, SEC_PER_DAY,
num2date, rrulewrapper, YearLocator,
MicrosecondLocator)
import alpaca_backtrader_api
import backtrader as bt
from datetime import datetime
#import matplotlibALPACA_API_KEY = "XXXX"
ALPACA_SECRET_KEY = "XXXX"
ALPACA_PAPER = Trueclass SmaCross(bt.SignalStrategy):
def init(self):
sma1, sma2 = bt.ind.SMA(period=10), bt.ind.SMA(period=30)
crossover = bt.ind.CrossOver(sma1, sma2)
self.signal_add(bt.SIGNAL_LONG, crossover)cerebro = bt.Cerebro()
cerebro.addstrategy(SmaCross)store = alpaca_backtrader_api.AlpacaStore(
key_id=ALPACA_API_KEY,
secret_key=ALPACA_SECRET_KEY,
paper=ALPACA_PAPER
)if not ALPACA_PAPER:
broker = store.getbroker() # or just alpaca_backtrader_api.AlpacaBroker()
cerebro.setbroker(broker)DataFactory = store.getdata # or use alpaca_backtrader_api.AlpacaData
data0 = DataFactory(dataname='AAPL', historical=True, fromdate=datetime(
2015, 1, 1), timeframe=bt.TimeFrame.Days)
cerebro.adddata(data0)print('Starting Portfolio Value: %.2f' % cerebro.broker.getvalue())
cerebro.run()
print('Final Portfolio Value: %.2f' % cerebro.broker.getvalue())
cerebro.plot() -
I am using MatPlotlib version 3.3.1
backtrader 1.9.76.123
python 3.8.5 -

-
I encountered the same issue.
python: 3.8.3
backtrader: 1.9.76.123
matplotlib: 3.3.1you can either downgrade to matplotlib 3.2.2 or refer this pull request to fix it yourself:
https://github.com/mementum/backtrader/pull/418