mirror of
https://github.com/wassname/catalyst.git
synced 2026-06-30 14:03:08 +08:00
4ba35d7d46
Instead of loading entire csv or xml into memory.
123 lines
3.5 KiB
Python
123 lines
3.5 KiB
Python
#
|
|
# Copyright 2013 Quantopian, Inc.
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
import collections
|
|
|
|
from datetime import datetime
|
|
|
|
import csv
|
|
|
|
from functools import partial
|
|
|
|
import requests
|
|
|
|
from loader_utils import (
|
|
date_conversion,
|
|
source_to_records,
|
|
Mapping
|
|
)
|
|
from zipline.protocol import DailyReturn
|
|
|
|
|
|
class BenchmarkDataNotFoundError(Exception):
|
|
pass
|
|
|
|
_BENCHMARK_MAPPING = {
|
|
# Need to add 'symbol'
|
|
'volume': (int, 'Volume'),
|
|
'open': (float, 'Open'),
|
|
'close': (float, 'Close'),
|
|
'high': (float, 'High'),
|
|
'low': (float, 'Low'),
|
|
'adj_close': (float, 'Adj Close'),
|
|
'date': (partial(date_conversion, date_pattern='%Y-%m-%d'), 'Date')
|
|
}
|
|
|
|
|
|
def benchmark_mappings():
|
|
return {key: Mapping(*value)
|
|
for key, value
|
|
in _BENCHMARK_MAPPING.iteritems()}
|
|
|
|
|
|
def get_raw_benchmark_data(start_date, end_date, symbol):
|
|
|
|
# create benchmark files
|
|
# ^GSPC 19500103
|
|
params = collections.OrderedDict((
|
|
('s', symbol),
|
|
# start_date month, zero indexed
|
|
('a', start_date.month - 1),
|
|
# start_date day
|
|
('b', start_date.day),
|
|
# start_date year
|
|
('c', start_date.year),
|
|
# end_date month, zero indexed
|
|
('d', end_date.month - 1),
|
|
# end_date day str(int(todate[6:8])) #day
|
|
('e', end_date.day),
|
|
# end_date year str(int(todate[0:4]))
|
|
('f', end_date.year),
|
|
# daily frequency
|
|
('g', 'd'),
|
|
))
|
|
|
|
res = requests.get('http://ichart.yahoo.com/table.csv',
|
|
params=params, stream=True)
|
|
|
|
if not res.ok:
|
|
raise BenchmarkDataNotFoundError("""
|
|
No benchmark data found for date range.
|
|
start_date={start_date}, end_date={end_date}, url={url}""".strip().
|
|
format(start_date=start_date,
|
|
end_date=end_date,
|
|
url=res.url))
|
|
|
|
return csv.DictReader(res.iter_lines())
|
|
|
|
|
|
def get_benchmark_data(symbol, start_date=None, end_date=None):
|
|
"""
|
|
Benchmarks from Yahoo.
|
|
"""
|
|
if start_date is None:
|
|
start_date = datetime(year=1950, month=1, day=3)
|
|
if end_date is None:
|
|
end_date = datetime.utcnow()
|
|
|
|
raw_benchmark_data = get_raw_benchmark_data(start_date, end_date, symbol)
|
|
|
|
mappings = benchmark_mappings()
|
|
|
|
return source_to_records(mappings, raw_benchmark_data)
|
|
|
|
|
|
def get_benchmark_returns(symbol, start_date=None, end_date=None):
|
|
if start_date is None:
|
|
start_date = datetime(year=1950, month=1, day=3)
|
|
if end_date is None:
|
|
end_date = datetime.utcnow()
|
|
|
|
benchmark_returns = []
|
|
|
|
for data_point in get_benchmark_data(symbol, start_date, end_date):
|
|
returns = (data_point['close'] - data_point['open']) / \
|
|
data_point['open']
|
|
daily_return = DailyReturn(date=data_point['date'], returns=returns)
|
|
benchmark_returns.append(daily_return)
|
|
|
|
# Reverse data so we can load it in reverse chron order.
|
|
benchmark_returns.reverse()
|
|
return benchmark_returns
|