mirror of
https://github.com/saymrwulf/zipline.git
synced 2026-05-14 20:58:10 +00:00
versioneer let's us track the version using git tags. This prevents issues like the 0.8.2->0.8.3 push. This also puts the number of commits from the release and the commit you are on in the version.
251 lines
7 KiB
Python
251 lines
7 KiB
Python
#!/usr/bin/env python
|
|
#
|
|
# Copyright 2014 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.
|
|
from __future__ import print_function
|
|
|
|
import re
|
|
import sys
|
|
from operator import lt, gt, eq, le, ge
|
|
from os.path import (
|
|
abspath,
|
|
dirname,
|
|
join,
|
|
)
|
|
from distutils.version import StrictVersion
|
|
from setuptools import (
|
|
Extension,
|
|
find_packages,
|
|
setup,
|
|
)
|
|
|
|
import versioneer
|
|
|
|
|
|
class LazyCythonizingList(list):
|
|
cythonized = False
|
|
|
|
def lazy_cythonize(self):
|
|
if self.cythonized:
|
|
return
|
|
self.cythonized = True
|
|
|
|
from Cython.Build import cythonize
|
|
from numpy import get_include
|
|
|
|
self[:] = cythonize(
|
|
[
|
|
Extension(*ext_args, include_dirs=[get_include()])
|
|
for ext_args in self
|
|
]
|
|
)
|
|
|
|
def __iter__(self):
|
|
self.lazy_cythonize()
|
|
return super(LazyCythonizingList, self).__iter__()
|
|
|
|
def __getitem__(self, num):
|
|
self.lazy_cythonize()
|
|
return super(LazyCythonizingList, self).__getitem__(num)
|
|
|
|
|
|
ext_modules = LazyCythonizingList([
|
|
('zipline.assets._assets', ['zipline/assets/_assets.pyx']),
|
|
('zipline.lib.adjusted_array', ['zipline/lib/adjusted_array.pyx']),
|
|
('zipline.lib.adjustment', ['zipline/lib/adjustment.pyx']),
|
|
('zipline.lib.rank', ['zipline/lib/rank.pyx']),
|
|
(
|
|
'zipline.data._equities',
|
|
['zipline/data/_equities.pyx'],
|
|
),
|
|
(
|
|
'zipline.data._adjustments',
|
|
['zipline/data/_adjustments.pyx'],
|
|
),
|
|
])
|
|
|
|
|
|
STR_TO_CMP = {
|
|
'<': lt,
|
|
'<=': le,
|
|
'=': eq,
|
|
'==': eq,
|
|
'>': gt,
|
|
'>=': ge,
|
|
}
|
|
|
|
|
|
def _filter_requirements(lines_iter):
|
|
for line in lines_iter:
|
|
line = line.strip()
|
|
if not line or line.startswith('#'):
|
|
continue
|
|
|
|
# pip install -r understands line with ;python_version<'3.0', but
|
|
# whatever happens inside extras_requires doesn't. Parse the line
|
|
# manually and conditionally add it if needed.
|
|
if ';' not in line:
|
|
yield line
|
|
continue
|
|
|
|
requirement, version_spec = line.split(';')
|
|
try:
|
|
groups = re.match(
|
|
"(python_version)([<>=]{1,2})(')([0-9\.]+)(')(.*)",
|
|
version_spec,
|
|
).groups()
|
|
comp = STR_TO_CMP[groups[1]]
|
|
version_spec = StrictVersion(groups[3])
|
|
except Exception as e:
|
|
# My kingdom for a 'raise from'!
|
|
raise AssertionError(
|
|
"Couldn't parse requirement line; '%s'\n"
|
|
"Error was:\n"
|
|
"%r" % (line, e)
|
|
)
|
|
|
|
sys_version = '.'.join(list(map(str, sys.version_info[:3])))
|
|
if comp(sys_version, version_spec):
|
|
yield requirement
|
|
|
|
|
|
REQ_UPPER_BOUNDS = {
|
|
}
|
|
|
|
|
|
def _with_bounds(req):
|
|
try:
|
|
req, lower = req.split('==')
|
|
except ValueError:
|
|
return req
|
|
else:
|
|
with_bounds = [req, '>=', lower]
|
|
upper = REQ_UPPER_BOUNDS.get(req)
|
|
if upper:
|
|
with_bounds.extend([',', upper])
|
|
return ''.join(with_bounds)
|
|
|
|
|
|
def read_requirements(path, strict_bounds):
|
|
"""
|
|
Read a requirements.txt file, expressed as a path relative to Zipline root.
|
|
|
|
Returns requirements with the pinned versions as lower bounds
|
|
if `strict_bounds` is falsey.
|
|
"""
|
|
real_path = join(dirname(abspath(__file__)), path)
|
|
with open(real_path) as f:
|
|
reqs = _filter_requirements(f.readlines())
|
|
|
|
if strict_bounds:
|
|
return list(reqs)
|
|
else:
|
|
return list(map(_with_bounds, reqs))
|
|
|
|
|
|
def install_requires(strict_bounds=False):
|
|
return read_requirements('etc/requirements.txt',
|
|
strict_bounds=strict_bounds)
|
|
|
|
|
|
def extras_requires():
|
|
dev_reqs = read_requirements('etc/requirements_dev.txt',
|
|
strict_bounds=True)
|
|
talib_reqs = ['TA-Lib==0.4.9']
|
|
return {
|
|
'dev': dev_reqs,
|
|
'talib': talib_reqs,
|
|
'all': dev_reqs + talib_reqs,
|
|
}
|
|
|
|
|
|
def module_requirements(requirements_path, module_names):
|
|
module_names = set(module_names)
|
|
found = set()
|
|
module_lines = []
|
|
parser = re.compile("([^=<>]+)([<=>]{1,2})(.*)")
|
|
for line in read_requirements(requirements_path, strict_bounds=False):
|
|
match = parser.match(line)
|
|
if match is None:
|
|
raise AssertionError("Could not parse requirement: '%s'" % line)
|
|
|
|
groups = match.groups()
|
|
name = groups[0]
|
|
if name in module_names:
|
|
found.add(name)
|
|
module_lines.append(line)
|
|
|
|
if found != module_names:
|
|
raise AssertionError(
|
|
"No requirements found for %s." % module_names - found
|
|
)
|
|
return module_lines
|
|
|
|
|
|
def pre_setup():
|
|
if not set(sys.argv) & {'install', 'develop', 'egg_info', 'bdist_wheel'}:
|
|
return
|
|
|
|
try:
|
|
import pip
|
|
if StrictVersion(pip.__version__) < StrictVersion('7.1.0'):
|
|
raise AssertionError(
|
|
"Zipline installation requires pip>=7.1.0, but your pip "
|
|
"version is {version}. \n"
|
|
"You can upgrade your pip with "
|
|
"'pip install --upgrade pip'.".format(
|
|
version=pip.__version__,
|
|
)
|
|
)
|
|
except ImportError:
|
|
raise AssertionError("Zipline installation requires pip")
|
|
|
|
required = ('Cython', 'numpy')
|
|
for line in module_requirements('etc/requirements.txt', required):
|
|
pip.main(['install', line])
|
|
|
|
|
|
pre_setup()
|
|
|
|
|
|
setup(
|
|
name='zipline',
|
|
version=versioneer.get_version(),
|
|
cmdclass=versioneer.get_cmdclass(),
|
|
description='A backtester for financial algorithms.',
|
|
author='Quantopian Inc.',
|
|
author_email='opensource@quantopian.com',
|
|
packages=find_packages('.', include=['zipline', 'zipline.*']),
|
|
ext_modules=ext_modules,
|
|
scripts=['scripts/run_algo.py'],
|
|
include_package_data=True,
|
|
license='Apache 2.0',
|
|
classifiers=[
|
|
'Development Status :: 4 - Beta',
|
|
'License :: OSI Approved :: Apache Software License',
|
|
'Natural Language :: English',
|
|
'Programming Language :: Python',
|
|
'Programming Language :: Python :: 2.7',
|
|
'Programming Language :: Python :: 3.3',
|
|
'Programming Language :: Python :: 3.4',
|
|
'Operating System :: OS Independent',
|
|
'Intended Audience :: Science/Research',
|
|
'Topic :: Office/Business :: Financial',
|
|
'Topic :: Scientific/Engineering :: Information Analysis',
|
|
'Topic :: System :: Distributed Computing',
|
|
],
|
|
install_requires=install_requires(),
|
|
extras_require=extras_requires(),
|
|
url="http://zipline.io",
|
|
)
|