You are here:  Home » 量化交易与机器学习 » zipline发生错误的解决方案(json.decoder.JSONDecodeError: Expecting value: line 1 column 1)

zipline运行时,发生以下情况的解决方案

(conda_zipline) Zipline>zipline run -f test.py --start 2014-4-1 --end 2014-8-1 --bundle custom-csvdir-bundle
[2019-09-11 00:40:20.167195] INFO: Loader: Cache at .zipline\data\SPY_benchmark.csv does not have data from 2014-04-01 00:00:00+00:00 to 2014-08-01 00:00:00+00:00.

[2019-09-11 00:40:20.167195] INFO: Loader: Downloading benchmark data for 'SPY' from 2014-03-31 00:00:00+00:00 to 2014-08-01 00:00:00+00:00

Traceback (most recent call last):
    raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

首先说一下,问题出在哪里了?

Zipline使用IEX API获取基准数据benchmarks.py

但是,根据IEX常见问题解答页面,图表api已于2019年6月15日删除。目前,使用此API尝试下载任何库存数据(如SPY)将只返回HTTP 403错误。不推荐使用的API的功能现在转移到新的API IEX Cloud,这需要在任何请求中为每个用户提供唯一的令牌。(去申请一个令牌也是很好的方法)

不想去申请的,就用下面的两种方法,自己适合哪种自己选择吧。

第一种:

默认情况下,通过在使一个HTTP请求溜索下载基准数据get_benchmark_returns()zipline/data/benchmarks.py。它返回一个pd.Series将被保存到csv文件ensure_benchmark_data()中的zipline/data/loaders.py。因此,我们可以通过将所有数据条目设置为零来创建虚拟基准文件。

方案是:修改上述两个文件。

zipline/data/benchmarks.py

import pandas as pd
from trading_calendars import get_calendar

def get_benchmark_returns(symbol, first_date, last_date):
    cal = get_calendar('NYSE')
    
    dates = cal.sessions_in_range(first_date, last_date)

    data = pd.DataFrame(0.0, index=dates, columns=['close'])
    data = data['close']

    return data.sort_index().iloc[1:]

zipline/data/loaders.py

修改前
data = get_benchmark_returns(symbol)
修改后
data = get_benchmark_returns(symbol, first_date, last_date)

第二种方法:

适用于yahoo的数据源

修改两个文件。

zipline/data/benchmarks.py

import numpy as np
import pandas as pd
import pandas_datareader.data as pd_reader

def get_benchmark_returns(symbol, first_date, last_date):
    """
    Get a Series of benchmark returns from Yahoo associated with `symbol`.
    Default is `SPY`.

    Parameters
    ----------
    symbol : str
        Benchmark symbol for which we're getting the returns.

    The data is provided by Yahoo Finance
    """
    data = pd_reader.DataReader(
        symbol,
        'yahoo',
        first_date,
        last_date
    )

    data = data['Close']

    data[pd.Timestamp('2008-12-15')] = np.nan
    data[pd.Timestamp('2009-08-11')] = np.nan
    data[pd.Timestamp('2012-02-02')] = np.nan

    data = data.fillna(method='ffill')

    return data.sort_index().tz_localize('UTC').pct_change(1).iloc[1:]

zipline/data/loaders.py

修改前
data = get_benchmark_returns(symbol)
修改后
data = get_benchmark_returns(symbol, first_date, last_date)