Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Binary packages, cleanups. #500

Draft
wants to merge 23 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
a461266
Move tests outside of the main package.
TkTech Feb 13, 2022
68c9180
Remove an overly aggressive .gitignore rule.
TkTech Feb 13, 2022
99359d5
Add binary package builds for py3.7+.
TkTech Feb 13, 2022
7933940
Speedup tests by only compiling ta-lib once.
TkTech Feb 13, 2022
a85fe02
Cleanup tests.
TkTech Feb 13, 2022
aa8db03
Working on release workflow.
TkTech Feb 13, 2022
c6d0ae3
Whatever github ci is running on gives less precise floating point re…
TkTech May 18, 2022
451747a
Try to simplify precision tests.
TkTech May 18, 2022
0b87c07
Squashed 'talib/upstream/' content from commit 4433a5b
TkTech May 18, 2022
87fc0ad
Merge commit '0b87c07bc229e49b8ee96dbc41d79c81d8a3ccdf' as 'talib/ups…
TkTech May 18, 2022
43d19e1
Completely bundle upstream ta-lib.
TkTech May 18, 2022
47d7508
Use requirements_tests.txt for all test reqs
TkTech May 18, 2022
ecc0369
Always use absolute imports for _ta_lib, which works properly on all …
TkTech May 18, 2022
38d75b8
Revert "Always use absolute imports for _ta_lib, which works properly…
TkTech May 18, 2022
c4e94bd
Trying to work around pip oddity
TkTech May 18, 2022
7680320
Do _not_ install polars which is 64bit only..
TkTech May 18, 2022
34331c1
Only test on >= py3.7, which is the oldest version still supported.
TkTech May 19, 2022
0e23258
Try splitting up our builds into more parallel tasks.
TkTech May 19, 2022
8c2ce0b
Avoid py3.7 on Mac OS 11.
TkTech May 19, 2022
6edebec
Forgot we needed pandas for the native tests.
TkTech May 20, 2022
c6ba7e8
Forgot we needed pandas for the native tests.
TkTech May 20, 2022
5f71b1c
Try to fix normal tests.
TkTech May 20, 2022
4ebe86e
Try to fix normal tests.
TkTech May 20, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
96 changes: 96 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
on:
workflow_dispatch:
push:

# tags:
# - 'v*' # Push events to matching v*, i.e. v1.0, v20.15.10

name: Creating release

jobs:
# Build & test simple source release before wasting hours building and
# testing the binary build matrix.
sdist:
name: "🏗 Creating source release"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2

- name: Setting up Python
uses: actions/setup-python@v2
with:
python-version: 3.8

- name: Installing python build dependencies
run: |
pip install --upgrade pip wheel

- name: Building source distribution
run: |
python setup.py sdist

