I'm trying to learn backtesting.py, when I run the following sample code, it pops up these errors, anyone could help? I tried to uninstall the Bokeh package and reinstall an older version, but it doen't work.
BokehDeprecationWarning: Passing lists of formats for DatetimeTickFormatter scales was deprecated in Bokeh 3.0. Configure a single string format for each scale
C:\Users\paul_\AppData\Local\Programs\Python\Python310\lib\site-packages\bokeh\models\formatters.py:399: UserWarning: DatetimeFormatter scales now only accept a single format. Using the first prodvided: '%d %b'
warnings.warn(f"DatetimeFormatter scales now only accept a single format. Using the first prodvided: {fmt[0]!r} ")
BokehDeprecationWarning: Passing lists of formats for DatetimeTickFormatter scales was deprecated in Bokeh 3.0. Configure a single string format for each scale
C:\Users\paul_\AppData\Local\Programs\Python\Python310\lib\site-packages\bokeh\models\formatters.py:399: UserWarning: DatetimeFormatter scales now only accept a single format. Using the first prodvided: '%m/%Y'
warnings.warn(f"DatetimeFormatter scales now only accept a single format. Using the first prodvided: {fmt[0]!r} ")
GridPlot(id='p11925', ...)
import bokeh
import datetime
import pandas_ta as ta
import pandas as pd
from backtesting import Backtest
from backtesting import Strategy
from backtesting.lib import crossover
from backtesting.test import GOOG
class RsiOscillator(Strategy):
upper_bound = 70
lower_bound = 30
rsi_window = 14
# Do as much initial computation as possible
def init(self):
self.rsi = self.I(ta.rsi, pd.Series(self.data.Close), self.rsi_window)
# Step through bars one by one
# Note that multiple buys are a thing here
def next(self):
if crossover(self.rsi, self.upper_bound):
self.position.close()
elif crossover(self.lower_bound, self.rsi):
self.buy()
bt = Backtest(GOOG, RsiOscillator, cash=10_000, commission=.002)
stats = bt.run()
bt.plot()
An issue was opened for this in the GitHub repo:
https://github.com/kernc/backtesting.py/issues/803
A comment in the issue suggests to downgrade bokeh to 2.4.3:
python3 -m pip install bokeh==2.4.3
This worked for me.
I had a similar issue, using Spyder IDE.
Found out I need to call the below for the plot to show for Spyder.
backtesting.set_bokeh_output(notebook=False)
I have update Python to version 3.11 & downgrade bokeh to 2.4.3
This worked for me.
Downgrading Bokeh didn't work for me.
But, after importing backtesting in Jupyter, I needed to do:
backtesting.set_bokeh_output(notebook=False)
The expected plot was then generated in a new interactive browser tab.
Related
Trying to plot data using the matplotlib.pyplot.plot_date function with datetime objects originating from the netCDF4.num2date function I get the following error:
In [1]: from netCDF4 import num2date
In [2]: from matplotlib.pyplot import plot_date
In [3]: d=num2date((86400,2*86400),"seconds since 2000-01-01")
In [4]: gca().plot_date(d,(0,1))
...
AttributeError: 'cftime._cftime.DatetimeGregorian' object has no attribute 'toordinal'
The above exception was the direct cause of the following exception:
ConversionError
...
ConversionError: Failed to convert value(s) to axis units: array([cftime.DatetimeGregorian(2000-01-02 00:00:00),
cftime.DatetimeGregorian(2000-01-03 00:00:00)], dtype=object)
The following package versions are installed:
pandas 1.0.3
matplotlib 3.2.1
netcdf4 1.5.1.2
cftime 1.1.1.2
As the same thing perfectly works on a different machine with older package versions, I assume a version issue.
Also, I've tried the solution suggested in this thread and other related threads which seemed like a similar issue, but
from pandas.plotting import register_matplotlib_converters
register_matplotlib_converters()
didn't help neither.
Any suggestions welcome;)
Found the answer myself, from version 1.1.0 the num2date function in the cftime package changed its default behaviour to return cftime datetime instances instead of python datetime instances where possible (the option argument only_use_cftime_datetimes is now True by default, instead of False). The plot_date function however, at least currently, doesn't handle these.
To avoid the issue, use the arguments only_use_cftime_dateimes=False and only_use_python_datetime=True or use the convenience function num2pydate.
I've got a trouble when trying to run my jupyter notebook on another computer.
Here I want to plot some time series with matplotlib.pyplot module in order to overlay some points afterwards :
plt.plot(data_df["timestamp"],data_df["sensor_00"])
But then the interpreter/jupyter notebook keep running and only output the following information :
[<matplotlib.lines.Line2D at 0x2a0f892a908>]
Yet the code is working if I use the dataframe's plot argument :
data_df.set_index("timestamp")["sensor_00"].plot()
Outputs:
Just like I'd want ! I know i could just content myself with the dataframe's plotting method but I'll need the matplolib library for further visualizations.
This trouble happens with pandas objects and even when converting the values I want in numpy array, I just keep the program running and not displaying any output.
configuration on both computers :
OS : windows 10 (same as the last computer I did run before).
matplotlib version: 3.1.0 (updated on the computer but didn't work either)
Pandas version : 0.24.2
Python version : 3.7.3 on the new computer and 3.6.8 on the latter but I've tested on a 3.6.8 environment and still didn't work
Alright after a few things I tried, my "timestamp" feature wasn't typed as a datetime object.
What I did to solve the problem :
data_df = data_df.set_index("timestamp")
data_df.index = pd.DatetimeIndex(data_df.index)
Once the timestamp feature is now datetime object it plots fast just as it's supposed to do.
I am trying to make a span in bokeh using jupyter widgets.
from ipywidgets import interact
import numpy as np
from scipy.stats import norm
from bokeh.sampledata.daylight import daylight_warsaw_2013
from bokeh.io import push_notebook, show, output_notebook
from bokeh.plotting import figure
from bokeh.models import Span
output_notebook()
p = figure()
x_axis = np.arange(-10, 10, 0.001)
# Mean = 0, SD = 2.
y_axis = norm.pdf(x_axis,0,2)
p.line(x_axis, y_axis, line_dash='solid', line_width=2)
cutoff = Span(location=1,
dimension='height', line_color='green',
line_dash='dashed', line_width=2)
p.add_layout(cutoff)
show(p, notebook_handle=True)
def update(new_cutoff_location):
cutoff.location = new_cutoff_location
push_notebook()
interact(update, new_cutoff_location = 1.0)
When I run this code I get ValueError: PATCH-DOC message requires at least one event at push_notebook(). I suspect this indicates that the update to cutoff.location isn't getting detected, so it it looks as if there are no changes to send. Passing the handle doesn't seem to make a difference. Looking at the sample code in this github issue, it looks like there used to be an set method on span elements, but there doesn't appear to be one on my span element cutoff. Maybe there is a different function I am supposed to call to register the change?
I'm on bokeh 0.12.11 with jupyter 1.0.0, jupyter-client 5.1.0, jupyter-console 5.2.0, jupyter-core 4.4.0
This appears to be a regression in Bokeh 0.12.11. Your code works with version 0.12.10 so the immediate workaround is to downgrade. I've made GitHub issue here that you can follow. We will issue a new point release with a fix ASAP.
UPDATE: The issue is now fixed in recent versions of Bokeh
I am trying to get a price of a stock from google by using pandas-datareader.data but when I try to call Amazon(amazons price right now is over 1,000) it gives me a value error. I assume it is because of the comma in the price. It automatically attempts to turn it into a float so I have no opportunity to use a .replace function.
ValueError: could not convert string to float: '1,001.30'
I seemingly cannot seem to find a workaround to this issue so any help would be very appreciated, thanks.
import pandas_datareader.data as web
def money(stock):
#df = web.DataReader(stock, "google", start=start, end=end)
df2 = web.get_quote_google(stock)
I think there seems to be currently a compatibility issue with panads and pandas_datareader. However, this might solve your problem using yahoo-finance:
use pip install yahoo-finance to install the module and then run
import yahoo_finance
import pandas as pd
symbol = yahoo_finance.Share("AMZN")
google_df = symbol.get_price()
This gives me no error on the price of Amazon
I am trying to draw a graph networkx using python 3.6 with Jupyter notebook and the network package with anaconda. But the graph is not drawing per the documentation, I am just getting a deprecated message.
CODE:
import networkx as nx
import csv
import matplotlib as plt
G = nx.read_pajek('Hi-tech.net')
nx.draw(G)
MESSAGE:
MatplotlibDeprecationWarning: pyplot.hold is deprecated.
Future behavior will be consistent with the long-time default:
plot commands add elements without first clearing the
Axes and/or Figure.
b = plt.ishold()
Future behavior will be consistent with the long-time default:
plot commands add elements without first clearing the
Axes and/or Figure.
plt.hold(b)
warnings.warn("axes.hold is deprecated, will be removed in 3.0")
To avoid this warning, I just simply replace
nx.draw(G)
by
nx.draw_networkx(G)
My Python is 3.4, Jupyter '1.0.0' and networkx '1.11'.
I was able to get rid of the message by going into the networkx library and simply placing # in front of the lines which produced the error.
I would infer the .hold() function is no longer necessary, nor does it need ot be replaced
I could get nx.draw(G) to work by adding the following line of command:
%matplotlib inline
As error suggest ... I change nx_pylab.py at 611
# if cb.is_numlike(alpha):
if isinstance(alpha,numbers.Number):
I just commented out the line 365 of file __init__.py in Lib\site-packages\matplotlib\cbook which reads
#deprecated('3.0', 'isinstance(..., numbers.Number)')