mirror of
https://github.com/wassname/catalyst.git
synced 2026-08-01 12:20:21 +08:00
This data bundle will use the quantopian mirror of the quandl WIKI data instead of downloading from quandl directly. This dramatically improves the speed because we do not pay the rate limiting for quandl and we can send the data in the format zipline expects.
166 lines
5.1 KiB
Python
166 lines
5.1 KiB
Python
import os
|
|
|
|
import numpy as np
|
|
import pandas as pd
|
|
from pandas_datareader.data import DataReader
|
|
import requests
|
|
|
|
from zipline.utils.cli import maybe_show_progress
|
|
|
|
|
|
def _cachpath(symbol, type_):
|
|
return '-'.join((symbol.replace(os.path.sep, '_'), type_))
|
|
|
|
|
|
def yahoo_equities(symbols, start=None, end=None):
|
|
"""Create a data bundle ingest function from a set of symbols loaded from
|
|
yahoo.
|
|
|
|
Parameters
|
|
----------
|
|
symbols : iterable[str]
|
|
The ticker symbols to load data for.
|
|
start : datetime, optional
|
|
The start date to query for. By default this pulls the full history
|
|
for the calendar.
|
|
end : datetime, optional
|
|
The end date to query for. By default this pulls the full history
|
|
for the calendar.
|
|
|
|
Returns
|
|
-------
|
|
ingest : callable
|
|
The bundle ingest function for the given set of symbols.
|
|
|
|
Examples
|
|
--------
|
|
This code should be added to ~/.zipline/extension.py
|
|
|
|
.. code-block:: python
|
|
|
|
from zipline.data.bundles import yahoo_equities, register
|
|
|
|
symbols = (
|
|
'AAPL',
|
|
'IBM',
|
|
'MSFT',
|
|
)
|
|
register('my_bundle', yahoo_equities(symbols))
|
|
|
|
Notes
|
|
-----
|
|
The sids for each symbol will be the index into the symbols sequence.
|
|
"""
|
|
# strict this in memory so that we can reiterate over it
|
|
symbols = tuple(symbols)
|
|
|
|
def ingest(environ,
|
|
asset_db_writer,
|
|
minute_bar_writer, # unused
|
|
daily_bar_writer,
|
|
adjustment_writer,
|
|
calendar,
|
|
cache,
|
|
show_progress,
|
|
output_dir,
|
|
# pass these as defaults to make them 'nonlocal' in py2
|
|
start=start,
|
|
end=end):
|
|
if start is None:
|
|
start = calendar[0]
|
|
if end is None:
|
|
end = None
|
|
|
|
metadata = pd.DataFrame(np.empty(len(symbols), dtype=[
|
|
('start_date', 'datetime64[ns]'),
|
|
('end_date', 'datetime64[ns]'),
|
|
('symbol', 'object'),
|
|
]))
|
|
|
|
def _pricing_iter():
|
|
sid = 0
|
|
with maybe_show_progress(
|
|
symbols,
|
|
show_progress,
|
|
label='Downloading Yahoo pricing data: ') as it, \
|
|
requests.Session() as session:
|
|
for symbol in it:
|
|
path = _cachpath(symbol, 'ohlcv')
|
|
try:
|
|
df = cache[path]
|
|
except KeyError:
|
|
df = cache[path] = DataReader(
|
|
symbol,
|
|
'yahoo',
|
|
start,
|
|
end,
|
|
session=session,
|
|
).sort_index()
|
|
|
|
# the start date is the date of the first trade and
|
|
# the end date is the date of the last trade
|
|
metadata.iloc[sid] = df.index[0], df.index[-1], symbol
|
|
df.rename(
|
|
columns={
|
|
'Open': 'open',
|
|
'High': 'high',
|
|
'Low': 'low',
|
|
'Close': 'close',
|
|
'Volume': 'volume',
|
|
},
|
|
inplace=True,
|
|
)
|
|
yield sid, df
|
|
sid += 1
|
|
|
|
daily_bar_writer.write(_pricing_iter(), show_progress=True)
|
|
|
|
symbol_map = pd.Series(metadata.symbol.index, metadata.symbol)
|
|
asset_db_writer.write(equities=metadata)
|
|
|
|
adjustments = []
|
|
with maybe_show_progress(
|
|
symbols,
|
|
show_progress,
|
|
label='Downloading Yahoo adjustment data: ') as it, \
|
|
requests.Session() as session:
|
|
for symbol in it:
|
|
path = _cachpath(symbol, 'adjustment')
|
|
try:
|
|
df = cache[path]
|
|
except KeyError:
|
|
df = cache[path] = DataReader(
|
|
symbol,
|
|
'yahoo-actions',
|
|
start,
|
|
end,
|
|
session=session,
|
|
).sort_index()
|
|
|
|
df['sid'] = symbol_map[symbol]
|
|
adjustments.append(df)
|
|
|
|
adj_df = pd.concat(adjustments)
|
|
adj_df.index.name = 'date'
|
|
adj_df.reset_index(inplace=True)
|
|
|
|
splits = adj_df[adj_df.action == 'SPLIT']
|
|
splits = splits.rename(
|
|
columns={'value': 'ratio', 'date': 'effective_date'},
|
|
)
|
|
splits.drop('action', axis=1, inplace=True)
|
|
|
|
dividends = adj_df[adj_df.action == 'DIVIDEND']
|
|
dividends = dividends.rename(
|
|
columns={'value': 'amount', 'date': 'ex_date'},
|
|
)
|
|
dividends.drop('action', axis=1, inplace=True)
|
|
# we do not have this data in the yahoo dataset
|
|
dividends['record_date'] = pd.NaT
|
|
dividends['declared_date'] = pd.NaT
|
|
dividends['pay_date'] = pd.NaT
|
|
|
|
adjustment_writer.write(splits=splits, dividends=dividends)
|
|
|
|
return ingest
|