stefan-jansen / zipline-reloaded

Zipline, a Pythonic Algorithmic Trading Library
https://zipline.ml4trading.io
Apache License 2.0
1.13k stars 210 forks source link

AttributeError: 'UTC' object has no attribute 'key' #227

Closed litonchen closed 1 week ago

litonchen commented 11 months ago

Dear Zipline Maintainers,

I have run zipline-reloaded on colab and my windows.

Both met the same problem. In colab: AttributeError: 'UTC' object has no attribute 'key'

windows: AttributeError: 'datetime.timezone' object has no attribute 'key'

I have checked the original package. The error come from parse_date in calendar_helpers.py. It works well.

from exchange_calendars.calendar_helpers import parse_date,parse_timestamp
ts = parse_timestamp("2020-08-21 00:00:00", 'start', raise_oob=False)
print(ts.tz.key)

How to fix the problem?

gnzsnz commented 11 months ago

this is working on my environment

pyenv virtualenv 3.11.6 test
pip install zipline-reloaded
python
Python 3.11.6 (main, Oct 27 2023, 15:55:33) [Clang 15.0.0 (clang-1500.0.40.1)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from exchange_calendars.calendar_helpers import parse_date,parse_timestamp
>>> ts = parse_timestamp("2020-08-21 00:00:00", 'start', raise_oob=False)
>>> print(ts.tz.key)
UTC

if this is an error it's an error on exchange_calendars and not on zipline-reloaded.

AlexHemingway commented 11 months ago

Hi @gnzsnz

I encounter the same issue as above. When I run your code it works for me and I print 'UTC' nonethless, when I run run_algorithm I get the error:

'''AttributeError: 'datetime.timezone' object has no attribute 'key''''

Any idea where this might come from? Both zipline and exchange_calendars are up to date.

Thanks!

jianjiu-chen commented 11 months ago

Hi @litonchen

I encountered the same error message, and solved the problem by making the variables passed to the start and end (parameters of the run_algorithm function) timezone unaware, ie, avoid using .tz_localize("UTC").

The problem lies in the parse_date function of the calendar_helpers.py (see the related code below):

    375 ts = parse_timestamp(date, param_name, raise_oob=False, side="left", utc=False)
    377 if ts.tz is not None:
    378     raise ValueError(
--> 379         f"Parameter `{param_name}` received with timezone defined as '{ts.tz.key}'"
    380         f" although a Date must be timezone naive."
    381     )

If start and end are timezone aware, the date parameter on line 375 will be timezone aware, and the ts (returned value) will also be timezone aware. Because utc=False, ts.tz won't be given a key attribute by parse_timestamp, resulting in the error. Your code chunk works because utc=True by default, and parse_timestamp function will change the ts by adding a key attribute to it.

gnzsnz commented 11 months ago

in my case, on notebook "02_backtesting_with_zipline" chapter 8

I have commented the lines causing problems and added below a fix.

def load_predictions(bundle):
    predictions = pd.read_hdf('../00_data/backtest.h5', 'data')[['predicted']].dropna()
    tickers = predictions.index.get_level_values(0).unique().tolist()

    assets = bundle.asset_finder.lookup_symbols(tickers, as_of_date=None)
    #predicted_sids = pd.Int64Index([asset.sid for asset in assets])
    predicted_sids = pd.Index([asset.sid for asset in assets])
    ticker_map = dict(zip(tickers, predicted_sids))
    return (predictions
            .unstack('ticker')
            .rename(columns=ticker_map)
            .predicted
            #.tz_localize('UTC')), assets
            .tz_localize(None)), assets

there are a few cases in the notebooks that require changes due to changes on the underlying APIs. this happens with pandas 2 and greater.

ctbo3 commented 5 months ago

Hi @jianjiu-chen & @gnzsnz ,

I'm running into the AttributeError: 'datetime.timezone' object has no attribute 'key' issue as well. I've tried localizing the start and end dates with no success. Any other ideas?

result = run_algorithm(start=start.tz_localize('UTC'),
                       end=end.tz_localize('UTC'),
gnzsnz commented 5 months ago

@ctbo3 .tz_localize(None) is not working?

wei-liu commented 5 months ago

I am running into this as well. My solution was change the start=datetime(2000,1, 1) to a timestamp:

result = run_algorithm(start=pd.Timestamp(2000,1,1) ...
gmaubach commented 2 months ago

The AttributError 'datetime.timezone' object has no attribute 'key' is not an issue of Zipline itself but of the underlying exchange_calendars module. I filed an issue in the exchange_calendars repo: https://github.com/gerrymanoim/exchange_calendars/issues/408 .

stefan-jansen commented 1 week ago

Question appears to have been addressed to the extent here possible.

jimwhite commented 5 days ago

The AttributError 'datetime.timezone' object has no attribute 'key' is not an issue of Zipline itself but of the underlying exchange_calendars module. I filed an issue in the exchange_calendars repo: gerrymanoim/exchange_calendars#408 .

Although they have not yet replied there, I expect they will not accept this as an bug in exchange_calendars. That error you're reporting is occurring at the point where a ValueError is being raised because a timezone aware date (line 377: if ts.tz is not None:) was given to parse_date which comes from the call to trading_calendar.sessions_distance:

https://github.com/stefan-jansen/zipline-reloaded/blob/e945ae1b9ffcb0b2b3222dae30e58c8cdd2a4a0d/src/zipline/utils/run_algo.py#L103

I suspect that if the problem arose from a change in behavior of sessions_distance it entered Zipline with the move from <3.4 to 4.x:

https://github.com/stefan-jansen/zipline-reloaded/pull/158 MAINT: Move to exchange-calendars 4.x and more