mirror of
https://github.com/wassname/catalyst.git
synced 2026-07-15 11:22:18 +08:00
204 lines
6.2 KiB
Python
204 lines
6.2 KiB
Python
import os
|
|
|
|
import numpy as np
|
|
import pandas as pd
|
|
from pandas_datareader.data import DataReader
|
|
import requests
|
|
|
|
from zipline.utils.calendars import register_calendar_alias
|
|
from zipline.utils.cli import maybe_show_progress
|
|
from .core import register
|
|
|
|
|
|
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,
|
|
start_session,
|
|
end_session,
|
|
cache,
|
|
show_progress,
|
|
output_dir,
|
|
# pass these as defaults to make them 'nonlocal' in py2
|
|
start=start,
|
|
end=end):
|
|
if start is None:
|
|
start = start_session
|
|
if end is None:
|
|
end = None
|
|
|
|
metadata = pd.DataFrame(np.empty(len(symbols), dtype=[
|
|
('start_date', 'datetime64[ns]'),
|
|
('end_date', 'datetime64[ns]'),
|
|
('auto_close_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
|
|
start_date = df.index[0]
|
|
end_date = df.index[-1]
|
|
# The auto_close date is the day after the last trade.
|
|
ac_date = end_date + pd.Timedelta(days=1)
|
|
metadata.iloc[sid] = start_date, end_date, ac_date, 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=show_progress)
|
|
|
|
symbol_map = pd.Series(metadata.symbol.index, metadata.symbol)
|
|
|
|
# Hardcode the exchange to "YAHOO" for all assets and (elsewhere)
|
|
# register "YAHOO" to resolve to the NYSE calendar, because these are
|
|
# all equities and thus can use the NYSE calendar.
|
|
metadata['exchange'] = "YAHOO"
|
|
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
|
|
|
|
|
|
# bundle used when creating test data
|
|
register(
|
|
'.test',
|
|
yahoo_equities(
|
|
(
|
|
'AMD',
|
|
'CERN',
|
|
'COST',
|
|
'DELL',
|
|
'GPS',
|
|
'INTC',
|
|
'MMM',
|
|
'AAPL',
|
|
'MSFT',
|
|
),
|
|
pd.Timestamp('2004-01-02', tz='utc'),
|
|
pd.Timestamp('2015-01-01', tz='utc'),
|
|
),
|
|
)
|
|
|
|
register_calendar_alias("YAHOO", "NYSE")
|