├── .gitattributes ├── .gitignore ├── .travis.yml ├── LICENSE ├── MANIFEST.in ├── README.md ├── docs ├── Makefile ├── conf.py ├── empyrical.rst ├── index.rst ├── make.bat ├── make_docs.bat └── modules.rst ├── empyrical ├── __init__.py ├── _version.py ├── deprecate.py ├── perf_attrib.py ├── periods.py ├── stats.py ├── tests │ ├── __init__.py │ ├── test_data │ │ ├── factor_loadings.csv │ │ ├── factor_returns.csv │ │ ├── intercepts.csv │ │ ├── positions.csv │ │ ├── residuals.csv │ │ └── returns.csv │ ├── test_perf_attrib.py │ └── test_stats.py └── utils.py ├── runtests.py ├── setup.cfg ├── setup.py └── versioneer.py /.gitattributes: -------------------------------------------------------------------------------- 1 | empyrical/_version.py export-subst 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | env/ 12 | build/ 13 | develop-eggs/ 14 | dist/ 15 | downloads/ 16 | eggs/ 17 | .eggs/ 18 | lib/ 19 | lib64/ 20 | parts/ 21 | sdist/ 22 | var/ 23 | *.egg-info/ 24 | .installed.cfg 25 | *.egg 26 | 27 | # PyInstaller 28 | # Usually these files are written by a python script from a template 29 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 30 | *.manifest 31 | *.spec 32 | 33 | # Installer logs 34 | pip-log.txt 35 | pip-delete-this-directory.txt 36 | 37 | # Unit test / coverage reports 38 | htmlcov/ 39 | .tox/ 40 | .coverage 41 | .coverage.* 42 | .cache 43 | nosetests.xml 44 | coverage.xml 45 | *,cover 46 | .hypothesis/ 47 | 48 | # Translations 49 | *.mo 50 | *.pot 51 | 52 | # Django stuff: 53 | *.log 54 | 55 | # Sphinx documentation 56 | docs/_build/ 57 | 58 | # PyBuilder 59 | target/ 60 | 61 | #Ipython Notebook 62 | .ipynb_checkpoints 63 | 64 | # JetBrains 65 | .idea/ 66 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: python 2 | sudo: false 3 | 4 | matrix: 5 | include: 6 | - python: 2.7 7 | env: PANDAS_VERSION=0.24.2 NUMPY_VERSION=1.12.1 SCIPY_VERSION=1.2.1 LIBGFORTRAN_VERSION=3.0 8 | - python: 2.7 9 | env: PANDAS_VERSION=0.20.1 NUMPY_VERSION=1.12.1 SCIPY_VERSION=0.19.0 LIBGFORTRAN_VERSION=3.0 10 | - python: 3.6 11 | env: PANDAS_VERSION=1.0.4 NUMPY_VERSION=1.18.4 SCIPY_VERSION=1.4.1 LIBGFORTRAN_VERSION=3.0 12 | - python: 3.6 13 | env: PANDAS_VERSION=0.20.1 NUMPY_VERSION=1.12.1 SCIPY_VERSION=0.19.0 LIBGFORTRAN_VERSION=3.0 14 | - python: 3.6 15 | env: PANDAS_VERSION=1.0.4 NUMPY_VERSION=1.18.4 SCIPY_VERSION=1.4.1 LIBGFORTRAN_VERSION=3.0 16 | - python: 3.7 17 | env: PANDAS_VERSION=1.0.4 NUMPY_VERSION=1.18.4 SCIPY_VERSION=1.4.1 LIBGFORTRAN_VERSION=3.0 18 | 19 | before_install: 20 | # We do this conditionally because it saves us some downloading if the 21 | # version is the same. 22 | - if [[ "$TRAVIS_PYTHON_VERSION" == "2.7" ]]; then 23 | wget https://repo.continuum.io/miniconda/Miniconda-latest-Linux-x86_64.sh -O miniconda.sh; 24 | else 25 | wget https://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh -O miniconda.sh; 26 | fi 27 | - bash miniconda.sh -b -p $HOME/miniconda 28 | - export PATH="$HOME/miniconda/bin:$PATH" 29 | - conda config --set always_yes yes --set changeps1 no 30 | - conda update -q conda 31 | 32 | install: 33 | - conda create -n testenv --yes -c conda-forge pip python=$TRAVIS_PYTHON_VERSION numpy=$NUMPY_VERSION pandas=$PANDAS_VERSION scipy=$SCIPY_VERSION libgfortran=$LIBGFORTRAN_VERSION 34 | - source activate testenv 35 | - pip install -e .[dev] 36 | 37 | before_script: 38 | - "flake8 ." 39 | 40 | script: 41 | - nosetests 42 | - source deactivate 43 | 44 | notifications: 45 | email: false 46 | 47 | branches: 48 | only: 49 | - master 50 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright 2018 Quantopian, Inc. 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include versioneer.py 2 | include empyrical/_version.py 3 | include LICENSE 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Build Status](https://travis-ci.org/quantopian/empyrical.svg?branch=master)](https://travis-ci.org/quantopian/empyrical) 2 | 3 | [![PyPI](https://img.shields.io/pypi/v/empyrical?color=%234ec726&style=flat-square)](https://pypi.org/project/empyrical/) 4 | 5 | # empyrical 6 | 7 | Common financial risk metrics. 8 | 9 | ## Table of Contents 10 | 11 | - [Installation](#installation) 12 | - [Usage](#usage) 13 | - [Support](#support) 14 | - [Contributing](#contributing) 15 | - [Testing](#testing) 16 | 17 | ## Installation 18 | ``` 19 | pip install empyrical 20 | ``` 21 | 22 | ## Usage 23 | 24 | Simple Statistics 25 | ```python 26 | import numpy as np 27 | from empyrical import max_drawdown, alpha_beta 28 | 29 | returns = np.array([.01, .02, .03, -.4, -.06, -.02]) 30 | benchmark_returns = np.array([.02, .02, .03, -.35, -.05, -.01]) 31 | 32 | # calculate the max drawdown 33 | max_drawdown(returns) 34 | 35 | # calculate alpha and beta 36 | alpha, beta = alpha_beta(returns, benchmark_returns) 37 | 38 | ``` 39 | 40 | Rolling Measures 41 | ```python 42 | import numpy as np 43 | from empyrical import roll_max_drawdown 44 | 45 | returns = np.array([.01, .02, .03, -.4, -.06, -.02]) 46 | 47 | # calculate the rolling max drawdown 48 | roll_max_drawdown(returns, window=3) 49 | 50 | ``` 51 | 52 | Pandas Support 53 | ```python 54 | import pandas as pd 55 | from empyrical import roll_up_capture, capture 56 | 57 | returns = pd.Series([.01, .02, .03, -.4, -.06, -.02]) 58 | 59 | # calculate a capture ratio 60 | capture(returns) 61 | 62 | # calculate capture for up markets on a rolling 60 day basis 63 | roll_up_capture(returns, window=60) 64 | ``` 65 | 66 | ## Support 67 | 68 | Please [open an issue](https://github.com/quantopian/empyrical/issues/new) for support. 69 | 70 | ### Deprecated: Data Reading via `pandas-datareader` 71 | 72 | As of early 2018, Yahoo Finance has suffered major API breaks with no stable 73 | replacement, and the Google Finance API has not been stable since late 2017 74 | [(source)](https://github.com/pydata/pandas-datareader/blob/da18fbd7621d473828d7fa81dfa5e0f9516b6793/README.rst). 75 | In recent months it has become a greater and greater strain on the `empyrical` 76 | development team to maintain support for fetching data through 77 | `pandas-datareader` and other third-party libraries, as these APIs are known to 78 | be unstable. 79 | 80 | As a result, all `empyrical` support for data reading functionality has been 81 | deprecated and will be removed in a future version. 82 | 83 | Users should beware that the following functions are now deprecated: 84 | 85 | - `empyrical.utils.cache_dir` 86 | - `empyrical.utils.data_path` 87 | - `empyrical.utils.ensure_directory` 88 | - `empyrical.utils.get_fama_french` 89 | - `empyrical.utils.load_portfolio_risk_factors` 90 | - `empyrical.utils.default_returns_func` 91 | - `empyrical.utils.get_symbol_returns_from_yahoo` 92 | 93 | Users should expect regular failures from the following functions, pending 94 | patches to the Yahoo or Google Finance API: 95 | 96 | - `empyrical.utils.default_returns_func` 97 | - `empyrical.utils.get_symbol_returns_from_yahoo` 98 | 99 | ## Contributing 100 | 101 | Please contribute using [Github Flow](https://guides.github.com/introduction/flow/). Create a branch, add commits, and [open a pull request](https://github.com/quantopian/empyrical/compare/). 102 | 103 | ## Testing 104 | - install requirements 105 | - "nose>=1.3.7", 106 | - "parameterized>=0.6.1" 107 | 108 | ``` 109 | ./runtests.py 110 | ``` 111 | -------------------------------------------------------------------------------- /docs/Makefile: -------------------------------------------------------------------------------- 1 | # Minimal makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line. 5 | SPHINXOPTS = 6 | SPHINXBUILD = python -msphinx 7 | SPHINXPROJ = empyrical 8 | SOURCEDIR = . 9 | BUILDDIR = _build 10 | 11 | # Put it first so that "make" without argument is like "make help". 12 | help: 13 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 14 | 15 | .PHONY: help Makefile 16 | 17 | # Catch-all target: route all unknown targets to Sphinx using the new 18 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). 19 | %: Makefile 20 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) -------------------------------------------------------------------------------- /docs/conf.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | # 4 | # empyrical documentation build configuration file, created by 5 | # sphinx-quickstart on Thu Jan 25 22:49:14 2018. 6 | # 7 | # This file is execfile()d with the current directory set to its 8 | # containing dir. 9 | # 10 | # Note that not all possible configuration values are present in this 11 | # autogenerated file. 12 | # 13 | # All configuration values have a default; values that are commented out 14 | # serve to show the default. 15 | 16 | # If extensions (or modules to document with autodoc) are in another directory, 17 | # add these directories to sys.path here. If the directory is relative to the 18 | # documentation root, use os.path.abspath to make it absolute, like shown here. 19 | # 20 | # import os 21 | # import sys 22 | # sys.path.insert(0, os.path.abspath('.')) 23 | import empyrical 24 | 25 | 26 | # -- General configuration ------------------------------------------------ 27 | 28 | # If your documentation needs a minimal Sphinx version, state it here. 29 | # 30 | # needs_sphinx = '1.0' 31 | 32 | # Add any Sphinx extension module names here, as strings. They can be 33 | # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom 34 | # ones. 35 | extensions = ['sphinx.ext.autodoc', 'sphinx.ext.githubpages', 36 | 'sphinx.ext.napoleon'] 37 | # Add any paths that contain templates here, relative to this directory. 38 | templates_path = ['_templates'] 39 | 40 | # The suffix(es) of source filenames. 41 | # You can specify multiple suffix as a list of string: 42 | # 43 | # source_suffix = ['.rst', '.md'] 44 | source_suffix = '.rst' 45 | 46 | # The master toctree document. 47 | master_doc = 'index' 48 | 49 | # General information about the project. 50 | project = 'empyrical' 51 | copyright = '2018, Quantopian' 52 | author = 'Quantopian' 53 | 54 | # The version info for the project you're documenting, acts as replacement for 55 | # |version| and |release|, also used in various other places throughout the 56 | # built documents. 57 | # 58 | # The short X.Y version. 59 | ver = empyrical.__version__ 60 | version = ver[:ver.find('+')] # get only the main part of the version 61 | # The full version, including alpha/beta/rc tags. 62 | release = version 63 | 64 | # The language for content autogenerated by Sphinx. Refer to documentation 65 | # for a list of supported languages. 66 | # 67 | # This is also used if you do content translation via gettext catalogs. 68 | # Usually you set "language" from the command line for these cases. 69 | language = None 70 | 71 | # List of patterns, relative to source directory, that match files and 72 | # directories to ignore when looking for source files. 73 | # This patterns also effect to html_static_path and html_extra_path 74 | exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store', '**tests**'] 75 | 76 | # The name of the Pygments (syntax highlighting) style to use. 77 | pygments_style = 'sphinx' 78 | 79 | # If true, `todo` and `todoList` produce output, else they produce nothing. 80 | todo_include_todos = False 81 | 82 | 83 | # -- Options for HTML output ---------------------------------------------- 84 | 85 | # The theme to use for HTML and HTML Help pages. See the documentation for 86 | # a list of builtin themes. 87 | # 88 | html_theme = 'default' 89 | 90 | # Theme options are theme-specific and customize the look and feel of a theme 91 | # further. For a list of options available for each theme, see the 92 | # documentation. 93 | # 94 | # html_theme_options = {} 95 | 96 | # Add any paths that contain custom static files (such as style sheets) here, 97 | # relative to this directory. They are copied after the builtin static files, 98 | # so a file named "default.css" will overwrite the builtin "default.css". 99 | html_static_path = ['_static'] 100 | 101 | # -- Options for HTMLHelp output ------------------------------------------ 102 | 103 | # Output file base name for HTML help builder. 104 | htmlhelp_basename = 'empyricaldoc' 105 | 106 | 107 | # -- Options for LaTeX output --------------------------------------------- 108 | 109 | latex_elements = { 110 | # The paper size ('letterpaper' or 'a4paper'). 111 | # 112 | # 'papersize': 'letterpaper', 113 | 114 | # The font size ('10pt', '11pt' or '12pt'). 115 | # 116 | # 'pointsize': '10pt', 117 | 118 | # Additional stuff for the LaTeX preamble. 119 | # 120 | # 'preamble': '', 121 | 122 | # Latex figure (float) alignment 123 | # 124 | # 'figure_align': 'htbp', 125 | } 126 | 127 | # Grouping the document tree into LaTeX files. List of tuples 128 | # (source start file, target name, title, 129 | # author, documentclass [howto, manual, or own class]). 130 | latex_documents = [ 131 | (master_doc, 'empyrical.tex', 'empyrical Documentation', 132 | 'Quontopian', 'manual'), 133 | ] 134 | 135 | 136 | # -- Options for manual page output --------------------------------------- 137 | 138 | # One entry per manual page. List of tuples 139 | # (source start file, name, description, authors, manual section). 140 | man_pages = [ 141 | (master_doc, 'empyrical', 'empyrical Documentation', 142 | [author], 1) 143 | ] 144 | 145 | 146 | # -- Options for Texinfo output ------------------------------------------- 147 | 148 | # Grouping the document tree into Texinfo files. List of tuples 149 | # (source start file, target name, title, author, 150 | # dir menu entry, description, category) 151 | texinfo_documents = [ 152 | (master_doc, 'empyrical', 'empyrical Documentation', 153 | author, 'empyrical', 'One line description of project.', 154 | 'Miscellaneous'), 155 | ] 156 | -------------------------------------------------------------------------------- /docs/empyrical.rst: -------------------------------------------------------------------------------- 1 | empyrical package 2 | ================= 3 | 4 | Submodules 5 | ---------- 6 | 7 | empyrical\.stats module 8 | ----------------------- 9 | 10 | .. automodule:: empyrical.stats 11 | :members: 12 | :undoc-members: 13 | :show-inheritance: 14 | 15 | empyrical\.utils module 16 | ----------------------- 17 | 18 | .. automodule:: empyrical.utils 19 | :members: 20 | :undoc-members: 21 | :show-inheritance: 22 | 23 | 24 | Module contents 25 | --------------- 26 | 27 | .. automodule:: empyrical 28 | :members: 29 | :undoc-members: 30 | :show-inheritance: 31 | -------------------------------------------------------------------------------- /docs/index.rst: -------------------------------------------------------------------------------- 1 | empyrical 2 | ========= 3 | 4 | Common financial risk metrics. 5 | 6 | Table of Contents 7 | ----------------- 8 | 9 | - `Installation <#installation>`__ 10 | - `Usage <#usage>`__ 11 | - `API <#api>`__ 12 | - `Support <#support>`__ 13 | - `Contributing <#contributing>`__ 14 | - `Testing <#testing>`__ 15 | - `Documentation <#documentation>`__ 16 | 17 | Source location 18 | --------------- 19 | Hosted on GitHub: https://github.com/quantopian/empyrical 20 | 21 | Installation 22 | ------------ 23 | 24 | :: 25 | 26 | pip install empyrical 27 | 28 | Usage 29 | ----- 30 | 31 | Simple Statistics 32 | 33 | .. code:: python 34 | 35 | import numpy as np 36 | from empyrical import max_drawdown, alpha_beta 37 | 38 | returns = np.array([.01, .02, .03, -.4, -.06, -.02]) 39 | benchmark_returns = np.array([.02, .02, .03, -.35, -.05, -.01]) 40 | 41 | # calculate the max drawdown 42 | max_drawdown(returns) 43 | 44 | # calculate alpha and beta 45 | alpha, beta = alpha_beta(returns, benchmark_returns) 46 | 47 | Rolling Measures 48 | 49 | .. code:: python 50 | 51 | import numpy as np 52 | from empyrical import roll_max_drawdown 53 | 54 | returns = np.array([.01, .02, .03, -.4, -.06, -.02]) 55 | 56 | # calculate the rolling max drawdown 57 | roll_max_drawdown(returns, window=3) 58 | 59 | Pandas Support 60 | 61 | .. code:: python 62 | 63 | import pandas as pd 64 | from empyrical import roll_up_capture, capture 65 | 66 | returns = pd.Series([.01, .02, .03, -.4, -.06, -.02]) 67 | 68 | # calculate a capture ratio 69 | capture(returns) 70 | 71 | # calculate capture for up markets on a rolling 60 day basis 72 | roll_up_capture(returns, window=60) 73 | 74 | API 75 | --- 76 | 77 | .. toctree:: 78 | :maxdepth: 2 79 | 80 | modules.rst 81 | 82 | Support 83 | ------- 84 | 85 | Please `open an 86 | issue `__ for 87 | support. 88 | 89 | Contributing 90 | ------------ 91 | 92 | Please contribute using `Github 93 | Flow `__. Create a branch, 94 | add commits, and `open a pull 95 | request `__. 96 | 97 | Testing 98 | ------- 99 | 100 | - install requirements 101 | - "nose>=1.3.7", 102 | - "parameterized>=0.6.1" 103 | 104 | :: 105 | 106 | python -m unittest 107 | 108 | 109 | Documentation 110 | ------------- 111 | To build this documentation requires `sphinx` 112 | 113 | :: 114 | 115 | cd docs 116 | make_docs.bat 117 | 118 | 119 | .. toctree:: 120 | :maxdepth: 2 121 | :caption: Contents: 122 | 123 | 124 | Indices and tables 125 | ================== 126 | 127 | * :ref:`genindex` 128 | * :ref:`modindex` 129 | * :ref:`search` 130 | -------------------------------------------------------------------------------- /docs/make.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | pushd %~dp0 4 | 5 | REM Command file for Sphinx documentation 6 | 7 | if "%SPHINXBUILD%" == "" ( 8 | set SPHINXBUILD=python -msphinx 9 | ) 10 | set SOURCEDIR=. 11 | set BUILDDIR=_build 12 | set SPHINXPROJ=empyrical 13 | 14 | if "%1" == "" goto help 15 | 16 | %SPHINXBUILD% >NUL 2>NUL 17 | if errorlevel 9009 ( 18 | echo. 19 | echo.The Sphinx module was not found. Make sure you have Sphinx installed, 20 | echo.then set the SPHINXBUILD environment variable to point to the full 21 | echo.path of the 'sphinx-build' executable. Alternatively you may add the 22 | echo.Sphinx directory to PATH. 23 | echo. 24 | echo.If you don't have Sphinx installed, grab it from 25 | echo.http://sphinx-doc.org/ 26 | exit /b 1 27 | ) 28 | 29 | %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% 30 | goto end 31 | 32 | :help 33 | %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% 34 | 35 | :end 36 | popd 37 | -------------------------------------------------------------------------------- /docs/make_docs.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | REM Makes the Sphinx documentation files 3 | 4 | FOR %%a IN (%~dp0\.) do set SOURCE=%%~dpa 5 | set OLD_PYTHONPATH=%PYTHONPATH% 6 | set PYTHONPATH=%PYTHONPATH%;%SOURCE% 7 | 8 | sphinx-apidoc -f -o . ../empyrical 9 | ./make.bat html 10 | set PYTHONPATH=%OLD_PYTHONPATH% 11 | -------------------------------------------------------------------------------- /docs/modules.rst: -------------------------------------------------------------------------------- 1 | empyrical 2 | ========= 3 | 4 | .. toctree:: 5 | :maxdepth: 4 6 | 7 | empyrical 8 | -------------------------------------------------------------------------------- /empyrical/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2016 Quantopian, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # flake8: noqa 16 | 17 | from ._version import get_versions 18 | __version__ = get_versions()['version'] 19 | del get_versions 20 | 21 | from .stats import ( 22 | aggregate_returns, 23 | alpha, 24 | alpha_aligned, 25 | alpha_beta, 26 | alpha_beta_aligned, 27 | annual_return, 28 | annual_volatility, 29 | beta, 30 | beta_aligned, 31 | cagr, 32 | beta_fragility_heuristic, 33 | beta_fragility_heuristic_aligned, 34 | gpd_risk_estimates, 35 | gpd_risk_estimates_aligned, 36 | calmar_ratio, 37 | capture, 38 | conditional_value_at_risk, 39 | cum_returns, 40 | cum_returns_final, 41 | down_alpha_beta, 42 | down_capture, 43 | downside_risk, 44 | excess_sharpe, 45 | max_drawdown, 46 | omega_ratio, 47 | roll_alpha, 48 | roll_alpha_aligned, 49 | roll_alpha_beta, 50 | roll_alpha_beta, 51 | roll_alpha_beta_aligned, 52 | roll_annual_volatility, 53 | roll_beta, 54 | roll_beta_aligned, 55 | roll_down_capture, 56 | roll_max_drawdown, 57 | roll_sharpe_ratio, 58 | roll_sortino_ratio, 59 | roll_up_capture, 60 | roll_up_down_capture, 61 | sharpe_ratio, 62 | simple_returns, 63 | sortino_ratio, 64 | stability_of_timeseries, 65 | tail_ratio, 66 | up_alpha_beta, 67 | up_capture, 68 | up_down_capture, 69 | value_at_risk, 70 | ) 71 | 72 | from .periods import ( 73 | DAILY, 74 | WEEKLY, 75 | MONTHLY, 76 | QUARTERLY, 77 | YEARLY 78 | ) 79 | 80 | 81 | from .perf_attrib import ( 82 | perf_attrib, 83 | compute_exposures, 84 | ) 85 | -------------------------------------------------------------------------------- /empyrical/_version.py: -------------------------------------------------------------------------------- 1 | 2 | # This file helps to compute a version number in source trees obtained from 3 | # git-archive tarball (such as those provided by githubs download-from-tag 4 | # feature). Distribution tarballs (built by setup.py sdist) and build 5 | # directories (produced by setup.py build) will contain a much shorter file 6 | # that just contains the computed version number. 7 | 8 | # This file is released into the public domain. Generated by 9 | # versioneer-0.16 (https://github.com/warner/python-versioneer) 10 | 11 | """Git implementation of _version.py.""" 12 | 13 | import errno 14 | import os 15 | import re 16 | import subprocess 17 | import sys 18 | 19 | 20 | def get_keywords(): 21 | """Get the keywords needed to look up the version information.""" 22 | # these strings will be replaced by git during git-archive. 23 | # setup.py/versioneer.py will grep for the variable names, so they must 24 | # each be defined on a line of their own. _version.py will just call 25 | # get_keywords(). 26 | git_refnames = " (HEAD -> master)" 27 | git_full = "40f61b4f229df10898d46d08f7b1bdc543c0f99c" 28 | keywords = {"refnames": git_refnames, "full": git_full} 29 | return keywords 30 | 31 | 32 | class VersioneerConfig: 33 | """Container for Versioneer configuration parameters.""" 34 | 35 | 36 | def get_config(): 37 | """Create, populate and return the VersioneerConfig() object.""" 38 | # these strings are filled in when 'setup.py versioneer' creates 39 | # _version.py 40 | cfg = VersioneerConfig() 41 | cfg.VCS = "git" 42 | cfg.style = "pep440" 43 | cfg.tag_prefix = "" 44 | cfg.parentdir_prefix = "empyrical-" 45 | cfg.versionfile_source = "empyrical/_version.py" 46 | cfg.verbose = False 47 | return cfg 48 | 49 | 50 | class NotThisMethod(Exception): 51 | """Exception raised if a method is not valid for the current scenario.""" 52 | 53 | 54 | LONG_VERSION_PY = {} 55 | HANDLERS = {} 56 | 57 | 58 | def register_vcs_handler(vcs, method): # decorator 59 | """Decorator to mark a method as the handler for a particular VCS.""" 60 | def decorate(f): 61 | """Store f in HANDLERS[vcs][method].""" 62 | if vcs not in HANDLERS: 63 | HANDLERS[vcs] = {} 64 | HANDLERS[vcs][method] = f 65 | return f 66 | return decorate 67 | 68 | 69 | def run_command(commands, args, cwd=None, verbose=False, hide_stderr=False): 70 | """Call the given command(s).""" 71 | assert isinstance(commands, list) 72 | p = None 73 | for c in commands: 74 | try: 75 | dispcmd = str([c] + args) 76 | # remember shell=False, so use git.cmd on windows, not just git 77 | p = subprocess.Popen([c] + args, cwd=cwd, stdout=subprocess.PIPE, 78 | stderr=(subprocess.PIPE if hide_stderr 79 | else None)) 80 | break 81 | except EnvironmentError: 82 | e = sys.exc_info()[1] 83 | if e.errno == errno.ENOENT: 84 | continue 85 | if verbose: 86 | print("unable to run %s" % dispcmd) 87 | print(e) 88 | return None 89 | else: 90 | if verbose: 91 | print("unable to find command, tried %s" % (commands,)) 92 | return None 93 | stdout = p.communicate()[0].strip() 94 | if sys.version_info[0] >= 3: 95 | stdout = stdout.decode() 96 | if p.returncode != 0: 97 | if verbose: 98 | print("unable to run %s (error)" % dispcmd) 99 | return None 100 | return stdout 101 | 102 | 103 | def versions_from_parentdir(parentdir_prefix, root, verbose): 104 | """Try to determine the version from the parent directory name. 105 | 106 | Source tarballs conventionally unpack into a directory that includes 107 | both the project name and a version string. 108 | """ 109 | dirname = os.path.basename(root) 110 | if not dirname.startswith(parentdir_prefix): 111 | if verbose: 112 | print("guessing rootdir is '%s', but '%s' doesn't start with " 113 | "prefix '%s'" % (root, dirname, parentdir_prefix)) 114 | raise NotThisMethod("rootdir doesn't start with parentdir_prefix") 115 | return {"version": dirname[len(parentdir_prefix):], 116 | "full-revisionid": None, 117 | "dirty": False, "error": None} 118 | 119 | 120 | @register_vcs_handler("git", "get_keywords") 121 | def git_get_keywords(versionfile_abs): 122 | """Extract version information from the given file.""" 123 | # the code embedded in _version.py can just fetch the value of these 124 | # keywords. When used from setup.py, we don't want to import _version.py, 125 | # so we do it with a regexp instead. This function is not used from 126 | # _version.py. 127 | keywords = {} 128 | try: 129 | f = open(versionfile_abs, "r") 130 | for line in f.readlines(): 131 | if line.strip().startswith("git_refnames ="): 132 | mo = re.search(r'=\s*"(.*)"', line) 133 | if mo: 134 | keywords["refnames"] = mo.group(1) 135 | if line.strip().startswith("git_full ="): 136 | mo = re.search(r'=\s*"(.*)"', line) 137 | if mo: 138 | keywords["full"] = mo.group(1) 139 | f.close() 140 | except EnvironmentError: 141 | pass 142 | return keywords 143 | 144 | 145 | @register_vcs_handler("git", "keywords") 146 | def git_versions_from_keywords(keywords, tag_prefix, verbose): 147 | """Get version information from git keywords.""" 148 | if not keywords: 149 | raise NotThisMethod("no keywords at all, weird") 150 | refnames = keywords["refnames"].strip() 151 | if refnames.startswith("$Format"): 152 | if verbose: 153 | print("keywords are unexpanded, not using") 154 | raise NotThisMethod("unexpanded keywords, not a git-archive tarball") 155 | refs = set([r.strip() for r in refnames.strip("()").split(",")]) 156 | # starting in git-1.8.3, tags are listed as "tag: foo-1.0" instead of 157 | # just "foo-1.0". If we see a "tag: " prefix, prefer those. 158 | TAG = "tag: " 159 | tags = set([r[len(TAG):] for r in refs if r.startswith(TAG)]) 160 | if not tags: 161 | # Either we're using git < 1.8.3, or there really are no tags. We use 162 | # a heuristic: assume all version tags have a digit. The old git %d 163 | # expansion behaves like git log --decorate=short and strips out the 164 | # refs/heads/ and refs/tags/ prefixes that would let us distinguish 165 | # between branches and tags. By ignoring refnames without digits, we 166 | # filter out many common branch names like "release" and 167 | # "stabilization", as well as "HEAD" and "master". 168 | tags = set([r for r in refs if re.search(r'\d', r)]) 169 | if verbose: 170 | print("discarding '%s', no digits" % ",".join(refs-tags)) 171 | if verbose: 172 | print("likely tags: %s" % ",".join(sorted(tags))) 173 | for ref in sorted(tags): 174 | # sorting will prefer e.g. "2.0" over "2.0rc1" 175 | if ref.startswith(tag_prefix): 176 | r = ref[len(tag_prefix):] 177 | if verbose: 178 | print("picking %s" % r) 179 | return {"version": r, 180 | "full-revisionid": keywords["full"].strip(), 181 | "dirty": False, "error": None 182 | } 183 | # no suitable tags, so version is "0+unknown", but full hex is still there 184 | if verbose: 185 | print("no suitable tags, using unknown + full revision id") 186 | return {"version": "0+unknown", 187 | "full-revisionid": keywords["full"].strip(), 188 | "dirty": False, "error": "no suitable tags"} 189 | 190 | 191 | @register_vcs_handler("git", "pieces_from_vcs") 192 | def git_pieces_from_vcs(tag_prefix, root, verbose, run_command=run_command): 193 | """Get version from 'git describe' in the root of the source tree. 194 | 195 | This only gets called if the git-archive 'subst' keywords were *not* 196 | expanded, and _version.py hasn't already been rewritten with a short 197 | version string, meaning we're inside a checked out source tree. 198 | """ 199 | if not os.path.exists(os.path.join(root, ".git")): 200 | if verbose: 201 | print("no .git in %s" % root) 202 | raise NotThisMethod("no .git directory") 203 | 204 | GITS = ["git"] 205 | if sys.platform == "win32": 206 | GITS = ["git.cmd", "git.exe"] 207 | # if there is a tag matching tag_prefix, this yields TAG-NUM-gHEX[-dirty] 208 | # if there isn't one, this yields HEX[-dirty] (no NUM) 209 | describe_out = run_command(GITS, ["describe", "--tags", "--dirty", 210 | "--always", "--long", 211 | "--match", "%s*" % tag_prefix], 212 | cwd=root) 213 | # --long was added in git-1.5.5 214 | if describe_out is None: 215 | raise NotThisMethod("'git describe' failed") 216 | describe_out = describe_out.strip() 217 | full_out = run_command(GITS, ["rev-parse", "HEAD"], cwd=root) 218 | if full_out is None: 219 | raise NotThisMethod("'git rev-parse' failed") 220 | full_out = full_out.strip() 221 | 222 | pieces = {} 223 | pieces["long"] = full_out 224 | pieces["short"] = full_out[:7] # maybe improved later 225 | pieces["error"] = None 226 | 227 | # parse describe_out. It will be like TAG-NUM-gHEX[-dirty] or HEX[-dirty] 228 | # TAG might have hyphens. 229 | git_describe = describe_out 230 | 231 | # look for -dirty suffix 232 | dirty = git_describe.endswith("-dirty") 233 | pieces["dirty"] = dirty 234 | if dirty: 235 | git_describe = git_describe[:git_describe.rindex("-dirty")] 236 | 237 | # now we have TAG-NUM-gHEX or HEX 238 | 239 | if "-" in git_describe: 240 | # TAG-NUM-gHEX 241 | mo = re.search(r'^(.+)-(\d+)-g([0-9a-f]+)$', git_describe) 242 | if not mo: 243 | # unparseable. Maybe git-describe is misbehaving? 244 | pieces["error"] = ("unable to parse git-describe output: '%s'" 245 | % describe_out) 246 | return pieces 247 | 248 | # tag 249 | full_tag = mo.group(1) 250 | if not full_tag.startswith(tag_prefix): 251 | if verbose: 252 | fmt = "tag '%s' doesn't start with prefix '%s'" 253 | print(fmt % (full_tag, tag_prefix)) 254 | pieces["error"] = ("tag '%s' doesn't start with prefix '%s'" 255 | % (full_tag, tag_prefix)) 256 | return pieces 257 | pieces["closest-tag"] = full_tag[len(tag_prefix):] 258 | 259 | # distance: number of commits since tag 260 | pieces["distance"] = int(mo.group(2)) 261 | 262 | # commit: short hex revision ID 263 | pieces["short"] = mo.group(3) 264 | 265 | else: 266 | # HEX: no tags 267 | pieces["closest-tag"] = None 268 | count_out = run_command(GITS, ["rev-list", "HEAD", "--count"], 269 | cwd=root) 270 | pieces["distance"] = int(count_out) # total number of commits 271 | 272 | return pieces 273 | 274 | 275 | def plus_or_dot(pieces): 276 | """Return a + if we don't already have one, else return a .""" 277 | if "+" in pieces.get("closest-tag", ""): 278 | return "." 279 | return "+" 280 | 281 | 282 | def render_pep440(pieces): 283 | """Build up version string, with post-release "local version identifier". 284 | 285 | Our goal: TAG[+DISTANCE.gHEX[.dirty]] . Note that if you 286 | get a tagged build and then dirty it, you'll get TAG+0.gHEX.dirty 287 | 288 | Exceptions: 289 | 1: no tags. git_describe was just HEX. 0+untagged.DISTANCE.gHEX[.dirty] 290 | """ 291 | if pieces["closest-tag"]: 292 | rendered = pieces["closest-tag"] 293 | if pieces["distance"] or pieces["dirty"]: 294 | rendered += plus_or_dot(pieces) 295 | rendered += "%d.g%s" % (pieces["distance"], pieces["short"]) 296 | if pieces["dirty"]: 297 | rendered += ".dirty" 298 | else: 299 | # exception #1 300 | rendered = "0+untagged.%d.g%s" % (pieces["distance"], 301 | pieces["short"]) 302 | if pieces["dirty"]: 303 | rendered += ".dirty" 304 | return rendered 305 | 306 | 307 | def render_pep440_pre(pieces): 308 | """TAG[.post.devDISTANCE] -- No -dirty. 309 | 310 | Exceptions: 311 | 1: no tags. 0.post.devDISTANCE 312 | """ 313 | if pieces["closest-tag"]: 314 | rendered = pieces["closest-tag"] 315 | if pieces["distance"]: 316 | rendered += ".post.dev%d" % pieces["distance"] 317 | else: 318 | # exception #1 319 | rendered = "0.post.dev%d" % pieces["distance"] 320 | return rendered 321 | 322 | 323 | def render_pep440_post(pieces): 324 | """TAG[.postDISTANCE[.dev0]+gHEX] . 325 | 326 | The ".dev0" means dirty. Note that .dev0 sorts backwards 327 | (a dirty tree will appear "older" than the corresponding clean one), 328 | but you shouldn't be releasing software with -dirty anyways. 329 | 330 | Exceptions: 331 | 1: no tags. 0.postDISTANCE[.dev0] 332 | """ 333 | if pieces["closest-tag"]: 334 | rendered = pieces["closest-tag"] 335 | if pieces["distance"] or pieces["dirty"]: 336 | rendered += ".post%d" % pieces["distance"] 337 | if pieces["dirty"]: 338 | rendered += ".dev0" 339 | rendered += plus_or_dot(pieces) 340 | rendered += "g%s" % pieces["short"] 341 | else: 342 | # exception #1 343 | rendered = "0.post%d" % pieces["distance"] 344 | if pieces["dirty"]: 345 | rendered += ".dev0" 346 | rendered += "+g%s" % pieces["short"] 347 | return rendered 348 | 349 | 350 | def render_pep440_old(pieces): 351 | """TAG[.postDISTANCE[.dev0]] . 352 | 353 | The ".dev0" means dirty. 354 | 355 | Eexceptions: 356 | 1: no tags. 0.postDISTANCE[.dev0] 357 | """ 358 | if pieces["closest-tag"]: 359 | rendered = pieces["closest-tag"] 360 | if pieces["distance"] or pieces["dirty"]: 361 | rendered += ".post%d" % pieces["distance"] 362 | if pieces["dirty"]: 363 | rendered += ".dev0" 364 | else: 365 | # exception #1 366 | rendered = "0.post%d" % pieces["distance"] 367 | if pieces["dirty"]: 368 | rendered += ".dev0" 369 | return rendered 370 | 371 | 372 | def render_git_describe(pieces): 373 | """TAG[-DISTANCE-gHEX][-dirty]. 374 | 375 | Like 'git describe --tags --dirty --always'. 376 | 377 | Exceptions: 378 | 1: no tags. HEX[-dirty] (note: no 'g' prefix) 379 | """ 380 | if pieces["closest-tag"]: 381 | rendered = pieces["closest-tag"] 382 | if pieces["distance"]: 383 | rendered += "-%d-g%s" % (pieces["distance"], pieces["short"]) 384 | else: 385 | # exception #1 386 | rendered = pieces["short"] 387 | if pieces["dirty"]: 388 | rendered += "-dirty" 389 | return rendered 390 | 391 | 392 | def render_git_describe_long(pieces): 393 | """TAG-DISTANCE-gHEX[-dirty]. 394 | 395 | Like 'git describe --tags --dirty --always -long'. 396 | The distance/hash is unconditional. 397 | 398 | Exceptions: 399 | 1: no tags. HEX[-dirty] (note: no 'g' prefix) 400 | """ 401 | if pieces["closest-tag"]: 402 | rendered = pieces["closest-tag"] 403 | rendered += "-%d-g%s" % (pieces["distance"], pieces["short"]) 404 | else: 405 | # exception #1 406 | rendered = pieces["short"] 407 | if pieces["dirty"]: 408 | rendered += "-dirty" 409 | return rendered 410 | 411 | 412 | def render(pieces, style): 413 | """Render the given version pieces into the requested style.""" 414 | if pieces["error"]: 415 | return {"version": "unknown", 416 | "full-revisionid": pieces.get("long"), 417 | "dirty": None, 418 | "error": pieces["error"]} 419 | 420 | if not style or style == "default": 421 | style = "pep440" # the default 422 | 423 | if style == "pep440": 424 | rendered = render_pep440(pieces) 425 | elif style == "pep440-pre": 426 | rendered = render_pep440_pre(pieces) 427 | elif style == "pep440-post": 428 | rendered = render_pep440_post(pieces) 429 | elif style == "pep440-old": 430 | rendered = render_pep440_old(pieces) 431 | elif style == "git-describe": 432 | rendered = render_git_describe(pieces) 433 | elif style == "git-describe-long": 434 | rendered = render_git_describe_long(pieces) 435 | else: 436 | raise ValueError("unknown style '%s'" % style) 437 | 438 | return {"version": rendered, "full-revisionid": pieces["long"], 439 | "dirty": pieces["dirty"], "error": None} 440 | 441 | 442 | def get_versions(): 443 | """Get version information or return default if unable to do so.""" 444 | # I am in _version.py, which lives at ROOT/VERSIONFILE_SOURCE. If we have 445 | # __file__, we can work backwards from there to the root. Some 446 | # py2exe/bbfreeze/non-CPython implementations don't do __file__, in which 447 | # case we can only use expanded keywords. 448 | 449 | cfg = get_config() 450 | verbose = cfg.verbose 451 | 452 | try: 453 | return git_versions_from_keywords(get_keywords(), cfg.tag_prefix, 454 | verbose) 455 | except NotThisMethod: 456 | pass 457 | 458 | try: 459 | root = os.path.realpath(__file__) 460 | # versionfile_source is the relative path from the top of the source 461 | # tree (where the .git directory might live) to this file. Invert 462 | # this to find the root from __file__. 463 | for i in cfg.versionfile_source.split('/'): 464 | root = os.path.dirname(root) 465 | except NameError: 466 | return {"version": "0+unknown", "full-revisionid": None, 467 | "dirty": None, 468 | "error": "unable to find root of source tree"} 469 | 470 | try: 471 | pieces = git_pieces_from_vcs(cfg.tag_prefix, root, verbose) 472 | return render(pieces, cfg.style) 473 | except NotThisMethod: 474 | pass 475 | 476 | try: 477 | if cfg.parentdir_prefix: 478 | return versions_from_parentdir(cfg.parentdir_prefix, root, verbose) 479 | except NotThisMethod: 480 | pass 481 | 482 | return {"version": "0+unknown", "full-revisionid": None, 483 | "dirty": None, 484 | "error": "unable to compute version"} 485 | -------------------------------------------------------------------------------- /empyrical/deprecate.py: -------------------------------------------------------------------------------- 1 | """Utilities for marking deprecated functions.""" 2 | # Copyright 2018 Quantopian, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | import warnings 17 | from functools import wraps 18 | 19 | 20 | def deprecated(msg=None, stacklevel=2): 21 | """ 22 | Used to mark a function as deprecated. 23 | Parameters 24 | ---------- 25 | msg : str 26 | The message to display in the deprecation warning. 27 | stacklevel : int 28 | How far up the stack the warning needs to go, before 29 | showing the relevant calling lines. 30 | Usage 31 | ----- 32 | @deprecated(msg='function_a is deprecated! Use function_b instead.') 33 | def function_a(*args, **kwargs): 34 | """ 35 | def deprecated_dec(fn): 36 | @wraps(fn) 37 | def wrapper(*args, **kwargs): 38 | warnings.warn( 39 | msg or "Function %s is deprecated." % fn.__name__, 40 | category=DeprecationWarning, 41 | stacklevel=stacklevel 42 | ) 43 | return fn(*args, **kwargs) 44 | return wrapper 45 | return deprecated_dec 46 | -------------------------------------------------------------------------------- /empyrical/perf_attrib.py: -------------------------------------------------------------------------------- 1 | from collections import OrderedDict 2 | import pandas as pd 3 | 4 | 5 | def perf_attrib(returns, 6 | positions, 7 | factor_returns, 8 | factor_loadings): 9 | """ 10 | Attributes the performance of a returns stream to a set of risk factors. 11 | 12 | Performance attribution determines how much each risk factor, e.g., 13 | momentum, the technology sector, etc., contributed to total returns, as 14 | well as the daily exposure to each of the risk factors. The returns that 15 | can be attributed to one of the given risk factors are the 16 | `common_returns`, and the returns that _cannot_ be attributed to a risk 17 | factor are the `specific_returns`. The `common_returns` and 18 | `specific_returns` summed together will always equal the total returns. 19 | 20 | Parameters 21 | ---------- 22 | returns : pd.Series 23 | Returns for each day in the date range. 24 | - Example: 25 | 2017-01-01 -0.017098 26 | 2017-01-02 0.002683 27 | 2017-01-03 -0.008669 28 | 29 | positions: pd.Series 30 | Daily holdings in percentages, indexed by date. 31 | - Examples: 32 | dt ticker 33 | 2017-01-01 AAPL 0.417582 34 | TLT 0.010989 35 | XOM 0.571429 36 | 2017-01-02 AAPL 0.202381 37 | TLT 0.535714 38 | XOM 0.261905 39 | 40 | factor_returns : pd.DataFrame 41 | Returns by factor, with date as index and factors as columns 42 | - Example: 43 | momentum reversal 44 | 2017-01-01 0.002779 -0.005453 45 | 2017-01-02 0.001096 0.010290 46 | 47 | factor_loadings : pd.DataFrame 48 | Factor loadings for all days in the date range, with date and ticker as 49 | index, and factors as columns. 50 | - Example: 51 | momentum reversal 52 | dt ticker 53 | 2017-01-01 AAPL -1.592914 0.852830 54 | TLT 0.184864 0.895534 55 | XOM 0.993160 1.149353 56 | 2017-01-02 AAPL -0.140009 -0.524952 57 | TLT -1.066978 0.185435 58 | XOM -1.798401 0.761549 59 | 60 | Returns 61 | ------- 62 | tuple of (risk_exposures_portfolio, perf_attribution) 63 | 64 | risk_exposures_portfolio : pd.DataFrame 65 | df indexed by datetime, with factors as columns 66 | - Example: 67 | momentum reversal 68 | dt 69 | 2017-01-01 -0.238655 0.077123 70 | 2017-01-02 0.821872 1.520515 71 | 72 | perf_attribution : pd.DataFrame 73 | df with factors, common returns, and specific returns as columns, 74 | and datetimes as index 75 | - Example: 76 | momentum reversal common_returns specific_returns 77 | dt 78 | 2017-01-01 0.249087 0.935925 1.185012 1.185012 79 | 2017-01-02 -0.003194 -0.400786 -0.403980 -0.403980 80 | 81 | Note 82 | ---- 83 | See https://en.wikipedia.org/wiki/Performance_attribution for more details. 84 | """ 85 | 86 | # Make risk data match time range of returns 87 | start = returns.index[0] 88 | end = returns.index[-1] 89 | factor_returns = factor_returns.loc[start:end] 90 | factor_loadings = factor_loadings.loc[start:end] 91 | 92 | factor_loadings.index = factor_loadings.index.set_names(['dt', 'ticker']) 93 | 94 | positions = positions.copy() 95 | positions.index = positions.index.set_names(['dt', 'ticker']) 96 | 97 | risk_exposures_portfolio = compute_exposures(positions, 98 | factor_loadings) 99 | 100 | perf_attrib_by_factor = risk_exposures_portfolio.multiply(factor_returns) 101 | common_returns = perf_attrib_by_factor.sum(axis='columns') 102 | 103 | tilt_exposure = risk_exposures_portfolio.mean() 104 | tilt_returns = factor_returns.multiply(tilt_exposure).sum(axis='columns') 105 | timing_returns = common_returns - tilt_returns 106 | specific_returns = returns - common_returns 107 | 108 | returns_df = pd.DataFrame(OrderedDict([ 109 | ('total_returns', returns), 110 | ('common_returns', common_returns), 111 | ('specific_returns', specific_returns), 112 | ('tilt_returns', tilt_returns), 113 | ('timing_returns', timing_returns) 114 | ])) 115 | 116 | return (risk_exposures_portfolio, 117 | pd.concat([perf_attrib_by_factor, returns_df], axis='columns')) 118 | 119 | 120 | def compute_exposures(positions, factor_loadings): 121 | """ 122 | Compute daily risk factor exposures. 123 | 124 | Parameters 125 | ---------- 126 | positions: pd.Series 127 | A series of holdings as percentages indexed by date and ticker. 128 | - Examples: 129 | dt ticker 130 | 2017-01-01 AAPL 0.417582 131 | TLT 0.010989 132 | XOM 0.571429 133 | 2017-01-02 AAPL 0.202381 134 | TLT 0.535714 135 | XOM 0.261905 136 | 137 | factor_loadings : pd.DataFrame 138 | Factor loadings for all days in the date range, with date and ticker as 139 | index, and factors as columns. 140 | - Example: 141 | momentum reversal 142 | dt ticker 143 | 2017-01-01 AAPL -1.592914 0.852830 144 | TLT 0.184864 0.895534 145 | XOM 0.993160 1.149353 146 | 2017-01-02 AAPL -0.140009 -0.524952 147 | TLT -1.066978 0.185435 148 | XOM -1.798401 0.761549 149 | 150 | Returns 151 | ------- 152 | risk_exposures_portfolio : pd.DataFrame 153 | df indexed by datetime, with factors as columns 154 | - Example: 155 | momentum reversal 156 | dt 157 | 2017-01-01 -0.238655 0.077123 158 | 2017-01-02 0.821872 1.520515 159 | """ 160 | risk_exposures = factor_loadings.multiply(positions, axis='rows') 161 | return risk_exposures.groupby(level='dt').sum() 162 | -------------------------------------------------------------------------------- /empyrical/periods.py: -------------------------------------------------------------------------------- 1 | APPROX_BDAYS_PER_MONTH = 21 2 | APPROX_BDAYS_PER_YEAR = 252 3 | 4 | MONTHS_PER_YEAR = 12 5 | WEEKS_PER_YEAR = 52 6 | QTRS_PER_YEAR = 4 7 | 8 | DAILY = 'daily' 9 | WEEKLY = 'weekly' 10 | MONTHLY = 'monthly' 11 | QUARTERLY = 'quarterly' 12 | YEARLY = 'yearly' 13 | 14 | ANNUALIZATION_FACTORS = { 15 | DAILY: APPROX_BDAYS_PER_YEAR, 16 | WEEKLY: WEEKS_PER_YEAR, 17 | MONTHLY: MONTHS_PER_YEAR, 18 | QUARTERLY: QTRS_PER_YEAR, 19 | YEARLY: 1 20 | } 21 | -------------------------------------------------------------------------------- /empyrical/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quantopian/empyrical/40f61b4f229df10898d46d08f7b1bdc543c0f99c/empyrical/tests/__init__.py -------------------------------------------------------------------------------- /empyrical/tests/test_data/factor_loadings.csv: -------------------------------------------------------------------------------- 1 | dt,ticker,materials,financials 2 | 2016-01-04,19001,1.0,1.0 3 | 2016-01-04,19002,1.0,1.0 4 | 2016-01-05,19001,1.0,1.0 5 | 2016-01-05,19002,1.0,1.0 6 | 2016-01-06,19001,1.0,1.0 7 | 2016-01-06,19002,1.0,1.0 8 | 2016-01-07,19001,1.0,1.0 9 | 2016-01-07,19002,1.0,1.0 10 | 2016-01-08,19001,1.0,1.0 11 | 2016-01-08,19002,1.0,1.0 12 | 2016-01-11,19001,1.0,1.0 13 | 2016-01-11,19002,1.0,1.0 14 | 2016-01-12,19001,1.0,1.0 15 | 2016-01-12,19002,1.0,1.0 16 | 2016-01-13,19001,1.0,1.0 17 | 2016-01-13,19002,1.0,1.0 18 | 2016-01-14,19001,1.0,1.0 19 | 2016-01-14,19002,1.0,1.0 20 | 2016-01-15,19001,1.0,1.0 21 | 2016-01-15,19002,1.0,1.0 22 | 2016-01-18,19001,1.0,1.0 23 | 2016-01-18,19002,1.0,1.0 24 | 2016-01-19,19001,1.0,1.0 25 | 2016-01-19,19002,1.0,1.0 26 | 2016-01-20,19001,1.0,1.0 27 | 2016-01-20,19002,1.0,1.0 28 | 2016-01-21,19001,1.0,1.0 29 | 2016-01-21,19002,1.0,1.0 30 | 2016-01-22,19001,1.0,1.0 31 | 2016-01-22,19002,1.0,1.0 32 | 2016-01-25,19001,1.0,1.0 33 | 2016-01-25,19002,1.0,1.0 34 | 2016-01-26,19001,1.0,1.0 35 | 2016-01-26,19002,1.0,1.0 36 | 2016-01-27,19001,1.0,1.0 37 | 2016-01-27,19002,1.0,1.0 38 | 2016-01-28,19001,1.0,1.0 39 | 2016-01-28,19002,1.0,1.0 40 | 2016-01-29,19001,1.0,1.0 41 | 2016-01-29,19002,1.0,1.0 42 | 2016-02-01,19001,1.0,1.0 43 | 2016-02-01,19002,1.0,1.0 44 | 2016-02-02,19001,1.0,1.0 45 | 2016-02-02,19002,1.0,1.0 46 | 2016-02-03,19001,1.0,1.0 47 | 2016-02-03,19002,1.0,1.0 48 | 2016-02-04,19001,1.0,1.0 49 | 2016-02-04,19002,1.0,1.0 50 | 2016-02-05,19001,1.0,1.0 51 | 2016-02-05,19002,1.0,1.0 52 | 2016-02-08,19001,1.0,1.0 53 | 2016-02-08,19002,1.0,1.0 54 | 2016-02-09,19001,1.0,1.0 55 | 2016-02-09,19002,1.0,1.0 56 | 2016-02-10,19001,1.0,1.0 57 | 2016-02-10,19002,1.0,1.0 58 | 2016-02-11,19001,1.0,1.0 59 | 2016-02-11,19002,1.0,1.0 60 | 2016-02-12,19001,1.0,1.0 61 | 2016-02-12,19002,1.0,1.0 62 | 2016-02-15,19001,1.0,1.0 63 | 2016-02-15,19002,1.0,1.0 64 | 2016-02-16,19001,1.0,1.0 65 | 2016-02-16,19002,1.0,1.0 66 | 2016-02-17,19001,1.0,1.0 67 | 2016-02-17,19002,1.0,1.0 68 | 2016-02-18,19001,1.0,1.0 69 | 2016-02-18,19002,1.0,1.0 70 | 2016-02-19,19001,1.0,1.0 71 | 2016-02-19,19002,1.0,1.0 72 | 2016-02-22,19001,1.0,1.0 73 | 2016-02-22,19002,1.0,1.0 74 | 2016-02-23,19001,1.0,1.0 75 | 2016-02-23,19002,1.0,1.0 76 | 2016-02-24,19001,1.0,1.0 77 | 2016-02-24,19002,1.0,1.0 78 | 2016-02-25,19001,1.0,1.0 79 | 2016-02-25,19002,1.0,1.0 80 | 2016-02-26,19001,1.0,1.0 81 | 2016-02-26,19002,1.0,1.0 82 | 2016-02-29,19001,1.0,1.0 83 | 2016-02-29,19002,1.0,1.0 84 | 2016-03-01,19001,1.0,1.0 85 | 2016-03-01,19002,1.0,1.0 86 | 2016-03-02,19001,1.0,1.0 87 | 2016-03-02,19002,1.0,1.0 88 | 2016-03-03,19001,1.0,1.0 89 | 2016-03-03,19002,1.0,1.0 90 | 2016-03-04,19001,1.0,1.0 91 | 2016-03-04,19002,1.0,1.0 92 | 2016-03-07,19001,1.0,1.0 93 | 2016-03-07,19002,1.0,1.0 94 | 2016-03-08,19001,1.0,1.0 95 | 2016-03-08,19002,1.0,1.0 96 | 2016-03-09,19001,1.0,1.0 97 | 2016-03-09,19002,1.0,1.0 98 | 2016-03-10,19001,1.0,1.0 99 | 2016-03-10,19002,1.0,1.0 100 | 2016-03-11,19001,1.0,1.0 101 | 2016-03-11,19002,1.0,1.0 102 | 2016-03-14,19001,1.0,1.0 103 | 2016-03-14,19002,1.0,1.0 104 | 2016-03-15,19001,1.0,1.0 105 | 2016-03-15,19002,1.0,1.0 106 | 2016-03-16,19001,1.0,1.0 107 | 2016-03-16,19002,1.0,1.0 108 | 2016-03-17,19001,1.0,1.0 109 | 2016-03-17,19002,1.0,1.0 110 | 2016-03-18,19001,1.0,1.0 111 | 2016-03-18,19002,1.0,1.0 112 | 2016-03-21,19001,1.0,1.0 113 | 2016-03-21,19002,1.0,1.0 114 | 2016-03-22,19001,1.0,1.0 115 | 2016-03-22,19002,1.0,1.0 116 | 2016-03-23,19001,1.0,1.0 117 | 2016-03-23,19002,1.0,1.0 118 | 2016-03-24,19001,1.0,1.0 119 | 2016-03-24,19002,1.0,1.0 120 | 2016-03-25,19001,1.0,1.0 121 | 2016-03-25,19002,1.0,1.0 122 | 2016-03-28,19001,1.0,1.0 123 | 2016-03-28,19002,1.0,1.0 124 | 2016-03-29,19001,1.0,1.0 125 | 2016-03-29,19002,1.0,1.0 126 | 2016-03-30,19001,1.0,1.0 127 | 2016-03-30,19002,1.0,1.0 128 | 2016-03-31,19001,1.0,1.0 129 | 2016-03-31,19002,1.0,1.0 130 | 2016-04-01,19001,1.0,1.0 131 | 2016-04-01,19002,1.0,1.0 132 | 2016-04-04,19001,1.0,1.0 133 | 2016-04-04,19002,1.0,1.0 134 | 2016-04-05,19001,1.0,1.0 135 | 2016-04-05,19002,1.0,1.0 136 | 2016-04-06,19001,1.0,1.0 137 | 2016-04-06,19002,1.0,1.0 138 | 2016-04-07,19001,1.0,1.0 139 | 2016-04-07,19002,1.0,1.0 140 | 2016-04-08,19001,1.0,1.0 141 | 2016-04-08,19002,1.0,1.0 142 | 2016-04-11,19001,1.0,1.0 143 | 2016-04-11,19002,1.0,1.0 144 | 2016-04-12,19001,1.0,1.0 145 | 2016-04-12,19002,1.0,1.0 146 | 2016-04-13,19001,1.0,1.0 147 | 2016-04-13,19002,1.0,1.0 148 | 2016-04-14,19001,1.0,1.0 149 | 2016-04-14,19002,1.0,1.0 150 | 2016-04-15,19001,1.0,1.0 151 | 2016-04-15,19002,1.0,1.0 152 | 2016-04-18,19001,1.0,1.0 153 | 2016-04-18,19002,1.0,1.0 154 | 2016-04-19,19001,1.0,1.0 155 | 2016-04-19,19002,1.0,1.0 156 | 2016-04-20,19001,1.0,1.0 157 | 2016-04-20,19002,1.0,1.0 158 | 2016-04-21,19001,1.0,1.0 159 | 2016-04-21,19002,1.0,1.0 160 | 2016-04-22,19001,1.0,1.0 161 | 2016-04-22,19002,1.0,1.0 162 | 2016-04-25,19001,1.0,1.0 163 | 2016-04-25,19002,1.0,1.0 164 | 2016-04-26,19001,1.0,1.0 165 | 2016-04-26,19002,1.0,1.0 166 | 2016-04-27,19001,1.0,1.0 167 | 2016-04-27,19002,1.0,1.0 168 | 2016-04-28,19001,1.0,1.0 169 | 2016-04-28,19002,1.0,1.0 170 | 2016-04-29,19001,1.0,1.0 171 | 2016-04-29,19002,1.0,1.0 172 | 2016-05-02,19001,1.0,1.0 173 | 2016-05-02,19002,1.0,1.0 174 | 2016-05-03,19001,1.0,1.0 175 | 2016-05-03,19002,1.0,1.0 176 | 2016-05-04,19001,1.0,1.0 177 | 2016-05-04,19002,1.0,1.0 178 | 2016-05-05,19001,1.0,1.0 179 | 2016-05-05,19002,1.0,1.0 180 | 2016-05-06,19001,1.0,1.0 181 | 2016-05-06,19002,1.0,1.0 182 | 2016-05-09,19001,1.0,1.0 183 | 2016-05-09,19002,1.0,1.0 184 | 2016-05-10,19001,1.0,1.0 185 | 2016-05-10,19002,1.0,1.0 186 | 2016-05-11,19001,1.0,1.0 187 | 2016-05-11,19002,1.0,1.0 188 | 2016-05-12,19001,1.0,1.0 189 | 2016-05-12,19002,1.0,1.0 190 | 2016-05-13,19001,1.0,1.0 191 | 2016-05-13,19002,1.0,1.0 192 | 2016-05-16,19001,1.0,1.0 193 | 2016-05-16,19002,1.0,1.0 194 | 2016-05-17,19001,1.0,1.0 195 | 2016-05-17,19002,1.0,1.0 196 | 2016-05-18,19001,1.0,1.0 197 | 2016-05-18,19002,1.0,1.0 198 | 2016-05-19,19001,1.0,1.0 199 | 2016-05-19,19002,1.0,1.0 200 | 2016-05-20,19001,1.0,1.0 201 | 2016-05-20,19002,1.0,1.0 202 | 2016-05-23,19001,1.0,1.0 203 | 2016-05-23,19002,1.0,1.0 204 | 2016-05-24,19001,1.0,1.0 205 | 2016-05-24,19002,1.0,1.0 206 | 2016-05-25,19001,1.0,1.0 207 | 2016-05-25,19002,1.0,1.0 208 | 2016-05-26,19001,1.0,1.0 209 | 2016-05-26,19002,1.0,1.0 210 | 2016-05-27,19001,1.0,1.0 211 | 2016-05-27,19002,1.0,1.0 212 | 2016-05-30,19001,1.0,1.0 213 | 2016-05-30,19002,1.0,1.0 214 | 2016-05-31,19001,1.0,1.0 215 | 2016-05-31,19002,1.0,1.0 216 | 2016-06-01,19001,1.0,1.0 217 | 2016-06-01,19002,1.0,1.0 218 | 2016-06-02,19001,1.0,1.0 219 | 2016-06-02,19002,1.0,1.0 220 | 2016-06-03,19001,1.0,1.0 221 | 2016-06-03,19002,1.0,1.0 222 | 2016-06-06,19001,1.0,1.0 223 | 2016-06-06,19002,1.0,1.0 224 | 2016-06-07,19001,1.0,1.0 225 | 2016-06-07,19002,1.0,1.0 226 | 2016-06-08,19001,1.0,1.0 227 | 2016-06-08,19002,1.0,1.0 228 | 2016-06-09,19001,1.0,1.0 229 | 2016-06-09,19002,1.0,1.0 230 | 2016-06-10,19001,1.0,1.0 231 | 2016-06-10,19002,1.0,1.0 232 | 2016-06-13,19001,1.0,1.0 233 | 2016-06-13,19002,1.0,1.0 234 | 2016-06-14,19001,1.0,1.0 235 | 2016-06-14,19002,1.0,1.0 236 | 2016-06-15,19001,1.0,1.0 237 | 2016-06-15,19002,1.0,1.0 238 | 2016-06-16,19001,1.0,1.0 239 | 2016-06-16,19002,1.0,1.0 240 | 2016-06-17,19001,1.0,1.0 241 | 2016-06-17,19002,1.0,1.0 242 | 2016-06-20,19001,1.0,1.0 243 | 2016-06-20,19002,1.0,1.0 244 | 2016-06-21,19001,1.0,1.0 245 | 2016-06-21,19002,1.0,1.0 246 | 2016-06-22,19001,1.0,1.0 247 | 2016-06-22,19002,1.0,1.0 248 | 2016-06-23,19001,1.0,1.0 249 | 2016-06-23,19002,1.0,1.0 250 | 2016-06-24,19001,1.0,1.0 251 | 2016-06-24,19002,1.0,1.0 252 | 2016-06-27,19001,1.0,1.0 253 | 2016-06-27,19002,1.0,1.0 254 | 2016-06-28,19001,1.0,1.0 255 | 2016-06-28,19002,1.0,1.0 256 | 2016-06-29,19001,1.0,1.0 257 | 2016-06-29,19002,1.0,1.0 258 | 2016-06-30,19001,1.0,1.0 259 | 2016-06-30,19002,1.0,1.0 260 | 2016-07-01,19001,1.0,1.0 261 | 2016-07-01,19002,1.0,1.0 262 | 2016-07-04,19001,1.0,1.0 263 | 2016-07-04,19002,1.0,1.0 264 | 2016-07-05,19001,1.0,1.0 265 | 2016-07-05,19002,1.0,1.0 266 | 2016-07-06,19001,1.0,1.0 267 | 2016-07-06,19002,1.0,1.0 268 | 2016-07-07,19001,1.0,1.0 269 | 2016-07-07,19002,1.0,1.0 270 | 2016-07-08,19001,1.0,1.0 271 | 2016-07-08,19002,1.0,1.0 272 | 2016-07-11,19001,1.0,1.0 273 | 2016-07-11,19002,1.0,1.0 274 | 2016-07-12,19001,1.0,1.0 275 | 2016-07-12,19002,1.0,1.0 276 | 2016-07-13,19001,1.0,1.0 277 | 2016-07-13,19002,1.0,1.0 278 | 2016-07-14,19001,1.0,1.0 279 | 2016-07-14,19002,1.0,1.0 280 | 2016-07-15,19001,1.0,1.0 281 | 2016-07-15,19002,1.0,1.0 282 | 2016-07-18,19001,1.0,1.0 283 | 2016-07-18,19002,1.0,1.0 284 | 2016-07-19,19001,1.0,1.0 285 | 2016-07-19,19002,1.0,1.0 286 | 2016-07-20,19001,1.0,1.0 287 | 2016-07-20,19002,1.0,1.0 288 | 2016-07-21,19001,1.0,1.0 289 | 2016-07-21,19002,1.0,1.0 290 | 2016-07-22,19001,1.0,1.0 291 | 2016-07-22,19002,1.0,1.0 292 | 2016-07-25,19001,1.0,1.0 293 | 2016-07-25,19002,1.0,1.0 294 | 2016-07-26,19001,1.0,1.0 295 | 2016-07-26,19002,1.0,1.0 296 | 2016-07-27,19001,1.0,1.0 297 | 2016-07-27,19002,1.0,1.0 298 | 2016-07-28,19001,1.0,1.0 299 | 2016-07-28,19002,1.0,1.0 300 | 2016-07-29,19001,1.0,1.0 301 | 2016-07-29,19002,1.0,1.0 302 | 2016-08-01,19001,1.0,1.0 303 | 2016-08-01,19002,1.0,1.0 304 | 2016-08-02,19001,1.0,1.0 305 | 2016-08-02,19002,1.0,1.0 306 | 2016-08-03,19001,1.0,1.0 307 | 2016-08-03,19002,1.0,1.0 308 | 2016-08-04,19001,1.0,1.0 309 | 2016-08-04,19002,1.0,1.0 310 | 2016-08-05,19001,1.0,1.0 311 | 2016-08-05,19002,1.0,1.0 312 | 2016-08-08,19001,1.0,1.0 313 | 2016-08-08,19002,1.0,1.0 314 | 2016-08-09,19001,1.0,1.0 315 | 2016-08-09,19002,1.0,1.0 316 | 2016-08-10,19001,1.0,1.0 317 | 2016-08-10,19002,1.0,1.0 318 | 2016-08-11,19001,1.0,1.0 319 | 2016-08-11,19002,1.0,1.0 320 | 2016-08-12,19001,1.0,1.0 321 | 2016-08-12,19002,1.0,1.0 322 | 2016-08-15,19001,1.0,1.0 323 | 2016-08-15,19002,1.0,1.0 324 | 2016-08-16,19001,1.0,1.0 325 | 2016-08-16,19002,1.0,1.0 326 | 2016-08-17,19001,1.0,1.0 327 | 2016-08-17,19002,1.0,1.0 328 | 2016-08-18,19001,1.0,1.0 329 | 2016-08-18,19002,1.0,1.0 330 | 2016-08-19,19001,1.0,1.0 331 | 2016-08-19,19002,1.0,1.0 332 | 2016-08-22,19001,1.0,1.0 333 | 2016-08-22,19002,1.0,1.0 334 | 2016-08-23,19001,1.0,1.0 335 | 2016-08-23,19002,1.0,1.0 336 | 2016-08-24,19001,1.0,1.0 337 | 2016-08-24,19002,1.0,1.0 338 | 2016-08-25,19001,1.0,1.0 339 | 2016-08-25,19002,1.0,1.0 340 | 2016-08-26,19001,1.0,1.0 341 | 2016-08-26,19002,1.0,1.0 342 | 2016-08-29,19001,1.0,1.0 343 | 2016-08-29,19002,1.0,1.0 344 | 2016-08-30,19001,1.0,1.0 345 | 2016-08-30,19002,1.0,1.0 346 | 2016-08-31,19001,1.0,1.0 347 | 2016-08-31,19002,1.0,1.0 348 | 2016-09-01,19001,1.0,1.0 349 | 2016-09-01,19002,1.0,1.0 350 | 2016-09-02,19001,1.0,1.0 351 | 2016-09-02,19002,1.0,1.0 352 | 2016-09-05,19001,1.0,1.0 353 | 2016-09-05,19002,1.0,1.0 354 | 2016-09-06,19001,1.0,1.0 355 | 2016-09-06,19002,1.0,1.0 356 | 2016-09-07,19001,1.0,1.0 357 | 2016-09-07,19002,1.0,1.0 358 | 2016-09-08,19001,1.0,1.0 359 | 2016-09-08,19002,1.0,1.0 360 | 2016-09-09,19001,1.0,1.0 361 | 2016-09-09,19002,1.0,1.0 362 | 2016-09-12,19001,1.0,1.0 363 | 2016-09-12,19002,1.0,1.0 364 | 2016-09-13,19001,1.0,1.0 365 | 2016-09-13,19002,1.0,1.0 366 | 2016-09-14,19001,1.0,1.0 367 | 2016-09-14,19002,1.0,1.0 368 | 2016-09-15,19001,1.0,1.0 369 | 2016-09-15,19002,1.0,1.0 370 | 2016-09-16,19001,1.0,1.0 371 | 2016-09-16,19002,1.0,1.0 372 | 2016-09-19,19001,1.0,1.0 373 | 2016-09-19,19002,1.0,1.0 374 | 2016-09-20,19001,1.0,1.0 375 | 2016-09-20,19002,1.0,1.0 376 | 2016-09-21,19001,1.0,1.0 377 | 2016-09-21,19002,1.0,1.0 378 | 2016-09-22,19001,1.0,1.0 379 | 2016-09-22,19002,1.0,1.0 380 | 2016-09-23,19001,1.0,1.0 381 | 2016-09-23,19002,1.0,1.0 382 | 2016-09-26,19001,1.0,1.0 383 | 2016-09-26,19002,1.0,1.0 384 | 2016-09-27,19001,1.0,1.0 385 | 2016-09-27,19002,1.0,1.0 386 | 2016-09-28,19001,1.0,1.0 387 | 2016-09-28,19002,1.0,1.0 388 | 2016-09-29,19001,1.0,1.0 389 | 2016-09-29,19002,1.0,1.0 390 | 2016-09-30,19001,1.0,1.0 391 | 2016-09-30,19002,1.0,1.0 392 | 2016-10-03,19001,1.0,1.0 393 | 2016-10-03,19002,1.0,1.0 394 | 2016-10-04,19001,1.0,1.0 395 | 2016-10-04,19002,1.0,1.0 396 | 2016-10-05,19001,1.0,1.0 397 | 2016-10-05,19002,1.0,1.0 398 | 2016-10-06,19001,1.0,1.0 399 | 2016-10-06,19002,1.0,1.0 400 | 2016-10-07,19001,1.0,1.0 401 | 2016-10-07,19002,1.0,1.0 402 | 2016-10-10,19001,1.0,1.0 403 | 2016-10-10,19002,1.0,1.0 404 | 2016-10-11,19001,1.0,1.0 405 | 2016-10-11,19002,1.0,1.0 406 | 2016-10-12,19001,1.0,1.0 407 | 2016-10-12,19002,1.0,1.0 408 | 2016-10-13,19001,1.0,1.0 409 | 2016-10-13,19002,1.0,1.0 410 | 2016-10-14,19001,1.0,1.0 411 | 2016-10-14,19002,1.0,1.0 412 | 2016-10-17,19001,1.0,1.0 413 | 2016-10-17,19002,1.0,1.0 414 | 2016-10-18,19001,1.0,1.0 415 | 2016-10-18,19002,1.0,1.0 416 | 2016-10-19,19001,1.0,1.0 417 | 2016-10-19,19002,1.0,1.0 418 | 2016-10-20,19001,1.0,1.0 419 | 2016-10-20,19002,1.0,1.0 420 | 2016-10-21,19001,1.0,1.0 421 | 2016-10-21,19002,1.0,1.0 422 | 2016-10-24,19001,1.0,1.0 423 | 2016-10-24,19002,1.0,1.0 424 | 2016-10-25,19001,1.0,1.0 425 | 2016-10-25,19002,1.0,1.0 426 | 2016-10-26,19001,1.0,1.0 427 | 2016-10-26,19002,1.0,1.0 428 | 2016-10-27,19001,1.0,1.0 429 | 2016-10-27,19002,1.0,1.0 430 | 2016-10-28,19001,1.0,1.0 431 | 2016-10-28,19002,1.0,1.0 432 | 2016-10-31,19001,1.0,1.0 433 | 2016-10-31,19002,1.0,1.0 434 | 2016-11-01,19001,1.0,1.0 435 | 2016-11-01,19002,1.0,1.0 436 | 2016-11-02,19001,1.0,1.0 437 | 2016-11-02,19002,1.0,1.0 438 | 2016-11-03,19001,1.0,1.0 439 | 2016-11-03,19002,1.0,1.0 440 | 2016-11-04,19001,1.0,1.0 441 | 2016-11-04,19002,1.0,1.0 442 | 2016-11-07,19001,1.0,1.0 443 | 2016-11-07,19002,1.0,1.0 444 | 2016-11-08,19001,1.0,1.0 445 | 2016-11-08,19002,1.0,1.0 446 | 2016-11-09,19001,1.0,1.0 447 | 2016-11-09,19002,1.0,1.0 448 | 2016-11-10,19001,1.0,1.0 449 | 2016-11-10,19002,1.0,1.0 450 | 2016-11-11,19001,1.0,1.0 451 | 2016-11-11,19002,1.0,1.0 452 | 2016-11-14,19001,1.0,1.0 453 | 2016-11-14,19002,1.0,1.0 454 | 2016-11-15,19001,1.0,1.0 455 | 2016-11-15,19002,1.0,1.0 456 | 2016-11-16,19001,1.0,1.0 457 | 2016-11-16,19002,1.0,1.0 458 | 2016-11-17,19001,1.0,1.0 459 | 2016-11-17,19002,1.0,1.0 460 | 2016-11-18,19001,1.0,1.0 461 | 2016-11-18,19002,1.0,1.0 462 | 2016-11-21,19001,1.0,1.0 463 | 2016-11-21,19002,1.0,1.0 464 | 2016-11-22,19001,1.0,1.0 465 | 2016-11-22,19002,1.0,1.0 466 | 2016-11-23,19001,1.0,1.0 467 | 2016-11-23,19002,1.0,1.0 468 | 2016-11-24,19001,1.0,1.0 469 | 2016-11-24,19002,1.0,1.0 470 | 2016-11-25,19001,1.0,1.0 471 | 2016-11-25,19002,1.0,1.0 472 | 2016-11-28,19001,1.0,1.0 473 | 2016-11-28,19002,1.0,1.0 474 | 2016-11-29,19001,1.0,1.0 475 | 2016-11-29,19002,1.0,1.0 476 | 2016-11-30,19001,1.0,1.0 477 | 2016-11-30,19002,1.0,1.0 478 | 2016-12-01,19001,1.0,1.0 479 | 2016-12-01,19002,1.0,1.0 480 | 2016-12-02,19001,1.0,1.0 481 | 2016-12-02,19002,1.0,1.0 482 | 2016-12-05,19001,1.0,1.0 483 | 2016-12-05,19002,1.0,1.0 484 | 2016-12-06,19001,1.0,1.0 485 | 2016-12-06,19002,1.0,1.0 486 | 2016-12-07,19001,1.0,1.0 487 | 2016-12-07,19002,1.0,1.0 488 | 2016-12-08,19001,1.0,1.0 489 | 2016-12-08,19002,1.0,1.0 490 | 2016-12-09,19001,1.0,1.0 491 | 2016-12-09,19002,1.0,1.0 492 | 2016-12-12,19001,1.0,1.0 493 | 2016-12-12,19002,1.0,1.0 494 | 2016-12-13,19001,1.0,1.0 495 | 2016-12-13,19002,1.0,1.0 496 | 2016-12-14,19001,1.0,1.0 497 | 2016-12-14,19002,1.0,1.0 498 | 2016-12-15,19001,1.0,1.0 499 | 2016-12-15,19002,1.0,1.0 500 | 2016-12-16,19001,1.0,1.0 501 | 2016-12-16,19002,1.0,1.0 502 | 2016-12-19,19001,1.0,1.0 503 | 2016-12-19,19002,1.0,1.0 504 | 2016-12-20,19001,1.0,1.0 505 | 2016-12-20,19002,1.0,1.0 506 | 2016-12-21,19001,1.0,1.0 507 | 2016-12-21,19002,1.0,1.0 508 | 2016-12-22,19001,1.0,1.0 509 | 2016-12-22,19002,1.0,1.0 510 | 2016-12-23,19001,1.0,1.0 511 | 2016-12-23,19002,1.0,1.0 512 | 2016-12-26,19001,1.0,1.0 513 | 2016-12-26,19002,1.0,1.0 514 | 2016-12-27,19001,1.0,1.0 515 | 2016-12-27,19002,1.0,1.0 516 | 2016-12-28,19001,1.0,1.0 517 | 2016-12-28,19002,1.0,1.0 518 | 2016-12-29,19001,1.0,1.0 519 | 2016-12-29,19002,1.0,1.0 520 | 2016-12-30,19001,1.0,1.0 521 | 2016-12-30,19002,1.0,1.0 522 | 2017-01-02,19001,1.0,1.0 523 | 2017-01-02,19002,1.0,1.0 524 | 2017-01-03,19001,1.0,1.0 525 | 2017-01-03,19002,1.0,1.0 526 | 2017-01-04,19001,1.0,1.0 527 | 2017-01-04,19002,1.0,1.0 528 | 2017-01-05,19001,1.0,1.0 529 | 2017-01-05,19002,1.0,1.0 530 | 2017-01-06,19001,1.0,1.0 531 | 2017-01-06,19002,1.0,1.0 532 | 2017-01-09,19001,1.0,1.0 533 | 2017-01-09,19002,1.0,1.0 534 | 2017-01-10,19001,1.0,1.0 535 | 2017-01-10,19002,1.0,1.0 536 | 2017-01-11,19001,1.0,1.0 537 | 2017-01-11,19002,1.0,1.0 538 | 2017-01-12,19001,1.0,1.0 539 | 2017-01-12,19002,1.0,1.0 540 | 2017-01-13,19001,1.0,1.0 541 | 2017-01-13,19002,1.0,1.0 542 | 2017-01-16,19001,1.0,1.0 543 | 2017-01-16,19002,1.0,1.0 544 | 2017-01-17,19001,1.0,1.0 545 | 2017-01-17,19002,1.0,1.0 546 | 2017-01-18,19001,1.0,1.0 547 | 2017-01-18,19002,1.0,1.0 548 | 2017-01-19,19001,1.0,1.0 549 | 2017-01-19,19002,1.0,1.0 550 | 2017-01-20,19001,1.0,1.0 551 | 2017-01-20,19002,1.0,1.0 552 | 2017-01-23,19001,1.0,1.0 553 | 2017-01-23,19002,1.0,1.0 554 | 2017-01-24,19001,1.0,1.0 555 | 2017-01-24,19002,1.0,1.0 556 | 2017-01-25,19001,1.0,1.0 557 | 2017-01-25,19002,1.0,1.0 558 | 2017-01-26,19001,1.0,1.0 559 | 2017-01-26,19002,1.0,1.0 560 | 2017-01-27,19001,1.0,1.0 561 | 2017-01-27,19002,1.0,1.0 562 | 2017-01-30,19001,1.0,1.0 563 | 2017-01-30,19002,1.0,1.0 564 | 2017-01-31,19001,1.0,1.0 565 | 2017-01-31,19002,1.0,1.0 566 | 2017-02-01,19001,1.0,1.0 567 | 2017-02-01,19002,1.0,1.0 568 | 2017-02-02,19001,1.0,1.0 569 | 2017-02-02,19002,1.0,1.0 570 | 2017-02-03,19001,1.0,1.0 571 | 2017-02-03,19002,1.0,1.0 572 | 2017-02-06,19001,1.0,1.0 573 | 2017-02-06,19002,1.0,1.0 574 | 2017-02-07,19001,1.0,1.0 575 | 2017-02-07,19002,1.0,1.0 576 | 2017-02-08,19001,1.0,1.0 577 | 2017-02-08,19002,1.0,1.0 578 | 2017-02-09,19001,1.0,1.0 579 | 2017-02-09,19002,1.0,1.0 580 | 2017-02-10,19001,1.0,1.0 581 | 2017-02-10,19002,1.0,1.0 582 | 2017-02-13,19001,1.0,1.0 583 | 2017-02-13,19002,1.0,1.0 584 | 2017-02-14,19001,1.0,1.0 585 | 2017-02-14,19002,1.0,1.0 586 | 2017-02-15,19001,1.0,1.0 587 | 2017-02-15,19002,1.0,1.0 588 | 2017-02-16,19001,1.0,1.0 589 | 2017-02-16,19002,1.0,1.0 590 | 2017-02-17,19001,1.0,1.0 591 | 2017-02-17,19002,1.0,1.0 592 | 2017-02-20,19001,1.0,1.0 593 | 2017-02-20,19002,1.0,1.0 594 | 2017-02-21,19001,1.0,1.0 595 | 2017-02-21,19002,1.0,1.0 596 | 2017-02-22,19001,1.0,1.0 597 | 2017-02-22,19002,1.0,1.0 598 | 2017-02-23,19001,1.0,1.0 599 | 2017-02-23,19002,1.0,1.0 600 | 2017-02-24,19001,1.0,1.0 601 | 2017-02-24,19002,1.0,1.0 602 | 2017-02-27,19001,1.0,1.0 603 | 2017-02-27,19002,1.0,1.0 604 | 2017-02-28,19001,1.0,1.0 605 | 2017-02-28,19002,1.0,1.0 606 | 2017-03-01,19001,1.0,1.0 607 | 2017-03-01,19002,1.0,1.0 608 | 2017-03-02,19001,1.0,1.0 609 | 2017-03-02,19002,1.0,1.0 610 | 2017-03-03,19001,1.0,1.0 611 | 2017-03-03,19002,1.0,1.0 612 | 2017-03-06,19001,1.0,1.0 613 | 2017-03-06,19002,1.0,1.0 614 | 2017-03-07,19001,1.0,1.0 615 | 2017-03-07,19002,1.0,1.0 616 | 2017-03-08,19001,1.0,1.0 617 | 2017-03-08,19002,1.0,1.0 618 | 2017-03-09,19001,1.0,1.0 619 | 2017-03-09,19002,1.0,1.0 620 | 2017-03-10,19001,1.0,1.0 621 | 2017-03-10,19002,1.0,1.0 622 | 2017-03-13,19001,1.0,1.0 623 | 2017-03-13,19002,1.0,1.0 624 | 2017-03-14,19001,1.0,1.0 625 | 2017-03-14,19002,1.0,1.0 626 | 2017-03-15,19001,1.0,1.0 627 | 2017-03-15,19002,1.0,1.0 628 | 2017-03-16,19001,1.0,1.0 629 | 2017-03-16,19002,1.0,1.0 630 | 2017-03-17,19001,1.0,1.0 631 | 2017-03-17,19002,1.0,1.0 632 | 2017-03-20,19001,1.0,1.0 633 | 2017-03-20,19002,1.0,1.0 634 | 2017-03-21,19001,1.0,1.0 635 | 2017-03-21,19002,1.0,1.0 636 | 2017-03-22,19001,1.0,1.0 637 | 2017-03-22,19002,1.0,1.0 638 | 2017-03-23,19001,1.0,1.0 639 | 2017-03-23,19002,1.0,1.0 640 | 2017-03-24,19001,1.0,1.0 641 | 2017-03-24,19002,1.0,1.0 642 | 2017-03-27,19001,1.0,1.0 643 | 2017-03-27,19002,1.0,1.0 644 | 2017-03-28,19001,1.0,1.0 645 | 2017-03-28,19002,1.0,1.0 646 | 2017-03-29,19001,1.0,1.0 647 | 2017-03-29,19002,1.0,1.0 648 | 2017-03-30,19001,1.0,1.0 649 | 2017-03-30,19002,1.0,1.0 650 | 2017-03-31,19001,1.0,1.0 651 | 2017-03-31,19002,1.0,1.0 652 | 2017-04-03,19001,1.0,1.0 653 | 2017-04-03,19002,1.0,1.0 654 | 2017-04-04,19001,1.0,1.0 655 | 2017-04-04,19002,1.0,1.0 656 | 2017-04-05,19001,1.0,1.0 657 | 2017-04-05,19002,1.0,1.0 658 | 2017-04-06,19001,1.0,1.0 659 | 2017-04-06,19002,1.0,1.0 660 | 2017-04-07,19001,1.0,1.0 661 | 2017-04-07,19002,1.0,1.0 662 | 2017-04-10,19001,1.0,1.0 663 | 2017-04-10,19002,1.0,1.0 664 | 2017-04-11,19001,1.0,1.0 665 | 2017-04-11,19002,1.0,1.0 666 | 2017-04-12,19001,1.0,1.0 667 | 2017-04-12,19002,1.0,1.0 668 | 2017-04-13,19001,1.0,1.0 669 | 2017-04-13,19002,1.0,1.0 670 | 2017-04-14,19001,1.0,1.0 671 | 2017-04-14,19002,1.0,1.0 672 | 2017-04-17,19001,1.0,1.0 673 | 2017-04-17,19002,1.0,1.0 674 | 2017-04-18,19001,1.0,1.0 675 | 2017-04-18,19002,1.0,1.0 676 | 2017-04-19,19001,1.0,1.0 677 | 2017-04-19,19002,1.0,1.0 678 | 2017-04-20,19001,1.0,1.0 679 | 2017-04-20,19002,1.0,1.0 680 | 2017-04-21,19001,1.0,1.0 681 | 2017-04-21,19002,1.0,1.0 682 | 2017-04-24,19001,1.0,1.0 683 | 2017-04-24,19002,1.0,1.0 684 | 2017-04-25,19001,1.0,1.0 685 | 2017-04-25,19002,1.0,1.0 686 | 2017-04-26,19001,1.0,1.0 687 | 2017-04-26,19002,1.0,1.0 688 | 2017-04-27,19001,1.0,1.0 689 | 2017-04-27,19002,1.0,1.0 690 | 2017-04-28,19001,1.0,1.0 691 | 2017-04-28,19002,1.0,1.0 692 | 2017-05-01,19001,1.0,1.0 693 | 2017-05-01,19002,1.0,1.0 694 | 2017-05-02,19001,1.0,1.0 695 | 2017-05-02,19002,1.0,1.0 696 | 2017-05-03,19001,1.0,1.0 697 | 2017-05-03,19002,1.0,1.0 698 | 2017-05-04,19001,1.0,1.0 699 | 2017-05-04,19002,1.0,1.0 700 | 2017-05-05,19001,1.0,1.0 701 | 2017-05-05,19002,1.0,1.0 702 | 2017-05-08,19001,1.0,1.0 703 | 2017-05-08,19002,1.0,1.0 704 | 2017-05-09,19001,1.0,1.0 705 | 2017-05-09,19002,1.0,1.0 706 | 2017-05-10,19001,1.0,1.0 707 | 2017-05-10,19002,1.0,1.0 708 | 2017-05-11,19001,1.0,1.0 709 | 2017-05-11,19002,1.0,1.0 710 | 2017-05-12,19001,1.0,1.0 711 | 2017-05-12,19002,1.0,1.0 712 | 2017-05-15,19001,1.0,1.0 713 | 2017-05-15,19002,1.0,1.0 714 | 2017-05-16,19001,1.0,1.0 715 | 2017-05-16,19002,1.0,1.0 716 | 2017-05-17,19001,1.0,1.0 717 | 2017-05-17,19002,1.0,1.0 718 | 2017-05-18,19001,1.0,1.0 719 | 2017-05-18,19002,1.0,1.0 720 | 2017-05-19,19001,1.0,1.0 721 | 2017-05-19,19002,1.0,1.0 722 | 2017-05-22,19001,1.0,1.0 723 | 2017-05-22,19002,1.0,1.0 724 | 2017-05-23,19001,1.0,1.0 725 | 2017-05-23,19002,1.0,1.0 726 | 2017-05-24,19001,1.0,1.0 727 | 2017-05-24,19002,1.0,1.0 728 | 2017-05-25,19001,1.0,1.0 729 | 2017-05-25,19002,1.0,1.0 730 | 2017-05-26,19001,1.0,1.0 731 | 2017-05-26,19002,1.0,1.0 732 | 2017-05-29,19001,1.0,1.0 733 | 2017-05-29,19002,1.0,1.0 734 | 2017-05-30,19001,1.0,1.0 735 | 2017-05-30,19002,1.0,1.0 736 | 2017-05-31,19001,1.0,1.0 737 | 2017-05-31,19002,1.0,1.0 738 | 2017-06-01,19001,1.0,1.0 739 | 2017-06-01,19002,1.0,1.0 740 | 2017-06-02,19001,1.0,1.0 741 | 2017-06-02,19002,1.0,1.0 742 | 2017-06-05,19001,1.0,1.0 743 | 2017-06-05,19002,1.0,1.0 744 | 2017-06-06,19001,1.0,1.0 745 | 2017-06-06,19002,1.0,1.0 746 | 2017-06-07,19001,1.0,1.0 747 | 2017-06-07,19002,1.0,1.0 748 | 2017-06-08,19001,1.0,1.0 749 | 2017-06-08,19002,1.0,1.0 750 | 2017-06-09,19001,1.0,1.0 751 | 2017-06-09,19002,1.0,1.0 752 | 2017-06-12,19001,1.0,1.0 753 | 2017-06-12,19002,1.0,1.0 754 | 2017-06-13,19001,1.0,1.0 755 | 2017-06-13,19002,1.0,1.0 756 | 2017-06-14,19001,1.0,1.0 757 | 2017-06-14,19002,1.0,1.0 758 | 2017-06-15,19001,1.0,1.0 759 | 2017-06-15,19002,1.0,1.0 760 | 2017-06-16,19001,1.0,1.0 761 | 2017-06-16,19002,1.0,1.0 762 | 2017-06-19,19001,1.0,1.0 763 | 2017-06-19,19002,1.0,1.0 764 | 2017-06-20,19001,1.0,1.0 765 | 2017-06-20,19002,1.0,1.0 766 | 2017-06-21,19001,1.0,1.0 767 | 2017-06-21,19002,1.0,1.0 768 | 2017-06-22,19001,1.0,1.0 769 | 2017-06-22,19002,1.0,1.0 770 | 2017-06-23,19001,1.0,1.0 771 | 2017-06-23,19002,1.0,1.0 772 | 2017-06-26,19001,1.0,1.0 773 | 2017-06-26,19002,1.0,1.0 774 | 2017-06-27,19001,1.0,1.0 775 | 2017-06-27,19002,1.0,1.0 776 | 2017-06-28,19001,1.0,1.0 777 | 2017-06-28,19002,1.0,1.0 778 | 2017-06-29,19001,1.0,1.0 779 | 2017-06-29,19002,1.0,1.0 780 | 2017-06-30,19001,1.0,1.0 781 | 2017-06-30,19002,1.0,1.0 782 | 2017-07-03,19001,1.0,1.0 783 | 2017-07-03,19002,1.0,1.0 784 | 2017-07-04,19001,1.0,1.0 785 | 2017-07-04,19002,1.0,1.0 786 | 2017-07-05,19001,1.0,1.0 787 | 2017-07-05,19002,1.0,1.0 788 | 2017-07-06,19001,1.0,1.0 789 | 2017-07-06,19002,1.0,1.0 790 | 2017-07-07,19001,1.0,1.0 791 | 2017-07-07,19002,1.0,1.0 792 | 2017-07-10,19001,1.0,1.0 793 | 2017-07-10,19002,1.0,1.0 794 | 2017-07-11,19001,1.0,1.0 795 | 2017-07-11,19002,1.0,1.0 796 | 2017-07-12,19001,1.0,1.0 797 | 2017-07-12,19002,1.0,1.0 798 | 2017-07-13,19001,1.0,1.0 799 | 2017-07-13,19002,1.0,1.0 800 | 2017-07-14,19001,1.0,1.0 801 | 2017-07-14,19002,1.0,1.0 802 | 2017-07-17,19001,1.0,1.0 803 | 2017-07-17,19002,1.0,1.0 804 | 2017-07-18,19001,1.0,1.0 805 | 2017-07-18,19002,1.0,1.0 806 | 2017-07-19,19001,1.0,1.0 807 | 2017-07-19,19002,1.0,1.0 808 | 2017-07-20,19001,1.0,1.0 809 | 2017-07-20,19002,1.0,1.0 810 | 2017-07-21,19001,1.0,1.0 811 | 2017-07-21,19002,1.0,1.0 812 | 2017-07-24,19001,1.0,1.0 813 | 2017-07-24,19002,1.0,1.0 814 | 2017-07-25,19001,1.0,1.0 815 | 2017-07-25,19002,1.0,1.0 816 | 2017-07-26,19001,1.0,1.0 817 | 2017-07-26,19002,1.0,1.0 818 | 2017-07-27,19001,1.0,1.0 819 | 2017-07-27,19002,1.0,1.0 820 | 2017-07-28,19001,1.0,1.0 821 | 2017-07-28,19002,1.0,1.0 822 | 2017-07-31,19001,1.0,1.0 823 | 2017-07-31,19002,1.0,1.0 824 | 2017-08-01,19001,1.0,1.0 825 | 2017-08-01,19002,1.0,1.0 826 | 2017-08-02,19001,1.0,1.0 827 | 2017-08-02,19002,1.0,1.0 828 | 2017-08-03,19001,1.0,1.0 829 | 2017-08-03,19002,1.0,1.0 830 | 2017-08-04,19001,1.0,1.0 831 | 2017-08-04,19002,1.0,1.0 832 | 2017-08-07,19001,1.0,1.0 833 | 2017-08-07,19002,1.0,1.0 834 | 2017-08-08,19001,1.0,1.0 835 | 2017-08-08,19002,1.0,1.0 836 | 2017-08-09,19001,1.0,1.0 837 | 2017-08-09,19002,1.0,1.0 838 | 2017-08-10,19001,1.0,1.0 839 | 2017-08-10,19002,1.0,1.0 840 | 2017-08-11,19001,1.0,1.0 841 | 2017-08-11,19002,1.0,1.0 842 | 2017-08-14,19001,1.0,1.0 843 | 2017-08-14,19002,1.0,1.0 844 | 2017-08-15,19001,1.0,1.0 845 | 2017-08-15,19002,1.0,1.0 846 | 2017-08-16,19001,1.0,1.0 847 | 2017-08-16,19002,1.0,1.0 848 | 2017-08-17,19001,1.0,1.0 849 | 2017-08-17,19002,1.0,1.0 850 | 2017-08-18,19001,1.0,1.0 851 | 2017-08-18,19002,1.0,1.0 852 | 2017-08-21,19001,1.0,1.0 853 | 2017-08-21,19002,1.0,1.0 854 | 2017-08-22,19001,1.0,1.0 855 | 2017-08-22,19002,1.0,1.0 856 | 2017-08-23,19001,1.0,1.0 857 | 2017-08-23,19002,1.0,1.0 858 | 2017-08-24,19001,1.0,1.0 859 | 2017-08-24,19002,1.0,1.0 860 | 2017-08-25,19001,1.0,1.0 861 | 2017-08-25,19002,1.0,1.0 862 | 2017-08-28,19001,1.0,1.0 863 | 2017-08-28,19002,1.0,1.0 864 | 2017-08-29,19001,1.0,1.0 865 | 2017-08-29,19002,1.0,1.0 866 | 2017-08-30,19001,1.0,1.0 867 | 2017-08-30,19002,1.0,1.0 868 | 2017-08-31,19001,1.0,1.0 869 | 2017-08-31,19002,1.0,1.0 870 | 2017-09-01,19001,1.0,1.0 871 | 2017-09-01,19002,1.0,1.0 872 | 2017-09-04,19001,1.0,1.0 873 | 2017-09-04,19002,1.0,1.0 874 | 2017-09-05,19001,1.0,1.0 875 | 2017-09-05,19002,1.0,1.0 876 | 2017-09-06,19001,1.0,1.0 877 | 2017-09-06,19002,1.0,1.0 878 | 2017-09-07,19001,1.0,1.0 879 | 2017-09-07,19002,1.0,1.0 880 | 2017-09-08,19001,1.0,1.0 881 | 2017-09-08,19002,1.0,1.0 882 | 2017-09-11,19001,1.0,1.0 883 | 2017-09-11,19002,1.0,1.0 884 | 2017-09-12,19001,1.0,1.0 885 | 2017-09-12,19002,1.0,1.0 886 | 2017-09-13,19001,1.0,1.0 887 | 2017-09-13,19002,1.0,1.0 888 | 2017-09-14,19001,1.0,1.0 889 | 2017-09-14,19002,1.0,1.0 890 | 2017-09-15,19001,1.0,1.0 891 | 2017-09-15,19002,1.0,1.0 892 | 2017-09-18,19001,1.0,1.0 893 | 2017-09-18,19002,1.0,1.0 894 | 2017-09-19,19001,1.0,1.0 895 | 2017-09-19,19002,1.0,1.0 896 | 2017-09-20,19001,1.0,1.0 897 | 2017-09-20,19002,1.0,1.0 898 | 2017-09-21,19001,1.0,1.0 899 | 2017-09-21,19002,1.0,1.0 900 | 2017-09-22,19001,1.0,1.0 901 | 2017-09-22,19002,1.0,1.0 902 | 2017-09-25,19001,1.0,1.0 903 | 2017-09-25,19002,1.0,1.0 904 | 2017-09-26,19001,1.0,1.0 905 | 2017-09-26,19002,1.0,1.0 906 | 2017-09-27,19001,1.0,1.0 907 | 2017-09-27,19002,1.0,1.0 908 | 2017-09-28,19001,1.0,1.0 909 | 2017-09-28,19002,1.0,1.0 910 | 2017-09-29,19001,1.0,1.0 911 | 2017-09-29,19002,1.0,1.0 912 | 2017-10-02,19001,1.0,1.0 913 | 2017-10-02,19002,1.0,1.0 914 | 2017-10-03,19001,1.0,1.0 915 | 2017-10-03,19002,1.0,1.0 916 | 2017-10-04,19001,1.0,1.0 917 | 2017-10-04,19002,1.0,1.0 918 | 2017-10-05,19001,1.0,1.0 919 | 2017-10-05,19002,1.0,1.0 920 | 2017-10-06,19001,1.0,1.0 921 | 2017-10-06,19002,1.0,1.0 922 | 2017-10-09,19001,1.0,1.0 923 | 2017-10-09,19002,1.0,1.0 924 | 2017-10-10,19001,1.0,1.0 925 | 2017-10-10,19002,1.0,1.0 926 | 2017-10-11,19001,1.0,1.0 927 | 2017-10-11,19002,1.0,1.0 928 | 2017-10-12,19001,1.0,1.0 929 | 2017-10-12,19002,1.0,1.0 930 | 2017-10-13,19001,1.0,1.0 931 | 2017-10-13,19002,1.0,1.0 932 | 2017-10-16,19001,1.0,1.0 933 | 2017-10-16,19002,1.0,1.0 934 | 2017-10-17,19001,1.0,1.0 935 | 2017-10-17,19002,1.0,1.0 936 | 2017-10-18,19001,1.0,1.0 937 | 2017-10-18,19002,1.0,1.0 938 | 2017-10-19,19001,1.0,1.0 939 | 2017-10-19,19002,1.0,1.0 940 | 2017-10-20,19001,1.0,1.0 941 | 2017-10-20,19002,1.0,1.0 942 | 2017-10-23,19001,1.0,1.0 943 | 2017-10-23,19002,1.0,1.0 944 | 2017-10-24,19001,1.0,1.0 945 | 2017-10-24,19002,1.0,1.0 946 | 2017-10-25,19001,1.0,1.0 947 | 2017-10-25,19002,1.0,1.0 948 | 2017-10-26,19001,1.0,1.0 949 | 2017-10-26,19002,1.0,1.0 950 | 2017-10-27,19001,1.0,1.0 951 | 2017-10-27,19002,1.0,1.0 952 | 2017-10-30,19001,1.0,1.0 953 | 2017-10-30,19002,1.0,1.0 954 | 2017-10-31,19001,1.0,1.0 955 | 2017-10-31,19002,1.0,1.0 956 | 2017-11-01,19001,1.0,1.0 957 | 2017-11-01,19002,1.0,1.0 958 | 2017-11-02,19001,1.0,1.0 959 | 2017-11-02,19002,1.0,1.0 960 | 2017-11-03,19001,1.0,1.0 961 | 2017-11-03,19002,1.0,1.0 962 | 2017-11-06,19001,1.0,1.0 963 | 2017-11-06,19002,1.0,1.0 964 | 2017-11-07,19001,1.0,1.0 965 | 2017-11-07,19002,1.0,1.0 966 | 2017-11-08,19001,1.0,1.0 967 | 2017-11-08,19002,1.0,1.0 968 | 2017-11-09,19001,1.0,1.0 969 | 2017-11-09,19002,1.0,1.0 970 | 2017-11-10,19001,1.0,1.0 971 | 2017-11-10,19002,1.0,1.0 972 | 2017-11-13,19001,1.0,1.0 973 | 2017-11-13,19002,1.0,1.0 974 | 2017-11-14,19001,1.0,1.0 975 | 2017-11-14,19002,1.0,1.0 976 | 2017-11-15,19001,1.0,1.0 977 | 2017-11-15,19002,1.0,1.0 978 | 2017-11-16,19001,1.0,1.0 979 | 2017-11-16,19002,1.0,1.0 980 | 2017-11-17,19001,1.0,1.0 981 | 2017-11-17,19002,1.0,1.0 982 | 2017-11-20,19001,1.0,1.0 983 | 2017-11-20,19002,1.0,1.0 984 | 2017-11-21,19001,1.0,1.0 985 | 2017-11-21,19002,1.0,1.0 986 | 2017-11-22,19001,1.0,1.0 987 | 2017-11-22,19002,1.0,1.0 988 | 2017-11-23,19001,1.0,1.0 989 | 2017-11-23,19002,1.0,1.0 990 | 2017-11-24,19001,1.0,1.0 991 | 2017-11-24,19002,1.0,1.0 992 | 2017-11-27,19001,1.0,1.0 993 | 2017-11-27,19002,1.0,1.0 994 | 2017-11-28,19001,1.0,1.0 995 | 2017-11-28,19002,1.0,1.0 996 | 2017-11-29,19001,1.0,1.0 997 | 2017-11-29,19002,1.0,1.0 998 | 2017-11-30,19001,1.0,1.0 999 | 2017-11-30,19002,1.0,1.0 1000 | 2017-12-01,19001,1.0,1.0 1001 | 2017-12-01,19002,1.0,1.0 1002 | 2017-12-04,19001,1.0,1.0 1003 | 2017-12-04,19002,1.0,1.0 1004 | 2017-12-05,19001,1.0,1.0 1005 | 2017-12-05,19002,1.0,1.0 1006 | 2017-12-06,19001,1.0,1.0 1007 | 2017-12-06,19002,1.0,1.0 1008 | 2017-12-07,19001,1.0,1.0 1009 | 2017-12-07,19002,1.0,1.0 1010 | -------------------------------------------------------------------------------- /empyrical/tests/test_data/factor_returns.csv: -------------------------------------------------------------------------------- 1 | ,materials,financials 2 | 2016-01-04,1.76405234597,0.400157208367 3 | 2016-01-05,0.978737984106,2.2408931992 4 | 2016-01-06,1.86755799015,-0.977277879876 5 | 2016-01-07,0.950088417526,-0.151357208298 6 | 2016-01-08,-0.103218851794,0.410598501938 7 | 2016-01-11,0.144043571161,1.45427350696 8 | 2016-01-12,0.761037725147,0.121675016493 9 | 2016-01-13,0.443863232745,0.333674327374 10 | 2016-01-14,1.49407907316,-0.205158263766 11 | 2016-01-15,0.313067701651,-0.854095739302 12 | 2016-01-18,-2.55298981583,0.65361859544 13 | 2016-01-19,0.86443619886,-0.742165020406 14 | 2016-01-20,2.26975462399,-1.4543656746 15 | 2016-01-21,0.0457585173014,-0.187183850026 16 | 2016-01-22,1.53277921436,1.4693587699 17 | 2016-01-25,0.154947425697,0.378162519602 18 | 2016-01-26,-0.88778574763,-1.98079646822 19 | 2016-01-27,-0.347912149326,0.156348969104 20 | 2016-01-28,1.23029068073,1.20237984878 21 | 2016-01-29,-0.387326817408,-0.302302750575 22 | 2016-02-01,-1.04855296507,-1.42001793718 23 | 2016-02-02,-1.70627019063,1.95077539523 24 | 2016-02-03,-0.509652181752,-0.438074301611 25 | 2016-02-04,-1.25279536005,0.777490355832 26 | 2016-02-05,-1.61389784756,-0.212740280214 27 | 2016-02-08,-0.895466561194,0.386902497859 28 | 2016-02-09,-0.510805137569,-1.18063218412 29 | 2016-02-10,-0.0281822283387,0.42833187053 30 | 2016-02-11,0.0665172223832,0.30247189774 31 | 2016-02-12,-0.634322093681,-0.362741165987 32 | 2016-02-15,-0.672460447776,-0.359553161541 33 | 2016-02-16,-0.813146282044,-1.72628260233 34 | 2016-02-17,0.177426142254,-0.401780936208 35 | 2016-02-18,-1.63019834697,0.462782255526 36 | 2016-02-19,-0.907298364383,0.0519453957961 37 | 2016-02-22,0.729090562178,0.128982910757 38 | 2016-02-23,1.13940068454,-1.23482582035 39 | 2016-02-24,0.402341641178,-0.68481009094 40 | 2016-02-25,-0.870797149182,-0.578849664764 41 | 2016-02-26,-0.311552532127,0.0561653422297 42 | 2016-02-29,-1.16514984078,0.900826486954 43 | 2016-03-01,0.46566243973,-1.53624368628 44 | 2016-03-02,1.4882521938,1.89588917603 45 | 2016-03-03,1.17877957116,-0.179924835812 46 | 2016-03-04,-1.07075262151,1.05445172693 47 | 2016-03-07,-0.403176946973,1.22244507038 48 | 2016-03-08,0.208274978077,0.976639036484 49 | 2016-03-09,0.356366397174,0.706573168192 50 | 2016-03-10,0.0105000207208,1.78587049391 51 | 2016-03-11,0.126912092704,0.401989363445 52 | 2016-03-14,1.88315069706,-1.34775906114 53 | 2016-03-15,-1.27048499849,0.969396708158 54 | 2016-03-16,-1.17312340511,1.94362118565 55 | 2016-03-17,-0.41361898076,-0.747454811441 56 | 2016-03-18,1.92294202648,1.48051479143 57 | 2016-03-21,1.86755896043,0.906044658275 58 | 2016-03-22,-0.861225685055,1.9100649531 59 | 2016-03-23,-0.268003370951,0.802456395796 60 | 2016-03-24,0.947251967774,-0.155010093091 61 | 2016-03-25,0.614079370346,0.922206671567 62 | 2016-03-28,0.376425531156,-1.09940079058 63 | 2016-03-29,0.298238174206,1.32638589669 64 | 2016-03-30,-0.694567859731,-0.149634540328 65 | 2016-03-31,-0.435153551722,1.84926372848 66 | 2016-04-01,0.672294757012,0.407461836241 67 | 2016-04-04,-0.769916074445,0.539249191292 68 | 2016-04-05,-0.674332660657,0.0318305582744 69 | 2016-04-06,-0.635846078379,0.676433294946 70 | 2016-04-07,0.576590816615,-0.208298755578 71 | 2016-04-08,0.396006712662,-1.09306150873 72 | 2016-04-11,-1.49125759271,0.439391701265 73 | 2016-04-12,0.166673495373,0.635031436892 74 | 2016-04-13,2.38314477486,0.94447948699 75 | 2016-04-14,-0.912822225444,1.1170162881 76 | 2016-04-15,-1.31590741051,-0.461584604815 77 | 2016-04-18,-0.0682416053246,1.71334272165 78 | 2016-04-19,-0.744754822048,-0.826438538659 79 | 2016-04-20,-0.0984525244254,-0.663478286362 80 | 2016-04-21,1.12663592211,-1.07993150836 81 | 2016-04-22,-1.14746865241,-0.437820044744 82 | 2016-04-25,-0.498032450692,1.92953205382 83 | 2016-04-26,0.949420806926,0.0875512413852 84 | 2016-04-27,-1.22543551883,0.844362976402 85 | 2016-04-28,-1.00021534739,-1.54477109678 86 | 2016-04-29,1.18802979235,0.316942611925 87 | 2016-05-02,0.920858823781,0.318727652943 88 | 2016-05-03,0.856830611903,-0.6510255933 89 | 2016-05-04,-1.03424284178,0.681594518282 90 | 2016-05-05,-0.803409664174,-0.68954977775 91 | 2016-05-06,-0.455532503517,0.0174791590251 92 | 2016-05-09,-0.353993911253,-1.37495129342 93 | 2016-05-10,-0.643618402833,-2.22340315222 94 | 2016-05-11,0.625231451027,-1.60205765561 95 | 2016-05-12,-1.10438333943,0.052165079261 96 | 2016-05-13,-0.739562996391,1.54301459541 97 | 2016-05-16,-1.29285690972,0.267050869349 98 | 2016-05-17,-0.0392828182275,-1.16809349774 99 | 2016-05-18,0.523276660532,-0.171546331222 100 | 2016-05-19,0.771790551214,0.823504153964 101 | 2016-05-20,2.16323594928,1.33652794944 102 | 2016-05-23,-0.369181837942,-0.239379177576 103 | 2016-05-24,1.09965959589,0.655263730723 104 | 2016-05-25,0.640131526098,-1.61695604431 105 | 2016-05-26,-0.0243261243989,-0.738030909206 106 | 2016-05-27,0.279924599043,-0.098150389643 107 | 2016-05-30,0.910178908093,0.317218215191 108 | 2016-05-31,0.786327962109,-0.466419096736 109 | 2016-06-01,-0.944446255918,-0.410049693203 110 | 2016-06-02,-0.0170204138614,0.379151735555 111 | 2016-06-03,2.25930895069,-0.0422571516606 112 | 2016-06-06,-0.955945000493,-0.345981775699 113 | 2016-06-07,-0.463595974646,0.481481473773 114 | 2016-06-08,-1.54079701444,0.0632619942003 115 | 2016-06-09,0.156506537965,0.2321810362 116 | 2016-06-10,-0.597316068965,-0.237921729736 117 | 2016-06-13,-1.42406090898,-0.493319883362 118 | 2016-06-14,-0.542861476017,0.416050046261 119 | 2016-06-15,-1.15618243182,0.78119810171 120 | 2016-06-16,1.49448454449,-2.06998502501 121 | 2016-06-17,0.426258730778,0.67690803503 122 | 2016-06-20,-0.637437025552,-0.397271814329 123 | 2016-06-21,-0.132880577587,-0.297790879402 124 | 2016-06-22,-0.309012969047,-1.67600380633 125 | 2016-06-23,1.15233156478,1.07961859204 126 | 2016-06-24,-0.813364259204,-1.4664243278 127 | 2016-06-27,0.521064876453,-0.575787969813 128 | 2016-06-28,0.141953163321,-0.319328417145 129 | 2016-06-29,0.69153875107,0.694749143656 130 | 2016-06-30,-0.725597378464,-1.3833639554 131 | 2016-07-01,-1.58293839734,0.610379379107 132 | 2016-07-04,-1.18885925778,-0.506816354299 133 | 2016-07-05,-0.596314038451,-0.0525672962695 134 | 2016-07-06,-1.93627980585,0.188778596794 135 | 2016-07-07,0.523891023834,0.0884220870447 136 | 2016-07-08,-0.310886171698,0.0974001662688 137 | 2016-07-11,0.39904634564,-2.77259275643 138 | 2016-07-12,1.95591230825,0.390093322688 139 | 2016-07-13,-0.652408582387,-0.390953375188 140 | 2016-07-14,0.493741777349,-0.116103939034 141 | 2016-07-15,-2.03068446778,2.06449286136 142 | 2016-07-18,-0.110540657232,1.02017271172 143 | 2016-07-19,-0.692049847784,1.53637705425 144 | 2016-07-20,0.286343688892,0.608843834475 145 | 2016-07-21,-1.04525336615,1.21114528968 146 | 2016-07-22,0.689818164535,1.30184622956 147 | 2016-07-25,-0.628087559642,-0.481027118461 148 | 2016-07-26,2.30391669768,-1.06001582272 149 | 2016-07-27,-0.135949700678,1.1368913626 150 | 2016-07-28,0.0977249677149,0.582953679753 151 | 2016-07-29,-0.399449029263,0.370055887848 152 | 2016-08-01,-1.30652685174,1.65813067962 153 | 2016-08-02,-0.118164045129,-0.680178203997 154 | 2016-08-03,0.666383082032,-0.460719787389 155 | 2016-08-04,-1.3342584714,-1.3467175058 156 | 2016-08-05,0.69377315269,-0.159573438146 157 | 2016-08-08,-0.133701559668,1.07774380598 158 | 2016-08-09,-1.12682580876,-0.730677752865 159 | 2016-08-10,-0.384879809181,0.0943515893171 160 | 2016-08-11,-0.0421714512906,-0.28688719239 161 | 2016-08-12,-0.0616264020956,-0.107305276291 162 | 2016-08-15,-0.719604388552,-0.812992988554 163 | 2016-08-16,0.274516357724,-0.890915082996 164 | 2016-08-17,-1.15735525919,-0.312292251126 165 | 2016-08-18,-0.157667016164,2.2567234973 166 | 2016-08-19,-0.704700275856,0.943260724969 167 | 2016-08-22,0.747188334205,-1.1889449552 168 | 2016-08-23,0.773252977403,-1.18388064019 169 | 2016-08-24,-2.659172238,0.606319524359 170 | 2016-08-25,-1.75589058344,0.450934461806 171 | 2016-08-26,-0.684010897737,1.65955079619 172 | 2016-08-29,1.06850939932,-0.453385803851 173 | 2016-08-30,-0.687837611029,-1.21407740309 174 | 2016-08-31,-0.440922632293,-0.280355495185 175 | 2016-09-01,-0.364693544392,0.156703855272 176 | 2016-09-02,0.578521497729,0.349654456993 177 | 2016-09-05,-0.764143923906,-1.4377914738 178 | 2016-09-06,1.3645318481,-0.68944918455 179 | 2016-09-07,-0.652293599935,-0.521189312301 180 | 2016-09-08,-1.84306955016,-0.47797400404 181 | 2016-09-09,-0.479655814008,0.620358298344 182 | 2016-09-12,0.698457149107,0.00377088908627 183 | 2016-09-13,0.931848374114,0.339964983801 184 | 2016-09-14,-0.0156821116026,0.160928168298 185 | 2016-09-15,-0.190653493581,-0.394849514033 186 | 2016-09-16,-0.267733536894,-1.12801133147 187 | 2016-09-19,0.280441705316,-0.99312361093 188 | 2016-09-20,0.841631264074,-0.249458580161 189 | 2016-09-21,0.0494949816501,0.493836776281 190 | 2016-09-22,0.643314465063,-1.57062340863 191 | 2016-09-23,-0.206903676164,0.880178912081 192 | 2016-09-26,-1.69810581943,0.387280475395 193 | 2016-09-27,-2.2555642294,-1.02250684364 194 | 2016-09-28,0.0386305518402,-1.65671510232 195 | 2016-09-29,-0.985510737684,-1.47183500746 196 | 2016-09-30,1.64813493221,0.164227755487 197 | 2016-10-03,0.567290277853,-0.222675100515 198 | 2016-10-04,-0.353431748757,-1.61647418865 199 | 2016-10-05,-0.291837362748,-0.761492211812 200 | 2016-10-06,0.857923924292,1.14110186666 201 | 2016-10-07,1.46657871557,0.852551939461 202 | 2016-10-10,-0.598653936923,-1.11589698596 203 | 2016-10-11,0.766663181645,0.356292817472 204 | 2016-10-12,-1.76853845068,0.355481792744 205 | 2016-10-13,0.814519822488,0.0589255891816 206 | 2016-10-14,-0.185053671009,-0.807648487616 207 | 2016-10-17,-1.44653469956,0.80029794934 208 | 2016-10-18,-0.309114444772,-0.233466661544 209 | 2016-10-19,1.73272118692,0.684501106859 210 | 2016-10-20,0.370825001281,0.142061805187 211 | 2016-10-21,1.51999486077,1.71958930742 212 | 2016-10-24,0.92950511148,0.582224591398 213 | 2016-10-25,-2.09460307121,0.123721914234 214 | 2016-10-26,-0.130106954194,0.0939532293856 215 | 2016-10-27,0.943046087323,-2.73967716719 216 | 2016-10-28,-0.56931205347,0.269904354941 217 | 2016-10-31,-0.466845546053,-1.41690611313 218 | 2016-11-01,0.868963486897,0.276871905846 219 | 2016-11-02,-0.971104570444,0.314817204516 220 | 2016-11-03,0.82158571205,0.00529264629936 221 | 2016-11-04,0.800564803431,0.0782601751617 222 | 2016-11-07,-0.395228982654,-1.1594205164 223 | 2016-11-08,-0.0859307669716,0.194292938046 224 | 2016-11-09,0.875832761587,-0.115107468487 225 | 2016-11-10,0.457415606221,-0.964612013734 226 | 2016-11-11,-0.782629155828,-0.110389299027 227 | 2016-11-14,-1.05462846399,0.820247837325 228 | 2016-11-15,0.463130329319,0.279095764392 229 | 2016-11-16,0.338904125216,2.02104356148 230 | 2016-11-17,-0.468864187967,-2.2014412855 231 | 2016-11-18,0.199300196896,-0.0506035409617 232 | 2016-11-21,-0.51751904251,-0.978829859359 233 | 2016-11-22,-0.439189521802,0.181338429218 234 | 2016-11-23,-0.502816700643,2.41245367954 235 | 2016-11-24,-0.960504381633,-0.793117362708 236 | 2016-11-25,-2.28862004001,0.251484415022 237 | 2016-11-28,-2.0164066278,-0.539454633375 238 | 2016-11-29,-0.275670534561,-0.709727965847 239 | 2016-11-30,1.73887267745,0.994394391315 240 | 2016-12-01,1.3191368763,-0.88241881855 241 | 2016-12-02,1.12859406451,0.496000946344 242 | 2016-12-05,0.771405948677,1.02943882878 243 | 2016-12-06,-0.908763245959,-0.424317620978 244 | 2016-12-07,0.862596011328,-2.65561909297 245 | 2016-12-08,1.51332808257,0.553132064208 246 | 2016-12-09,-0.0457039606602,0.220507655757 247 | 2016-12-12,-1.02993528331,-0.349943364589 248 | 2016-12-13,1.10028433822,1.29802197233 249 | 2016-12-14,2.69622405256,-0.0739246662804 250 | 2016-12-15,-0.658552966805,-0.51423396594 251 | 2016-12-16,-1.01804187529,-0.0778547559409 252 | 2016-12-19,0.382732430012,-0.034242280532 253 | 2016-12-20,1.09634684567,-0.234215801345 254 | 2016-12-21,-0.347450652499,-0.58126847686 255 | 2016-12-22,-1.63263452623,-1.56776772431 256 | 2016-12-23,-1.17915793064,1.30142807166 257 | 2016-12-26,0.89526027289,1.37496406639 258 | 2016-12-27,-1.33221165459,-1.96862468979 259 | 2016-12-28,-0.660056320134,0.175818953296 260 | 2016-12-29,0.49869027491,1.04797215597 261 | 2016-12-30,0.284279670807,1.74266878066 262 | 2017-01-02,-0.222605680948,-0.913079218042 263 | 2017-01-03,-1.68121821549,-0.888971358095 264 | 2017-01-04,0.242117960985,-0.888720257354 265 | 2017-01-05,0.936742463535,1.41232770604 266 | 2017-01-06,-2.36958690523,0.864052300498 267 | 2017-01-09,-2.23960405866,0.40149905509 268 | 2017-01-10,1.22487056419,0.0648561063436 269 | 2017-01-11,-1.2796891732,-0.585431204278 270 | 2017-01-12,-0.261645445711,-0.18224478379 271 | 2017-01-13,-0.202896840767,-0.109882779309 272 | 2017-01-16,0.21348004891,-1.20857365373 273 | 2017-01-17,-0.24201982987,1.51826117036 274 | 2017-01-18,-0.384645423143,-0.443836093155 275 | 2017-01-19,1.07819730371,-2.55918466634 276 | 2017-01-20,1.18137860129,-0.631903758005 277 | 2017-01-23,0.163928572453,0.0963213559212 278 | 2017-01-24,0.94246811922,-0.267594746235 279 | 2017-01-25,-0.678025781564,1.29784579065 280 | 2017-01-26,-2.36417381714,0.0203341817052 281 | 2017-01-27,-1.34792542263,-0.761573388257 282 | 2017-01-30,2.01125668146,-0.0445954264559 283 | 2017-01-31,0.195069697151,-1.78156285571 284 | 2017-02-01,-0.729044658795,0.196557400729 285 | 2017-02-02,0.354757693113,0.616886554393 286 | 2017-02-03,0.00862789891758,0.527004208455 287 | 2017-02-06,0.453781912636,-1.829740411 288 | 2017-02-07,0.0370057219101,0.767902407733 289 | 2017-02-08,0.589879820735,-0.363858809971 290 | 2017-02-09,-0.805626507539,-1.11831192432 291 | 2017-02-10,-0.131054011541,1.13307987956 292 | 2017-02-13,-1.95180410148,-0.659891729729 293 | 2017-02-14,-1.13980245543,0.784957521241 294 | 2017-02-15,-0.554309626571,-0.470637658155 295 | 2017-02-16,-0.216949569937,0.445393250895 296 | 2017-02-17,-0.39238899815,-3.0461430548 297 | 2017-02-20,0.543311891388,0.439042957672 298 | 2017-02-21,-0.219541028331,-1.08403662067 299 | 2017-02-22,0.351780110681,0.379235533536 300 | 2017-02-23,-0.470032882701,-0.216731470576 301 | 2017-02-24,-0.930156502524,-0.178589092087 302 | 2017-02-27,-1.55042934508,0.417318821032 303 | 2017-02-28,-0.944368490824,0.238103147832 304 | 2017-03-01,-1.40596291627,-0.59005764587 305 | 2017-03-02,-0.110489405066,-1.66069981187 306 | 2017-03-03,0.11514787314,-0.37914756288 307 | 2017-03-06,-1.74235619781,-1.30324275411 308 | 2017-03-07,0.605120084082,0.895555985551 309 | 2017-03-08,-0.13190863978,0.40476181204 310 | 2017-03-09,0.223843563313,0.329622982128 311 | 2017-03-10,1.28598400708,-1.50699839821 312 | 2017-03-13,0.676460732362,-0.382008955578 313 | 2017-03-14,-0.224258934252,-0.302249730455 314 | 2017-03-15,-0.375147116661,-1.22619619178 315 | 2017-03-16,0.183339199258,1.67094303279 316 | 2017-03-17,-0.0561330204488,-0.0013850427351 317 | 2017-03-20,-0.687299037157,-0.117474546418 318 | 2017-03-21,0.466166426034,-0.370242440704 319 | 2017-03-22,-0.453804041052,0.403264540163 320 | 2017-03-23,-0.918004769819,0.252496627077 321 | 2017-03-24,0.820321797261,1.35994854168 322 | 2017-03-27,-0.0903820072769,1.36759723981 323 | 2017-03-28,1.03440988648,-0.996212640371 324 | 2017-03-29,-1.21793851159,-0.304963637854 325 | 2017-03-30,1.02893549259,-0.07228700756 326 | 2017-03-31,-0.600657557658,1.55224318005 327 | 2017-04-03,0.286904488003,-2.32059427579 328 | 2017-04-04,0.317160626293,0.520040614571 329 | 2017-04-05,0.225608654471,0.449712100232 330 | 2017-04-06,-0.067275608923,-1.31839586964 331 | 2017-04-07,-0.37070400322,-0.945615795556 332 | 2017-04-10,-0.932740910794,-1.2630683491 333 | 2017-04-11,0.45248909264,0.0978961454126 334 | 2017-04-12,-0.448165362681,-0.64933792773 335 | 2017-04-13,-0.0234231050215,1.07919472811 336 | 2017-04-14,-2.0042157155,0.376876520851 337 | 2017-04-17,-0.545711974018,-1.88458584498 338 | 2017-04-18,-1.94570308316,-0.912783494135 339 | 2017-04-19,0.219509555793,0.39306293398 340 | 2017-04-20,-0.938981572678,1.01702099141 341 | 2017-04-21,1.42298349652,0.396086584957 342 | 2017-04-24,-0.591402667808,1.12441918451 343 | 2017-04-25,0.755395695663,0.867407411355 344 | 2017-04-26,-0.656463674972,-2.83455450527 345 | 2017-04-27,2.11679102148,-1.61087840345 346 | 2017-04-28,-0.0357680718602,2.38074535122 347 | 2017-05-01,0.330576756274,0.949246473558 348 | 2017-05-02,-1.50239656938,-1.77766695473 349 | 2017-05-03,-0.53270279198,1.09074973443 350 | 2017-05-04,-0.346249447647,-0.794636321071 351 | 2017-05-05,0.197967289945,1.08193521848 352 | 2017-05-08,-1.44494019907,-1.21054299412 353 | 2017-05-09,-0.788669254509,1.09463837471 354 | 2017-05-10,0.234821525949,2.13215341057 355 | 2017-05-11,0.936445725831,-0.0350951768697 356 | 2017-05-12,1.26507783809,0.211497012732 357 | 2017-05-15,-0.704921352507,0.679974844245 358 | 2017-05-16,-0.696326653861,-0.290397100804 359 | 2017-05-17,1.32778269596,-0.101281486217 360 | 2017-05-18,-0.803141387342,-0.464337691435 361 | 2017-05-19,1.02179058559,-0.552540673417 362 | 2017-05-22,-0.386870846851,-0.510292739634 363 | 2017-05-23,0.18392549434,-0.385489760376 364 | 2017-05-24,-1.60183604897,-0.887180941845 365 | 2017-05-25,-0.932789041506,1.24331938446 366 | 2017-05-26,0.812674042109,0.5872593794 367 | 2017-05-29,-0.505358317264,-0.815791541994 368 | 2017-05-30,-0.507517601657,-1.05188010255 369 | 2017-05-31,2.49720039159,-2.24532164837 370 | 2017-06-01,0.564008535074,-1.28455229799 371 | 2017-06-02,-0.104343491495,-0.988001942494 372 | 2017-06-05,-1.17762896248,-1.14019630093 373 | 2017-06-06,1.75498615374,-0.13298842231 374 | 2017-06-07,-0.765702194478,0.555786964083 375 | 2017-06-08,0.0103493145663,0.720033759342 376 | 2017-06-09,-1.82425665594,0.303603904462 377 | 2017-06-12,0.772694837102,-1.66159829111 378 | 2017-06-13,0.448195284423,1.69618157283 379 | 2017-06-14,-0.0148577033547,0.821405937025 380 | 2017-06-15,0.670570450311,-0.707505697511 381 | 2017-06-16,0.0397667345865,-1.56699471086 382 | 2017-06-19,-0.451303037103,0.265687974966 383 | 2017-06-20,0.723100493738,0.0246121252479 384 | 2017-06-21,0.719983730143,-1.10290621296 385 | 2017-06-22,-0.101697274555,0.0192793845131 386 | 2017-06-23,1.84959124668,-0.2141666562 387 | 2017-06-26,-0.499016637994,0.0213512238435 388 | 2017-06-27,-0.91911344487,0.192753849065 389 | 2017-06-28,-0.365055216546,-1.79132754804 390 | 2017-06-29,-0.0585865511339,-0.31754309393 391 | 2017-06-30,-1.63242330207,-0.0671341546145 392 | 2017-07-03,1.48935596207,0.521303748276 393 | 2017-07-04,0.611927192731,-1.34149672558 394 | 2017-07-05,0.476898368922,0.14844958138 395 | 2017-07-06,0.529045238334,0.422628621709 396 | 2017-07-07,-1.3597807255,-0.041400811558 397 | 2017-07-10,-0.757870860425,-0.0500840942848 398 | 2017-07-11,-0.897400926902,1.31247036714 399 | 2017-07-12,-0.858972388444,-0.898942156466 400 | 2017-07-13,0.0745864065436,-1.0770990694 401 | 2017-07-14,-0.424663302433,-0.829964597538 402 | 2017-07-17,1.41117206389,0.785803826831 403 | 2017-07-18,-0.0574695184654,-0.391217052174 404 | 2017-07-19,0.940917614575,0.405204080323 405 | 2017-07-20,0.498052404683,-0.0261922373443 406 | 2017-07-21,-1.68823002777,-0.11246598256 407 | 2017-07-24,-0.532489919209,0.64505527346 408 | 2017-07-25,1.01184243299,-0.657951044761 409 | 2017-07-26,0.468385234277,1.73587899769 410 | 2017-07-27,-0.667712720571,1.68192174007 411 | 2017-07-28,-0.852585847171,0.022959755608 412 | 2017-07-31,-0.0111456118418,0.0114988998701 413 | 2017-08-01,-0.837678041908,-0.591183103764 414 | 2017-08-02,-0.667720286359,0.326962595404 415 | 2017-08-03,0.33003511451,2.22594433174 416 | 2017-08-04,1.37098900629,-0.509843242138 417 | 2017-08-07,0.324869615796,0.997117980792 418 | 2017-08-08,0.0306018243385,-0.0696415784469 419 | 2017-08-09,0.0515749427699,0.867276628808 420 | 2017-08-10,-0.848320522805,-0.32566946882 421 | 2017-08-11,0.470433144846,0.311447071554 422 | 2017-08-14,0.239582759856,-0.369801166304 423 | 2017-08-15,0.972535789143,2.1338682472 424 | 2017-08-16,0.406415493676,-0.19317670155 425 | 2017-08-17,0.755740288895,-0.539132636753 426 | 2017-08-18,-0.749690344703,0.0328087476137 427 | 2017-08-21,-2.58279663297,-1.15395036365 428 | 2017-08-22,-0.347961855921,-1.35338885815 429 | 2017-08-23,-1.03264310189,-0.436748337458 430 | 2017-08-24,-1.64296529353,-0.40607179626 431 | 2017-08-25,-0.535270164533,0.025405208385 432 | 2017-08-28,1.15418403049,0.172504416493 433 | 2017-08-29,0.0210620213421,0.0994544570307 434 | 2017-08-30,0.227392775121,-1.01673864861 435 | 2017-08-31,-0.114775324771,0.308751241837 436 | 2017-09-01,-1.37075998254,0.865652922816 437 | 2017-09-04,1.08137603446,-0.631375988449 438 | 2017-09-05,-0.241337791453,-0.87819034281 439 | 2017-09-06,0.699380483588,-1.06122228745 440 | 2017-09-07,-0.222477010243,-0.858919907808 441 | 2017-09-08,0.0509542770113,-1.79422927149 442 | 2017-09-11,1.32646164237,-0.964606424206 443 | 2017-09-12,0.0598946831163,-0.21252304477 444 | 2017-09-13,-0.762114511922,-0.887780136636 445 | 2017-09-14,0.936398543552,-0.525640593102 446 | 2017-09-15,0.271170184637,-0.801496885394 447 | 2017-09-18,-0.647181431848,0.472247150088 448 | 2017-09-19,0.930408496111,-0.175316402327 449 | 2017-09-20,-1.42191987164,1.99795607975 450 | 2017-09-21,-0.856549308234,-1.54158739967 451 | 2017-09-22,2.59442458777,-0.404032293851 452 | 2017-09-25,-1.46173268826,-0.683439766789 453 | 2017-09-26,0.367544896022,0.190311557594 454 | 2017-09-27,-0.851729197254,1.82272360013 455 | 2017-09-28,-0.521579677993,-1.18468659041 456 | 2017-09-29,0.960693398461,1.32906284654 457 | 2017-10-02,-0.817493097616,-1.40134729304 458 | 2017-10-03,1.03043826742,-2.04732361306 459 | 2017-10-04,-1.2266216594,0.96744615005 460 | 2017-10-05,-0.0553525480224,-0.263937348593 461 | 2017-10-06,0.352816606494,-0.152774423545 462 | 2017-10-09,-1.29868672216,1.27607534601 463 | 2017-10-10,1.32501405289,0.205332563778 464 | 2017-10-11,0.045134015432,2.33962480602 465 | 2017-10-12,-0.276432845016,-0.259576981834 466 | 2017-10-13,0.364481249241,1.47132195614 467 | 2017-10-16,1.59277075442,-0.258572631677 468 | 2017-10-17,0.308331245959,-1.37808346706 469 | 2017-10-18,-0.311976107916,-0.840290395479 470 | 2017-10-19,-1.0068317523,1.68157671627 471 | 2017-10-20,-0.792286661806,-0.531605908011 472 | 2017-10-23,0.365848787917,1.29782526697 473 | 2017-10-24,0.481115126389,2.75935511402 474 | 2017-10-25,-0.0746679782511,0.25871644023 475 | 2017-10-26,0.275600673984,1.43504938679 476 | 2017-10-27,0.50723895111,-0.116229700387 477 | 2017-10-30,-0.947488594907,0.244443455962 478 | 2017-10-31,1.40134483129,-0.410381793658 479 | 2017-11-01,0.528943618417,0.246147788685 480 | 2017-11-02,0.863519658381,-0.804753740638 481 | 2017-11-03,2.34664703053,-1.27916110703 482 | 2017-11-06,-0.365551089986,0.938092540906 483 | 2017-11-07,0.296733172494,0.829986159081 484 | 2017-11-08,-0.496102333983,-0.0748049826803 485 | 2017-11-09,0.0122319836388,1.56925961454 486 | 2017-11-10,0.690429024383,0.796672108365 487 | 2017-11-13,-0.657926092537,0.968882638563 488 | 2017-11-14,0.225581663569,1.38914531568 489 | 2017-11-15,2.01406015492,-0.306765776027 490 | 2017-11-16,-0.406303130445,-0.864044991102 491 | 2017-11-17,-0.143579511716,-0.38202544895 492 | 2017-11-20,0.359504399571,-0.144566816934 493 | 2017-11-21,-0.361599280782,1.06458513613 494 | 2017-11-22,-0.937880231151,0.433107953151 495 | 2017-11-23,-0.405941727188,0.72436850487 496 | 2017-11-24,1.38526154672,-0.303098253424 497 | 2017-11-27,0.441032907273,0.178792865733 498 | 2017-11-28,-0.799422399543,0.240787509742 499 | 2017-11-29,0.289120505279,0.412870820446 500 | 2017-11-30,-0.19839889682,0.0941923003101 501 | 2017-12-01,-1.14761094484,-0.35811407548 502 | 2017-12-04,0.55596267971,0.892473887332 503 | 2017-12-05,-0.422314824125,0.104714029433 504 | 2017-12-06,0.228053325124,0.201479946704 505 | 2017-12-07,0.5407735853,-1.81807763038 506 | -------------------------------------------------------------------------------- /empyrical/tests/test_data/intercepts.csv: -------------------------------------------------------------------------------- 1 | 19001,0.0 2 | 19002,0.0 3 | -------------------------------------------------------------------------------- /empyrical/tests/test_data/positions.csv: -------------------------------------------------------------------------------- 1 | ,19001,19002,cash 2 | 2016-01-04,1.0,1.0,0.0 3 | 2016-01-05,1.0,1.0,0.0 4 | 2016-01-06,1.0,1.0,0.0 5 | 2016-01-07,1.0,1.0,0.0 6 | 2016-01-08,1.0,1.0,0.0 7 | 2016-01-11,1.0,1.0,0.0 8 | 2016-01-12,1.0,1.0,0.0 9 | 2016-01-13,1.0,1.0,0.0 10 | 2016-01-14,1.0,1.0,0.0 11 | 2016-01-15,1.0,1.0,0.0 12 | 2016-01-18,1.0,1.0,0.0 13 | 2016-01-19,1.0,1.0,0.0 14 | 2016-01-20,1.0,1.0,0.0 15 | 2016-01-21,1.0,1.0,0.0 16 | 2016-01-22,1.0,1.0,0.0 17 | 2016-01-25,1.0,1.0,0.0 18 | 2016-01-26,1.0,1.0,0.0 19 | 2016-01-27,1.0,1.0,0.0 20 | 2016-01-28,1.0,1.0,0.0 21 | 2016-01-29,1.0,1.0,0.0 22 | 2016-02-01,1.0,1.0,0.0 23 | 2016-02-02,1.0,1.0,0.0 24 | 2016-02-03,1.0,1.0,0.0 25 | 2016-02-04,1.0,1.0,0.0 26 | 2016-02-05,1.0,1.0,0.0 27 | 2016-02-08,1.0,1.0,0.0 28 | 2016-02-09,1.0,1.0,0.0 29 | 2016-02-10,1.0,1.0,0.0 30 | 2016-02-11,1.0,1.0,0.0 31 | 2016-02-12,1.0,1.0,0.0 32 | 2016-02-15,1.0,1.0,0.0 33 | 2016-02-16,1.0,1.0,0.0 34 | 2016-02-17,1.0,1.0,0.0 35 | 2016-02-18,1.0,1.0,0.0 36 | 2016-02-19,1.0,1.0,0.0 37 | 2016-02-22,1.0,1.0,0.0 38 | 2016-02-23,1.0,1.0,0.0 39 | 2016-02-24,1.0,1.0,0.0 40 | 2016-02-25,1.0,1.0,0.0 41 | 2016-02-26,1.0,1.0,0.0 42 | 2016-02-29,1.0,1.0,0.0 43 | 2016-03-01,1.0,1.0,0.0 44 | 2016-03-02,1.0,1.0,0.0 45 | 2016-03-03,1.0,1.0,0.0 46 | 2016-03-04,1.0,1.0,0.0 47 | 2016-03-07,1.0,1.0,0.0 48 | 2016-03-08,1.0,1.0,0.0 49 | 2016-03-09,1.0,1.0,0.0 50 | 2016-03-10,1.0,1.0,0.0 51 | 2016-03-11,1.0,1.0,0.0 52 | 2016-03-14,1.0,1.0,0.0 53 | 2016-03-15,1.0,1.0,0.0 54 | 2016-03-16,1.0,1.0,0.0 55 | 2016-03-17,1.0,1.0,0.0 56 | 2016-03-18,1.0,1.0,0.0 57 | 2016-03-21,1.0,1.0,0.0 58 | 2016-03-22,1.0,1.0,0.0 59 | 2016-03-23,1.0,1.0,0.0 60 | 2016-03-24,1.0,1.0,0.0 61 | 2016-03-25,1.0,1.0,0.0 62 | 2016-03-28,1.0,1.0,0.0 63 | 2016-03-29,1.0,1.0,0.0 64 | 2016-03-30,1.0,1.0,0.0 65 | 2016-03-31,1.0,1.0,0.0 66 | 2016-04-01,1.0,1.0,0.0 67 | 2016-04-04,1.0,1.0,0.0 68 | 2016-04-05,1.0,1.0,0.0 69 | 2016-04-06,1.0,1.0,0.0 70 | 2016-04-07,1.0,1.0,0.0 71 | 2016-04-08,1.0,1.0,0.0 72 | 2016-04-11,1.0,1.0,0.0 73 | 2016-04-12,1.0,1.0,0.0 74 | 2016-04-13,1.0,1.0,0.0 75 | 2016-04-14,1.0,1.0,0.0 76 | 2016-04-15,1.0,1.0,0.0 77 | 2016-04-18,1.0,1.0,0.0 78 | 2016-04-19,1.0,1.0,0.0 79 | 2016-04-20,1.0,1.0,0.0 80 | 2016-04-21,1.0,1.0,0.0 81 | 2016-04-22,1.0,1.0,0.0 82 | 2016-04-25,1.0,1.0,0.0 83 | 2016-04-26,1.0,1.0,0.0 84 | 2016-04-27,1.0,1.0,0.0 85 | 2016-04-28,1.0,1.0,0.0 86 | 2016-04-29,1.0,1.0,0.0 87 | 2016-05-02,1.0,1.0,0.0 88 | 2016-05-03,1.0,1.0,0.0 89 | 2016-05-04,1.0,1.0,0.0 90 | 2016-05-05,1.0,1.0,0.0 91 | 2016-05-06,1.0,1.0,0.0 92 | 2016-05-09,1.0,1.0,0.0 93 | 2016-05-10,1.0,1.0,0.0 94 | 2016-05-11,1.0,1.0,0.0 95 | 2016-05-12,1.0,1.0,0.0 96 | 2016-05-13,1.0,1.0,0.0 97 | 2016-05-16,1.0,1.0,0.0 98 | 2016-05-17,1.0,1.0,0.0 99 | 2016-05-18,1.0,1.0,0.0 100 | 2016-05-19,1.0,1.0,0.0 101 | 2016-05-20,1.0,1.0,0.0 102 | 2016-05-23,1.0,1.0,0.0 103 | 2016-05-24,1.0,1.0,0.0 104 | 2016-05-25,1.0,1.0,0.0 105 | 2016-05-26,1.0,1.0,0.0 106 | 2016-05-27,1.0,1.0,0.0 107 | 2016-05-30,1.0,1.0,0.0 108 | 2016-05-31,1.0,1.0,0.0 109 | 2016-06-01,1.0,1.0,0.0 110 | 2016-06-02,1.0,1.0,0.0 111 | 2016-06-03,1.0,1.0,0.0 112 | 2016-06-06,1.0,1.0,0.0 113 | 2016-06-07,1.0,1.0,0.0 114 | 2016-06-08,1.0,1.0,0.0 115 | 2016-06-09,1.0,1.0,0.0 116 | 2016-06-10,1.0,1.0,0.0 117 | 2016-06-13,1.0,1.0,0.0 118 | 2016-06-14,1.0,1.0,0.0 119 | 2016-06-15,1.0,1.0,0.0 120 | 2016-06-16,1.0,1.0,0.0 121 | 2016-06-17,1.0,1.0,0.0 122 | 2016-06-20,1.0,1.0,0.0 123 | 2016-06-21,1.0,1.0,0.0 124 | 2016-06-22,1.0,1.0,0.0 125 | 2016-06-23,1.0,1.0,0.0 126 | 2016-06-24,1.0,1.0,0.0 127 | 2016-06-27,1.0,1.0,0.0 128 | 2016-06-28,1.0,1.0,0.0 129 | 2016-06-29,1.0,1.0,0.0 130 | 2016-06-30,1.0,1.0,0.0 131 | 2016-07-01,1.0,1.0,0.0 132 | 2016-07-04,1.0,1.0,0.0 133 | 2016-07-05,1.0,1.0,0.0 134 | 2016-07-06,1.0,1.0,0.0 135 | 2016-07-07,1.0,1.0,0.0 136 | 2016-07-08,1.0,1.0,0.0 137 | 2016-07-11,1.0,1.0,0.0 138 | 2016-07-12,1.0,1.0,0.0 139 | 2016-07-13,1.0,1.0,0.0 140 | 2016-07-14,1.0,1.0,0.0 141 | 2016-07-15,1.0,1.0,0.0 142 | 2016-07-18,1.0,1.0,0.0 143 | 2016-07-19,1.0,1.0,0.0 144 | 2016-07-20,1.0,1.0,0.0 145 | 2016-07-21,1.0,1.0,0.0 146 | 2016-07-22,1.0,1.0,0.0 147 | 2016-07-25,1.0,1.0,0.0 148 | 2016-07-26,1.0,1.0,0.0 149 | 2016-07-27,1.0,1.0,0.0 150 | 2016-07-28,1.0,1.0,0.0 151 | 2016-07-29,1.0,1.0,0.0 152 | 2016-08-01,1.0,1.0,0.0 153 | 2016-08-02,1.0,1.0,0.0 154 | 2016-08-03,1.0,1.0,0.0 155 | 2016-08-04,1.0,1.0,0.0 156 | 2016-08-05,1.0,1.0,0.0 157 | 2016-08-08,1.0,1.0,0.0 158 | 2016-08-09,1.0,1.0,0.0 159 | 2016-08-10,1.0,1.0,0.0 160 | 2016-08-11,1.0,1.0,0.0 161 | 2016-08-12,1.0,1.0,0.0 162 | 2016-08-15,1.0,1.0,0.0 163 | 2016-08-16,1.0,1.0,0.0 164 | 2016-08-17,1.0,1.0,0.0 165 | 2016-08-18,1.0,1.0,0.0 166 | 2016-08-19,1.0,1.0,0.0 167 | 2016-08-22,1.0,1.0,0.0 168 | 2016-08-23,1.0,1.0,0.0 169 | 2016-08-24,1.0,1.0,0.0 170 | 2016-08-25,1.0,1.0,0.0 171 | 2016-08-26,1.0,1.0,0.0 172 | 2016-08-29,1.0,1.0,0.0 173 | 2016-08-30,1.0,1.0,0.0 174 | 2016-08-31,1.0,1.0,0.0 175 | 2016-09-01,1.0,1.0,0.0 176 | 2016-09-02,1.0,1.0,0.0 177 | 2016-09-05,1.0,1.0,0.0 178 | 2016-09-06,1.0,1.0,0.0 179 | 2016-09-07,1.0,1.0,0.0 180 | 2016-09-08,1.0,1.0,0.0 181 | 2016-09-09,1.0,1.0,0.0 182 | 2016-09-12,1.0,1.0,0.0 183 | 2016-09-13,1.0,1.0,0.0 184 | 2016-09-14,1.0,1.0,0.0 185 | 2016-09-15,1.0,1.0,0.0 186 | 2016-09-16,1.0,1.0,0.0 187 | 2016-09-19,1.0,1.0,0.0 188 | 2016-09-20,1.0,1.0,0.0 189 | 2016-09-21,1.0,1.0,0.0 190 | 2016-09-22,1.0,1.0,0.0 191 | 2016-09-23,1.0,1.0,0.0 192 | 2016-09-26,1.0,1.0,0.0 193 | 2016-09-27,1.0,1.0,0.0 194 | 2016-09-28,1.0,1.0,0.0 195 | 2016-09-29,1.0,1.0,0.0 196 | 2016-09-30,1.0,1.0,0.0 197 | 2016-10-03,1.0,1.0,0.0 198 | 2016-10-04,1.0,1.0,0.0 199 | 2016-10-05,1.0,1.0,0.0 200 | 2016-10-06,1.0,1.0,0.0 201 | 2016-10-07,1.0,1.0,0.0 202 | 2016-10-10,1.0,1.0,0.0 203 | 2016-10-11,1.0,1.0,0.0 204 | 2016-10-12,1.0,1.0,0.0 205 | 2016-10-13,1.0,1.0,0.0 206 | 2016-10-14,1.0,1.0,0.0 207 | 2016-10-17,1.0,1.0,0.0 208 | 2016-10-18,1.0,1.0,0.0 209 | 2016-10-19,1.0,1.0,0.0 210 | 2016-10-20,1.0,1.0,0.0 211 | 2016-10-21,1.0,1.0,0.0 212 | 2016-10-24,1.0,1.0,0.0 213 | 2016-10-25,1.0,1.0,0.0 214 | 2016-10-26,1.0,1.0,0.0 215 | 2016-10-27,1.0,1.0,0.0 216 | 2016-10-28,1.0,1.0,0.0 217 | 2016-10-31,1.0,1.0,0.0 218 | 2016-11-01,1.0,1.0,0.0 219 | 2016-11-02,1.0,1.0,0.0 220 | 2016-11-03,1.0,1.0,0.0 221 | 2016-11-04,1.0,1.0,0.0 222 | 2016-11-07,1.0,1.0,0.0 223 | 2016-11-08,1.0,1.0,0.0 224 | 2016-11-09,1.0,1.0,0.0 225 | 2016-11-10,1.0,1.0,0.0 226 | 2016-11-11,1.0,1.0,0.0 227 | 2016-11-14,1.0,1.0,0.0 228 | 2016-11-15,1.0,1.0,0.0 229 | 2016-11-16,1.0,1.0,0.0 230 | 2016-11-17,1.0,1.0,0.0 231 | 2016-11-18,1.0,1.0,0.0 232 | 2016-11-21,1.0,1.0,0.0 233 | 2016-11-22,1.0,1.0,0.0 234 | 2016-11-23,1.0,1.0,0.0 235 | 2016-11-24,1.0,1.0,0.0 236 | 2016-11-25,1.0,1.0,0.0 237 | 2016-11-28,1.0,1.0,0.0 238 | 2016-11-29,1.0,1.0,0.0 239 | 2016-11-30,1.0,1.0,0.0 240 | 2016-12-01,1.0,1.0,0.0 241 | 2016-12-02,1.0,1.0,0.0 242 | 2016-12-05,1.0,1.0,0.0 243 | 2016-12-06,1.0,1.0,0.0 244 | 2016-12-07,1.0,1.0,0.0 245 | 2016-12-08,1.0,1.0,0.0 246 | 2016-12-09,1.0,1.0,0.0 247 | 2016-12-12,1.0,1.0,0.0 248 | 2016-12-13,1.0,1.0,0.0 249 | 2016-12-14,1.0,1.0,0.0 250 | 2016-12-15,1.0,1.0,0.0 251 | 2016-12-16,1.0,1.0,0.0 252 | 2016-12-19,1.0,1.0,0.0 253 | 2016-12-20,1.0,1.0,0.0 254 | 2016-12-21,1.0,1.0,0.0 255 | 2016-12-22,1.0,1.0,0.0 256 | 2016-12-23,1.0,1.0,0.0 257 | 2016-12-26,1.0,1.0,0.0 258 | 2016-12-27,1.0,1.0,0.0 259 | 2016-12-28,1.0,1.0,0.0 260 | 2016-12-29,1.0,1.0,0.0 261 | 2016-12-30,1.0,1.0,0.0 262 | 2017-01-02,1.0,1.0,0.0 263 | 2017-01-03,1.0,1.0,0.0 264 | 2017-01-04,1.0,1.0,0.0 265 | 2017-01-05,1.0,1.0,0.0 266 | 2017-01-06,1.0,1.0,0.0 267 | 2017-01-09,1.0,1.0,0.0 268 | 2017-01-10,1.0,1.0,0.0 269 | 2017-01-11,1.0,1.0,0.0 270 | 2017-01-12,1.0,1.0,0.0 271 | 2017-01-13,1.0,1.0,0.0 272 | 2017-01-16,1.0,1.0,0.0 273 | 2017-01-17,1.0,1.0,0.0 274 | 2017-01-18,1.0,1.0,0.0 275 | 2017-01-19,1.0,1.0,0.0 276 | 2017-01-20,1.0,1.0,0.0 277 | 2017-01-23,1.0,1.0,0.0 278 | 2017-01-24,1.0,1.0,0.0 279 | 2017-01-25,1.0,1.0,0.0 280 | 2017-01-26,1.0,1.0,0.0 281 | 2017-01-27,1.0,1.0,0.0 282 | 2017-01-30,1.0,1.0,0.0 283 | 2017-01-31,1.0,1.0,0.0 284 | 2017-02-01,1.0,1.0,0.0 285 | 2017-02-02,1.0,1.0,0.0 286 | 2017-02-03,1.0,1.0,0.0 287 | 2017-02-06,1.0,1.0,0.0 288 | 2017-02-07,1.0,1.0,0.0 289 | 2017-02-08,1.0,1.0,0.0 290 | 2017-02-09,1.0,1.0,0.0 291 | 2017-02-10,1.0,1.0,0.0 292 | 2017-02-13,1.0,1.0,0.0 293 | 2017-02-14,1.0,1.0,0.0 294 | 2017-02-15,1.0,1.0,0.0 295 | 2017-02-16,1.0,1.0,0.0 296 | 2017-02-17,1.0,1.0,0.0 297 | 2017-02-20,1.0,1.0,0.0 298 | 2017-02-21,1.0,1.0,0.0 299 | 2017-02-22,1.0,1.0,0.0 300 | 2017-02-23,1.0,1.0,0.0 301 | 2017-02-24,1.0,1.0,0.0 302 | 2017-02-27,1.0,1.0,0.0 303 | 2017-02-28,1.0,1.0,0.0 304 | 2017-03-01,1.0,1.0,0.0 305 | 2017-03-02,1.0,1.0,0.0 306 | 2017-03-03,1.0,1.0,0.0 307 | 2017-03-06,1.0,1.0,0.0 308 | 2017-03-07,1.0,1.0,0.0 309 | 2017-03-08,1.0,1.0,0.0 310 | 2017-03-09,1.0,1.0,0.0 311 | 2017-03-10,1.0,1.0,0.0 312 | 2017-03-13,1.0,1.0,0.0 313 | 2017-03-14,1.0,1.0,0.0 314 | 2017-03-15,1.0,1.0,0.0 315 | 2017-03-16,1.0,1.0,0.0 316 | 2017-03-17,1.0,1.0,0.0 317 | 2017-03-20,1.0,1.0,0.0 318 | 2017-03-21,1.0,1.0,0.0 319 | 2017-03-22,1.0,1.0,0.0 320 | 2017-03-23,1.0,1.0,0.0 321 | 2017-03-24,1.0,1.0,0.0 322 | 2017-03-27,1.0,1.0,0.0 323 | 2017-03-28,1.0,1.0,0.0 324 | 2017-03-29,1.0,1.0,0.0 325 | 2017-03-30,1.0,1.0,0.0 326 | 2017-03-31,1.0,1.0,0.0 327 | 2017-04-03,1.0,1.0,0.0 328 | 2017-04-04,1.0,1.0,0.0 329 | 2017-04-05,1.0,1.0,0.0 330 | 2017-04-06,1.0,1.0,0.0 331 | 2017-04-07,1.0,1.0,0.0 332 | 2017-04-10,1.0,1.0,0.0 333 | 2017-04-11,1.0,1.0,0.0 334 | 2017-04-12,1.0,1.0,0.0 335 | 2017-04-13,1.0,1.0,0.0 336 | 2017-04-14,1.0,1.0,0.0 337 | 2017-04-17,1.0,1.0,0.0 338 | 2017-04-18,1.0,1.0,0.0 339 | 2017-04-19,1.0,1.0,0.0 340 | 2017-04-20,1.0,1.0,0.0 341 | 2017-04-21,1.0,1.0,0.0 342 | 2017-04-24,1.0,1.0,0.0 343 | 2017-04-25,1.0,1.0,0.0 344 | 2017-04-26,1.0,1.0,0.0 345 | 2017-04-27,1.0,1.0,0.0 346 | 2017-04-28,1.0,1.0,0.0 347 | 2017-05-01,1.0,1.0,0.0 348 | 2017-05-02,1.0,1.0,0.0 349 | 2017-05-03,1.0,1.0,0.0 350 | 2017-05-04,1.0,1.0,0.0 351 | 2017-05-05,1.0,1.0,0.0 352 | 2017-05-08,1.0,1.0,0.0 353 | 2017-05-09,1.0,1.0,0.0 354 | 2017-05-10,1.0,1.0,0.0 355 | 2017-05-11,1.0,1.0,0.0 356 | 2017-05-12,1.0,1.0,0.0 357 | 2017-05-15,1.0,1.0,0.0 358 | 2017-05-16,1.0,1.0,0.0 359 | 2017-05-17,1.0,1.0,0.0 360 | 2017-05-18,1.0,1.0,0.0 361 | 2017-05-19,1.0,1.0,0.0 362 | 2017-05-22,1.0,1.0,0.0 363 | 2017-05-23,1.0,1.0,0.0 364 | 2017-05-24,1.0,1.0,0.0 365 | 2017-05-25,1.0,1.0,0.0 366 | 2017-05-26,1.0,1.0,0.0 367 | 2017-05-29,1.0,1.0,0.0 368 | 2017-05-30,1.0,1.0,0.0 369 | 2017-05-31,1.0,1.0,0.0 370 | 2017-06-01,1.0,1.0,0.0 371 | 2017-06-02,1.0,1.0,0.0 372 | 2017-06-05,1.0,1.0,0.0 373 | 2017-06-06,1.0,1.0,0.0 374 | 2017-06-07,1.0,1.0,0.0 375 | 2017-06-08,1.0,1.0,0.0 376 | 2017-06-09,1.0,1.0,0.0 377 | 2017-06-12,1.0,1.0,0.0 378 | 2017-06-13,1.0,1.0,0.0 379 | 2017-06-14,1.0,1.0,0.0 380 | 2017-06-15,1.0,1.0,0.0 381 | 2017-06-16,1.0,1.0,0.0 382 | 2017-06-19,1.0,1.0,0.0 383 | 2017-06-20,1.0,1.0,0.0 384 | 2017-06-21,1.0,1.0,0.0 385 | 2017-06-22,1.0,1.0,0.0 386 | 2017-06-23,1.0,1.0,0.0 387 | 2017-06-26,1.0,1.0,0.0 388 | 2017-06-27,1.0,1.0,0.0 389 | 2017-06-28,1.0,1.0,0.0 390 | 2017-06-29,1.0,1.0,0.0 391 | 2017-06-30,1.0,1.0,0.0 392 | 2017-07-03,1.0,1.0,0.0 393 | 2017-07-04,1.0,1.0,0.0 394 | 2017-07-05,1.0,1.0,0.0 395 | 2017-07-06,1.0,1.0,0.0 396 | 2017-07-07,1.0,1.0,0.0 397 | 2017-07-10,1.0,1.0,0.0 398 | 2017-07-11,1.0,1.0,0.0 399 | 2017-07-12,1.0,1.0,0.0 400 | 2017-07-13,1.0,1.0,0.0 401 | 2017-07-14,1.0,1.0,0.0 402 | 2017-07-17,1.0,1.0,0.0 403 | 2017-07-18,1.0,1.0,0.0 404 | 2017-07-19,1.0,1.0,0.0 405 | 2017-07-20,1.0,1.0,0.0 406 | 2017-07-21,1.0,1.0,0.0 407 | 2017-07-24,1.0,1.0,0.0 408 | 2017-07-25,1.0,1.0,0.0 409 | 2017-07-26,1.0,1.0,0.0 410 | 2017-07-27,1.0,1.0,0.0 411 | 2017-07-28,1.0,1.0,0.0 412 | 2017-07-31,1.0,1.0,0.0 413 | 2017-08-01,1.0,1.0,0.0 414 | 2017-08-02,1.0,1.0,0.0 415 | 2017-08-03,1.0,1.0,0.0 416 | 2017-08-04,1.0,1.0,0.0 417 | 2017-08-07,1.0,1.0,0.0 418 | 2017-08-08,1.0,1.0,0.0 419 | 2017-08-09,1.0,1.0,0.0 420 | 2017-08-10,1.0,1.0,0.0 421 | 2017-08-11,1.0,1.0,0.0 422 | 2017-08-14,1.0,1.0,0.0 423 | 2017-08-15,1.0,1.0,0.0 424 | 2017-08-16,1.0,1.0,0.0 425 | 2017-08-17,1.0,1.0,0.0 426 | 2017-08-18,1.0,1.0,0.0 427 | 2017-08-21,1.0,1.0,0.0 428 | 2017-08-22,1.0,1.0,0.0 429 | 2017-08-23,1.0,1.0,0.0 430 | 2017-08-24,1.0,1.0,0.0 431 | 2017-08-25,1.0,1.0,0.0 432 | 2017-08-28,1.0,1.0,0.0 433 | 2017-08-29,1.0,1.0,0.0 434 | 2017-08-30,1.0,1.0,0.0 435 | 2017-08-31,1.0,1.0,0.0 436 | 2017-09-01,1.0,1.0,0.0 437 | 2017-09-04,1.0,1.0,0.0 438 | 2017-09-05,1.0,1.0,0.0 439 | 2017-09-06,1.0,1.0,0.0 440 | 2017-09-07,1.0,1.0,0.0 441 | 2017-09-08,1.0,1.0,0.0 442 | 2017-09-11,1.0,1.0,0.0 443 | 2017-09-12,1.0,1.0,0.0 444 | 2017-09-13,1.0,1.0,0.0 445 | 2017-09-14,1.0,1.0,0.0 446 | 2017-09-15,1.0,1.0,0.0 447 | 2017-09-18,1.0,1.0,0.0 448 | 2017-09-19,1.0,1.0,0.0 449 | 2017-09-20,1.0,1.0,0.0 450 | 2017-09-21,1.0,1.0,0.0 451 | 2017-09-22,1.0,1.0,0.0 452 | 2017-09-25,1.0,1.0,0.0 453 | 2017-09-26,1.0,1.0,0.0 454 | 2017-09-27,1.0,1.0,0.0 455 | 2017-09-28,1.0,1.0,0.0 456 | 2017-09-29,1.0,1.0,0.0 457 | 2017-10-02,1.0,1.0,0.0 458 | 2017-10-03,1.0,1.0,0.0 459 | 2017-10-04,1.0,1.0,0.0 460 | 2017-10-05,1.0,1.0,0.0 461 | 2017-10-06,1.0,1.0,0.0 462 | 2017-10-09,1.0,1.0,0.0 463 | 2017-10-10,1.0,1.0,0.0 464 | 2017-10-11,1.0,1.0,0.0 465 | 2017-10-12,1.0,1.0,0.0 466 | 2017-10-13,1.0,1.0,0.0 467 | 2017-10-16,1.0,1.0,0.0 468 | 2017-10-17,1.0,1.0,0.0 469 | 2017-10-18,1.0,1.0,0.0 470 | 2017-10-19,1.0,1.0,0.0 471 | 2017-10-20,1.0,1.0,0.0 472 | 2017-10-23,1.0,1.0,0.0 473 | 2017-10-24,1.0,1.0,0.0 474 | 2017-10-25,1.0,1.0,0.0 475 | 2017-10-26,1.0,1.0,0.0 476 | 2017-10-27,1.0,1.0,0.0 477 | 2017-10-30,1.0,1.0,0.0 478 | 2017-10-31,1.0,1.0,0.0 479 | 2017-11-01,1.0,1.0,0.0 480 | 2017-11-02,1.0,1.0,0.0 481 | 2017-11-03,1.0,1.0,0.0 482 | 2017-11-06,1.0,1.0,0.0 483 | 2017-11-07,1.0,1.0,0.0 484 | 2017-11-08,1.0,1.0,0.0 485 | 2017-11-09,1.0,1.0,0.0 486 | 2017-11-10,1.0,1.0,0.0 487 | 2017-11-13,1.0,1.0,0.0 488 | 2017-11-14,1.0,1.0,0.0 489 | 2017-11-15,1.0,1.0,0.0 490 | 2017-11-16,1.0,1.0,0.0 491 | 2017-11-17,1.0,1.0,0.0 492 | 2017-11-20,1.0,1.0,0.0 493 | 2017-11-21,1.0,1.0,0.0 494 | 2017-11-22,1.0,1.0,0.0 495 | 2017-11-23,1.0,1.0,0.0 496 | 2017-11-24,1.0,1.0,0.0 497 | 2017-11-27,1.0,1.0,0.0 498 | 2017-11-28,1.0,1.0,0.0 499 | 2017-11-29,1.0,1.0,0.0 500 | 2017-11-30,1.0,1.0,0.0 501 | 2017-12-01,1.0,1.0,0.0 502 | 2017-12-04,1.0,1.0,0.0 503 | 2017-12-05,1.0,1.0,0.0 504 | 2017-12-06,1.0,1.0,0.0 505 | 2017-12-07,1.0,1.0,0.0 506 | -------------------------------------------------------------------------------- /empyrical/tests/test_data/residuals.csv: -------------------------------------------------------------------------------- 1 | ,19001,19002 2 | 2016-01-04,0.0,0.0 3 | 2016-01-05,0.0,0.0 4 | 2016-01-06,0.0,0.0 5 | 2016-01-07,0.0,0.0 6 | 2016-01-08,0.0,0.0 7 | 2016-01-11,0.0,0.0 8 | 2016-01-12,0.0,0.0 9 | 2016-01-13,0.0,0.0 10 | 2016-01-14,0.0,0.0 11 | 2016-01-15,0.0,0.0 12 | 2016-01-18,0.0,0.0 13 | 2016-01-19,0.0,0.0 14 | 2016-01-20,0.0,0.0 15 | 2016-01-21,0.0,0.0 16 | 2016-01-22,0.0,0.0 17 | 2016-01-25,0.0,0.0 18 | 2016-01-26,0.0,0.0 19 | 2016-01-27,0.0,0.0 20 | 2016-01-28,0.0,0.0 21 | 2016-01-29,0.0,0.0 22 | 2016-02-01,0.0,0.0 23 | 2016-02-02,0.0,0.0 24 | 2016-02-03,0.0,0.0 25 | 2016-02-04,0.0,0.0 26 | 2016-02-05,0.0,0.0 27 | 2016-02-08,0.0,0.0 28 | 2016-02-09,0.0,0.0 29 | 2016-02-10,0.0,0.0 30 | 2016-02-11,0.0,0.0 31 | 2016-02-12,0.0,0.0 32 | 2016-02-15,0.0,0.0 33 | 2016-02-16,0.0,0.0 34 | 2016-02-17,0.0,0.0 35 | 2016-02-18,0.0,0.0 36 | 2016-02-19,0.0,0.0 37 | 2016-02-22,0.0,0.0 38 | 2016-02-23,0.0,0.0 39 | 2016-02-24,0.0,0.0 40 | 2016-02-25,0.0,0.0 41 | 2016-02-26,0.0,0.0 42 | 2016-02-29,0.0,0.0 43 | 2016-03-01,0.0,0.0 44 | 2016-03-02,0.0,0.0 45 | 2016-03-03,0.0,0.0 46 | 2016-03-04,0.0,0.0 47 | 2016-03-07,0.0,0.0 48 | 2016-03-08,0.0,0.0 49 | 2016-03-09,0.0,0.0 50 | 2016-03-10,0.0,0.0 51 | 2016-03-11,0.0,0.0 52 | 2016-03-14,0.0,0.0 53 | 2016-03-15,0.0,0.0 54 | 2016-03-16,0.0,0.0 55 | 2016-03-17,0.0,0.0 56 | 2016-03-18,0.0,0.0 57 | 2016-03-21,0.0,0.0 58 | 2016-03-22,0.0,0.0 59 | 2016-03-23,0.0,0.0 60 | 2016-03-24,0.0,0.0 61 | 2016-03-25,0.0,0.0 62 | 2016-03-28,0.0,0.0 63 | 2016-03-29,0.0,0.0 64 | 2016-03-30,0.0,0.0 65 | 2016-03-31,0.0,0.0 66 | 2016-04-01,0.0,0.0 67 | 2016-04-04,0.0,0.0 68 | 2016-04-05,0.0,0.0 69 | 2016-04-06,0.0,0.0 70 | 2016-04-07,0.0,0.0 71 | 2016-04-08,0.0,0.0 72 | 2016-04-11,0.0,0.0 73 | 2016-04-12,0.0,0.0 74 | 2016-04-13,0.0,0.0 75 | 2016-04-14,0.0,0.0 76 | 2016-04-15,0.0,0.0 77 | 2016-04-18,0.0,0.0 78 | 2016-04-19,0.0,0.0 79 | 2016-04-20,0.0,0.0 80 | 2016-04-21,0.0,0.0 81 | 2016-04-22,0.0,0.0 82 | 2016-04-25,0.0,0.0 83 | 2016-04-26,0.0,0.0 84 | 2016-04-27,0.0,0.0 85 | 2016-04-28,0.0,0.0 86 | 2016-04-29,0.0,0.0 87 | 2016-05-02,0.0,0.0 88 | 2016-05-03,0.0,0.0 89 | 2016-05-04,0.0,0.0 90 | 2016-05-05,0.0,0.0 91 | 2016-05-06,0.0,0.0 92 | 2016-05-09,0.0,0.0 93 | 2016-05-10,0.0,0.0 94 | 2016-05-11,0.0,0.0 95 | 2016-05-12,0.0,0.0 96 | 2016-05-13,0.0,0.0 97 | 2016-05-16,0.0,0.0 98 | 2016-05-17,0.0,0.0 99 | 2016-05-18,0.0,0.0 100 | 2016-05-19,0.0,0.0 101 | 2016-05-20,0.0,0.0 102 | 2016-05-23,0.0,0.0 103 | 2016-05-24,0.0,0.0 104 | 2016-05-25,0.0,0.0 105 | 2016-05-26,0.0,0.0 106 | 2016-05-27,0.0,0.0 107 | 2016-05-30,0.0,0.0 108 | 2016-05-31,0.0,0.0 109 | 2016-06-01,0.0,0.0 110 | 2016-06-02,0.0,0.0 111 | 2016-06-03,0.0,0.0 112 | 2016-06-06,0.0,0.0 113 | 2016-06-07,0.0,0.0 114 | 2016-06-08,0.0,0.0 115 | 2016-06-09,0.0,0.0 116 | 2016-06-10,0.0,0.0 117 | 2016-06-13,0.0,0.0 118 | 2016-06-14,0.0,0.0 119 | 2016-06-15,0.0,0.0 120 | 2016-06-16,0.0,0.0 121 | 2016-06-17,0.0,0.0 122 | 2016-06-20,0.0,0.0 123 | 2016-06-21,0.0,0.0 124 | 2016-06-22,0.0,0.0 125 | 2016-06-23,0.0,0.0 126 | 2016-06-24,0.0,0.0 127 | 2016-06-27,0.0,0.0 128 | 2016-06-28,0.0,0.0 129 | 2016-06-29,0.0,0.0 130 | 2016-06-30,0.0,0.0 131 | 2016-07-01,0.0,0.0 132 | 2016-07-04,0.0,0.0 133 | 2016-07-05,0.0,0.0 134 | 2016-07-06,0.0,0.0 135 | 2016-07-07,0.0,0.0 136 | 2016-07-08,0.0,0.0 137 | 2016-07-11,0.0,0.0 138 | 2016-07-12,0.0,0.0 139 | 2016-07-13,0.0,0.0 140 | 2016-07-14,0.0,0.0 141 | 2016-07-15,0.0,0.0 142 | 2016-07-18,0.0,0.0 143 | 2016-07-19,0.0,0.0 144 | 2016-07-20,0.0,0.0 145 | 2016-07-21,0.0,0.0 146 | 2016-07-22,0.0,0.0 147 | 2016-07-25,0.0,0.0 148 | 2016-07-26,0.0,0.0 149 | 2016-07-27,0.0,0.0 150 | 2016-07-28,0.0,0.0 151 | 2016-07-29,0.0,0.0 152 | 2016-08-01,0.0,0.0 153 | 2016-08-02,0.0,0.0 154 | 2016-08-03,0.0,0.0 155 | 2016-08-04,0.0,0.0 156 | 2016-08-05,0.0,0.0 157 | 2016-08-08,0.0,0.0 158 | 2016-08-09,0.0,0.0 159 | 2016-08-10,0.0,0.0 160 | 2016-08-11,0.0,0.0 161 | 2016-08-12,0.0,0.0 162 | 2016-08-15,0.0,0.0 163 | 2016-08-16,0.0,0.0 164 | 2016-08-17,0.0,0.0 165 | 2016-08-18,0.0,0.0 166 | 2016-08-19,0.0,0.0 167 | 2016-08-22,0.0,0.0 168 | 2016-08-23,0.0,0.0 169 | 2016-08-24,0.0,0.0 170 | 2016-08-25,0.0,0.0 171 | 2016-08-26,0.0,0.0 172 | 2016-08-29,0.0,0.0 173 | 2016-08-30,0.0,0.0 174 | 2016-08-31,0.0,0.0 175 | 2016-09-01,0.0,0.0 176 | 2016-09-02,0.0,0.0 177 | 2016-09-05,0.0,0.0 178 | 2016-09-06,0.0,0.0 179 | 2016-09-07,0.0,0.0 180 | 2016-09-08,0.0,0.0 181 | 2016-09-09,0.0,0.0 182 | 2016-09-12,0.0,0.0 183 | 2016-09-13,0.0,0.0 184 | 2016-09-14,0.0,0.0 185 | 2016-09-15,0.0,0.0 186 | 2016-09-16,0.0,0.0 187 | 2016-09-19,0.0,0.0 188 | 2016-09-20,0.0,0.0 189 | 2016-09-21,0.0,0.0 190 | 2016-09-22,0.0,0.0 191 | 2016-09-23,0.0,0.0 192 | 2016-09-26,0.0,0.0 193 | 2016-09-27,0.0,0.0 194 | 2016-09-28,0.0,0.0 195 | 2016-09-29,0.0,0.0 196 | 2016-09-30,0.0,0.0 197 | 2016-10-03,0.0,0.0 198 | 2016-10-04,0.0,0.0 199 | 2016-10-05,0.0,0.0 200 | 2016-10-06,0.0,0.0 201 | 2016-10-07,0.0,0.0 202 | 2016-10-10,0.0,0.0 203 | 2016-10-11,0.0,0.0 204 | 2016-10-12,0.0,0.0 205 | 2016-10-13,0.0,0.0 206 | 2016-10-14,0.0,0.0 207 | 2016-10-17,0.0,0.0 208 | 2016-10-18,0.0,0.0 209 | 2016-10-19,0.0,0.0 210 | 2016-10-20,0.0,0.0 211 | 2016-10-21,0.0,0.0 212 | 2016-10-24,0.0,0.0 213 | 2016-10-25,0.0,0.0 214 | 2016-10-26,0.0,0.0 215 | 2016-10-27,0.0,0.0 216 | 2016-10-28,0.0,0.0 217 | 2016-10-31,0.0,0.0 218 | 2016-11-01,0.0,0.0 219 | 2016-11-02,0.0,0.0 220 | 2016-11-03,0.0,0.0 221 | 2016-11-04,0.0,0.0 222 | 2016-11-07,0.0,0.0 223 | 2016-11-08,0.0,0.0 224 | 2016-11-09,0.0,0.0 225 | 2016-11-10,0.0,0.0 226 | 2016-11-11,0.0,0.0 227 | 2016-11-14,0.0,0.0 228 | 2016-11-15,0.0,0.0 229 | 2016-11-16,0.0,0.0 230 | 2016-11-17,0.0,0.0 231 | 2016-11-18,0.0,0.0 232 | 2016-11-21,0.0,0.0 233 | 2016-11-22,0.0,0.0 234 | 2016-11-23,0.0,0.0 235 | 2016-11-24,0.0,0.0 236 | 2016-11-25,0.0,0.0 237 | 2016-11-28,0.0,0.0 238 | 2016-11-29,0.0,0.0 239 | 2016-11-30,0.0,0.0 240 | 2016-12-01,0.0,0.0 241 | 2016-12-02,0.0,0.0 242 | 2016-12-05,0.0,0.0 243 | 2016-12-06,0.0,0.0 244 | 2016-12-07,0.0,0.0 245 | 2016-12-08,0.0,0.0 246 | 2016-12-09,0.0,0.0 247 | 2016-12-12,0.0,0.0 248 | 2016-12-13,0.0,0.0 249 | 2016-12-14,0.0,0.0 250 | 2016-12-15,0.0,0.0 251 | 2016-12-16,0.0,0.0 252 | 2016-12-19,0.0,0.0 253 | 2016-12-20,0.0,0.0 254 | 2016-12-21,0.0,0.0 255 | 2016-12-22,0.0,0.0 256 | 2016-12-23,0.0,0.0 257 | 2016-12-26,0.0,0.0 258 | 2016-12-27,0.0,0.0 259 | 2016-12-28,0.0,0.0 260 | 2016-12-29,0.0,0.0 261 | 2016-12-30,0.0,0.0 262 | 2017-01-02,0.0,0.0 263 | 2017-01-03,0.0,0.0 264 | 2017-01-04,0.0,0.0 265 | 2017-01-05,0.0,0.0 266 | 2017-01-06,0.0,0.0 267 | 2017-01-09,0.0,0.0 268 | 2017-01-10,0.0,0.0 269 | 2017-01-11,0.0,0.0 270 | 2017-01-12,0.0,0.0 271 | 2017-01-13,0.0,0.0 272 | 2017-01-16,0.0,0.0 273 | 2017-01-17,0.0,0.0 274 | 2017-01-18,0.0,0.0 275 | 2017-01-19,0.0,0.0 276 | 2017-01-20,0.0,0.0 277 | 2017-01-23,0.0,0.0 278 | 2017-01-24,0.0,0.0 279 | 2017-01-25,0.0,0.0 280 | 2017-01-26,0.0,0.0 281 | 2017-01-27,0.0,0.0 282 | 2017-01-30,0.0,0.0 283 | 2017-01-31,0.0,0.0 284 | 2017-02-01,0.0,0.0 285 | 2017-02-02,0.0,0.0 286 | 2017-02-03,0.0,0.0 287 | 2017-02-06,0.0,0.0 288 | 2017-02-07,0.0,0.0 289 | 2017-02-08,0.0,0.0 290 | 2017-02-09,0.0,0.0 291 | 2017-02-10,0.0,0.0 292 | 2017-02-13,0.0,0.0 293 | 2017-02-14,0.0,0.0 294 | 2017-02-15,0.0,0.0 295 | 2017-02-16,0.0,0.0 296 | 2017-02-17,0.0,0.0 297 | 2017-02-20,0.0,0.0 298 | 2017-02-21,0.0,0.0 299 | 2017-02-22,0.0,0.0 300 | 2017-02-23,0.0,0.0 301 | 2017-02-24,0.0,0.0 302 | 2017-02-27,0.0,0.0 303 | 2017-02-28,0.0,0.0 304 | 2017-03-01,0.0,0.0 305 | 2017-03-02,0.0,0.0 306 | 2017-03-03,0.0,0.0 307 | 2017-03-06,0.0,0.0 308 | 2017-03-07,0.0,0.0 309 | 2017-03-08,0.0,0.0 310 | 2017-03-09,0.0,0.0 311 | 2017-03-10,0.0,0.0 312 | 2017-03-13,0.0,0.0 313 | 2017-03-14,0.0,0.0 314 | 2017-03-15,0.0,0.0 315 | 2017-03-16,0.0,0.0 316 | 2017-03-17,0.0,0.0 317 | 2017-03-20,0.0,0.0 318 | 2017-03-21,0.0,0.0 319 | 2017-03-22,0.0,0.0 320 | 2017-03-23,0.0,0.0 321 | 2017-03-24,0.0,0.0 322 | 2017-03-27,0.0,0.0 323 | 2017-03-28,0.0,0.0 324 | 2017-03-29,0.0,0.0 325 | 2017-03-30,0.0,0.0 326 | 2017-03-31,0.0,0.0 327 | 2017-04-03,0.0,0.0 328 | 2017-04-04,0.0,0.0 329 | 2017-04-05,0.0,0.0 330 | 2017-04-06,0.0,0.0 331 | 2017-04-07,0.0,0.0 332 | 2017-04-10,0.0,0.0 333 | 2017-04-11,0.0,0.0 334 | 2017-04-12,0.0,0.0 335 | 2017-04-13,0.0,0.0 336 | 2017-04-14,0.0,0.0 337 | 2017-04-17,0.0,0.0 338 | 2017-04-18,0.0,0.0 339 | 2017-04-19,0.0,0.0 340 | 2017-04-20,0.0,0.0 341 | 2017-04-21,0.0,0.0 342 | 2017-04-24,0.0,0.0 343 | 2017-04-25,0.0,0.0 344 | 2017-04-26,0.0,0.0 345 | 2017-04-27,0.0,0.0 346 | 2017-04-28,0.0,0.0 347 | 2017-05-01,0.0,0.0 348 | 2017-05-02,0.0,0.0 349 | 2017-05-03,0.0,0.0 350 | 2017-05-04,0.0,0.0 351 | 2017-05-05,0.0,0.0 352 | 2017-05-08,0.0,0.0 353 | 2017-05-09,0.0,0.0 354 | 2017-05-10,0.0,0.0 355 | 2017-05-11,0.0,0.0 356 | 2017-05-12,0.0,0.0 357 | 2017-05-15,0.0,0.0 358 | 2017-05-16,0.0,0.0 359 | 2017-05-17,0.0,0.0 360 | 2017-05-18,0.0,0.0 361 | 2017-05-19,0.0,0.0 362 | 2017-05-22,0.0,0.0 363 | 2017-05-23,0.0,0.0 364 | 2017-05-24,0.0,0.0 365 | 2017-05-25,0.0,0.0 366 | 2017-05-26,0.0,0.0 367 | 2017-05-29,0.0,0.0 368 | 2017-05-30,0.0,0.0 369 | 2017-05-31,0.0,0.0 370 | 2017-06-01,0.0,0.0 371 | 2017-06-02,0.0,0.0 372 | 2017-06-05,0.0,0.0 373 | 2017-06-06,0.0,0.0 374 | 2017-06-07,0.0,0.0 375 | 2017-06-08,0.0,0.0 376 | 2017-06-09,0.0,0.0 377 | 2017-06-12,0.0,0.0 378 | 2017-06-13,0.0,0.0 379 | 2017-06-14,0.0,0.0 380 | 2017-06-15,0.0,0.0 381 | 2017-06-16,0.0,0.0 382 | 2017-06-19,0.0,0.0 383 | 2017-06-20,0.0,0.0 384 | 2017-06-21,0.0,0.0 385 | 2017-06-22,0.0,0.0 386 | 2017-06-23,0.0,0.0 387 | 2017-06-26,0.0,0.0 388 | 2017-06-27,0.0,0.0 389 | 2017-06-28,0.0,0.0 390 | 2017-06-29,0.0,0.0 391 | 2017-06-30,0.0,0.0 392 | 2017-07-03,0.0,0.0 393 | 2017-07-04,0.0,0.0 394 | 2017-07-05,0.0,0.0 395 | 2017-07-06,0.0,0.0 396 | 2017-07-07,0.0,0.0 397 | 2017-07-10,0.0,0.0 398 | 2017-07-11,0.0,0.0 399 | 2017-07-12,0.0,0.0 400 | 2017-07-13,0.0,0.0 401 | 2017-07-14,0.0,0.0 402 | 2017-07-17,0.0,0.0 403 | 2017-07-18,0.0,0.0 404 | 2017-07-19,0.0,0.0 405 | 2017-07-20,0.0,0.0 406 | 2017-07-21,0.0,0.0 407 | 2017-07-24,0.0,0.0 408 | 2017-07-25,0.0,0.0 409 | 2017-07-26,0.0,0.0 410 | 2017-07-27,0.0,0.0 411 | 2017-07-28,0.0,0.0 412 | 2017-07-31,0.0,0.0 413 | 2017-08-01,0.0,0.0 414 | 2017-08-02,0.0,0.0 415 | 2017-08-03,0.0,0.0 416 | 2017-08-04,0.0,0.0 417 | 2017-08-07,0.0,0.0 418 | 2017-08-08,0.0,0.0 419 | 2017-08-09,0.0,0.0 420 | 2017-08-10,0.0,0.0 421 | 2017-08-11,0.0,0.0 422 | 2017-08-14,0.0,0.0 423 | 2017-08-15,0.0,0.0 424 | 2017-08-16,0.0,0.0 425 | 2017-08-17,0.0,0.0 426 | 2017-08-18,0.0,0.0 427 | 2017-08-21,0.0,0.0 428 | 2017-08-22,0.0,0.0 429 | 2017-08-23,0.0,0.0 430 | 2017-08-24,0.0,0.0 431 | 2017-08-25,0.0,0.0 432 | 2017-08-28,0.0,0.0 433 | 2017-08-29,0.0,0.0 434 | 2017-08-30,0.0,0.0 435 | 2017-08-31,0.0,0.0 436 | 2017-09-01,0.0,0.0 437 | 2017-09-04,0.0,0.0 438 | 2017-09-05,0.0,0.0 439 | 2017-09-06,0.0,0.0 440 | 2017-09-07,0.0,0.0 441 | 2017-09-08,0.0,0.0 442 | 2017-09-11,0.0,0.0 443 | 2017-09-12,0.0,0.0 444 | 2017-09-13,0.0,0.0 445 | 2017-09-14,0.0,0.0 446 | 2017-09-15,0.0,0.0 447 | 2017-09-18,0.0,0.0 448 | 2017-09-19,0.0,0.0 449 | 2017-09-20,0.0,0.0 450 | 2017-09-21,0.0,0.0 451 | 2017-09-22,0.0,0.0 452 | 2017-09-25,0.0,0.0 453 | 2017-09-26,0.0,0.0 454 | 2017-09-27,0.0,0.0 455 | 2017-09-28,0.0,0.0 456 | 2017-09-29,0.0,0.0 457 | 2017-10-02,0.0,0.0 458 | 2017-10-03,0.0,0.0 459 | 2017-10-04,0.0,0.0 460 | 2017-10-05,0.0,0.0 461 | 2017-10-06,0.0,0.0 462 | 2017-10-09,0.0,0.0 463 | 2017-10-10,0.0,0.0 464 | 2017-10-11,0.0,0.0 465 | 2017-10-12,0.0,0.0 466 | 2017-10-13,0.0,0.0 467 | 2017-10-16,0.0,0.0 468 | 2017-10-17,0.0,0.0 469 | 2017-10-18,0.0,0.0 470 | 2017-10-19,0.0,0.0 471 | 2017-10-20,0.0,0.0 472 | 2017-10-23,0.0,0.0 473 | 2017-10-24,0.0,0.0 474 | 2017-10-25,0.0,0.0 475 | 2017-10-26,0.0,0.0 476 | 2017-10-27,0.0,0.0 477 | 2017-10-30,0.0,0.0 478 | 2017-10-31,0.0,0.0 479 | 2017-11-01,0.0,0.0 480 | 2017-11-02,0.0,0.0 481 | 2017-11-03,0.0,0.0 482 | 2017-11-06,0.0,0.0 483 | 2017-11-07,0.0,0.0 484 | 2017-11-08,0.0,0.0 485 | 2017-11-09,0.0,0.0 486 | 2017-11-10,0.0,0.0 487 | 2017-11-13,0.0,0.0 488 | 2017-11-14,0.0,0.0 489 | 2017-11-15,0.0,0.0 490 | 2017-11-16,0.0,0.0 491 | 2017-11-17,0.0,0.0 492 | 2017-11-20,0.0,0.0 493 | 2017-11-21,0.0,0.0 494 | 2017-11-22,0.0,0.0 495 | 2017-11-23,0.0,0.0 496 | 2017-11-24,0.0,0.0 497 | 2017-11-27,0.0,0.0 498 | 2017-11-28,0.0,0.0 499 | 2017-11-29,0.0,0.0 500 | 2017-11-30,0.0,0.0 501 | 2017-12-01,0.0,0.0 502 | 2017-12-04,0.0,0.0 503 | 2017-12-05,0.0,0.0 504 | 2017-12-06,0.0,0.0 505 | 2017-12-07,0.0,0.0 506 | -------------------------------------------------------------------------------- /empyrical/tests/test_data/returns.csv: -------------------------------------------------------------------------------- 1 | 2016-01-04,2.16420955433 2 | 2016-01-05,3.21963118331 3 | 2016-01-06,0.890280110274 4 | 2016-01-07,0.798731209228 5 | 2016-01-08,0.307379650145 6 | 2016-01-11,1.59831707812 7 | 2016-01-12,0.88271274164 8 | 2016-01-13,0.77753756012 9 | 2016-01-14,1.28892080939 10 | 2016-01-15,-0.541028037651 11 | 2016-01-18,-1.89937122039 12 | 2016-01-19,0.122271178453 13 | 2016-01-20,0.815388949389 14 | 2016-01-21,-0.141425332724 15 | 2016-01-22,3.00213798426 16 | 2016-01-25,0.533109945299 17 | 2016-01-26,-2.86858221585 18 | 2016-01-27,-0.191563180222 19 | 2016-01-28,2.43267052951 20 | 2016-01-29,-0.689629567983 21 | 2016-02-01,-2.46857090225 22 | 2016-02-02,0.244505204607 23 | 2016-02-03,-0.947726483363 24 | 2016-02-04,-0.475305004218 25 | 2016-02-05,-1.82663812777 26 | 2016-02-08,-0.508564063334 27 | 2016-02-09,-1.69143732169 28 | 2016-02-10,0.400149642192 29 | 2016-02-11,0.368989120123 30 | 2016-02-12,-0.997063259668 31 | 2016-02-15,-1.03201360932 32 | 2016-02-16,-2.53942888438 33 | 2016-02-17,-0.224354793955 34 | 2016-02-18,-1.16741609144 35 | 2016-02-19,-0.855352968587 36 | 2016-02-22,0.858073472935 37 | 2016-02-23,-0.0954251358104 38 | 2016-02-24,-0.282468449763 39 | 2016-02-25,-1.44964681395 40 | 2016-02-26,-0.255387189898 41 | 2016-02-29,-0.264323353829 42 | 2016-03-01,-1.07058124655 43 | 2016-03-02,3.38414136983 44 | 2016-03-03,0.998854735347 45 | 2016-03-04,-0.0163008945794 46 | 2016-03-07,0.819268123409 47 | 2016-03-08,1.18491401456 48 | 2016-03-09,1.06293956537 49 | 2016-03-10,1.79637051463 50 | 2016-03-11,0.528901456148 51 | 2016-03-14,0.535391635914 52 | 2016-03-15,-0.301088290328 53 | 2016-03-16,0.770497780535 54 | 2016-03-17,-1.1610737922 55 | 2016-03-18,3.40345681791 56 | 2016-03-21,2.7736036187 57 | 2016-03-22,1.04883926804 58 | 2016-03-23,0.534453024845 59 | 2016-03-24,0.792241874683 60 | 2016-03-25,1.53628604191 61 | 2016-03-28,-0.722975259429 62 | 2016-03-29,1.62462407089 63 | 2016-03-30,-0.844202400059 64 | 2016-03-31,1.41411017676 65 | 2016-04-01,1.07975659325 66 | 2016-04-04,-0.230666883153 67 | 2016-04-05,-0.642502102383 68 | 2016-04-06,0.0405872165676 69 | 2016-04-07,0.368292061037 70 | 2016-04-08,-0.697054796069 71 | 2016-04-11,-1.05186589144 72 | 2016-04-12,0.801704932265 73 | 2016-04-13,3.32762426185 74 | 2016-04-14,0.204194062652 75 | 2016-04-15,-1.77749201533 76 | 2016-04-18,1.64510111632 77 | 2016-04-19,-1.57119336071 78 | 2016-04-20,-0.761930810788 79 | 2016-04-21,0.0467044137431 80 | 2016-04-22,-1.58528869716 81 | 2016-04-25,1.43149960312 82 | 2016-04-26,1.03697204831 83 | 2016-04-27,-0.381072542429 84 | 2016-04-28,-2.54498644417 85 | 2016-04-29,1.50497240428 86 | 2016-05-02,1.23958647672 87 | 2016-05-03,0.205805018603 88 | 2016-05-04,-0.352648323503 89 | 2016-05-05,-1.49295944192 90 | 2016-05-06,-0.438053344492 91 | 2016-05-09,-1.72894520467 92 | 2016-05-10,-2.86702155506 93 | 2016-05-11,-0.97682620458 94 | 2016-05-12,-1.05221826017 95 | 2016-05-13,0.803451599015 96 | 2016-05-16,-1.02580604037 97 | 2016-05-17,-1.20737631597 98 | 2016-05-18,0.35173032931 99 | 2016-05-19,1.59529470518 100 | 2016-05-20,3.49976389872 101 | 2016-05-23,-0.608561015518 102 | 2016-05-24,1.75492332661 103 | 2016-05-25,-0.976824518213 104 | 2016-05-26,-0.762357033605 105 | 2016-05-27,0.1817742094 106 | 2016-05-30,1.22739712328 107 | 2016-05-31,0.319908865373 108 | 2016-06-01,-1.35449594912 109 | 2016-06-02,0.362131321694 110 | 2016-06-03,2.21705179903 111 | 2016-06-06,-1.30192677619 112 | 2016-06-07,0.0178854991274 113 | 2016-06-08,-1.47753502024 114 | 2016-06-09,0.388687574166 115 | 2016-06-10,-0.835237798701 116 | 2016-06-13,-1.91738079234 117 | 2016-06-14,-0.126811429755 118 | 2016-06-15,-0.374984330112 119 | 2016-06-16,-0.575500480522 120 | 2016-06-17,1.10316676581 121 | 2016-06-20,-1.03470883988 122 | 2016-06-21,-0.430671456989 123 | 2016-06-22,-1.98501677538 124 | 2016-06-23,2.23195015682 125 | 2016-06-24,-2.27978858701 126 | 2016-06-27,-0.0547230933603 127 | 2016-06-28,-0.177375253824 128 | 2016-06-29,1.38628789473 129 | 2016-06-30,-2.10896133386 130 | 2016-07-01,-0.972559018228 131 | 2016-07-04,-1.69567561208 132 | 2016-07-05,-0.64888133472 133 | 2016-07-06,-1.74750120905 134 | 2016-07-07,0.612313110879 135 | 2016-07-08,-0.21348600543 136 | 2016-07-11,-2.37354641079 137 | 2016-07-12,2.34600563094 138 | 2016-07-13,-1.04336195757 139 | 2016-07-14,0.377637838315 140 | 2016-07-15,0.0338083935778 141 | 2016-07-18,0.909632054483 142 | 2016-07-19,0.844327206461 143 | 2016-07-20,0.895187523368 144 | 2016-07-21,0.165891923536 145 | 2016-07-22,1.9916643941 146 | 2016-07-25,-1.1091146781 147 | 2016-07-26,1.24390087496 148 | 2016-07-27,1.00094166192 149 | 2016-07-28,0.680678647468 150 | 2016-07-29,-0.0293931414154 151 | 2016-08-01,0.351603827883 152 | 2016-08-02,-0.798342249125 153 | 2016-08-03,0.205663294643 154 | 2016-08-04,-2.6809759772 155 | 2016-08-05,0.534199714544 156 | 2016-08-08,0.944042246308 157 | 2016-08-09,-1.85750356162 158 | 2016-08-10,-0.290528219864 159 | 2016-08-11,-0.32905864368 160 | 2016-08-12,-0.168931678387 161 | 2016-08-15,-1.53259737711 162 | 2016-08-16,-0.616398725272 163 | 2016-08-17,-1.46964751032 164 | 2016-08-18,2.09905648113 165 | 2016-08-19,0.238560449113 166 | 2016-08-22,-0.441756620999 167 | 2016-08-23,-0.410627662791 168 | 2016-08-24,-2.05285271364 169 | 2016-08-25,-1.30495612163 170 | 2016-08-26,0.975539898453 171 | 2016-08-29,0.615123595465 172 | 2016-08-30,-1.90191501412 173 | 2016-08-31,-0.721278127477 174 | 2016-09-01,-0.207989689119 175 | 2016-09-02,0.928175954722 176 | 2016-09-05,-2.20193539771 177 | 2016-09-06,0.675082663553 178 | 2016-09-07,-1.17348291224 179 | 2016-09-08,-2.3210435542 180 | 2016-09-09,0.140702484336 181 | 2016-09-12,0.702228038194 182 | 2016-09-13,1.27181335792 183 | 2016-09-14,0.145246056696 184 | 2016-09-15,-0.585503007615 185 | 2016-09-16,-1.39574486836 186 | 2016-09-19,-0.712681905613 187 | 2016-09-20,0.592172683913 188 | 2016-09-21,0.543331757931 189 | 2016-09-22,-0.927308943571 190 | 2016-09-23,0.673275235917 191 | 2016-09-26,-1.31082534404 192 | 2016-09-27,-3.27807107304 193 | 2016-09-28,-1.61808455048 194 | 2016-09-29,-2.45734574515 195 | 2016-09-30,1.81236268769 196 | 2016-10-03,0.344615177338 197 | 2016-10-04,-1.96990593741 198 | 2016-10-05,-1.05332957456 199 | 2016-10-06,1.99902579095 200 | 2016-10-07,2.31913065504 201 | 2016-10-10,-1.71455092288 202 | 2016-10-11,1.12295599912 203 | 2016-10-12,-1.41305665793 204 | 2016-10-13,0.873445411669 205 | 2016-10-14,-0.992702158626 206 | 2016-10-17,-0.646236750223 207 | 2016-10-18,-0.542581106315 208 | 2016-10-19,2.41722229378 209 | 2016-10-20,0.512886806468 210 | 2016-10-21,3.23958416818 211 | 2016-10-24,1.51172970288 212 | 2016-10-25,-1.97088115697 213 | 2016-10-26,-0.0361537248081 214 | 2016-10-27,-1.79663107987 215 | 2016-10-28,-0.299407698529 216 | 2016-10-31,-1.88375165918 217 | 2016-11-01,1.14583539274 218 | 2016-11-02,-0.656287365929 219 | 2016-11-03,0.826878358349 220 | 2016-11-04,0.878824978593 221 | 2016-11-07,-1.55464949905 222 | 2016-11-08,0.108362171074 223 | 2016-11-09,0.7607252931 224 | 2016-11-10,-0.507196407513 225 | 2016-11-11,-0.893018454854 226 | 2016-11-14,-0.23438062666 227 | 2016-11-15,0.742226093711 228 | 2016-11-16,2.3599476867 229 | 2016-11-17,-2.67030547347 230 | 2016-11-18,0.148696655935 231 | 2016-11-21,-1.49634890187 232 | 2016-11-22,-0.257851092584 233 | 2016-11-23,1.9096369789 234 | 2016-11-24,-1.75362174434 235 | 2016-11-25,-2.03713562499 236 | 2016-11-28,-2.55586126117 237 | 2016-11-29,-0.985398500407 238 | 2016-11-30,2.73326706877 239 | 2016-12-01,0.436718057752 240 | 2016-12-02,1.62459501086 241 | 2016-12-05,1.80084477746 242 | 2016-12-06,-1.33308086694 243 | 2016-12-07,-1.79302308165 244 | 2016-12-08,2.06646014678 245 | 2016-12-09,0.174803695097 246 | 2016-12-12,-1.3798786479 247 | 2016-12-13,2.39830631055 248 | 2016-12-14,2.62229938628 249 | 2016-12-15,-1.17278693274 250 | 2016-12-16,-1.09589663123 251 | 2016-12-19,0.34849014948 252 | 2016-12-20,0.862131044321 253 | 2016-12-21,-0.928719129359 254 | 2016-12-22,-3.20040225054 255 | 2016-12-23,0.122270141027 256 | 2016-12-26,2.27022433928 257 | 2016-12-27,-3.30083634438 258 | 2016-12-28,-0.484237366838 259 | 2016-12-29,1.54666243088 260 | 2016-12-30,2.02694845146 261 | 2017-01-02,-1.13568489899 262 | 2017-01-03,-2.57018957359 263 | 2017-01-04,-0.646602296369 264 | 2017-01-05,2.34907016957 265 | 2017-01-06,-1.50553460473 266 | 2017-01-09,-1.83810500357 267 | 2017-01-10,1.28972667054 268 | 2017-01-11,-1.86512037748 269 | 2017-01-12,-0.443890229501 270 | 2017-01-13,-0.312779620076 271 | 2017-01-16,-0.995093604823 272 | 2017-01-17,1.27624134049 273 | 2017-01-18,-0.828481516298 274 | 2017-01-19,-1.48098736263 275 | 2017-01-20,0.549474843283 276 | 2017-01-23,0.260249928374 277 | 2017-01-24,0.674873372985 278 | 2017-01-25,0.619820009087 279 | 2017-01-26,-2.34383963544 280 | 2017-01-27,-2.10949881089 281 | 2017-01-30,1.96666125501 282 | 2017-01-31,-1.58649315855 283 | 2017-02-01,-0.532487258066 284 | 2017-02-02,0.971644247506 285 | 2017-02-03,0.535632107372 286 | 2017-02-06,-1.37595849837 287 | 2017-02-07,0.804908129643 288 | 2017-02-08,0.226021010764 289 | 2017-02-09,-1.92393843186 290 | 2017-02-10,1.00202586802 291 | 2017-02-13,-2.61169583121 292 | 2017-02-14,-0.354844934186 293 | 2017-02-15,-1.02494728473 294 | 2017-02-16,0.228443680958 295 | 2017-02-17,-3.43853205295 296 | 2017-02-20,0.98235484906 297 | 2017-02-21,-1.303577649 298 | 2017-02-22,0.731015644217 299 | 2017-02-23,-0.686764353276 300 | 2017-02-24,-1.10874559461 301 | 2017-02-27,-1.13311052405 302 | 2017-02-28,-0.706265342992 303 | 2017-03-01,-1.99602056214 304 | 2017-03-02,-1.77118921694 305 | 2017-03-03,-0.26399968974 306 | 2017-03-06,-3.04559895192 307 | 2017-03-07,1.50067606963 308 | 2017-03-08,0.272853172261 309 | 2017-03-09,0.553466545441 310 | 2017-03-10,-0.221014391134 311 | 2017-03-13,0.294451776784 312 | 2017-03-14,-0.526508664707 313 | 2017-03-15,-1.60134330844 314 | 2017-03-16,1.85428223205 315 | 2017-03-17,-0.0575180631839 316 | 2017-03-20,-0.804773583575 317 | 2017-03-21,0.0959239853297 318 | 2017-03-22,-0.0505395008888 319 | 2017-03-23,-0.665508142742 320 | 2017-03-24,2.18027033894 321 | 2017-03-27,1.27721523253 322 | 2017-03-28,0.0381972461105 323 | 2017-03-29,-1.52290214945 324 | 2017-03-30,0.956648485035 325 | 2017-03-31,0.951585622391 326 | 2017-04-03,-2.03368978779 327 | 2017-04-04,0.837201240864 328 | 2017-04-05,0.675320754703 329 | 2017-04-06,-1.38567147857 330 | 2017-04-07,-1.31631979878 331 | 2017-04-10,-2.1958092599 332 | 2017-04-11,0.550385238052 333 | 2017-04-12,-1.09750329041 334 | 2017-04-13,1.05577162309 335 | 2017-04-14,-1.62733919465 336 | 2017-04-17,-2.430297819 337 | 2017-04-18,-2.8584865773 338 | 2017-04-19,0.612572489773 339 | 2017-04-20,0.0780394187355 340 | 2017-04-21,1.81907008147 341 | 2017-04-24,0.533016516702 342 | 2017-04-25,1.62280310702 343 | 2017-04-26,-3.49101818025 344 | 2017-04-27,0.505912618034 345 | 2017-04-28,2.34497727936 346 | 2017-05-01,1.27982322983 347 | 2017-05-02,-3.28006352412 348 | 2017-05-03,0.558046942455 349 | 2017-05-04,-1.14088576872 350 | 2017-05-05,1.27990250842 351 | 2017-05-08,-2.6554831932 352 | 2017-05-09,0.305969120203 353 | 2017-05-10,2.36697493652 354 | 2017-05-11,0.901350548961 355 | 2017-05-12,1.47657485082 356 | 2017-05-15,-0.0249465082623 357 | 2017-05-16,-0.986723754665 358 | 2017-05-17,1.22650120974 359 | 2017-05-18,-1.26747907878 360 | 2017-05-19,0.469249912172 361 | 2017-05-22,-0.897163586484 362 | 2017-05-23,-0.201564266035 363 | 2017-05-24,-2.48901699082 364 | 2017-05-25,0.310530342949 365 | 2017-05-26,1.39993342151 366 | 2017-05-29,-1.32114985926 367 | 2017-05-30,-1.55939770421 368 | 2017-05-31,0.251878743216 369 | 2017-06-01,-0.720543762919 370 | 2017-06-02,-1.09234543399 371 | 2017-06-05,-2.31782526342 372 | 2017-06-06,1.62199773143 373 | 2017-06-07,-0.209915230395 374 | 2017-06-08,0.730383073908 375 | 2017-06-09,-1.52065275148 376 | 2017-06-12,-0.888903454012 377 | 2017-06-13,2.14437685725 378 | 2017-06-14,0.80654823367 379 | 2017-06-15,-0.0369352471997 380 | 2017-06-16,-1.52722797628 381 | 2017-06-19,-0.185615062136 382 | 2017-06-20,0.747712618986 383 | 2017-06-21,-0.382922482812 384 | 2017-06-22,-0.0824178900418 385 | 2017-06-23,1.63542459048 386 | 2017-06-26,-0.477665414151 387 | 2017-06-27,-0.726359595805 388 | 2017-06-28,-2.15638276459 389 | 2017-06-29,-0.376129645064 390 | 2017-06-30,-1.69955745668 391 | 2017-07-03,2.01065971035 392 | 2017-07-04,-0.729569532852 393 | 2017-07-05,0.625347950302 394 | 2017-07-06,0.951673860043 395 | 2017-07-07,-1.40118153706 396 | 2017-07-10,-0.80795495471 397 | 2017-07-11,0.415069440239 398 | 2017-07-12,-1.75791454491 399 | 2017-07-13,-1.00251266286 400 | 2017-07-14,-1.25462789997 401 | 2017-07-17,2.19697589072 402 | 2017-07-18,-0.448686570639 403 | 2017-07-19,1.3461216949 404 | 2017-07-20,0.471860167339 405 | 2017-07-21,-1.80069601033 406 | 2017-07-24,0.112565354251 407 | 2017-07-25,0.353891388233 408 | 2017-07-26,2.20426423196 409 | 2017-07-27,1.0142090195 410 | 2017-07-28,-0.829626091563 411 | 2017-07-31,0.000353288028221 412 | 2017-08-01,-1.42886114567 413 | 2017-08-02,-0.340757690955 414 | 2017-08-03,2.55597944625 415 | 2017-08-04,0.861145764153 416 | 2017-08-07,1.32198759659 417 | 2017-08-08,-0.0390397541084 418 | 2017-08-09,0.918851571578 419 | 2017-08-10,-1.17398999163 420 | 2017-08-11,0.781880216401 421 | 2017-08-14,-0.130218406447 422 | 2017-08-15,3.10640403635 423 | 2017-08-16,0.213238792126 424 | 2017-08-17,0.216607652142 425 | 2017-08-18,-0.716881597089 426 | 2017-08-21,-3.73674699662 427 | 2017-08-22,-1.70135071407 428 | 2017-08-23,-1.46939143935 429 | 2017-08-24,-2.04903708979 430 | 2017-08-25,-0.509864956148 431 | 2017-08-28,1.32668844699 432 | 2017-08-29,0.120516478373 433 | 2017-08-30,-0.789345873489 434 | 2017-08-31,0.193975917066 435 | 2017-09-01,-0.505107059727 436 | 2017-09-04,0.450000046009 437 | 2017-09-05,-1.11952813426 438 | 2017-09-06,-0.361841803858 439 | 2017-09-07,-1.08139691805 440 | 2017-09-08,-1.74327499448 441 | 2017-09-11,0.361855218159 442 | 2017-09-12,-0.152628361654 443 | 2017-09-13,-1.64989464856 444 | 2017-09-14,0.410757950451 445 | 2017-09-15,-0.530326700757 446 | 2017-09-18,-0.17493428176 447 | 2017-09-19,0.755092093784 448 | 2017-09-20,0.57603620811 449 | 2017-09-21,-2.39813670791 450 | 2017-09-22,2.19039229392 451 | 2017-09-25,-2.14517245505 452 | 2017-09-26,0.557856453616 453 | 2017-09-27,0.970994402874 454 | 2017-09-28,-1.7062662684 455 | 2017-09-29,2.289756245 456 | 2017-10-02,-2.21884039066 457 | 2017-10-03,-1.01688534564 458 | 2017-10-04,-0.259175509346 459 | 2017-10-05,-0.319289896615 460 | 2017-10-06,0.200042182949 461 | 2017-10-09,-0.0226113761569 462 | 2017-10-10,1.53034661666 463 | 2017-10-11,2.38475882145 464 | 2017-10-12,-0.53600982685 465 | 2017-10-13,1.83580320538 466 | 2017-10-16,1.33419812274 467 | 2017-10-17,-1.0697522211 468 | 2017-10-18,-1.1522665034 469 | 2017-10-19,0.674744963968 470 | 2017-10-20,-1.32389256982 471 | 2017-10-23,1.66367405489 472 | 2017-10-24,3.24047024041 473 | 2017-10-25,0.184048461979 474 | 2017-10-26,1.71065006077 475 | 2017-10-27,0.391009250722 476 | 2017-10-30,-0.703045138945 477 | 2017-10-31,0.990963037634 478 | 2017-11-01,0.775091407101 479 | 2017-11-02,0.0587659177434 480 | 2017-11-03,1.0674859235 481 | 2017-11-06,0.57254145092 482 | 2017-11-07,1.12671933158 483 | 2017-11-08,-0.570907316663 484 | 2017-11-09,1.58149159817 485 | 2017-11-10,1.48710113275 486 | 2017-11-13,0.310956546026 487 | 2017-11-14,1.61472697925 488 | 2017-11-15,1.70729437889 489 | 2017-11-16,-1.27034812155 490 | 2017-11-17,-0.525604960667 491 | 2017-11-20,0.214937582637 492 | 2017-11-21,0.702985855346 493 | 2017-11-22,-0.504772278 494 | 2017-11-23,0.318426777681 495 | 2017-11-24,1.0821632933 496 | 2017-11-27,0.619825773006 497 | 2017-11-28,-0.558634889801 498 | 2017-11-29,0.701991325725 499 | 2017-11-30,-0.10420659651 500 | 2017-12-01,-1.50572502032 501 | 2017-12-04,1.44843656704 502 | 2017-12-05,-0.317600794692 503 | 2017-12-06,0.429533271829 504 | 2017-12-07,-1.27730404508 505 | -------------------------------------------------------------------------------- /empyrical/tests/test_perf_attrib.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import pandas as pd 3 | import unittest 4 | 5 | from empyrical.perf_attrib import perf_attrib 6 | 7 | 8 | class PerfAttribTestCase(unittest.TestCase): 9 | 10 | def test_perf_attrib_simple(self): 11 | 12 | start_date = '2017-01-01' 13 | periods = 2 14 | dts = pd.date_range(start_date, periods=periods) 15 | dts.name = 'dt' 16 | 17 | tickers = ['stock1', 'stock2'] 18 | styles = ['risk_factor1', 'risk_factor2'] 19 | 20 | returns = pd.Series(data=[0.1, 0.1], index=dts) 21 | 22 | factor_returns = pd.DataFrame( 23 | columns=styles, 24 | index=dts, 25 | data={'risk_factor1': [.1, .1], 26 | 'risk_factor2': [.1, .1]} 27 | ) 28 | 29 | index = pd.MultiIndex.from_product( 30 | [dts, tickers], names=['dt', 'ticker']) 31 | 32 | positions = pd.Series([0.2857142857142857, 0.7142857142857143, 33 | 0.2857142857142857, 0.7142857142857143], 34 | index=index) 35 | 36 | factor_loadings = pd.DataFrame( 37 | columns=styles, 38 | index=index, 39 | data={'risk_factor1': [0.25, 0.25, 0.25, 0.25], 40 | 'risk_factor2': [0.25, 0.25, 0.25, 0.25]} 41 | ) 42 | 43 | expected_perf_attrib_output = pd.DataFrame( 44 | index=dts, 45 | columns=['risk_factor1', 'risk_factor2', 'total_returns', 46 | 'common_returns', 'specific_returns', 47 | 'tilt_returns', 'timing_returns'], 48 | data={'risk_factor1': [0.025, 0.025], 49 | 'risk_factor2': [0.025, 0.025], 50 | 'common_returns': [0.05, 0.05], 51 | 'specific_returns': [0.05, 0.05], 52 | 'tilt_returns': [0.05, 0.05], 53 | 'timing_returns': [0.0, 0.0], 54 | 'total_returns': returns} 55 | ) 56 | 57 | expected_exposures_portfolio = pd.DataFrame( 58 | index=dts, 59 | columns=['risk_factor1', 'risk_factor2'], 60 | data={'risk_factor1': [0.25, 0.25], 61 | 'risk_factor2': [0.25, 0.25]} 62 | ) 63 | 64 | exposures_portfolio, perf_attrib_output = perf_attrib(returns, 65 | positions, 66 | factor_returns, 67 | factor_loadings) 68 | 69 | pd.util.testing.assert_frame_equal(expected_perf_attrib_output, 70 | perf_attrib_output) 71 | 72 | pd.util.testing.assert_frame_equal(expected_exposures_portfolio, 73 | exposures_portfolio) 74 | 75 | # test long and short positions 76 | positions = pd.Series([0.5, -0.5, 0.5, -0.5], index=index) 77 | 78 | exposures_portfolio, perf_attrib_output = perf_attrib(returns, 79 | positions, 80 | factor_returns, 81 | factor_loadings) 82 | 83 | expected_perf_attrib_output = pd.DataFrame( 84 | index=dts, 85 | columns=['risk_factor1', 'risk_factor2', 'total_returns', 86 | 'common_returns', 'specific_returns', 87 | 'tilt_returns', 'timing_returns'], 88 | data={'risk_factor1': [0.0, 0.0], 89 | 'risk_factor2': [0.0, 0.0], 90 | 'common_returns': [0.0, 0.0], 91 | 'specific_returns': [0.1, 0.1], 92 | 'tilt_returns': [0.0, 0.0], 93 | 'timing_returns': [0.0, 0.0], 94 | 'total_returns': returns} 95 | ) 96 | 97 | expected_exposures_portfolio = pd.DataFrame( 98 | index=dts, 99 | columns=['risk_factor1', 'risk_factor2'], 100 | data={'risk_factor1': [0.0, 0.0], 101 | 'risk_factor2': [0.0, 0.0]} 102 | ) 103 | 104 | pd.util.testing.assert_frame_equal(expected_perf_attrib_output, 105 | perf_attrib_output) 106 | 107 | pd.util.testing.assert_frame_equal(expected_exposures_portfolio, 108 | exposures_portfolio) 109 | 110 | # test long and short positions with tilt exposure 111 | positions = pd.Series([1.0, -0.5, 1.0, -0.5], index=index) 112 | 113 | exposures_portfolio, perf_attrib_output = perf_attrib(returns, 114 | positions, 115 | factor_returns, 116 | factor_loadings) 117 | 118 | expected_perf_attrib_output = pd.DataFrame( 119 | index=dts, 120 | columns=['risk_factor1', 'risk_factor2', 'total_returns', 121 | 'common_returns', 'specific_returns', 122 | 'tilt_returns', 'timing_returns'], 123 | data={'risk_factor1': [0.0125, 0.0125], 124 | 'risk_factor2': [0.0125, 0.0125], 125 | 'common_returns': [0.025, 0.025], 126 | 'specific_returns': [0.075, 0.075], 127 | 'tilt_returns': [0.025, 0.025], 128 | 'timing_returns': [0.0, 0.0], 129 | 'total_returns': returns} 130 | ) 131 | 132 | expected_exposures_portfolio = pd.DataFrame( 133 | index=dts, 134 | columns=['risk_factor1', 'risk_factor2'], 135 | data={'risk_factor1': [0.125, 0.125], 136 | 'risk_factor2': [0.125, 0.125]} 137 | ) 138 | 139 | pd.util.testing.assert_frame_equal(expected_perf_attrib_output, 140 | perf_attrib_output) 141 | 142 | pd.util.testing.assert_frame_equal(expected_exposures_portfolio, 143 | exposures_portfolio) 144 | 145 | def test_perf_attrib_regression(self): 146 | 147 | positions = pd.read_csv('empyrical/tests/test_data/positions.csv', 148 | index_col=0, parse_dates=True) 149 | 150 | positions.columns = [int(col) if col != 'cash' else col 151 | for col in positions.columns] 152 | 153 | positions = positions.divide(positions.sum(axis='columns'), 154 | axis='rows') 155 | positions = positions.drop('cash', axis='columns').stack() 156 | 157 | returns = pd.read_csv('empyrical/tests/test_data/returns.csv', 158 | index_col=0, parse_dates=True, 159 | header=None, squeeze=True) 160 | 161 | factor_loadings = pd.read_csv( 162 | 'empyrical/tests/test_data/factor_loadings.csv', 163 | index_col=[0, 1], parse_dates=True 164 | ) 165 | 166 | factor_returns = pd.read_csv( 167 | 'empyrical/tests/test_data/factor_returns.csv', 168 | index_col=0, parse_dates=True 169 | ) 170 | 171 | residuals = pd.read_csv('empyrical/tests/test_data/residuals.csv', 172 | index_col=0, parse_dates=True) 173 | 174 | residuals.columns = [int(col) for col in residuals.columns] 175 | 176 | intercepts = pd.read_csv('empyrical/tests/test_data/intercepts.csv', 177 | index_col=0, header=None, squeeze=True) 178 | 179 | risk_exposures_portfolio, perf_attrib_output = perf_attrib( 180 | returns, 181 | positions, 182 | factor_returns, 183 | factor_loadings, 184 | ) 185 | 186 | specific_returns = perf_attrib_output['specific_returns'] 187 | common_returns = perf_attrib_output['common_returns'] 188 | combined_returns = specific_returns + common_returns 189 | 190 | # since all returns are factor returns, common returns should be 191 | # equivalent to total returns, and specific returns should be 0 192 | pd.util.testing.assert_series_equal(returns, 193 | common_returns, 194 | check_names=False) 195 | 196 | self.assertTrue(np.isclose(specific_returns, 0).all()) 197 | 198 | # specific and common returns combined should equal total returns 199 | pd.util.testing.assert_series_equal(returns, 200 | combined_returns, 201 | check_names=False) 202 | 203 | # check that residuals + intercepts = specific returns 204 | self.assertTrue(np.isclose((residuals + intercepts), 0).all()) 205 | 206 | # check that exposure * factor returns = common returns 207 | expected_common_returns = risk_exposures_portfolio.multiply( 208 | factor_returns, axis='rows' 209 | ).sum(axis='columns') 210 | 211 | pd.util.testing.assert_series_equal(expected_common_returns, 212 | common_returns, 213 | check_names=False) 214 | 215 | # since factor loadings are ones, portfolio risk exposures 216 | # should be ones 217 | pd.util.testing.assert_frame_equal( 218 | risk_exposures_portfolio, 219 | pd.DataFrame(np.ones_like(risk_exposures_portfolio), 220 | index=risk_exposures_portfolio.index, 221 | columns=risk_exposures_portfolio.columns) 222 | ) 223 | -------------------------------------------------------------------------------- /empyrical/utils.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2018 Quantopian, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | from datetime import datetime 16 | from functools import wraps 17 | from os import makedirs, environ 18 | from os.path import expanduser, join, getmtime, isdir 19 | import errno 20 | import warnings 21 | 22 | import numpy as np 23 | from numpy.lib.stride_tricks import as_strided 24 | import pandas as pd 25 | from pandas.tseries.offsets import BDay 26 | try: 27 | from pandas_datareader import data as web 28 | except ImportError: 29 | msg = ("Unable to import pandas_datareader. Suppressing import error and " 30 | "continuing. All data reading functionality will raise errors; but " 31 | "has been deprecated and will be removed in a later version.") 32 | warnings.warn(msg) 33 | from .deprecate import deprecated 34 | 35 | DATAREADER_DEPRECATION_WARNING = \ 36 | ("Yahoo and Google Finance have suffered large API breaks with no " 37 | "stable replacement. As a result, any data reading functionality " 38 | "in empyrical has been deprecated and will be removed in a future " 39 | "version. See README.md for more details: " 40 | "\n\n" 41 | "\thttps://github.com/quantopian/pyfolio/blob/master/README.md") 42 | try: 43 | # fast versions 44 | import bottleneck as bn 45 | 46 | def _wrap_function(f): 47 | @wraps(f) 48 | def wrapped(*args, **kwargs): 49 | out = kwargs.pop('out', None) 50 | data = f(*args, **kwargs) 51 | if out is None: 52 | out = data 53 | else: 54 | out[()] = data 55 | 56 | return out 57 | 58 | return wrapped 59 | 60 | nanmean = _wrap_function(bn.nanmean) 61 | nanstd = _wrap_function(bn.nanstd) 62 | nansum = _wrap_function(bn.nansum) 63 | nanmax = _wrap_function(bn.nanmax) 64 | nanmin = _wrap_function(bn.nanmin) 65 | nanargmax = _wrap_function(bn.nanargmax) 66 | nanargmin = _wrap_function(bn.nanargmin) 67 | except ImportError: 68 | # slower numpy 69 | nanmean = np.nanmean 70 | nanstd = np.nanstd 71 | nansum = np.nansum 72 | nanmax = np.nanmax 73 | nanmin = np.nanmin 74 | nanargmax = np.nanargmax 75 | nanargmin = np.nanargmin 76 | 77 | 78 | def roll(*args, **kwargs): 79 | """ 80 | Calculates a given statistic across a rolling time period. 81 | 82 | Parameters 83 | ---------- 84 | returns : pd.Series or np.ndarray 85 | Daily returns of the strategy, noncumulative. 86 | - See full explanation in :func:`~empyrical.stats.cum_returns`. 87 | factor_returns (optional): float / series 88 | Benchmark return to compare returns against. 89 | function: 90 | the function to run for each rolling window. 91 | window (keyword): int 92 | the number of periods included in each calculation. 93 | (other keywords): other keywords that are required to be passed to the 94 | function in the 'function' argument may also be passed in. 95 | 96 | Returns 97 | ------- 98 | np.ndarray, pd.Series 99 | depends on input type 100 | ndarray(s) ==> ndarray 101 | Series(s) ==> pd.Series 102 | 103 | A Series or ndarray of the results of the stat across the rolling 104 | window. 105 | 106 | """ 107 | func = kwargs.pop('function') 108 | window = kwargs.pop('window') 109 | if len(args) > 2: 110 | raise ValueError("Cannot pass more than 2 return sets") 111 | 112 | if len(args) == 2: 113 | if not isinstance(args[0], type(args[1])): 114 | raise ValueError("The two returns arguments are not the same.") 115 | 116 | if isinstance(args[0], np.ndarray): 117 | return _roll_ndarray(func, window, *args, **kwargs) 118 | return _roll_pandas(func, window, *args, **kwargs) 119 | 120 | 121 | def up(returns, factor_returns, **kwargs): 122 | """ 123 | Calculates a given statistic filtering only positive factor return periods. 124 | 125 | Parameters 126 | ---------- 127 | returns : pd.Series or np.ndarray 128 | Daily returns of the strategy, noncumulative. 129 | - See full explanation in :func:`~empyrical.stats.cum_returns`. 130 | factor_returns (optional): float / series 131 | Benchmark return to compare returns against. 132 | function: 133 | the function to run for each rolling window. 134 | (other keywords): other keywords that are required to be passed to the 135 | function in the 'function' argument may also be passed in. 136 | 137 | Returns 138 | ------- 139 | Same as the return of the function 140 | """ 141 | func = kwargs.pop('function') 142 | returns = returns[factor_returns > 0] 143 | factor_returns = factor_returns[factor_returns > 0] 144 | return func(returns, factor_returns, **kwargs) 145 | 146 | 147 | def down(returns, factor_returns, **kwargs): 148 | """ 149 | Calculates a given statistic filtering only negative factor return periods. 150 | 151 | Parameters 152 | ---------- 153 | returns : pd.Series or np.ndarray 154 | Daily returns of the strategy, noncumulative. 155 | - See full explanation in :func:`~empyrical.stats.cum_returns`. 156 | factor_returns (optional): float / series 157 | Benchmark return to compare returns against. 158 | function: 159 | the function to run for each rolling window. 160 | (other keywords): other keywords that are required to be passed to the 161 | function in the 'function' argument may also be passed in. 162 | 163 | Returns 164 | ------- 165 | Same as the return of the 'function' 166 | """ 167 | func = kwargs.pop('function') 168 | returns = returns[factor_returns < 0] 169 | factor_returns = factor_returns[factor_returns < 0] 170 | return func(returns, factor_returns, **kwargs) 171 | 172 | 173 | def _roll_ndarray(func, window, *args, **kwargs): 174 | data = [] 175 | for i in range(window, len(args[0]) + 1): 176 | rets = [s[i-window:i] for s in args] 177 | data.append(func(*rets, **kwargs)) 178 | return np.array(data) 179 | 180 | 181 | def _roll_pandas(func, window, *args, **kwargs): 182 | data = {} 183 | index_values = [] 184 | for i in range(window, len(args[0]) + 1): 185 | rets = [s.iloc[i-window:i] for s in args] 186 | index_value = args[0].index[i - 1] 187 | index_values.append(index_value) 188 | data[index_value] = func(*rets, **kwargs) 189 | return pd.Series(data, index=type(args[0].index)(index_values)) 190 | 191 | 192 | @deprecated(msg=DATAREADER_DEPRECATION_WARNING) 193 | def cache_dir(environ=environ): 194 | try: 195 | return environ['EMPYRICAL_CACHE_DIR'] 196 | except KeyError: 197 | return join( 198 | 199 | environ.get( 200 | 'XDG_CACHE_HOME', 201 | expanduser('~/.cache/'), 202 | ), 203 | 'empyrical', 204 | ) 205 | 206 | 207 | @deprecated(msg=DATAREADER_DEPRECATION_WARNING) 208 | def data_path(name): 209 | return join(cache_dir(), name) 210 | 211 | 212 | @deprecated(msg=DATAREADER_DEPRECATION_WARNING) 213 | def ensure_directory(path): 214 | """ 215 | Ensure that a directory named "path" exists. 216 | """ 217 | 218 | try: 219 | makedirs(path) 220 | except OSError as exc: 221 | if exc.errno != errno.EEXIST or not isdir(path): 222 | raise 223 | 224 | 225 | def get_utc_timestamp(dt): 226 | """ 227 | Returns the Timestamp/DatetimeIndex 228 | with either localized or converted to UTC. 229 | 230 | Parameters 231 | ---------- 232 | dt : Timestamp/DatetimeIndex 233 | the date(s) to be converted 234 | 235 | Returns 236 | ------- 237 | same type as input 238 | date(s) converted to UTC 239 | """ 240 | 241 | dt = pd.to_datetime(dt) 242 | try: 243 | dt = dt.tz_localize('UTC') 244 | except TypeError: 245 | dt = dt.tz_convert('UTC') 246 | return dt 247 | 248 | 249 | _1_bday = BDay() 250 | 251 | 252 | def _1_bday_ago(): 253 | return pd.Timestamp.now().normalize() - _1_bday 254 | 255 | 256 | @deprecated(msg=DATAREADER_DEPRECATION_WARNING) 257 | def get_fama_french(): 258 | """ 259 | Retrieve Fama-French factors via pandas-datareader 260 | Returns 261 | ------- 262 | pandas.DataFrame 263 | Percent change of Fama-French factors 264 | """ 265 | 266 | start = '1/1/1970' 267 | research_factors = web.DataReader('F-F_Research_Data_Factors_daily', 268 | 'famafrench', start=start)[0] 269 | momentum_factor = web.DataReader('F-F_Momentum_Factor_daily', 270 | 'famafrench', start=start)[0] 271 | five_factors = research_factors.join(momentum_factor).dropna() 272 | five_factors /= 100. 273 | five_factors.index = five_factors.index.tz_localize('utc') 274 | 275 | five_factors.columns = five_factors.columns.str.strip() 276 | 277 | return five_factors 278 | 279 | 280 | @deprecated(msg=DATAREADER_DEPRECATION_WARNING) 281 | def get_returns_cached(filepath, update_func, latest_dt, **kwargs): 282 | """ 283 | Get returns from a cached file if the cache is recent enough, 284 | otherwise, try to retrieve via a provided update function and 285 | update the cache file. 286 | Parameters 287 | ---------- 288 | filepath : str 289 | Path to cached csv file 290 | update_func : function 291 | Function to call in case cache is not up-to-date. 292 | latest_dt : pd.Timestamp (tz=UTC) 293 | Latest datetime required in csv file. 294 | **kwargs : Keyword arguments 295 | Optional keyword arguments will be passed to update_func() 296 | Returns 297 | ------- 298 | pandas.DataFrame 299 | DataFrame containing returns 300 | """ 301 | 302 | update_cache = False 303 | 304 | try: 305 | mtime = getmtime(filepath) 306 | except OSError as e: 307 | if e.errno != errno.ENOENT: 308 | raise 309 | update_cache = True 310 | else: 311 | 312 | file_dt = pd.Timestamp(mtime, unit='s') 313 | 314 | if latest_dt.tzinfo: 315 | file_dt = file_dt.tz_localize('utc') 316 | 317 | if file_dt < latest_dt: 318 | update_cache = True 319 | else: 320 | returns = pd.read_csv(filepath, index_col=0, parse_dates=True) 321 | returns.index = returns.index.tz_localize("UTC") 322 | 323 | if update_cache: 324 | returns = update_func(**kwargs) 325 | try: 326 | ensure_directory(cache_dir()) 327 | except OSError as e: 328 | warnings.warn( 329 | 'could not update cache: {}. {}: {}'.format( 330 | filepath, type(e).__name__, e, 331 | ), 332 | UserWarning, 333 | ) 334 | 335 | try: 336 | returns.to_csv(filepath) 337 | except OSError as e: 338 | warnings.warn( 339 | 'could not update cache {}. {}: {}'.format( 340 | filepath, type(e).__name__, e, 341 | ), 342 | UserWarning, 343 | ) 344 | 345 | return returns 346 | 347 | 348 | @deprecated(msg=DATAREADER_DEPRECATION_WARNING) 349 | def load_portfolio_risk_factors(filepath_prefix=None, start=None, end=None): 350 | """ 351 | Load risk factors Mkt-Rf, SMB, HML, Rf, and UMD. 352 | Data is stored in HDF5 file. If the data is more than 2 353 | days old, redownload from Dartmouth. 354 | Returns 355 | ------- 356 | five_factors : pd.DataFrame 357 | Risk factors timeseries. 358 | """ 359 | 360 | if start is None: 361 | start = '1/1/1970' 362 | if end is None: 363 | end = _1_bday_ago() 364 | 365 | start = get_utc_timestamp(start) 366 | end = get_utc_timestamp(end) 367 | 368 | if filepath_prefix is None: 369 | filepath = data_path('factors.csv') 370 | else: 371 | filepath = filepath_prefix 372 | 373 | five_factors = get_returns_cached(filepath, get_fama_french, end) 374 | 375 | return five_factors.loc[start:end] 376 | 377 | 378 | @deprecated(msg=DATAREADER_DEPRECATION_WARNING) 379 | def get_treasury_yield(start=None, end=None, period='3MO'): 380 | """ 381 | Load treasury yields from FRED. 382 | 383 | Parameters 384 | ---------- 385 | start : date, optional 386 | Earliest date to fetch data for. 387 | Defaults to earliest date available. 388 | end : date, optional 389 | Latest date to fetch data for. 390 | Defaults to latest date available. 391 | period : {'1MO', '3MO', '6MO', 1', '5', '10'}, optional 392 | Which maturity to use. 393 | Returns 394 | ------- 395 | pd.Series 396 | Annual treasury yield for every day. 397 | """ 398 | 399 | if start is None: 400 | start = '1/1/1970' 401 | if end is None: 402 | end = _1_bday_ago() 403 | 404 | treasury = web.DataReader("DGS3{}".format(period), "fred", 405 | start, end) 406 | 407 | treasury = treasury.ffill() 408 | 409 | return treasury 410 | 411 | 412 | @deprecated(msg=DATAREADER_DEPRECATION_WARNING) 413 | def get_symbol_returns_from_yahoo(symbol, start=None, end=None): 414 | """ 415 | Wrapper for pandas.io.data.get_data_yahoo(). 416 | Retrieves prices for symbol from yahoo and computes returns 417 | based on adjusted closing prices. 418 | 419 | Parameters 420 | ---------- 421 | symbol : str 422 | Symbol name to load, e.g. 'SPY' 423 | start : pandas.Timestamp compatible, optional 424 | Start date of time period to retrieve 425 | end : pandas.Timestamp compatible, optional 426 | End date of time period to retrieve 427 | 428 | Returns 429 | ------- 430 | pandas.DataFrame 431 | Returns of symbol in requested period. 432 | """ 433 | 434 | try: 435 | px = web.get_data_yahoo(symbol, start=start, end=end) 436 | px['date'] = pd.to_datetime(px['date']) 437 | px.set_index('date', drop=False, inplace=True) 438 | rets = px[['adjclose']].pct_change().dropna() 439 | except Exception as e: 440 | warnings.warn( 441 | 'Yahoo Finance read failed: {}, falling back to Google'.format(e), 442 | UserWarning) 443 | px = web.get_data_google(symbol, start=start, end=end) 444 | rets = px[['Close']].pct_change().dropna() 445 | 446 | rets.index = rets.index.tz_localize("UTC") 447 | rets.columns = [symbol] 448 | return rets 449 | 450 | 451 | @deprecated(msg=DATAREADER_DEPRECATION_WARNING) 452 | def default_returns_func(symbol, start=None, end=None): 453 | """ 454 | Gets returns for a symbol. 455 | Queries Yahoo Finance. Attempts to cache SPY. 456 | 457 | Parameters 458 | ---------- 459 | symbol : str 460 | Ticker symbol, e.g. APPL. 461 | start : date, optional 462 | Earliest date to fetch data for. 463 | Defaults to earliest date available. 464 | end : date, optional 465 | Latest date to fetch data for. 466 | Defaults to latest date available. 467 | 468 | Returns 469 | ------- 470 | pd.Series 471 | Daily returns for the symbol. 472 | - See full explanation in tears.create_full_tear_sheet (returns). 473 | """ 474 | 475 | if start is None: 476 | start = '1/1/1970' 477 | if end is None: 478 | end = _1_bday_ago() 479 | 480 | start = get_utc_timestamp(start) 481 | end = get_utc_timestamp(end) 482 | 483 | if symbol == 'SPY': 484 | filepath = data_path('spy.csv') 485 | rets = get_returns_cached(filepath, 486 | get_symbol_returns_from_yahoo, 487 | end, 488 | symbol='SPY', 489 | start='1/1/1970', 490 | end=datetime.now()) 491 | rets = rets[start:end] 492 | else: 493 | rets = get_symbol_returns_from_yahoo(symbol, start=start, end=end) 494 | 495 | return rets[symbol] 496 | 497 | 498 | def rolling_window(array, length, mutable=False): 499 | """ 500 | Restride an array of shape 501 | 502 | (X_0, ... X_N) 503 | 504 | into an array of shape 505 | 506 | (length, X_0 - length + 1, ... X_N) 507 | 508 | where each slice at index i along the first axis is equivalent to 509 | 510 | result[i] = array[length * i:length * (i + 1)] 511 | 512 | Parameters 513 | ---------- 514 | array : np.ndarray 515 | The base array. 516 | length : int 517 | Length of the synthetic first axis to generate. 518 | mutable : bool, optional 519 | Return a mutable array? The returned array shares the same memory as 520 | the input array. This means that writes into the returned array affect 521 | ``array``. The returned array also uses strides to map the same values 522 | to multiple indices. Writes to a single index may appear to change many 523 | values in the returned array. 524 | 525 | Returns 526 | ------- 527 | out : np.ndarray 528 | 529 | Example 530 | ------- 531 | >>> from numpy import arange 532 | >>> a = arange(25).reshape(5, 5) 533 | >>> a 534 | array([[ 0, 1, 2, 3, 4], 535 | [ 5, 6, 7, 8, 9], 536 | [10, 11, 12, 13, 14], 537 | [15, 16, 17, 18, 19], 538 | [20, 21, 22, 23, 24]]) 539 | 540 | >>> rolling_window(a, 2) 541 | array([[[ 0, 1, 2, 3, 4], 542 | [ 5, 6, 7, 8, 9]], 543 | 544 | [[ 5, 6, 7, 8, 9], 545 | [10, 11, 12, 13, 14]], 546 | 547 | [[10, 11, 12, 13, 14], 548 | [15, 16, 17, 18, 19]], 549 | 550 | [[15, 16, 17, 18, 19], 551 | [20, 21, 22, 23, 24]]]) 552 | """ 553 | if not length: 554 | raise ValueError("Can't have 0-length window") 555 | 556 | orig_shape = array.shape 557 | if not orig_shape: 558 | raise IndexError("Can't restride a scalar.") 559 | elif orig_shape[0] < length: 560 | raise IndexError( 561 | "Can't restride array of shape {shape} with" 562 | " a window length of {len}".format( 563 | shape=orig_shape, 564 | len=length, 565 | ) 566 | ) 567 | 568 | num_windows = (orig_shape[0] - length + 1) 569 | new_shape = (num_windows, length) + orig_shape[1:] 570 | 571 | new_strides = (array.strides[0],) + array.strides 572 | 573 | out = as_strided(array, new_shape, new_strides) 574 | out.setflags(write=mutable) 575 | return out 576 | -------------------------------------------------------------------------------- /runtests.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | import unittest 4 | import warnings 5 | 6 | 7 | if __name__ == '__main__': 8 | with warnings.catch_warnings(): 9 | warnings.simplefilter('ignore', category=RuntimeWarning) 10 | loader = unittest.TestLoader() 11 | tests = loader.discover('.') 12 | testRunner = unittest.runner.TextTestRunner() 13 | testRunner.run(tests) 14 | -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | [metadata] 2 | description-file = README.md 3 | license_file = LICENSE 4 | 5 | # See the docstring in versioneer.py for instructions. Note that you must 6 | # re-run 'versioneer.py setup' after changing this section, and commit the 7 | # resulting files. 8 | [versioneer] 9 | VCS = git 10 | style = pep440 11 | versionfile_source = empyrical/_version.py 12 | versionfile_build = empyrical/_version.py 13 | tag_prefix = "" 14 | parentdir_prefix = empyrical- 15 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # Copyright 2016 Quantopian, Inc. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | from setuptools import setup 17 | import versioneer 18 | 19 | 20 | DISTNAME = "empyrical" 21 | DESCRIPTION = """empyrical is a Python library with performance and risk \ 22 | statistics commonly used in quantitative finance""" 23 | LONG_DESCRIPTION = """empyrical is a Python library with performance and risk 24 | statistics commonly used in quantitative finance by `Quantopian Inc`_. 25 | 26 | .. _Quantopian Inc: https://www.quantopian.com 27 | .. _Zipline: https://zipline.io 28 | .. _pyfolio: https://quantopian.github.io/pyfolio/ 29 | """ 30 | MAINTAINER = "Quantopian Inc" 31 | MAINTAINER_EMAIL = "opensource@quantopian.com" 32 | AUTHOR = "Quantopian Inc" 33 | AUTHOR_EMAIL = "opensource@quantopian.com" 34 | URL = "https://github.com/quantopian/empyrical" 35 | LICENSE = "Apache License, Version 2.0" 36 | 37 | classifiers = [ 38 | "Development Status :: 4 - Beta", 39 | "Programming Language :: Python", 40 | "Programming Language :: Python :: 2", 41 | "Programming Language :: Python :: 3", 42 | "Programming Language :: Python :: 2.7", 43 | "Programming Language :: Python :: 3.4", 44 | "Programming Language :: Python :: 3.5", 45 | "License :: OSI Approved :: Apache Software License", 46 | "Intended Audience :: Science/Research", 47 | "Topic :: Scientific/Engineering", 48 | "Topic :: Scientific/Engineering :: Mathematics", 49 | "Operating System :: OS Independent" 50 | ] 51 | 52 | 53 | test_reqs = [ 54 | "nose>=1.3.7", 55 | "parameterized>=0.6.1" 56 | ] 57 | 58 | 59 | requirements = [ 60 | 'numpy>=1.9.2', 61 | 'pandas>=0.16.1', 62 | 'scipy>=0.15.1', 63 | 'six', 64 | "pandas-datareader>=0.2" 65 | ] 66 | 67 | extras_requirements = { 68 | "dev": [ 69 | "nose==1.3.7", 70 | "parameterized==0.6.1", 71 | "flake8==2.5.1" 72 | ] 73 | } 74 | 75 | 76 | if __name__ == "__main__": 77 | setup( 78 | name=DISTNAME, 79 | cmdclass=versioneer.get_cmdclass(), 80 | version=versioneer.get_version(), 81 | maintainer=MAINTAINER, 82 | maintainer_email=MAINTAINER_EMAIL, 83 | description=DESCRIPTION, 84 | license=LICENSE, 85 | url=URL, 86 | long_description=LONG_DESCRIPTION, 87 | packages=["empyrical", "empyrical.tests"], 88 | classifiers=classifiers, 89 | install_requires=requirements, 90 | extras_require=extras_requirements, 91 | tests_require=test_reqs, 92 | test_suite="nose.collector" 93 | ) 94 | --------------------------------------------------------------------------------