quantopian / zipline

Zipline, a Pythonic Algorithmic Trading Library
https://www.zipline.io
Apache License 2.0
17.58k stars 4.71k forks source link

run_algorithm() fails because get_benchmark_returns() cannot fetch data from api.iextrading.com (403 Forbidden) #2607

Closed narun4sk closed 4 years ago

narun4sk commented 4 years ago

Dear Zipline Maintainers,

Before I tell you about my issue, let me describe my environment:

Environment

Now that you know a little about me, let me tell you about the issue I am having:

Description of Issue

zipline.run_algorithm is failing because internally it calls zipline.data.benchmarks.get_benchmark_returns, which then tries to fetch some data from the https://api.iextrading.com/1.0/stock/{}/chart/5y, however the site returns 403 Forbidden.

Example:

In [8]: r = requests.get('https://api.iextrading.com/1.0/stock/{}/chart/5y'.format('AAPL'))                                                                                                                                                   

In [9]: r.status_code                                                                                                                                                                                                                         
Out[9]: 403

In [10]: r.reason                                                                                                                                                                                                                             
Out[10]: 'Forbidden'

Relevant zipline stack trace:

<...>
  File "/home/jupyter/env/lib/python3.5/site-packages/zipline/utils/run_algo.py", line 430, in run_algorithm
    blotter=blotter,
  File "/home/jupyter/env/lib/python3.5/site-packages/zipline/utils/run_algo.py", line 159, in _run
    trading_days=trading_calendar.schedule[start:end].index,
  File "/home/jupyter/env/lib/python3.5/site-packages/zipline/finance/trading.py", line 103, in __init__
    self.bm_symbol,
  File "/home/jupyter/env/lib/python3.5/site-packages/zipline/data/loader.py", line 149, in load_market_data
    environ,
  File "/home/jupyter/env/lib/python3.5/site-packages/zipline/data/loader.py", line 216, in ensure_benchmark_data
    data = get_benchmark_returns(symbol)
  File "/home/jupyter/env/lib/python3.5/site-packages/zipline/data/benchmarks.py", line 35, in get_benchmark_returns
    data = r.json()
  File "/home/jupyter/env/lib/python3.5/site-packages/requests/models.py", line 897, in json
    return complexjson.loads(self.text, **kwargs)
  File "/usr/lib/python3.5/json/__init__.py", line 319, in loads
    return _default_decoder.decode(s)
  File "/usr/lib/python3.5/json/decoder.py", line 339, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "/usr/lib/python3.5/json/decoder.py", line 357, in raw_decode
    raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

Here is how you can reproduce this issue on your machine:

In [11]: from zipline.data.benchmarks import get_benchmark_returns                                                                                                                                                                            

In [12]: get_benchmark_returns('AAPL')                                                                                                                                                                                                        
---------------------------------------------------------------------------
JSONDecodeError                           Traceback (most recent call last)
<ipython-input-12-2a3dcf6e4f20> in <module>
----> 1 get_benchmark_returns('AAPL')

~/env/lib/python3.5/site-packages/zipline/data/benchmarks.py in get_benchmark_returns(symbol)
     33         'https://api.iextrading.com/1.0/stock/{}/chart/5y'.format(symbol)
     34     )
---> 35     data = r.json()
     36 
     37     df = pd.DataFrame(data)

~/env/lib/python3.5/site-packages/requests/models.py in json(self, **kwargs)
    895                     # used.
    896                     pass
--> 897         return complexjson.loads(self.text, **kwargs)
    898 
    899     @property

/usr/lib/python3.5/json/__init__.py in loads(s, encoding, cls, object_hook, parse_float, parse_int, parse_constant, object_pairs_hook, **kw)
    317             parse_int is None and parse_float is None and
    318             parse_constant is None and object_pairs_hook is None and not kw):
--> 319         return _default_decoder.decode(s)
    320     if cls is None:
    321         cls = JSONDecoder