- uses: actions/upload-artifact@v2
with:
path: dist/*.tar.gz

# Build the wheels which do not require host emulation.
build_wheels:
name: "🏗 py${{ matrix.py }} on ${{ matrix.os }}"
runs-on: ${{ matrix.os }}
env:
CIBW_BUILD: "${{ matrix.py }}-*"
CIBW_ARCHS_LINUX: auto
CIBW_ARCHS_MACOS: auto universal2
CIBW_ARCHS_WINDOWS: auto
# musllinux builds, but is unstable, see https://github.com/numpy/numpy/pull/21200
CIBW_SKIP: "*-musllinux_*"
# Ensure numpy is installed first to get around a bug with setuptools
# which causes conflicts when installing eggs.
CIBW_BEFORE_BUILD: "pip install numpy"
CIBW_BEFORE_TEST: "pip install pytest flake8 pandas"
CIBW_TEST_COMMAND: "pytest {project}/tests"
# Can't test cross-compiled Mac OS builds.
CIBW_TEST_SKIP: "*_arm64 *_universal2:arm64"
strategy:
fail-fast: false
matrix:
os: [ubuntu-20.04, windows-2019, macos-11]
py: ["cp38", "cp39", "cp310"]

steps:
- uses: actions/checkout@v2

- name: Building binary wheels
uses: pypa/[email protected]

- uses: actions/upload-artifact@v2
with:
path: ./wheelhouse/*.whl

# Build the wheels which require host emulation.
# ppc64le compilation works, but is unbelievably slow.
# We're talking half a day. Ice this until it can be improved.
# build_emulated_wheels:
# name: "🏗 py${{ matrix.py }} (${{ matrix.arch }})"
# runs-on: ubuntu-20.04
# strategy:
# fail-fast: false
# matrix:
# py: ["cp38", "cp39", "cp310"]
# arch: [aarch64, ppc64le]

# steps:
# - uses: actions/checkout@v2

# - name: Setting up Qemu for host emulation
# uses: docker/setup-qemu-action@v1

# - name: Building binary wheels
# uses: pypa/[email protected]
# env:
# CIBW_ARCHS: "${{ matrix.arch }}"
# CIBW_BUILD: "${{ matrix.py }}-*"

# - uses: actions/upload-artifact@v2
# with:
# path: ./wheelhouse/*.whl
34 changes: 12 additions & 22 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,47 +2,37 @@ name: Tests

on:
push:
branches: [ master ]
pull_request:
branches: [ master ]

jobs:
build:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
python-version: ["3.6", "3.7", "3.8", "3.9", "3.10"]
python-version: ["3.8", "3.9", "3.10"]
steps:
- uses: actions/checkout@v2

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version }}

- name: Install dependencies
run: |
python -m pip install --upgrade pip wheel
python -m pip install -r requirements.txt
python -m pip install -r requirements_test.txt
pip install flake8 pytest
./tools/build_talib_from_source.bash $DEPS_PATH
env:
DEPS_PATH: ${{ github.workspace }}/dependencies
TA_INCLUDE_PATH: ${{ github.workspace }}/dependencies/include
TA_LIBRARY_PATH: ${{ github.workspace }}/dependencies/lib
- name: Build cython modules in-place
pip install --upgrade pip wheel
pip install numpy flake8 pytest pandas polars

- name: Installing Python TA-Lib
run: |
python setup.py build_ext --inplace --include-dirs=$TA_INCLUDE_PATH --library-dirs=$TA_LIBRARY_PATH
env:
TA_INCLUDE_PATH: ${{ github.workspace }}/dependencies/include
TA_LIBRARY_PATH: ${{ github.workspace }}/dependencies/lib
python setup.py install

- name: Lint with flake8
run: |
# stop the build if there are Python syntax errors or undefined names
flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
# exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
#flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics

- name: Test with pytest
run: |
PYTHONPATH=. pytest
env:
LD_LIBRARY_PATH: ${{ github.workspace }}/dependencies/lib
python -m pytest tests
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ docs/.tadoc.org.html
build/
dist/
*.so
.*
*~
*.egg-info/

198 changes: 16 additions & 182 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,196 +38,30 @@ Or checkout the sources and run ``setup.py`` yourself:
$ python setup.py install
```

It also appears possible to install via
Unofficial packages are available on
[Conda Forge](https://anaconda.org/conda-forge/ta-lib):

```
$ conda install -c conda-forge ta-lib
```

### Dependencies

To use TA-Lib for python, you need to have the
[TA-Lib](http://ta-lib.org/hdr_dw.html) already installed. You should
probably follow their installation directions for your platform, but some
suggestions are included below for reference.

##### Mac OS X

```
$ brew install ta-lib
```

If you are using a M1 laptop and Homebrew, then you can set these before
Binary packages are provided for the following setups. Older version of Python
and other architectures may be supported, but will require a C compiler when
installing:

```
$ export TA_INCLUDE_PATH="$(brew --prefix ta-lib)/include"
$ export TA_LIBRARY_PATH="$(brew --prefix ta-lib)/lib"
$ arch -arm64 brew install ta-lib
```

You might also find this helpful on M1, particularly if you have tried
several different installations without success:

```
$ your-arm64-python -m pip install --no-cache-dir ta-lib
```

##### Windows

Download [ta-lib-0.4.0-msvc.zip](http://prdownloads.sourceforge.net/ta-lib/ta-lib-0.4.0-msvc.zip)
and unzip to ``C:\ta-lib``.

> This is a 32-bit binary release. If you want to use 64-bit Python, you will
> need to build a 64-bit version of the library. Some unofficial (**and
> unsupported**) instructions for building on 64-bit Windows 10, here for
> reference:
>
> 1. Download and Unzip ``ta-lib-0.4.0-msvc.zip``
> 2. Move the Unzipped Folder ``ta-lib`` to ``C:\``
> 3. Download and Install Visual Studio Community 2015
> * Remember to Select ``[Visual C++]`` Feature
> 4. Build TA-Lib Library
> * From Windows Start Menu, Start ``[VS2015 x64 Native Tools Command
> Prompt]``
> * Move to ``C:\ta-lib\c\make\cdr\win32\msvc``
> * Build the Library ``nmake``

You might also try these unofficial windows binaries for both 32-bit and
64-bit:

https://www.lfd.uci.edu/~gohlke/pythonlibs/#ta-lib

##### Linux

Download [ta-lib-0.4.0-src.tar.gz](http://prdownloads.sourceforge.net/ta-lib/ta-lib-0.4.0-src.tar.gz) and:

```
$ tar -xzf ta-lib-0.4.0-src.tar.gz
$ cd ta-lib/
$ ./configure --prefix=/usr
$ make
$ sudo make install
```

> If you build ``TA-Lib`` using ``make -jX`` it will fail but that's OK!
> Simply rerun ``make -jX`` followed by ``[sudo] make install``.

Note: if your directory path includes spaces, the installation will probably
fail with ``No such file or directory`` errors.

### Troubleshooting

If you get a warning that looks like this:

```
setup.py:79: UserWarning: Cannot find ta-lib library, installation may fail.
warnings.warn('Cannot find ta-lib library, installation may fail.')
```

This typically means ``setup.py`` can't find the underlying ``TA-Lib``
library, a dependency which needs to be installed.

If you installed the underlying ``TA-Lib`` library with a custom prefix
(e.g., with ``./configure --prefix=$PREFIX``), then when you go to install
this python wrapper you can specify additional search paths to find the
library and include files for the underlying ``TA-Lib`` library using the
``TA_LIBRARY_PATH`` and ``TA_INCLUDE_PATH`` environment variables:

```sh
$ export TA_LIBRARY_PATH=$PREFIX/lib
$ export TA_INCLUDE_PATH=$PREFIX/include
$ python setup.py install # or pip install ta-lib
```

Sometimes installation will produce build errors like this:

```
talib/_ta_lib.c:601:10: fatal error: ta-lib/ta_defs.h: No such file or directory
601 | #include "ta-lib/ta_defs.h"
| ^~~~~~~~~~~~~~~~~~
compilation terminated.
```

or:

```
common.obj : error LNK2001: unresolved external symbol TA_SetUnstablePeriod
common.obj : error LNK2001: unresolved external symbol TA_Shutdown
common.obj : error LNK2001: unresolved external symbol TA_Initialize
common.obj : error LNK2001: unresolved external symbol TA_GetUnstablePeriod
common.obj : error LNK2001: unresolved external symbol TA_GetVersionString
```

This typically means that it can't find the underlying ``TA-Lib`` library, a
dependency which needs to be installed. On Windows, this could be caused by
installing the 32-bit binary distribution of the underlying ``TA-Lib`` library,
but trying to use it with 64-bit Python.

Sometimes installation will fail with errors like this:

```
talib/common.c:8:22: fatal error: pyconfig.h: No such file or directory
#include "pyconfig.h"
^
compilation terminated.
error: command 'x86_64-linux-gnu-gcc' failed with exit status 1
```

This typically means that you need the Python headers, and should run
something like:

```
$ sudo apt-get install python3-dev
```

Sometimes building the underlying ``TA-Lib`` library has errors running
``make`` that look like this:

```
../libtool: line 1717: cd: .libs/libta_lib.lax/libta_abstract.a: No such file or directory
make[2]: *** [libta_lib.la] Error 1
make[1]: *** [all-recursive] Error 1
make: *** [all-recursive] Error 1
```

This might mean that the directory path to the underlying ``TA-Lib`` library
has spaces in the directory names. Try putting it in a path that does not have
any spaces and trying again.

Sometimes you might get this error running ``setup.py``:

```
/usr/include/limits.h:26:10: fatal error: bits/libc-header-start.h: No such file or directory
#include <bits/libc-header-start.h>
^~~~~~~~~~~~~~~~~~~~~~~~~~
```

This is likely an issue with trying to compile for 32-bit platform but
without the appropriate headers. You might find some success looking at the
first answer to [this question](https://stackoverflow.com/questions/54082459/fatal-error-bits-libc-header-start-h-no-such-file-or-directory-while-compili).

If you wonder why ``STOCHRSI`` gives you different results than you expect,
probably you want ``STOCH`` applied to ``RSI``, which is a little different
than the ``STOCHRSI`` which is ``STOCHF`` applied to ``RSI``:

```python
>>> import talib
>>> import numpy
>>> c = numpy.random.randn(100)

# this is the library function
>>> k, d = talib.STOCHRSI(c)

# this produces the same result, calling STOCHF
>>> rsi = talib.RSI(c)
>>> k, d = talib.STOCHF(rsi, rsi, rsi)

# you might want this instead, calling STOCH
>>> rsi = talib.RSI(c)
>>> k, d = talib.STOCH(rsi, rsi, rsi)
```
| | Python 3.8 | Python 3.9 | Python 3.10 |
|---------------------|------------|------------|-------------|
| Linux (x86) | ✓ | ✓ | ✓ |
| Linux (x86_64) | ✓ | ✓ | ✓ |
| Linux (aarch64) | ✓ | ✓ | ✓ |
| Mac OS (x86_64) | ✓ | ✓ | ✓ |
| Mac OS (M1/aarch64) | ✓ | ✓ | ✓ |
| Windows (x86) | ✓ | ✓ | ✓ |
| Windows (x86_64) | ✓ | ✓ | ✓ |

Support is primarily limited by what versions of Python are supported by recent
versions of numpy. When building locally, make sure you're using a version of
numpy that supports your Python version.

## Function API

Expand Down
2 changes: 1 addition & 1 deletion requirements_test.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
-r requirements.txt
pandas
pytest
polars
flake8
Loading