Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue with bt.plot() #1158

Open
btk-42 opened this issue Jul 13, 2024 · 6 comments
Open

Issue with bt.plot() #1158

btk-42 opened this issue Jul 13, 2024 · 6 comments

Comments

@btk-42
Copy link

btk-42 commented Jul 13, 2024

Expected Behavior

bt.plot() doesn't show up and returns error.

Actual Behavior

error:

/home/my_login/.virtualenvs/test-gwyt/lib/python3.12/site-packages/backtesting/test/__init__.py:8: FutureWarning: The argument 'infer_datetime_format' is deprecated and will be removed in a future version. A strict version of it is now the default, see https://pandas.pydata.org/pdeps/0004-consistent-to-datetime-parsing.html. You can safely remove this argument.
  return pd.read_csv(join(dirname(__file__), filename),
/home/my_login/.virtualenvs/test-gwyt/lib/python3.12/site-packages/backtesting/test/__init__.py:8: FutureWarning: The argument 'infer_datetime_format' is deprecated and will be removed in a future version. A strict version of it is now the default, see https://pandas.pydata.org/pdeps/0004-consistent-to-datetime-parsing.html. You can safely remove this argument.
  return pd.read_csv(join(dirname(__file__), filename),
Traceback (most recent call last):
  File "/home/my_login/test/app.py", line 28, in <module>
    bt.plot()
  File "/home/my_login/.virtualenvs/test-gwyt/lib/python3.12/site-packages/backtesting/backtesting.py", line 1592, in plot
    return plot(
           ^^^^^
  File "/home/my_login/.virtualenvs/test-gwyt/lib/python3.12/site-packages/backtesting/_plotting.py", line 250, in plot
    formatter=DatetimeTickFormatter(days=['%d %b', '%a %d'],
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/my_login/.virtualenvs/test-gwyt/lib/python3.12/site-packages/bokeh/models/formatters.py", line 593, in __init__
    super().__init__(*args, **kwargs)
  File "/home/my_login/.virtualenvs/test-gwyt/lib/python3.12/site-packages/bokeh/models/formatters.py", line 93, in __init__
    super().__init__(*args, **kwargs)
  File "/home/my_login/.virtualenvs/test-gwyt/lib/python3.12/site-packages/bokeh/model/model.py", line 119, in __init__
    super().__init__(**kwargs)
  File "/home/my_login/.virtualenvs/test-gwyt/lib/python3.12/site-packages/bokeh/core/has_props.py", line 304, in __init__
    setattr(self, name, value)
  File "/home/my_login/.virtualenvs/test-gwyt/lib/python3.12/site-packages/bokeh/core/has_props.py", line 336, in __setattr__
    return super().__setattr__(name, value)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/my_login/.virtualenvs/test-gwyt/lib/python3.12/site-packages/bokeh/core/property/descriptors.py", line 330, in __set__
    value = self.property.prepare_value(obj, self.name, value)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/my_login/.virtualenvs/test-gwyt/lib/python3.12/site-packages/bokeh/core/property/bases.py", line 363, in prepare_value
    raise ValueError(f"failed to validate {obj_repr}.{name}: {error}")
ValueError: failed to validate DatetimeTickFormatter(id='p1046', ...).days: expected a value of type str, got ['%d %b', '%a %d'] of type list

Steps to Reproduce

  1. Install backtesting
  2. run example code

code:

from backtesting import Backtest, Strategy
from backtesting.lib import crossover

from backtesting.test import SMA, GOOG


class SmaCross(Strategy):
    n1 = 10
    n2 = 20

    def init(self):
        close = self.data.Close
        self.sma1 = self.I(SMA, close, self.n1)
        self.sma2 = self.I(SMA, close, self.n2)

    def next(self):
        if crossover(self.sma1, self.sma2):
            self.buy()
        elif crossover(self.sma2, self.sma1):
            self.sell()


bt = Backtest(GOOG, SmaCross,
              cash=10000, commission=.002,
              exclusive_orders=True)

output = bt.run()
bt.plot()

Additional info

Installing bokeh==3.4.2 fix the issue but makes everything lag and some other errors appears

/home/my_login/.virtualenvs/test-gwyt/lib/python3.12/site-packages/backtesting/test/__init__.py:8: FutureWarning: The argument 'infer_datetime_format' is deprecated and will be removed in a future version. A strict version of it is now the default, see https://pandas.pydata.org/pdeps/0004-consistent-to-datetime-parsing.html. You can safely remove this argument.
  return pd.read_csv(join(dirname(__file__), filename),
/home/my_login/.virtualenvs/test-gwyt/lib/python3.12/site-packages/backtesting/test/__init__.py:8: FutureWarning: The argument 'infer_datetime_format' is deprecated and will be removed in a future version. A strict version of it is now the default, see https://pandas.pydata.org/pdeps/0004-consistent-to-datetime-parsing.html. You can safely remove this argument.
  return pd.read_csv(join(dirname(__file__), filename),
BokehDeprecationWarning: Passing lists of formats for DatetimeTickFormatter scales was deprecated in Bokeh 3.0. Configure a single string format for each scale
/home/my_login/.virtualenvs/test-gwyt/lib/python3.12/site-packages/backtesting/_plotting.py:250: UserWarning: DatetimeFormatter scales now only accept a single format. Using the first provided: '%d %b'
  formatter=DatetimeTickFormatter(days=['%d %b', '%a %d'],
BokehDeprecationWarning: Passing lists of formats for DatetimeTickFormatter scales was deprecated in Bokeh 3.0. Configure a single string format for each scale
/home/my_login/.virtualenvs/test-gwyt/lib/python3.12/site-packages/backtesting/_plotting.py:250: UserWarning: DatetimeFormatter scales now only accept a single format. Using the first provided: '%m/%Y'
  formatter=DatetimeTickFormatter(days=['%d %b', '%a %d'],
/home/my_login/.virtualenvs/test-gwyt/lib/python3.12/site-packages/backtesting/_plotting.py:456: FutureWarning: 'M' is deprecated and will be removed in a future version, please use 'ME' instead.
  .resample(resample_rule, label='left')
/home/my_login/.virtualenvs/test-gwyt/lib/python3.12/site-packages/backtesting/_plotting.py:659: UserWarning: found multiple competing values for 'toolbar.active_drag' property; using the latest value
  fig = gridplot(
/home/my_login/.virtualenvs/test-gwyt/lib/python3.12/site-packages/backtesting/_plotting.py:659: UserWarning: found multiple competing values for 'toolbar.active_scroll' property; using the latest value
  fig = gridplot(
@sirkuredda
Copy link

Install the latest version from GitHub to incorporate recent fixes:
pip install git+https://github.com/kernc/backtesting.py.git

The PyPI version (0.3.3) may not include the necessary fix

@Dante-Berth
Copy link

Dante-Berth commented Aug 9, 2024

The solution is :
In the file named _plotting.py

if is_datetime_index:
       fig_ohlc.xaxis.formatter = CustomJSTickFormatter(
        args=dict(axis=fig_ohlc.xaxis[0],
                  formatter=DatetimeTickFormatter(
                      days="%d %b %Y",     # Example format for days
                      months="%b %Y",      # Example format for months
                      hours="%H:%M",       # Example format for hours
                      minutes="%H:%M",     # Example format for minutes
                      seconds="%H:%M:%S"   # Example format for seconds
                  ),
                  source=source)

Best regards

@0xAquaWolf
Copy link

Install the latest version from GitHub to incorporate recent fixes: pip install git+https://github.com/kernc/backtesting.py.git

The PyPI version (0.3.3) may not include the necessary fix

This helped me a lot, i was pulling out my hair yesterday trying to get this to work i tried everything under the sun, thank you so much, when will PyPi be updated to reflect the new changes?

@kenho811
Copy link

I experienced the same issue and came across this thread.

THe solution here works perfectly (#1158 (comment))

When will we have the update in PyPI please?

Thank you!!

@S1x-Data-Team
Copy link

if is_datetime_index:
fig_ohlc.xaxis.formatter = CustomJSTickFormatter(
args=dict(axis=fig_ohlc.xaxis[0],
formatter=DatetimeTickFormatter(
days="%d %b %Y", # Example format for days
months="%b %Y", # Example format for months
hours="%H:%M", # Example format for hours
minutes="%H:%M", # Example format for minutes
seconds="%H:%M:%S" # Example format for seconds
),

installing from git returning same error

@jkim12johnkim
Copy link

jkim12johnkim commented Nov 19, 2024

Not sure if this is still relevant but I had the same error until I made some adjustments to the initial data frame.

Initially,
df = yf.Ticker("SPY").history(start='2010-01-01', end='2021-01-01').tz_localize(None)
df.drop('Dividends', axis=1, inplace=True)
df.drop('Stock Splits', axis=1, inplace=True)
df.drop('Capital Gains', axis=1, inplace=True)
df=df[df.High!=df.Low]

returned "ValueError: failed to validate DatetimeTickFormatter(id='p1996', ...).days: expected a value of type str, got ['%d %b', '%a %d'] of type list" for bt.plot()

But once I reset the index:

df = yf.Ticker("SPY").history(start='2010-01-01', end='2021-01-01').tz_localize(None)

df=df[df.High!=df.Low]
df.drop('Dividends', axis=1, inplace=True)
df.drop('Stock Splits', axis=1, inplace=True)
df.drop('Capital Gains', axis=1, inplace=True)
df.reset_index(inplace=True)

bt.plot() returns the figures

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants