diff --git a/.travis.yml b/.travis.yml index 4faf2244..70c3bc58 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,16 +1,16 @@ language: python sudo: false -matrix: - fast_finish: true - include: - - python: 2.7 - env: PANDAS_VERSION=0.16.1 NUMPY_VERSION=1.9.2 SCIPY_VERSION=0.15.1 CACHE_DIR=$HOME/.cache/.pip/pip_np19 - - python: 2.7 - env: PANDAS_VERSION=0.17.1 NUMPY_VERSION=1.10.2 SCIPY_VERSION=0.16.1 CACHE_DIR=$HOME/.cache/.pip/pip_np110 - - python: 3.4 - env: PANDAS_VERSION=0.16.1 NUMPY_VERSION=1.9.2 SCIPY_VERSION=0.15.1 CACHE_DIR=$HOME/.cache/.pip/pip_np19 - - python: 3.4 - env: PANDAS_VERSION=0.17.1 NUMPY_VERSION=1.10.2 SCIPY_VERSION=0.16.1 CACHE_DIR=$HOME/.cache/.pip/pip_np110 +fast_finish: true +python: + - 2.7 + - 3.4 +env: + global: + # ANACONDA_TOKEN with api:write + - secure: "RJJjjQloUjCSkhII93QM+YAsr6YYq7hPFvlbnT07ogn1NeUPsVCyJ97oiZfKtPgdbd24hdQP/CHfB0HgTTES8n996tN3QWc4hZj0e10kFyIlas9qnkrRYRR1jxGShBDXrLdx/tGh8z1qnnCm1fy+fDhAF7Zerouwy4EA2YEzxdE=" + matrix: + - PANDAS_VERSION=0.16.1 NUMPY_VERSION=1.9.2 SCIPY_VERSION=0.15.1 + - PANDAS_VERSION=0.17.1 NUMPY_VERSION=1.10.4 SCIPY_VERSION=0.16.1 cache: directories: - $HOME/.cache/.pip/ @@ -24,18 +24,46 @@ before_install: - sed -i "s/pandas==.*/pandas==$PANDAS_VERSION/" etc/requirements.txt - sed -i "s/scipy==.*/scipy==$SCIPY_VERSION/" etc/requirements.txt install: - - conda create -n testenv --yes -c quantopian pip python=$TRAVIS_PYTHON_VERSION numpy=$NUMPY_VERSION scipy=$SCIPY_VERSION libgfortran=1.0 ta-lib=0.4.9 + - conda install conda-build=1.19.2 anaconda-client=1.3.1 --yes + + - TALIB_VERSION=$(cat ./etc/requirements_talib.txt | sed "s/TA-Lib==\(.*\)/\1/") + - conda create -n testenv --yes -c quantopian pip python=$TRAVIS_PYTHON_VERSION numpy=$NUMPY_VERSION scipy=$SCIPY_VERSION libgfortran=1.0 ta-lib=$TALIB_VERSION - source activate testenv + - IFS='.' read -r -a NPY_VERSION_ARR <<< "$NUMPY_VERSION" + - CONDA_NPY=${NPY_VERSION_ARR[0]}${NPY_VERSION_ARR[1]} + - CONDA_PY=$TRAVIS_PYTHON_VERSION + - CACHE_DIR="$HOME/.cache/.pip/pip_np""CONDA_NPY" - pip install --upgrade pip coverage coveralls --cache-dir=$CACHE_DIR - pip install -r etc/requirements.txt --cache-dir=$CACHE_DIR - pip install -r etc/requirements_dev.txt --cache-dir=$CACHE_DIR - pip install -r etc/requirements_blaze.txt --cache-dir=$CACHE_DIR # this uses git requirements right now - - pip install -e . --cache-dir=$CACHE_DIR + - pip install -r etc/requirements_talib.txt --cache-dir=$CACHE_DIR + - pip install -e .[all] --cache-dir=$CACHE_DIR before_script: - pip freeze | sort script: - nosetests tests/ - flake8 zipline tests + # deactive env to get access to anaconda command + - source deactivate + - if [[ "$TRAVIS_SECURE_ENV_VARS" = "true" && "$TRAVIS_BRANCH" = "master" && "$TRAVIS_PULL_REQUEST" = "false" ]]; then DO_UPLOAD="true"; else DO_UPLOAD="false"; fi + - | + for recipe in $(ls -d conda/*/ | xargs -I {} basename {}); do + if [[ "$recipe" = "zipline" ]]; then continue; fi + + conda build conda/$recipe --python=$CONDA_PY --numpy=$CONDA_NPY --skip-existing -c quantopian -c https://conda.anaconda.org/quantopian/label/ci + RECIPE_OUTPUT=$(conda build conda/$recipe --python=$CONDA_PY --numpy=$CONDA_NPY --output) + if [[ -f "$RECIPE_OUTPUT" && "$DO_UPLOAD" = "true" ]]; then anaconda -t $ANACONDA_TOKEN upload "$RECIPE_OUTPUT" -u quantopian --label ci; fi + done + + # unshallow the clone so the conda build can clone it. + - git fetch --unshallow + - exec 3>&1; ZP_OUT=$(conda build conda/zipline --python=$CONDA_PY --numpy=$CONDA_NPY -c quantopian -c https://conda.anaconda.org/quantopian/label/ci | tee >(cat - >&3)) + - ZP_OUTPUT=$(echo "$ZP_OUT" | grep "anaconda upload" | awk '{print $NF}') + - if [[ "$DO_UPLOAD" = "true" ]]; then anaconda -t $ANACONDA_TOKEN upload $ZP_OUTPUT -u quantopian --label ci; fi + # reactivate env (necessary for coveralls) + - source activate testenv + after_success: - coveralls diff --git a/README.rst b/README.rst index 81729acc..23ee09c7 100644 --- a/README.rst +++ b/README.rst @@ -4,7 +4,8 @@ Zipline |Gitter| |version status| |downloads| -|build status| +|travis status| +|appveyor status| |Coverage Status| Zipline is a Pythonic algorithmic trading library. It is an event-driven @@ -179,8 +180,10 @@ https://github.com/quantopian/zipline/wiki/Contribution-Requests :target: https://pypi.python.org/pypi/zipline .. |downloads| image:: https://img.shields.io/pypi/dd/zipline.svg :target: https://pypi.python.org/pypi/zipline -.. |build status| image:: https://travis-ci.org/quantopian/zipline.png?branch=master +.. |travis status| image:: https://travis-ci.org/quantopian/zipline.png?branch=master :target: https://travis-ci.org/quantopian/zipline +.. |appveyor status| image:: https://ci.appveyor.com/api/projects/status/github/quantopian/zipline?branch=master&svg=true + :target: https://ci.appveyor.com/project/quantopian/zipline/branch/master .. |Coverage Status| image:: https://coveralls.io/repos/quantopian/zipline/badge.png :target: https://coveralls.io/r/quantopian/zipline diff --git a/appveyor.yml b/appveyor.yml new file mode 100644 index 00000000..3bad42b3 --- /dev/null +++ b/appveyor.yml @@ -0,0 +1,109 @@ +#matrix: +# fast_finish: true + +environment: + global: + # SDK v7.0 MSVC Express 2008's SetEnv.cmd script will fail if the + # /E:ON and /V:ON options are not enabled in the batch script intepreter + # See: http://stackoverflow.com/a/13751649/163740 + CMD_IN_ENV: "cmd /E:ON /V:ON /C .\\ci\\appveyor\\run_with_env.cmd" + + # with api:write + ANACONDA_TOKEN: + secure: "u3oPlANiKY5g1yMtcK+2MQfb4ViKGEap3TcBtvS7Y1InyeWs80Ko3/PsP7Lp6qwq" + + matrix: + - PYTHON_VERSION: "2.7" + PYTHON_ARCH: "64" + PANDAS_VERSION: "0.16.1" + NUMPY_VERSION: "1.9.2" + SCIPY_VERSION: "0.15.1" + + - PYTHON_VERSION: "3.4" + PYTHON_ARCH: "64" + PANDAS_VERSION: "0.16.1" + NUMPY_VERSION: "1.9.2" + SCIPY_VERSION: "0.15.1" + + - PYTHON_VERSION: "2.7" + PYTHON_ARCH: "64" + PANDAS_VERSION: "0.17.1" + NUMPY_VERSION: "1.10.4" + SCIPY_VERSION: "0.16.1" + + - PYTHON_VERSION: "3.4" + PYTHON_ARCH: "64" + PANDAS_VERSION: "0.17.1" + NUMPY_VERSION: "1.10.4" + SCIPY_VERSION: "0.16.1" + +# We always use a 64-bit machine, but can build x86 distributions +# with the PYTHON_ARCH variable (which is used by CMD_IN_ENV). +platform: + - x64 + +cache: + - '%LOCALAPPDATA%\pip\Cache' + +# all our python builds have to happen in tests_script... +build: false + +init: + - "ECHO %PYTHON_VERSION% %PYTHON_ARCH% %PYTHON%" + - "ECHO %NUMPY_VERSION%" + +install: + # If there is a newer build queued for the same PR, cancel this one. + # The AppVeyor 'rollout builds' option is supposed to serve the same + # purpose but it is problematic because it tends to cancel builds pushed + # directly to master instead of just PR builds (or the converse). + # credits: JuliaLang developers. + - ps: if ($env:APPVEYOR_PULL_REQUEST_NUMBER -and $env:APPVEYOR_BUILD_NUMBER -ne ((Invoke-RestMethod ` + https://ci.appveyor.com/api/projects/$env:APPVEYOR_ACCOUNT_NAME/$env:APPVEYOR_PROJECT_SLUG/history?recordsNumber=50).builds | ` + Where-Object pullRequestId -eq $env:APPVEYOR_PULL_REQUEST_NUMBER)[0].buildNumber) { ` + throw "There are newer queued builds for this pull request, failing early." } + + - ps: $NPY_VERSION_ARR=$env:NUMPY_VERSION -split '.', 0, 'simplematch' + - ps: $env:CONDA_NPY=$NPY_VERSION_ARR[0..1] -join "" + - ps: $PY_VERSION_ARR=$env:PYTHON_VERSION -split '.', 0, 'simplematch' + - ps: $env:CONDA_PY=$PY_VERSION_ARR[0..1] -join "" + - SET PYTHON=C:\Python%CONDA_PY%_64 + # Get cygwin's git out of our PATH. See https://github.com/omnia-md/conda-dev-recipes/pull/16/files#diff-180360612c6b8c4ed830919bbb4dd459 + - "del C:\\cygwin\\bin\\git.exe" + # this installs the appropriate Miniconda (Py2/Py3, 32/64 bit), + - powershell .\ci\appveyor\install.ps1 + - SET PATH=%PYTHON%;%PYTHON%\Scripts;%PATH% + - sed -i "s/numpy==.*/numpy==%NUMPY_VERSION%/" etc/requirements.txt + - sed -i "s/pandas==.*/pandas==%PANDAS_VERSION%/" etc/requirements.txt + - sed -i "s/scipy==.*/scipy==%SCIPY_VERSION%/" etc/requirements.txt + + - conda info -a + - conda install conda-build=1.19.2 anaconda-client=1.3.1 --yes -q + # https://blog.ionelmc.ro/2014/12/21/compiling-python-extensions-on-windows/ for 64bit C compilation + - ps: copy .\ci\appveyor\vcvars64.bat "C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\bin\amd64" + - "%CMD_IN_ENV% python .\\ci\\make_conda_packages.py" + + # test that we can conda install zipline in a new env + - conda create -n installenv --yes -q --use-local python=%PYTHON_VERSION% numpy=%NUMPY_VERSION% zipline -c quantopian -c https://conda.anaconda.org/quantopian/label/ci + + - ps: $env:BCOLZ_VERSION=(sls "bcolz==(.*)" .\etc\requirements.txt -ca).matches.groups[1].value + - ps: $env:NUMEXPR_VERSION=(sls "numexpr==(.*)" .\etc\requirements.txt -ca).matches.groups[1].value + - ps: $env:TALIB_VERSION=(sls "TA-Lib==(.*)" .\etc\requirements_talib.txt -ca).matches.groups[1].value + - conda create -n testenv --yes -q --use-local pip python=%PYTHON_VERSION% numpy=%NUMPY_VERSION% scipy=%SCIPY_VERSION% ta-lib=%TALIB_VERSION% bcolz=%BCOLZ_VERSION% numexpr=%NUMEXPR_VERSION% -c quantopian -c https://conda.anaconda.org/quantopian/label/ci + - activate testenv + - SET CACHE_DIR=%LOCALAPPDATA%\pip\Cache\pip_np%CONDA_NPY%py%CONDA_PY% + - pip install -r etc/requirements.txt --cache-dir=%CACHE_DIR% + - pip install -r etc/requirements_dev.txt --cache-dir=%CACHE_DIR% + # this uses git requirements right now + - pip install -r etc/requirements_blaze.txt --cache-dir=%CACHE_DIR% + - pip install -r etc/requirements_talib.txt --cache-dir=%CACHE_DIR% + - pip install -e .[all] --cache-dir=%CACHE_DIR% + - pip freeze | sort + +test_script: + - nosetests tests/ + - flake8 zipline tests + +branches: + only: + - master diff --git a/ci/appveyor/install.ps1 b/ci/appveyor/install.ps1 new file mode 100644 index 00000000..c964973c --- /dev/null +++ b/ci/appveyor/install.ps1 @@ -0,0 +1,96 @@ +# Sample script to install Miniconda under Windows +# Authors: Olivier Grisel, Jonathan Helmus and Kyle Kastner, Robert McGibbon +# License: CC0 1.0 Universal: http://creativecommons.org/publicdomain/zero/1.0/ + +$MINICONDA_URL = "http://repo.continuum.io/miniconda/" + + +function DownloadMiniconda ($python_version, $platform_suffix) { + $webclient = New-Object System.Net.WebClient + if ($python_version -match "3.4") { + $filename = "Miniconda3-latest-Windows-" + $platform_suffix + ".exe" + } else { + $filename = "Miniconda-latest-Windows-" + $platform_suffix + ".exe" + } + $url = $MINICONDA_URL + $filename + + $basedir = $pwd.Path + "\" + $filepath = $basedir + $filename + if (Test-Path $filename) { + Write-Host "Reusing" $filepath + return $filepath + } + + # Download and retry up to 3 times in case of network transient errors. + Write-Host "Downloading" $filename "from" $url + $retry_attempts = 2 + for($i=0; $i -lt $retry_attempts; $i++){ + try { + $webclient.DownloadFile($url, $filepath) + break + } + Catch [Exception]{ + Start-Sleep 1 + } + } + if (Test-Path $filepath) { + Write-Host "File saved at" $filepath + } else { + # Retry once to get the error message if any at the last try + $webclient.DownloadFile($url, $filepath) + } + return $filepath +} + + +function InstallMiniconda ($python_version, $architecture, $python_home) { + Write-Host "Installing Python" $python_version "for" $architecture "bit architecture to" $python_home + if (Test-Path $python_home) { + Write-Host $python_home "already exists, skipping." + return $false + } + if ($architecture -match "32") { + $platform_suffix = "x86" + } else { + $platform_suffix = "x86_64" + } + + $filepath = DownloadMiniconda $python_version $platform_suffix + Write-Host "Installing" $filepath "to" $python_home + $install_log = $python_home + ".log" + $args = "/S /D=$python_home" + Write-Host $filepath $args + Start-Process -FilePath $filepath -ArgumentList $args -Wait -Passthru + if (Test-Path $python_home) { + Write-Host "Python $python_version ($architecture) installation complete" + } else { + Write-Host "Failed to install Python in $python_home" + Get-Content -Path $install_log + Exit 1 + } +} + + +function InstallCondaPackages ($python_home, $spec) { + $conda_path = $python_home + "\Scripts\conda.exe" + $args = "install --yes " + $spec + Write-Host ("conda " + $args) + Start-Process -FilePath "$conda_path" -ArgumentList $args -Wait -Passthru +} + +function UpdateConda ($python_home) { + $conda_path = $python_home + "\Scripts\conda.exe" + Write-Host "Updating conda..." + $args = "update --yes conda" + Write-Host $conda_path $args + Start-Process -FilePath "$conda_path" -ArgumentList $args -Wait -Passthru +} + + +function main () { + InstallMiniconda $env:PYTHON_VERSION $env:PYTHON_ARCH $env:PYTHON + UpdateConda $env:PYTHON + InstallCondaPackages $env:PYTHON "conda-build jinja2 anaconda-client" +} + +main diff --git a/ci/appveyor/run_with_env.cmd b/ci/appveyor/run_with_env.cmd new file mode 100644 index 00000000..848f4608 --- /dev/null +++ b/ci/appveyor/run_with_env.cmd @@ -0,0 +1,95 @@ +:: EXPECTED ENV VARS: PYTHON_ARCH (either x86 or x64) +:: CONDA_PY (either 27, 33, 35 etc. - only major version is extracted) +:: +:: +:: To build extensions for 64 bit Python 3, we need to configure environment +:: variables to use the MSVC 2010 C++ compilers from GRMSDKX_EN_DVD.iso of: +:: MS Windows SDK for Windows 7 and .NET Framework 4 (SDK v7.1) +:: +:: To build extensions for 64 bit Python 2, we need to configure environment +:: variables to use the MSVC 2008 C++ compilers from GRMSDKX_EN_DVD.iso of: +:: MS Windows SDK for Windows 7 and .NET Framework 3.5 (SDK v7.0) +:: +:: 32 bit builds, and 64-bit builds for 3.5 and beyond, do not require specific +:: environment configurations. +:: +:: Note: this script needs to be run with the /E:ON and /V:ON flags for the +:: cmd interpreter, at least for (SDK v7.0) +:: +:: More details at: +:: https://github.com/cython/cython/wiki/64BitCythonExtensionsOnWindows +:: http://stackoverflow.com/a/13751649/163740 +:: +:: Author: Phil Elson +:: Original Author: Olivier Grisel (https://github.com/ogrisel/python-appveyor-demo) +:: License: CC0 1.0 Universal: http://creativecommons.org/publicdomain/zero/1.0/ +:: +:: Notes about batch files for Python people: +:: +:: Quotes in values are literally part of the values: +:: SET FOO="bar" +:: FOO is now five characters long: " b a r " +:: If you don't want quotes, don't include them on the right-hand side. +:: +:: The CALL lines at the end of this file look redundant, but if you move them +:: outside of the IF clauses, they do not run properly in the SET_SDK_64==Y +:: case, I don't know why. +:: originally from https://github.com/pelson/Obvious-CI/blob/master/scripts/obvci_appveyor_python_build_env.cmd +@ECHO OFF + +SET COMMAND_TO_RUN=%* +SET WIN_SDK_ROOT=C:\Program Files\Microsoft SDKs\Windows + +:: Extract the major and minor versions, and allow for the minor version to be +:: more than 9. This requires the version number to have two dots in it. +SET MAJOR_PYTHON_VERSION=%CONDA_PY:~0,1% + +IF "%CONDA_PY:~2,1%" == "" ( + :: CONDA_PY style, such as 27, 34 etc. + SET MINOR_PYTHON_VERSION=%CONDA_PY:~1,1% +) ELSE ( + IF "%CONDA_PY:~3,1%" == "." ( + SET MINOR_PYTHON_VERSION=%CONDA_PY:~2,1% + ) ELSE ( + SET MINOR_PYTHON_VERSION=%CONDA_PY:~2,2% + ) +) + +:: Based on the Python version, determine what SDK version to use, and whether +:: to set the SDK for 64-bit. +IF %MAJOR_PYTHON_VERSION% == 2 ( + SET WINDOWS_SDK_VERSION="v7.0" + SET SET_SDK_64=Y +) ELSE ( + IF %MAJOR_PYTHON_VERSION% == 3 ( + SET WINDOWS_SDK_VERSION="v7.1" + IF %MINOR_PYTHON_VERSION% LEQ 4 ( + SET SET_SDK_64=Y + ) ELSE ( + SET SET_SDK_64=N + ) + ) ELSE ( + ECHO Unsupported Python version: "%MAJOR_PYTHON_VERSION%" + EXIT /B 1 + ) +) + +IF "%PYTHON_ARCH%"=="64" ( + IF %SET_SDK_64% == Y ( + ECHO Configuring Windows SDK %WINDOWS_SDK_VERSION% for Python %MAJOR_PYTHON_VERSION% on a 64 bit architecture + SET DISTUTILS_USE_SDK=1 + SET MSSdk=1 + "%WIN_SDK_ROOT%\%WINDOWS_SDK_VERSION%\Setup\WindowsSdkVer.exe" -q -version:%WINDOWS_SDK_VERSION% + "%WIN_SDK_ROOT%\%WINDOWS_SDK_VERSION%\Bin\SetEnv.cmd" /x64 /release + ECHO Executing: %COMMAND_TO_RUN% + call %COMMAND_TO_RUN% || EXIT /B 1 + ) ELSE ( + ECHO Using default MSVC build environment for 64 bit architecture + ECHO Executing: %COMMAND_TO_RUN% + call %COMMAND_TO_RUN% || EXIT /B 1 + ) +) ELSE ( + ECHO Using default MSVC build environment for 32 bit architecture + ECHO Executing: %COMMAND_TO_RUN% + call %COMMAND_TO_RUN% || EXIT /B 1 +) diff --git a/ci/appveyor/vcvars64.bat b/ci/appveyor/vcvars64.bat new file mode 100644 index 00000000..ef77b9d3 --- /dev/null +++ b/ci/appveyor/vcvars64.bat @@ -0,0 +1 @@ +CALL "C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\SetEnv.cmd" /x64 diff --git a/ci/make_conda_packages.py b/ci/make_conda_packages.py new file mode 100644 index 00000000..240e2606 --- /dev/null +++ b/ci/make_conda_packages.py @@ -0,0 +1,60 @@ +import os +import re +import subprocess + + +def get_immediate_subdirectories(a_dir): + return [name for name in os.listdir(a_dir) + if os.path.isdir(os.path.join(a_dir, name))] + + +def iter_stdout(cmd): + p = subprocess.Popen(cmd, + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT) + + try: + for line in iter(p.stdout.readline, b''): + yield line.decode().rstrip() + finally: + retcode = p.wait() + if retcode: + raise subprocess.CalledProcessError(retcode, cmd[0]) + + +PKG_PATH_PATTERN = re.compile(".* anaconda upload (?P.+)$") + + +def main(env, do_upload): + for recipe in get_immediate_subdirectories('conda'): + cmd = ["conda", "build", os.path.join('conda', recipe), + "--python", env['CONDA_PY'], + "--numpy", env['CONDA_NPY'], + "--skip-existing", + "-c", "quantopian", + "-c", "https://conda.anaconda.org/quantopian/label/ci"] + + output = None + + for line in iter_stdout(cmd): + print(line) + + if not output: + match = PKG_PATH_PATTERN.match(line) + if match: + output = match.group('pkg_path') + + if output and os.path.exists(output) and do_upload: + cmd = ["anaconda", "-t", env['ANACONDA_TOKEN'], + "upload", output, "-u", "quantopian", "--label", "ci"] + + for line in iter_stdout(cmd): + print(line) + + +if __name__ == '__main__': + env = os.environ.copy() + main(env, + do_upload=(env.get('ANACONDA_TOKEN') and + env.get('APPVEYOR_REPO_BRANCH') == 'master') and + 'APPVEYOR_PULL_REQUEST_NUMBER' not in env) diff --git a/conda/numexpr/bld.bat b/conda/numexpr/bld.bat new file mode 100644 index 00000000..87b1481d --- /dev/null +++ b/conda/numexpr/bld.bat @@ -0,0 +1,8 @@ +"%PYTHON%" setup.py install +if errorlevel 1 exit 1 + +:: Add more build steps here, if they are necessary. + +:: See +:: http://docs.continuum.io/conda/build.html +:: for a list of environment variables that are set during the build process. diff --git a/conda/numexpr/build.sh b/conda/numexpr/build.sh new file mode 100644 index 00000000..4d7fc032 --- /dev/null +++ b/conda/numexpr/build.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +$PYTHON setup.py install + +# Add more build steps here, if they are necessary. + +# See +# http://docs.continuum.io/conda/build.html +# for a list of environment variables that are set during the build process. diff --git a/conda/numexpr/meta.yaml b/conda/numexpr/meta.yaml new file mode 100644 index 00000000..f712ab3c --- /dev/null +++ b/conda/numexpr/meta.yaml @@ -0,0 +1,22 @@ +package: + name: numexpr + version: "2.4.6" + +source: + fn: numexpr-2.4.6.tar.gz + url: https://pypi.python.org/packages/source/n/numexpr/numexpr-2.4.6.tar.gz + md5: 17ac6fafc9ea1ce3eb970b9abccb4fbd + +requirements: + build: + - python + - numpy x.x + + run: + - python + - numpy x.x + +test: + # Python imports + imports: + - numexpr diff --git a/conda/ta-lib/bld.bat b/conda/ta-lib/bld.bat index 7c933e4f..6ef9c91a 100644 --- a/conda/ta-lib/bld.bat +++ b/conda/ta-lib/bld.bat @@ -1,2 +1,35 @@ -%SYS_PYTHON% setup.py build --compiler msvc -%SYS_PYTHON% setup.py install --prefix=%PREFIX% +rmdir /s /q "C:\ta-lib\" +powershell -Command "(New-Object Net.WebClient).DownloadFile('http://prdownloads.sourceforge.net/ta-lib/ta-lib-0.4.0-msvc.zip', 'ta-lib-0.4.0-msvc.zip')" +IF %ERRORLEVEL% == 1; exit 1 +powershell -Command "Add-Type -AssemblyName System.IO.Compression.FileSystem;[System.IO.Compression.ZipFile]::ExtractToDirectory('ta-lib-0.4.0-msvc.zip', 'C:\')" +IF %ERRORLEVEL% == 1; exit 1 +pushd C:\ta-lib\c\ +pushd make\cdd\win32\msvc +nmake +IF %ERRORLEVEL% == 1; exit 1 +popd +pushd make\cdr\win32\msvc +nmake +IF %ERRORLEVEL% == 1; exit 1 +popd +pushd make\cmd\win32\msvc +nmake +IF %ERRORLEVEL% == 1; exit 1 +popd +pushd make\cmr\win32\msvc +nmake +IF %ERRORLEVEL% == 1; exit 1 +popd +pushd make\csd\win32\msvc +nmake +IF %ERRORLEVEL% == 1; exit 1 +popd +pushd make\csr\win32\msvc +nmake +IF %ERRORLEVEL% == 1; exit 1 +popd +popd +del ta-lib-0.4.0-msvc.zip + +python setup.py build --compiler msvc +python setup.py install --prefix=%PREFIX% diff --git a/conda/zipline/bld.bat b/conda/zipline/bld.bat index 87b1481d..ebb1aa4d 100644 --- a/conda/zipline/bld.bat +++ b/conda/zipline/bld.bat @@ -1,4 +1,4 @@ -"%PYTHON%" setup.py install +"%PYTHON%" setup.py install --single-version-externally-managed --record=record.txt if errorlevel 1 exit 1 :: Add more build steps here, if they are necessary. diff --git a/conda/zipline/meta.yaml b/conda/zipline/meta.yaml index ebb82b5c..bc86cec4 100644 --- a/conda/zipline/meta.yaml +++ b/conda/zipline/meta.yaml @@ -2,17 +2,20 @@ package: name: zipline - version: {{ environ.get('GIT_DESCRIBE_TAG', '')}} + version: {{ GIT_DESCRIBE_TAG|replace('v', '') }} build: - number: {{ environ.get('GIT_DESCRIBE_NUMBER', 0) }} + number: {{ GIT_DESCRIBE_NUMBER|int }} + string: np{{ NPY_VER|replace('.', '') }}py{{ PY_VER|replace('.', '') }}_{{ ( + GIT_BUILD_STR if GIT_DESCRIBE_NUMBER|int != 0 else '0' + ) }} source: git_url: ../../ requirements: build: - - python + - python {{ PY_VER }}* {% for req in data.get('build_requires', []) -%} - {{req}} {% endfor %} diff --git a/etc/requirements.txt b/etc/requirements.txt index cdfbb839..60342568 100644 --- a/etc/requirements.txt +++ b/etc/requirements.txt @@ -41,7 +41,7 @@ decorator==4.0.0 networkx==1.9.1 # NumericalExpression pipeline terms. -numexpr==2.4.3 +numexpr==2.4.6 # On disk storage format for pipeline data. bcolz==0.12.1 diff --git a/etc/requirements_talib.txt b/etc/requirements_talib.txt new file mode 100644 index 00000000..478a392b --- /dev/null +++ b/etc/requirements_talib.txt @@ -0,0 +1 @@ +TA-Lib==0.4.9 diff --git a/setup.py b/setup.py index 9844a0ad..07ccb62f 100644 --- a/setup.py +++ b/setup.py @@ -195,15 +195,15 @@ def install_requires(strict_bounds=False, conda_format=False): def extras_requires(conda_format=False): - dev_reqs = read_requirements('etc/requirements_dev.txt', + extras = { + extra: read_requirements('etc/requirements_{0}.txt'.format(extra), strict_bounds=True, conda_format=conda_format) - talib_reqs = ['TA-Lib==0.4.9'] - return { - 'dev': dev_reqs, - 'talib': talib_reqs, - 'all': dev_reqs + talib_reqs, + for extra in ('dev', 'talib') } + extras['all'] = [req for reqs in extras.values() for req in reqs] + + return extras def module_requirements(requirements_path, module_names, strict_bounds, diff --git a/tests/pipeline/test_adjusted_array.py b/tests/pipeline/test_adjusted_array.py index a5fab747..a2a8cde0 100644 --- a/tests/pipeline/test_adjusted_array.py +++ b/tests/pipeline/test_adjusted_array.py @@ -365,7 +365,7 @@ class AdjustedArrayTestCase(TestCase): frame[0, 0] = 5.0 def test_bad_input(self): - msg = "Mask shape \(2, 3\) != data shape \(5, 5\)" + msg = "Mask shape \(2L?, 3L?\) != data shape \(5L?, 5L?\)" data = arange(25).reshape(5, 5) bad_mask = array([[0, 1, 1], [0, 0, 1]], dtype=bool) diff --git a/tests/pipeline/test_numerical_expression.py b/tests/pipeline/test_numerical_expression.py index 040ed124..9922004d 100644 --- a/tests/pipeline/test_numerical_expression.py +++ b/tests/pipeline/test_numerical_expression.py @@ -34,7 +34,7 @@ from zipline.pipeline.expression import ( NumericalExpression, NUMEXPR_MATH_FUNCS, ) -from zipline.testing import check_arrays +from zipline.testing import check_allclose from zipline.utils.numpy_utils import datetime64ns_dtype, float64_dtype @@ -91,7 +91,7 @@ class NumericalExpressionTestCase(TestCase): self.mask.columns, self.mask.values, ) - check_arrays(result, expected) + check_allclose(result, expected) def check_constant_output(self, expr, expected): self.assertFalse(isnan(expected)) diff --git a/tests/pipeline/test_pipeline_algo.py b/tests/pipeline/test_pipeline_algo.py index f0aea648..b4f59536 100644 --- a/tests/pipeline/test_pipeline_algo.py +++ b/tests/pipeline/test_pipeline_algo.py @@ -344,10 +344,10 @@ class PipelineAlgorithmTestCase(TestCase): cls.tempdir = tempdir = TempDirectory() tempdir.create() try: - cls.raw_data, cls.bar_reader = cls.create_bar_reader(tempdir) - cls.adj_reader = cls.create_adjustment_reader(tempdir) + cls.raw_data, bar_reader = cls.create_bar_reader(tempdir) + adj_reader = cls.create_adjustment_reader(tempdir) cls.pipeline_loader = USEquityPricingLoader( - cls.bar_reader, cls.adj_reader + bar_reader, adj_reader ) except: cls.tempdir.cleanup() @@ -358,6 +358,7 @@ class PipelineAlgorithmTestCase(TestCase): @classmethod def tearDownClass(cls): + del cls.pipeline_loader del cls.env cls.tempdir.cleanup() diff --git a/tests/utils/test_preprocess.py b/tests/utils/test_preprocess.py index 4f425b16..2626cedb 100644 --- a/tests/utils/test_preprocess.py +++ b/tests/utils/test_preprocess.py @@ -280,7 +280,7 @@ class PreprocessTestCase(TestCase): self.assertIs(c_ret, good_c) with self.assertRaises(TypeError) as e: - foo(good_a, arange(3), good_c) + foo(good_a, arange(3, dtype='int64'), good_c) expected_message = ( "{qualname}() expected a value with dtype 'datetime64[ns]'" diff --git a/zipline/data/_adjustments.pyx b/zipline/data/_adjustments.pyx index b53474f2..5fded76b 100644 --- a/zipline/data/_adjustments.pyx +++ b/zipline/data/_adjustments.pyx @@ -18,6 +18,7 @@ from cpython cimport ( ) from numpy import ( + int64, uint32, zeros, ) @@ -208,7 +209,7 @@ cpdef load_adjustments_from_sqlite(object adjustments_db, # sqlite3.Connection dict col_adjustments cdef ndarray[int64_t, ndim=1] _dates_seconds = \ - dates.values.astype('datetime64[s]').view(int) + dates.values.astype('datetime64[s]').view(int64) # Pre-populate date index cache. for i, dt in enumerate(_dates_seconds): diff --git a/zipline/data/us_equity_pricing.py b/zipline/data/us_equity_pricing.py index 6b15f013..8d508b9e 100644 --- a/zipline/data/us_equity_pricing.py +++ b/zipline/data/us_equity_pricing.py @@ -302,8 +302,9 @@ class DailyBarWriterFromCSVs(BcolzDailyBarWriter): return array.astype(uint32) elif colname == 'day': nanos_per_second = (1000 * 1000 * 1000) - self.check_uint_safe(arrmax.view(int) / nanos_per_second, colname) - return (array.view(int) / nanos_per_second).astype(uint32) + self.check_uint_safe(arrmax.view(int64) / nanos_per_second, + colname) + return (array.view(int64) / nanos_per_second).astype(uint32) @staticmethod def check_uint_safe(value, colname): diff --git a/zipline/pipeline/loaders/synthetic.py b/zipline/pipeline/loaders/synthetic.py index 1d983a53..a212b2c0 100644 --- a/zipline/pipeline/loaders/synthetic.py +++ b/zipline/pipeline/loaders/synthetic.py @@ -173,7 +173,8 @@ class SeededRandomLoader(PrecomputedLoader): """ Return uniformly-distributed integers between 0 and 100. """ - return self.state.random_integers(low=0, high=100, size=shape) + return (self.state.random_integers(low=0, high=100, size=shape) + .astype('int64')) # default is system int def _datetime_values(self, shape): """ diff --git a/zipline/testing/core.py b/zipline/testing/core.py index ea26bceb..15d1a703 100644 --- a/zipline/testing/core.py +++ b/zipline/testing/core.py @@ -568,7 +568,8 @@ def check_allclose(actual, """ if type(actual) != type(desired): raise AssertionError("%s != %s" % (type(actual), type(desired))) - return assert_allclose(actual, desired, err_msg=err_msg, verbose=True) + return assert_allclose(actual, desired, rtol=rtol, atol=atol, + err_msg=err_msg, verbose=verbose) def check_arrays(x, y, err_msg='', verbose=True):