/usr/lib/python3.5/json/decoder.py in decode(self, s, _w)
    337 
    338         """
--> 339         obj, end = self.raw_decode(s, idx=_w(s, 0).end())
    340         end = _w(s, end).end()
    341         if end != len(s):

/usr/lib/python3.5/json/decoder.py in raw_decode(self, s, idx)
    355             obj, end = self.scan_once(s, idx)
    356         except StopIteration as err:
--> 357             raise JSONDecodeError("Expecting value", s, err.value) from None
    358         return obj, end

JSONDecodeError: Expecting value: line 1 column 1 (char 0)
narun4sk commented 4 years ago
Help on function load_market_data in module zipline.data.loader:

load_market_data(trading_day=None, trading_days=None, bm_symbol='SPY', environ=None)
    Load benchmark returns and treasury yield curves for the given calendar and
    benchmark symbol.

    Benchmarks are downloaded as a Series from IEX Trading.  Treasury curves
    are US Treasury Bond rates and are downloaded from 'www.federalreserve.gov'
    by default.  For Canadian exchanges, a loader for Canadian bonds from the
    Bank of Canada is also available.

    Results downloaded from the internet are cached in
    ~/.zipline/data. Subsequent loads will attempt to read from the cached
    files before falling back to redownload.

I probably can extract the same data from the other internet sources... What format does zipline expect? It's quite an annoying issue for me, as I cannot proceed any further with my learning :disappointed:

If this may draw a bit more attention from the devs, this ongoing issue also breaks your Quickstart:

$ zipline run -f dual_moving_average.py --start 2014-1-1 --end 2018-1-1 -o dma.pickle
[2020-01-06 20:31:38.548002] INFO: Loader: Cache at /home/jupyter/.zipline/data/SPY_benchmark.csv does not have data from 2014-01-02 00:00:00+00:00 to 2017-12-29 00:00:00+00:00.

[2020-01-06 20:31:38.548265] INFO: Loader: Downloading benchmark data for 'SPY' from 2013-12-31 00:00:00+00:00 to 2017-12-29 00:00:00+00:00
Traceback (most recent call last):
  File "/home/jupyter/env/bin/zipline", line 8, in <module>
    sys.exit(main())
  File "/home/jupyter/env/lib/python3.5/site-packages/click/core.py", line 764, in __call__
    return self.main(*args, **kwargs)
  File "/home/jupyter/env/lib/python3.5/site-packages/click/core.py", line 717, in main
    rv = self.invoke(ctx)
  File "/home/jupyter/env/lib/python3.5/site-packages/click/core.py", line 1137, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/home/jupyter/env/lib/python3.5/site-packages/click/core.py", line 956, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/home/jupyter/env/lib/python3.5/site-packages/click/core.py", line 555, in invoke
    return callback(*args, **kwargs)
  File "/home/jupyter/env/lib/python3.5/site-packages/zipline/__main__.py", line 107, in _
    return f(*args, **kwargs)
  File "/home/jupyter/env/lib/python3.5/site-packages/click/decorators.py", line 17, in new_func
    return f(get_current_context(), *args, **kwargs)
  File "/home/jupyter/env/lib/python3.5/site-packages/zipline/__main__.py", line 276, in run
    blotter=blotter,
  File "/home/jupyter/env/lib/python3.5/site-packages/zipline/utils/run_algo.py", line 159, in _run
    trading_days=trading_calendar.schedule[start:end].index,
  File "/home/jupyter/env/lib/python3.5/site-packages/zipline/finance/trading.py", line 103, in __init__
    self.bm_symbol,
  File "/home/jupyter/env/lib/python3.5/site-packages/zipline/data/loader.py", line 149, in load_market_data
    environ,
  File "/home/jupyter/env/lib/python3.5/site-packages/zipline/data/loader.py", line 216, in ensure_benchmark_data
    data = get_benchmark_returns(symbol)
  File "/home/jupyter/env/lib/python3.5/site-packages/zipline/data/benchmarks.py", line 35, in get_benchmark_returns
    data = r.json()
  File "/home/jupyter/env/lib/python3.5/site-packages/requests/models.py", line 897, in json
    return complexjson.loads(self.text, **kwargs)
  File "/usr/lib/python3.5/json/__init__.py", line 319, in loads
    return _default_decoder.decode(s)
  File "/usr/lib/python3.5/json/decoder.py", line 339, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "/usr/lib/python3.5/json/decoder.py", line 357, in raw_decode
    raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
CapitalZe commented 4 years ago

I don't think Zipline is supported anymore.

narun4sk commented 4 years ago

@CapitalZe what do you mean by zipline not supported anymore? AFAIK project is not dead, isn't it?

CapitalZe commented 4 years ago

I'm not sure, but support seems to have waned dramatically over the past couple of months. I seldom see support or replies to the communities questions and issues.

I'm probably wrong though.

samatix commented 4 years ago

Hi @narun4sk ,

This is a known issue. You can check https://github.com/quantopian/zipline/issues/2480

The data management (from Quandl, IEX or other) used for the backtesting should be improved and configured outside zipline as a prerequisite.

Thanks

samatix commented 4 years ago

Hi @CapitalZe, Zipline is still maintained as per https://github.com/quantopian/zipline/pull/2558#issuecomment-562742435

ssanderson commented 4 years ago

I'm working to consolidate the issues around the benchmark into a single location in https://github.com/quantopian/zipline/issues/2627. Closing this in favor of that issue. Feel free to ping there or to reopen this if you think there's information in this issue that's not captured in the other one.