├── .gitignore
├── .travis.yml
├── LICENSE.md
├── MANIFEST.in
├── README.rst
├── docs
├── Makefile
├── make.bat
└── source
│ ├── conf.py
│ └── index.rst
├── pandas_finance
├── __init__.py
├── api.py
└── tests
│ ├── __init__.py
│ ├── nosy.cfg
│ └── test_api.py
├── requirements.txt
├── setup.cfg
├── setup.py
└── tox.ini
/.gitignore:
--------------------------------------------------------------------------------
1 | __pycache__
2 | *.pyc
3 | *.egg-info
4 | .eggs
5 | .coverage
6 | build
7 | dist
8 | docs/build
9 |
10 | *.sqlite
11 | .idea/
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | sudo: false
2 |
3 | language: python
4 |
5 | env:
6 | - PYTHON=2.7 PANDAS=0.22
7 | - PYTHON=3.5 PANDAS=0.21
8 | - PYTHON=3.6 PANDAS=0.23.0
9 | - PYTHON=3.6 PANDAS=0.25.0
10 | - PYTHON=3.6 PANDAS="MASTER"
11 |
12 | matrix:
13 | allow_failures:
14 | - env: PYTHON=3.6 PANDAS="MASTER"
15 | - env: PYTHON=2.7 PANDAS=0.22
16 |
17 | install:
18 | # You may want to periodically update this, although the conda update
19 | # conda line below will keep everything up-to-date. We do this
20 | # conditionally because it saves us some downloading if the version is
21 | # the same.
22 | - if [[ "$PYTHON" == "2.7" ]]; then
23 | wget http://repo.continuum.io/miniconda/Miniconda-latest-Linux-x86_64.sh -O miniconda.sh;
24 | else
25 | wget http://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 | - hash -r
30 | - conda config --set always_yes yes --set changeps1 no
31 | - conda config --add channels pandas
32 | - conda update -q conda
33 | # Useful for debugging any issues with conda
34 | - conda info -a
35 | - conda create -q -n test-environment python=$PYTHON nose coverage setuptools html5lib lxml
36 | - source activate test-environment
37 | - if [[ "$PANDAS" == "MASTER" ]]; then
38 | conda install bottleneck numpy pytz python-dateutil;
39 | PRE_WHEELS="https://7933911d6844c6c53a7d-47bd50c35cd79bd838daf386af554a83.ssl.cf2.rackcdn.com";
40 | pip install --pre --upgrade --timeout=60 -f $PRE_WHEELS pandas;
41 | else
42 | conda install bottleneck numpy pandas=$PANDAS;
43 | fi
44 |
45 | - pip install coveralls --quiet
46 | - conda list
47 | - python setup.py install
48 |
49 | script:
50 | - nosetests -v --with-coverage --cover-package=pandas_finance
51 |
52 | after_success:
53 | - coveralls
54 |
55 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | =======
2 | License
3 | =======
4 |
5 | pandas is distributed under a 3-clause ("Simplified" or "New") BSD
6 | license. Parts of NumPy, SciPy, numpydoc, bottleneck, which all have
7 | BSD-compatible licenses, are included. Their licenses follow the pandas
8 | license.
9 |
10 | pandas license
11 | ==============
12 |
13 | Copyright (c) 2011-2012, Lambda Foundry, Inc. and PyData Development Team
14 | All rights reserved.
15 |
16 | Copyright (c) 2008-2011 AQR Capital Management, LLC
17 | All rights reserved.
18 |
19 | Redistribution and use in source and binary forms, with or without
20 | modification, are permitted provided that the following conditions are
21 | met:
22 |
23 | * Redistributions of source code must retain the above copyright
24 | notice, this list of conditions and the following disclaimer.
25 |
26 | * Redistributions in binary form must reproduce the above
27 | copyright notice, this list of conditions and the following
28 | disclaimer in the documentation and/or other materials provided
29 | with the distribution.
30 |
31 | * Neither the name of the copyright holder nor the names of any
32 | contributors may be used to endorse or promote products derived
33 | from this software without specific prior written permission.
34 |
35 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS
36 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
37 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
38 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
39 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
41 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
42 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
43 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
44 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
45 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
46 |
47 | About the Copyright Holders
48 | ===========================
49 |
50 | AQR Capital Management began pandas development in 2008. Development was
51 | led by Wes McKinney. AQR released the source under this license in 2009.
52 | Wes is now an employee of Lambda Foundry, and remains the pandas project
53 | lead.
54 |
55 | The PyData Development Team is the collection of developers of the PyData
56 | project. This includes all of the PyData sub-projects, including pandas. The
57 | core team that coordinates development on GitHub can be found here:
58 | http://github.com/pydata.
59 |
60 | Full credits for pandas contributors can be found in the documentation.
61 |
62 | Our Copyright Policy
63 | ====================
64 |
65 | PyData uses a shared copyright model. Each contributor maintains copyright
66 | over their contributions to PyData. However, it is important to note that
67 | these contributions are typically only changes to the repositories. Thus,
68 | the PyData source code, in its entirety, is not the copyright of any single
69 | person or institution. Instead, it is the collective copyright of the
70 | entire PyData Development Team. If individual contributors want to maintain
71 | a record of what changes/contributions they have specific copyright on,
72 | they should indicate their copyright in the commit message of the change
73 | when they commit the change to one of the PyData repositories.
74 |
75 | With this in mind, the following banner should be used in any source code
76 | file to indicate the copyright and license terms:
77 |
78 | #-----------------------------------------------------------------------------
79 | # Copyright (c) 2012, PyData Development Team
80 | # All rights reserved.
81 | #
82 | # Distributed under the terms of the BSD Simplified License.
83 | #
84 | # The full license is in the LICENSE file, distributed with this software.
85 | #-----------------------------------------------------------------------------
86 |
87 | Other licenses can be found in the LICENSES directory.
88 |
--------------------------------------------------------------------------------
/MANIFEST.in:
--------------------------------------------------------------------------------
1 | include README.rst
2 | include LICENSE.md
3 | include pandas_finance/*.py
4 |
5 | include pandas_finance/tests/*.py
6 | include pandas_finance/tests/data/*
7 |
--------------------------------------------------------------------------------
/README.rst:
--------------------------------------------------------------------------------
1 | pandas-finance
2 | =================
3 |
4 | High level API for access to and analysis of financial data.
5 |
6 | .. image:: https://travis-ci.org/davidastephens/pandas-finance.svg?branch=master
7 | :target: https://travis-ci.org/davidastephens/pandas-finance
8 |
9 | .. image:: https://coveralls.io/repos/davidastephens/pandas-finance/badge.svg?branch=master
10 | :target: https://coveralls.io/r/davidastephens/pandas-finance
11 |
12 | .. image:: https://readthedocs.org/projects/pandas-finance/badge/?version=latest
13 | :target: http://pandas-finance.readthedocs.org/en/latest/
14 |
15 | Installation
16 | ------------
17 |
18 | Install via pip
19 |
20 | .. code-block:: shell
21 |
22 | $ pip install pandas-finance
23 |
24 | Usage
25 | -----
26 |
27 | .. code-block:: python
28 |
29 | from pandas_finance import Equity
30 | aapl = Equity('AAPL')
31 | aapl.annual_dividend
32 | aapl.dividend_yield
33 | aapl.price
34 | aapl.options
35 | aapl.hist_vol(30)
36 | aapl.rolling_hist_vol(30)
37 |
38 | Data is automatically cached for 1 hr using requests_cache.
39 |
40 | See the `pandas-finance documentation `_ for more details.
41 |
--------------------------------------------------------------------------------
/docs/Makefile:
--------------------------------------------------------------------------------
1 | # Makefile for Sphinx documentation
2 | #
3 |
4 | # You can set these variables from the command line.
5 | SPHINXOPTS =
6 | SPHINXBUILD = sphinx-build
7 | PAPER =
8 | BUILDDIR = build
9 |
10 | # User-friendly check for sphinx-build
11 | ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1)
12 | $(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/)
13 | endif
14 |
15 | # Internal variables.
16 | PAPEROPT_a4 = -D latex_paper_size=a4
17 | PAPEROPT_letter = -D latex_paper_size=letter
18 | ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source
19 | # the i18n builder cannot share the environment and doctrees with the others
20 | I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source
21 |
22 | .PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext
23 |
24 | help:
25 | @echo "Please use \`make ' where is one of"
26 | @echo " html to make standalone HTML files"
27 | @echo " dirhtml to make HTML files named index.html in directories"
28 | @echo " singlehtml to make a single large HTML file"
29 | @echo " pickle to make pickle files"
30 | @echo " json to make JSON files"
31 | @echo " htmlhelp to make HTML files and a HTML help project"
32 | @echo " qthelp to make HTML files and a qthelp project"
33 | @echo " devhelp to make HTML files and a Devhelp project"
34 | @echo " epub to make an epub"
35 | @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
36 | @echo " latexpdf to make LaTeX files and run them through pdflatex"
37 | @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx"
38 | @echo " text to make text files"
39 | @echo " man to make manual pages"
40 | @echo " texinfo to make Texinfo files"
41 | @echo " info to make Texinfo files and run them through makeinfo"
42 | @echo " gettext to make PO message catalogs"
43 | @echo " changes to make an overview of all changed/added/deprecated items"
44 | @echo " xml to make Docutils-native XML files"
45 | @echo " pseudoxml to make pseudoxml-XML files for display purposes"
46 | @echo " linkcheck to check all external links for integrity"
47 | @echo " doctest to run all doctests embedded in the documentation (if enabled)"
48 |
49 | clean:
50 | rm -rf $(BUILDDIR)/*
51 |
52 | html:
53 | $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
54 | @echo
55 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
56 |
57 | dirhtml:
58 | $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
59 | @echo
60 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
61 |
62 | singlehtml:
63 | $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
64 | @echo
65 | @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
66 |
67 | pickle:
68 | $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
69 | @echo
70 | @echo "Build finished; now you can process the pickle files."
71 |
72 | json:
73 | $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
74 | @echo
75 | @echo "Build finished; now you can process the JSON files."
76 |
77 | htmlhelp:
78 | $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
79 | @echo
80 | @echo "Build finished; now you can run HTML Help Workshop with the" \
81 | ".hhp project file in $(BUILDDIR)/htmlhelp."
82 |
83 | qthelp:
84 | $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
85 | @echo
86 | @echo "Build finished; now you can run "qcollectiongenerator" with the" \
87 | ".qhcp project file in $(BUILDDIR)/qthelp, like this:"
88 | @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/pandas-finance.qhcp"
89 | @echo "To view the help file:"
90 | @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/pandas-finance.qhc"
91 |
92 | devhelp:
93 | $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
94 | @echo
95 | @echo "Build finished."
96 | @echo "To view the help file:"
97 | @echo "# mkdir -p $$HOME/.local/share/devhelp/pandas-finance"
98 | @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/pandas-finance"
99 | @echo "# devhelp"
100 |
101 | epub:
102 | $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
103 | @echo
104 | @echo "Build finished. The epub file is in $(BUILDDIR)/epub."
105 |
106 | latex:
107 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
108 | @echo
109 | @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
110 | @echo "Run \`make' in that directory to run these through (pdf)latex" \
111 | "(use \`make latexpdf' here to do that automatically)."
112 |
113 | latexpdf:
114 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
115 | @echo "Running LaTeX files through pdflatex..."
116 | $(MAKE) -C $(BUILDDIR)/latex all-pdf
117 | @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
118 |
119 | latexpdfja:
120 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
121 | @echo "Running LaTeX files through platex and dvipdfmx..."
122 | $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja
123 | @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
124 |
125 | text:
126 | $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
127 | @echo
128 | @echo "Build finished. The text files are in $(BUILDDIR)/text."
129 |
130 | man:
131 | $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
132 | @echo
133 | @echo "Build finished. The manual pages are in $(BUILDDIR)/man."
134 |
135 | texinfo:
136 | $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
137 | @echo
138 | @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
139 | @echo "Run \`make' in that directory to run these through makeinfo" \
140 | "(use \`make info' here to do that automatically)."
141 |
142 | info:
143 | $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
144 | @echo "Running Texinfo files through makeinfo..."
145 | make -C $(BUILDDIR)/texinfo info
146 | @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
147 |
148 | gettext:
149 | $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
150 | @echo
151 | @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
152 |
153 | changes:
154 | $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
155 | @echo
156 | @echo "The overview file is in $(BUILDDIR)/changes."
157 |
158 | linkcheck:
159 | $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
160 | @echo
161 | @echo "Link check complete; look for any errors in the above output " \
162 | "or in $(BUILDDIR)/linkcheck/output.txt."
163 |
164 | doctest:
165 | $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
166 | @echo "Testing of doctests in the sources finished, look at the " \
167 | "results in $(BUILDDIR)/doctest/output.txt."
168 |
169 | xml:
170 | $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml
171 | @echo
172 | @echo "Build finished. The XML files are in $(BUILDDIR)/xml."
173 |
174 | pseudoxml:
175 | $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml
176 | @echo
177 | @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml."
178 |
--------------------------------------------------------------------------------
/docs/make.bat:
--------------------------------------------------------------------------------
1 | @ECHO OFF
2 |
3 | REM Command file for Sphinx documentation
4 |
5 | if "%SPHINXBUILD%" == "" (
6 | set SPHINXBUILD=sphinx-build
7 | )
8 | set BUILDDIR=build
9 | set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% source
10 | set I18NSPHINXOPTS=%SPHINXOPTS% source
11 | if NOT "%PAPER%" == "" (
12 | set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
13 | set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS%
14 | )
15 |
16 | if "%1" == "" goto help
17 |
18 | if "%1" == "help" (
19 | :help
20 | echo.Please use `make ^` where ^ is one of
21 | echo. html to make standalone HTML files
22 | echo. dirhtml to make HTML files named index.html in directories
23 | echo. singlehtml to make a single large HTML file
24 | echo. pickle to make pickle files
25 | echo. json to make JSON files
26 | echo. htmlhelp to make HTML files and a HTML help project
27 | echo. qthelp to make HTML files and a qthelp project
28 | echo. devhelp to make HTML files and a Devhelp project
29 | echo. epub to make an epub
30 | echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter
31 | echo. text to make text files
32 | echo. man to make manual pages
33 | echo. texinfo to make Texinfo files
34 | echo. gettext to make PO message catalogs
35 | echo. changes to make an overview over all changed/added/deprecated items
36 | echo. xml to make Docutils-native XML files
37 | echo. pseudoxml to make pseudoxml-XML files for display purposes
38 | echo. linkcheck to check all external links for integrity
39 | echo. doctest to run all doctests embedded in the documentation if enabled
40 | goto end
41 | )
42 |
43 | if "%1" == "clean" (
44 | for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
45 | del /q /s %BUILDDIR%\*
46 | goto end
47 | )
48 |
49 |
50 | %SPHINXBUILD% 2> nul
51 | if errorlevel 9009 (
52 | echo.
53 | echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
54 | echo.installed, then set the SPHINXBUILD environment variable to point
55 | echo.to the full path of the 'sphinx-build' executable. Alternatively you
56 | echo.may add the Sphinx directory to PATH.
57 | echo.
58 | echo.If you don't have Sphinx installed, grab it from
59 | echo.http://sphinx-doc.org/
60 | exit /b 1
61 | )
62 |
63 | if "%1" == "html" (
64 | %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
65 | if errorlevel 1 exit /b 1
66 | echo.
67 | echo.Build finished. The HTML pages are in %BUILDDIR%/html.
68 | goto end
69 | )
70 |
71 | if "%1" == "dirhtml" (
72 | %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
73 | if errorlevel 1 exit /b 1
74 | echo.
75 | echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
76 | goto end
77 | )
78 |
79 | if "%1" == "singlehtml" (
80 | %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml
81 | if errorlevel 1 exit /b 1
82 | echo.
83 | echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.
84 | goto end
85 | )
86 |
87 | if "%1" == "pickle" (
88 | %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
89 | if errorlevel 1 exit /b 1
90 | echo.
91 | echo.Build finished; now you can process the pickle files.
92 | goto end
93 | )
94 |
95 | if "%1" == "json" (
96 | %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
97 | if errorlevel 1 exit /b 1
98 | echo.
99 | echo.Build finished; now you can process the JSON files.
100 | goto end
101 | )
102 |
103 | if "%1" == "htmlhelp" (
104 | %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
105 | if errorlevel 1 exit /b 1
106 | echo.
107 | echo.Build finished; now you can run HTML Help Workshop with the ^
108 | .hhp project file in %BUILDDIR%/htmlhelp.
109 | goto end
110 | )
111 |
112 | if "%1" == "qthelp" (
113 | %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
114 | if errorlevel 1 exit /b 1
115 | echo.
116 | echo.Build finished; now you can run "qcollectiongenerator" with the ^
117 | .qhcp project file in %BUILDDIR%/qthelp, like this:
118 | echo.^> qcollectiongenerator %BUILDDIR%\qthelp\pandas-finance.qhcp
119 | echo.To view the help file:
120 | echo.^> assistant -collectionFile %BUILDDIR%\qthelp\pandas-finance.ghc
121 | goto end
122 | )
123 |
124 | if "%1" == "devhelp" (
125 | %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp
126 | if errorlevel 1 exit /b 1
127 | echo.
128 | echo.Build finished.
129 | goto end
130 | )
131 |
132 | if "%1" == "epub" (
133 | %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub
134 | if errorlevel 1 exit /b 1
135 | echo.
136 | echo.Build finished. The epub file is in %BUILDDIR%/epub.
137 | goto end
138 | )
139 |
140 | if "%1" == "latex" (
141 | %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
142 | if errorlevel 1 exit /b 1
143 | echo.
144 | echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
145 | goto end
146 | )
147 |
148 | if "%1" == "latexpdf" (
149 | %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
150 | cd %BUILDDIR%/latex
151 | make all-pdf
152 | cd %BUILDDIR%/..
153 | echo.
154 | echo.Build finished; the PDF files are in %BUILDDIR%/latex.
155 | goto end
156 | )
157 |
158 | if "%1" == "latexpdfja" (
159 | %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
160 | cd %BUILDDIR%/latex
161 | make all-pdf-ja
162 | cd %BUILDDIR%/..
163 | echo.
164 | echo.Build finished; the PDF files are in %BUILDDIR%/latex.
165 | goto end
166 | )
167 |
168 | if "%1" == "text" (
169 | %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text
170 | if errorlevel 1 exit /b 1
171 | echo.
172 | echo.Build finished. The text files are in %BUILDDIR%/text.
173 | goto end
174 | )
175 |
176 | if "%1" == "man" (
177 | %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man
178 | if errorlevel 1 exit /b 1
179 | echo.
180 | echo.Build finished. The manual pages are in %BUILDDIR%/man.
181 | goto end
182 | )
183 |
184 | if "%1" == "texinfo" (
185 | %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo
186 | if errorlevel 1 exit /b 1
187 | echo.
188 | echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo.
189 | goto end
190 | )
191 |
192 | if "%1" == "gettext" (
193 | %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale
194 | if errorlevel 1 exit /b 1
195 | echo.
196 | echo.Build finished. The message catalogs are in %BUILDDIR%/locale.
197 | goto end
198 | )
199 |
200 | if "%1" == "changes" (
201 | %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
202 | if errorlevel 1 exit /b 1
203 | echo.
204 | echo.The overview file is in %BUILDDIR%/changes.
205 | goto end
206 | )
207 |
208 | if "%1" == "linkcheck" (
209 | %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
210 | if errorlevel 1 exit /b 1
211 | echo.
212 | echo.Link check complete; look for any errors in the above output ^
213 | or in %BUILDDIR%/linkcheck/output.txt.
214 | goto end
215 | )
216 |
217 | if "%1" == "doctest" (
218 | %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
219 | if errorlevel 1 exit /b 1
220 | echo.
221 | echo.Testing of doctests in the sources finished, look at the ^
222 | results in %BUILDDIR%/doctest/output.txt.
223 | goto end
224 | )
225 |
226 | if "%1" == "xml" (
227 | %SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml
228 | if errorlevel 1 exit /b 1
229 | echo.
230 | echo.Build finished. The XML files are in %BUILDDIR%/xml.
231 | goto end
232 | )
233 |
234 | if "%1" == "pseudoxml" (
235 | %SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml
236 | if errorlevel 1 exit /b 1
237 | echo.
238 | echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml.
239 | goto end
240 | )
241 |
242 | :end
243 |
--------------------------------------------------------------------------------
/docs/source/conf.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | #
3 | # pandas-finance documentation build configuration file, created by
4 | # sphinx-quickstart on Sun Nov 22 14:31:26 2015.
5 | #
6 | # This file is execfile()d with the current directory set to its
7 | # containing dir.
8 | #
9 | # Note that not all possible configuration values are present in this
10 | # autogenerated file.
11 | #
12 | # All configuration values have a default; values that are commented out
13 | # serve to show the default.
14 |
15 | import sys
16 | import os
17 |
18 | # If extensions (or modules to document with autodoc) are in another directory,
19 | # add these directories to sys.path here. If the directory is relative to the
20 | # documentation root, use os.path.abspath to make it absolute, like shown here.
21 | #sys.path.insert(0, os.path.abspath('.'))
22 |
23 | # -- General configuration ------------------------------------------------
24 |
25 | # If your documentation needs a minimal Sphinx version, state it here.
26 | #needs_sphinx = '1.0'
27 |
28 | # Add any Sphinx extension module names here, as strings. They can be
29 | # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
30 | # ones.
31 | extensions = [
32 | 'sphinx.ext.autodoc',
33 | 'sphinx.ext.doctest',
34 | 'sphinx.ext.viewcode',
35 | ]
36 |
37 | # Add any paths that contain templates here, relative to this directory.
38 | templates_path = ['_templates']
39 |
40 | # The suffix of source filenames.
41 | source_suffix = '.rst'
42 |
43 | # The encoding of source files.
44 | #source_encoding = 'utf-8-sig'
45 |
46 | # The master toctree document.
47 | master_doc = 'index'
48 |
49 | # General information about the project.
50 | project = u'pandas-finance'
51 | copyright = u'2015, David Stephens'
52 |
53 | # The version info for the project you're documenting, acts as replacement for
54 | # |version| and |release|, also used in various other places throughout the
55 | # built documents.
56 | #
57 | # The short X.Y version.
58 | version = '0.1.0'
59 | # The full version, including alpha/beta/rc tags.
60 | release = '0.1.0'
61 |
62 | # The language for content autogenerated by Sphinx. Refer to documentation
63 | # for a list of supported languages.
64 | #language = None
65 |
66 | # There are two options for replacing |today|: either, you set today to some
67 | # non-false value, then it is used:
68 | #today = ''
69 | # Else, today_fmt is used as the format for a strftime call.
70 | #today_fmt = '%B %d, %Y'
71 |
72 | # List of patterns, relative to source directory, that match files and
73 | # directories to ignore when looking for source files.
74 | exclude_patterns = []
75 |
76 | # The reST default role (used for this markup: `text`) to use for all
77 | # documents.
78 | #default_role = None
79 |
80 | # If true, '()' will be appended to :func: etc. cross-reference text.
81 | #add_function_parentheses = True
82 |
83 | # If true, the current module name will be prepended to all description
84 | # unit titles (such as .. function::).
85 | #add_module_names = True
86 |
87 | # If true, sectionauthor and moduleauthor directives will be shown in the
88 | # output. They are ignored by default.
89 | #show_authors = False
90 |
91 | # The name of the Pygments (syntax highlighting) style to use.
92 | pygments_style = 'sphinx'
93 |
94 | # A list of ignored prefixes for module index sorting.
95 | #modindex_common_prefix = []
96 |
97 | # If true, keep warnings as "system message" paragraphs in the built documents.
98 | #keep_warnings = False
99 |
100 |
101 | # -- Options for HTML output ----------------------------------------------
102 |
103 | # The theme to use for HTML and HTML Help pages. See the documentation for
104 | # a list of builtin themes.
105 | html_theme = 'default'
106 |
107 | # Theme options are theme-specific and customize the look and feel of a theme
108 | # further. For a list of options available for each theme, see the
109 | # documentation.
110 | #html_theme_options = {}
111 |
112 | # Add any paths that contain custom themes here, relative to this directory.
113 | #html_theme_path = []
114 |
115 | # The name for this set of Sphinx documents. If None, it defaults to
116 | # " v documentation".
117 | #html_title = None
118 |
119 | # A shorter title for the navigation bar. Default is the same as html_title.
120 | #html_short_title = None
121 |
122 | # The name of an image file (relative to this directory) to place at the top
123 | # of the sidebar.
124 | #html_logo = None
125 |
126 | # The name of an image file (within the static path) to use as favicon of the
127 | # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
128 | # pixels large.
129 | #html_favicon = None
130 |
131 | # Add any paths that contain custom static files (such as style sheets) here,
132 | # relative to this directory. They are copied after the builtin static files,
133 | # so a file named "default.css" will overwrite the builtin "default.css".
134 | html_static_path = ['_static']
135 |
136 | # Add any extra paths that contain custom files (such as robots.txt or
137 | # .htaccess) here, relative to this directory. These files are copied
138 | # directly to the root of the documentation.
139 | #html_extra_path = []
140 |
141 | # If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
142 | # using the given strftime format.
143 | #html_last_updated_fmt = '%b %d, %Y'
144 |
145 | # If true, SmartyPants will be used to convert quotes and dashes to
146 | # typographically correct entities.
147 | #html_use_smartypants = True
148 |
149 | # Custom sidebar templates, maps document names to template names.
150 | #html_sidebars = {}
151 |
152 | # Additional templates that should be rendered to pages, maps page names to
153 | # template names.
154 | #html_additional_pages = {}
155 |
156 | # If false, no module index is generated.
157 | #html_domain_indices = True
158 |
159 | # If false, no index is generated.
160 | #html_use_index = True
161 |
162 | # If true, the index is split into individual pages for each letter.
163 | #html_split_index = False
164 |
165 | # If true, links to the reST sources are added to the pages.
166 | #html_show_sourcelink = True
167 |
168 | # If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
169 | #html_show_sphinx = True
170 |
171 | # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
172 | #html_show_copyright = True
173 |
174 | # If true, an OpenSearch description file will be output, and all pages will
175 | # contain a tag referring to it. The value of this option must be the
176 | # base URL from which the finished HTML is served.
177 | #html_use_opensearch = ''
178 |
179 | # This is the file name suffix for HTML files (e.g. ".xhtml").
180 | #html_file_suffix = None
181 |
182 | # Output file base name for HTML help builder.
183 | htmlhelp_basename = 'pandas-financedoc'
184 |
185 |
186 | # -- Options for LaTeX output ---------------------------------------------
187 |
188 | latex_elements = {
189 | # The paper size ('letterpaper' or 'a4paper').
190 | #'papersize': 'letterpaper',
191 |
192 | # The font size ('10pt', '11pt' or '12pt').
193 | #'pointsize': '10pt',
194 |
195 | # Additional stuff for the LaTeX preamble.
196 | #'preamble': '',
197 | }
198 |
199 | # Grouping the document tree into LaTeX files. List of tuples
200 | # (source start file, target name, title,
201 | # author, documentclass [howto, manual, or own class]).
202 | latex_documents = [
203 | ('index', 'pandas-finance.tex', u'pandas-finance Documentation',
204 | u'David Stephens', 'manual'),
205 | ]
206 |
207 | # The name of an image file (relative to this directory) to place at the top of
208 | # the title page.
209 | #latex_logo = None
210 |
211 | # For "manual" documents, if this is true, then toplevel headings are parts,
212 | # not chapters.
213 | #latex_use_parts = False
214 |
215 | # If true, show page references after internal links.
216 | #latex_show_pagerefs = False
217 |
218 | # If true, show URL addresses after external links.
219 | #latex_show_urls = False
220 |
221 | # Documents to append as an appendix to all manuals.
222 | #latex_appendices = []
223 |
224 | # If false, no module index is generated.
225 | #latex_domain_indices = True
226 |
227 |
228 | # -- Options for manual page output ---------------------------------------
229 |
230 | # One entry per manual page. List of tuples
231 | # (source start file, name, description, authors, manual section).
232 | man_pages = [
233 | ('index', 'pandas-finance', u'pandas-finance Documentation',
234 | [u'David Stephens'], 1)
235 | ]
236 |
237 | # If true, show URL addresses after external links.
238 | #man_show_urls = False
239 |
240 |
241 | # -- Options for Texinfo output -------------------------------------------
242 |
243 | # Grouping the document tree into Texinfo files. List of tuples
244 | # (source start file, target name, title, author,
245 | # dir menu entry, description, category)
246 | texinfo_documents = [
247 | ('index', 'pandas-finance', u'pandas-finance Documentation',
248 | u'David Stephens', 'pandas-finance', 'One line description of project.',
249 | 'Miscellaneous'),
250 | ]
251 |
252 | # Documents to append as an appendix to all manuals.
253 | #texinfo_appendices = []
254 |
255 | # If false, no module index is generated.
256 | #texinfo_domain_indices = True
257 |
258 | # How to display URL addresses: 'footnote', 'no', or 'inline'.
259 | #texinfo_show_urls = 'footnote'
260 |
261 | # If true, do not generate a @detailmenu in the "Top" node's menu.
262 | #texinfo_no_detailmenu = False
263 |
--------------------------------------------------------------------------------
/docs/source/index.rst:
--------------------------------------------------------------------------------
1 | .. pandas-finance documentation master file, created by
2 | sphinx-quickstart on Sun Nov 22 14:31:26 2015.
3 | You can adapt this file completely to your liking, but it should at least
4 | contain the root `toctree` directive.
5 |
6 | Welcome to pandas-finance's documentation!
7 | ==========================================
8 |
9 | Contents:
10 |
11 | .. toctree::
12 | :maxdepth: 2
13 |
14 |
15 |
16 | Indices and tables
17 | ==================
18 |
19 | * :ref:`genindex`
20 | * :ref:`modindex`
21 | * :ref:`search`
22 |
23 |
--------------------------------------------------------------------------------
/pandas_finance/__init__.py:
--------------------------------------------------------------------------------
1 | __version__ = version = '0.1.3'
2 |
3 | from .api import Equity, Option, OptionChain
4 |
--------------------------------------------------------------------------------
/pandas_finance/api.py:
--------------------------------------------------------------------------------
1 | import datetime
2 | import math
3 | import json
4 |
5 | import pandas as pd
6 | from pandas import DataFrame, Series
7 | from pandas_datareader.yahoo.quotes import YahooQuotesReader
8 | import yfinance as yf
9 |
10 | import pandas_datareader.data as pdr
11 | import requests_cache
12 | import empyrical
13 |
14 | TRADING_DAYS = 252
15 | CACHE_HRS = 1
16 | START_DATE = datetime.date(1990, 1, 1)
17 | QUERY_STRING = "https://query1.finance.yahoo.com/v10/finance/quoteSummary/{ticker}?lang=en-US®ion=US&modules={modules}&corsDomain=finance.yahoo.com"
18 | HEADERS = {
19 | "Connection": "keep-alive",
20 | "Expires": str(-1),
21 | "Upgrade-Insecure-Requests": str(1),
22 | # Google Chrome:
23 | "User-Agent": (
24 | "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 "
25 | "(KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36"
26 | ),
27 | }
28 | _DEFAULT_PARAMS = {
29 | "lang": "en-US",
30 | "corsDomain": "finance.yahoo.com",
31 | ".tsrc": "finance",
32 | }
33 |
34 |
35 | class FixedYahooQuotesReader(YahooQuotesReader):
36 | def __init__(self, *args, crumb=None, **kwargs):
37 | super(FixedYahooQuotesReader, self).__init__(*args, **kwargs)
38 | self.crumb = crumb
39 | def params(self, symbol):
40 | params = super().params(symbol)
41 | params.update({"crumb": self.crumb})
42 | return params
43 | def _read_lines(self, out):
44 | data = json.loads(out.read())["quoteResponse"]["result"][0]
45 | idx = data.pop('symbol')
46 | data["price"] = data["regularMarketPrice"]
47 | return Series(data)
48 |
49 |
50 | class Equity(object):
51 | def __init__(self, ticker, session=None):
52 | self.ticker = ticker
53 | self.yf_ticker = yf.Ticker(self.ticker)
54 |
55 | if session:
56 | self._session = session
57 | else:
58 | self._session = self._get_session()
59 | with self._session.cache_disabled():
60 | self.crumb = self._session.get(
61 | 'https://query1.finance.yahoo.com/v1/test/getcrumb').text
62 |
63 | def _get_session(self):
64 | session = requests_cache.CachedSession(
65 | cache_name="pf-cache",
66 | backend="sqlite",
67 | expire_after=datetime.timedelta(hours=CACHE_HRS),
68 | )
69 | session.headers.update(HEADERS)
70 | with session.cache_disabled():
71 | session.get('https://fc.yahoo.com')
72 | return session
73 |
74 | @property
75 | def options(self):
76 | return OptionChain(self)
77 |
78 | @property
79 | def close(self):
80 | """Returns pandas series of closing price"""
81 | return self.trading_data["Close"]
82 |
83 | @property
84 | def adj_close(self):
85 | """Returns pandas series of closing price"""
86 | return self.trading_data["Adj Close"]
87 |
88 | @property
89 | def returns(self):
90 | return self.adj_close.pct_change()
91 |
92 | @property
93 | def trading_data(self):
94 | return self.yf_ticker.history(start=START_DATE)
95 |
96 | @property
97 | def actions(self):
98 | return pdr.get_data_yahoo_actions(
99 | self.ticker, session=self._session, start=START_DATE
100 | )
101 |
102 | @property
103 | def dividends(self):
104 | dividends = self.yf_ticker.get_dividends()
105 | dividends.name = "Dividends"
106 | return dividends
107 |
108 | @property
109 | def splits(self):
110 | splits = self.yf_ticker.get_splits()
111 | splits.name = "Splits"
112 | return splits
113 |
114 | @property
115 | def annual_dividend(self):
116 | if "forwardAnnualDividendRate" in self.quotes.index:
117 | return self.quotes["forwardAnnualDividendRate"]
118 | elif "trailingAnnualDividendRate" in self.quotes.index:
119 | return self.quotes["trailingAnnualDividendRate"]
120 | else:
121 | return 0
122 |
123 | @property
124 | def dividend_yield(self):
125 | return self.annual_dividend / self.price
126 |
127 | @property
128 | def price(self):
129 | return self.quotes["price"]
130 |
131 | @property
132 | def closed(self):
133 | "Market is closed or open"
134 | return self.quotes["marketState"].lower() == "closed"
135 |
136 | @property
137 | def currency(self):
138 | return self.quotes["currency"]
139 |
140 | @property
141 | def market_cap(self):
142 | return float(self.quotes["marketCap"])
143 |
144 | @property
145 | def shares_os(self):
146 | return int(self.quotes["sharesOutstanding"])
147 |
148 | def hist_vol(self, days, end_date=None):
149 | days = int(days)
150 | if end_date:
151 | data = self.returns[:end_date]
152 | else:
153 | data = self.returns
154 | data = data.iloc[-days:]
155 | return data.std() * math.sqrt(TRADING_DAYS)
156 |
157 | def rolling_hist_vol(self, days, end_date=None):
158 | days = int(days)
159 | if end_date:
160 | data = self.returns[:end_date]
161 | else:
162 | data = self.returns
163 | return data.rolling(days).std() * math.sqrt(TRADING_DAYS)
164 |
165 | @property
166 | def profile(self):
167 | response = self._session.get(
168 | QUERY_STRING.format(ticker=self.ticker, modules="assetProfile")
169 | ).json()
170 | asset_profile = response["quoteSummary"]["result"][0]["assetProfile"]
171 | del asset_profile["companyOfficers"]
172 | profile = pd.DataFrame.from_dict(asset_profile, orient="index")[0]
173 | profile.name = ""
174 | profile.index = [name.capitalize() for name in profile.index]
175 | rename = {"Fulltimeemployees": "Full Time Employees"}
176 | profile.rename(index=rename, inplace=True)
177 |
178 | return profile
179 |
180 | @property
181 | def quotes(self):
182 | return FixedYahooQuotesReader(self.ticker, session=self._session, crumb=self.crumb).read()
183 |
184 | @property
185 | def quote(self):
186 | return self.quotes
187 |
188 | @property
189 | def sector(self):
190 | return self.profile["Sector"]
191 |
192 | @property
193 | def industry(self):
194 | return self.profile["Industry"]
195 |
196 | @property
197 | def employees(self):
198 | return self.profile["Full Time Employees"]
199 |
200 | @property
201 | def name(self):
202 | return self.quotes["longName"]
203 |
204 | def alpha_beta(self, index, start=None, end=None):
205 | index_rets = Equity(index).returns
206 | rets = self.returns
207 | data = pd.DataFrame()
208 | data["Index"] = index_rets
209 | data["Rets"] = rets
210 | data = data.fillna(0)
211 |
212 | if start:
213 | data = data[start:]
214 | if end:
215 | data = data[start:end]
216 |
217 | return empyrical.alpha_beta(data["Rets"], data["Index"])
218 |
219 | def beta(self, index, start=None, end=None):
220 | alpha, beta = self.alpha_beta(index, start, end)
221 | return beta
222 |
223 | def alpha(self, index, start=None, end=None):
224 | alpha, beta = self.alpha_beta(index, start, end)
225 | return alpha
226 |
227 | def vwap(self, end_date=None, days=30):
228 | days = int(days)
229 | if end_date:
230 | data = self.trading_data[:end_date]
231 | else:
232 | data = self.trading_data
233 | data = data.iloc[-days:]
234 | return (data["Close"] * data["Volume"]).sum() / data["Volume"].sum()
235 |
236 | def hist_vol_by_days(self, end_date=None, min_days=10, max_days=600):
237 | "Returns the historical vol for a range of trading days ending on end_date."
238 | min_days = int(min_days)
239 | max_days = int(max_days)
240 | if end_date:
241 | returns = self.returns[:end_date]
242 | else:
243 | returns = self.returns
244 |
245 | output = {}
246 | for i in range(min_days, max_days):
247 | output[i] = returns[-i:].std() * math.sqrt(TRADING_DAYS)
248 |
249 | return pd.Series(output)
250 |
251 |
252 | class Option(object):
253 | def __init__(self):
254 | pass
255 |
256 |
257 | class OptionChain(object):
258 | def __init__(self, underlying):
259 | self.underlying = underlying
260 | self._session = self.underlying._session
261 | self._pdr = pdr.Options(self.underlying.ticker, "yahoo", session=self._session)
262 |
263 | @property
264 | def all_data(self):
265 | return self._pdr.get_all_data()
266 |
267 | @property
268 | def calls(self):
269 | data = self.all_data
270 | mask = data.index.get_level_values("Type") == "calls"
271 | return data[mask]
272 |
273 | @property
274 | def puts(self):
275 | data = self.all_data
276 | mask = data.index.get_level_values("Type") == "puts"
277 | return data[mask]
278 |
279 | @property
280 | def near_puts(self):
281 | return self._pdr._chop_data(self.puts, 5, self.underlying.price)
282 |
283 | @property
284 | def near_calls(self):
285 | return self._pdr._chop_data(self.calls, 5, self.underlying.price)
286 |
287 | def __getattr__(self, key):
288 | if hasattr(self._pdr, key):
289 | return getattr(self._pdr, key)
290 |
291 | def __dir__(self):
292 | return sorted(set((dir(type(self)) + list(self.__dict__) + dir(self._pdr))))
293 |
--------------------------------------------------------------------------------
/pandas_finance/tests/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davidastephens/pandas-finance/d58e64f893a7ec267106b2c265cd9b4d0b189d4e/pandas_finance/tests/__init__.py
--------------------------------------------------------------------------------
/pandas_finance/tests/nosy.cfg:
--------------------------------------------------------------------------------
1 | #sample config file section for nosy
2 |
3 | # Including this file in the paths to check allows you to change
4 | # nose's behaviour on the fly.
5 |
6 | [nosy]
7 | # Paths to check for changed files; changes cause nose to be run
8 | base_path = ./
9 | glob_patterns = *.py
10 | exclude_patterns = *_flymake.*
11 | extra_paths = nosy.cfg
12 | # Command line options to pass to nose
13 | options =
14 | # Command line arguments to pass to nose; e.g. part of test suite to run
15 | tests =
16 |
--------------------------------------------------------------------------------
/pandas_finance/tests/test_api.py:
--------------------------------------------------------------------------------
1 | import datetime
2 | import unittest
3 |
4 | import pandas as pd
5 |
6 | from pandas_finance import Equity, OptionChain
7 |
8 |
9 | class TestEquity(unittest.TestCase):
10 | @classmethod
11 | def setUpClass(cls):
12 | cls.aapl = Equity("AAPL")
13 | cls.date = datetime.date(2013, 1, 25)
14 | cls.tsla = Equity("TSLA")
15 |
16 | def test_equity_price(self):
17 | self.assertAlmostEqual(self.aapl.close[self.date], 62.84, 2)
18 |
19 | def test_historical_vol(self):
20 | vol = self.aapl.hist_vol(30, end_date=self.date)
21 | self.assertAlmostEqual(vol, 0.484, 3)
22 |
23 | @unittest.skip("Yahoo options api broken")
24 | def test_options(self):
25 | self.assertIsInstance(self.aapl.options, OptionChain)
26 |
27 | def test_annual_dividend(self):
28 | self.assertEqual(self.aapl.annual_dividend, 3.00)
29 | self.assertEqual(self.tsla.annual_dividend, 0)
30 |
31 | def test_dividends(self):
32 | self.assertEqual(self.aapl.dividends[datetime.date(2015, 11, 5)], 0.52)
33 |
34 | def test_splits(self):
35 | self.assertAlmostEqual(self.aapl.splits[datetime.date(2014, 6, 9)], 0.142857, 5)
36 |
37 | def test_dividends_no_data(self):
38 | self.assertEqual(len(self.tsla.dividends), 0)
39 |
40 | def test_price(self):
41 | self.assertIsInstance(self.aapl.price, float)
42 |
43 | def test_sector(self):
44 | self.assertEqual(self.aapl.sector, "Technology")
45 |
46 | def test_employees(self):
47 | self.assertGreaterEqual(self.aapl.employees, 100000)
48 |
49 | def test_industry(self):
50 | self.assertEqual(self.aapl.industry, "Consumer Electronics")
51 |
52 | def test_name(self):
53 | self.assertEqual(self.aapl.name, "Apple Inc.")
54 |
55 | def test_quotes(self):
56 | self.assertIsInstance(self.aapl.quotes["price"], float)
57 |
58 | def test_quote(self):
59 | self.assertIsInstance(self.aapl.quote["price"], float)
60 |
61 | def test_shares_os(self):
62 | self.assertIsInstance(self.aapl.shares_os, int)
63 |
64 | def test_market_cap(self):
65 | self.assertIsInstance(self.aapl.market_cap, float)
66 |
67 | def test_closed(self):
68 | self.assertIsInstance(self.aapl.closed, bool)
69 |
70 | def test_currency(self):
71 | self.assertEqual(self.aapl.currency, "USD")
72 |
73 | def test_rolling_hist_vol(self):
74 | self.assertIsInstance(self.aapl.rolling_hist_vol(20), pd.Series)
75 | self.assertAlmostEqual(self.aapl.rolling_hist_vol(20)[self.date], 0.562, 3)
76 |
77 | def test_hist_vol_by_days(self):
78 | self.assertIsInstance(self.aapl.hist_vol_by_days(), pd.Series)
79 | self.assertAlmostEqual(self.aapl.hist_vol_by_days(self.date)[20], 0.562, 3)
80 |
81 |
82 | class TestOptionChain(unittest.TestCase):
83 | @classmethod
84 | @unittest.skip("Skip option tests due to broken yahoo api")
85 | def setUpClass(cls):
86 | cls.aapl = Equity("AAPL")
87 | cls.options = OptionChain(cls.aapl)
88 |
89 | def test_options(self):
90 | self.assertIsInstance(self.options.all_data, pd.DataFrame)
91 |
92 | def test_calls(self):
93 | self.assertIsInstance(self.options.calls, pd.DataFrame)
94 | self.assertTrue(
95 | (self.options.calls.index.get_level_values("Type") == "calls").all()
96 | )
97 |
98 | def test_puts(self):
99 | self.assertIsInstance(self.options.puts, pd.DataFrame)
100 | self.assertTrue(
101 | (self.options.puts.index.get_level_values("Type") == "puts").all()
102 | )
103 |
104 | def test_near_calls(self):
105 | self.assertIsInstance(self.options.near_calls, pd.DataFrame)
106 | self.assertTrue(
107 | (self.options.near_calls.index.get_level_values("Type") == "calls").all()
108 | )
109 |
110 | def test_near_puts(self):
111 | self.assertIsInstance(self.options.near_puts, pd.DataFrame)
112 | self.assertTrue(
113 | (self.options.near_puts.index.get_level_values("Type") == "puts").all()
114 | )
115 |
116 |
117 | class TestOption(unittest.TestCase):
118 | @classmethod
119 | @unittest.skip("Skip option tests due to broken yahoo api")
120 | def setUpClass(cls):
121 | cls.aapl = Equity("AAPL")
122 | cls.options = OptionChain(cls.aapl)
123 |
124 | def test_options(self):
125 | self.options.all_data
126 |
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | pandas
2 | requests-cache
3 | pandas-datareader>=0.7.0
4 | empyrical
5 | yfinance
6 |
7 |
--------------------------------------------------------------------------------
/setup.cfg:
--------------------------------------------------------------------------------
1 | [bdist_wheel]
2 | universal = 1
--------------------------------------------------------------------------------
/setup.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | from ast import parse
5 | import os
6 | from setuptools import setup, find_packages
7 |
8 |
9 | NAME = 'pandas-finance'
10 |
11 |
12 | def version():
13 | """Return version string."""
14 | with open(os.path.join(os.path.abspath(os.path.dirname(__file__)),
15 | 'pandas_finance',
16 | '__init__.py')) as input_file:
17 | for line in input_file:
18 | if line.startswith('__version__'):
19 | return parse(line).body[0].value.s
20 |
21 |
22 | def readme():
23 | with open('README.rst') as f:
24 | return f.read()
25 |
26 | install_requires = []
27 | with open("./requirements.txt") as f:
28 | install_requires = f.read().splitlines()
29 |
30 | setup(
31 | name=NAME,
32 | version=version(),
33 | description="High level API for access to and analysis of financial data.",
34 | long_description=readme(),
35 | license='BSD License',
36 | author='David Stephens',
37 | author_email='david@davidstephens.io',
38 | url='https://github.com/davidastephens/pandas-finance',
39 | classifiers=[
40 | 'Development Status :: 1 - Planning',
41 | 'Environment :: Console',
42 | 'Intended Audience :: Science/Research',
43 | 'Operating System :: OS Independent',
44 | 'Programming Language :: Cython',
45 | 'Programming Language :: Python',
46 | 'Programming Language :: Python :: 2',
47 | 'Programming Language :: Python :: 2.7',
48 | 'Programming Language :: Python :: 3',
49 | 'Programming Language :: Python :: 3.2',
50 | 'Programming Language :: Python :: 3.3',
51 | 'Programming Language :: Python :: 3.4',
52 | 'Programming Language :: Python :: 3.5',
53 | 'Programming Language :: Python :: 3.6',
54 | 'Topic :: Scientific/Engineering',
55 | ],
56 | keywords='data',
57 | install_requires=install_requires,
58 | packages=find_packages(exclude=['contrib', 'docs', 'tests*']),
59 | test_suite='tests',
60 | zip_safe=False,
61 | )
62 |
--------------------------------------------------------------------------------
/tox.ini:
--------------------------------------------------------------------------------
1 | [tox]
2 | envlist=py{26,27,32,33,34}
3 |
4 | [testenv]
5 | commands=
6 | nosetests
7 | deps=
8 | nose
9 |
10 | [testenv:py26]
11 | deps=
12 | unittest2
13 | {[testenv]deps}
14 |
--------------------------------------------------------------------------------