How to Integrate BanTA Python Bindings into Existing Python Projects
BanTA Python bindings let you call high-performance Go technical analysis indicators from Python via the bbta module generated by gopy.
The banbox/banta repository ships its core technical-analysis engine as a Go package, but exposes all indicators through gopy-generated Python bindings that compile into a native shared library. You can integrate these bindings into any existing Python project—whether you use plain Python, NumPy, or pandas—to execute fast indicator calculations without rewriting your data pipeline.
Prerequisites: Installing Build Dependencies
Before compiling the bindings, you need both Python packaging tools and the Go toolchain installed on your system.
Python Environment Setup
Install the required Python build dependencies using pip:
python3 -m pip install pybindgen setuptools wheel
Go Toolchain Installation
You also need the Go compiler and the gopy generator. Install goimports and gopy via the Go command:
go install golang.org/x/tools/cmd/goimports@latest
go install github.com/go-python/gopy@latest
Compiling the BanTA Python Bindings
The compilation process uses gopy to generate CPython extensions from the Go wrapper files located in python/ta/ and python/tav/.
Linux and macOS Build Process
Run the following command from the repository root to generate the shared object file (_out/*.so):
gopy build -output=_out -vm=python3 \
-name=bbta \
-dynamic-link=True \
github.com/banbox/banta/python/ta \
github.com/banbox/banta/python/tav
This produces a native shared library in the _out/ directory containing the ta and tav submodules.
Windows Build Process
On Windows, the same command produces a .pyd file instead of .so:
gopy build -output=_out -vm=python3 ^
-name=bbta ^
github.com/banbox/banta/python/ta ^
github.com/banbox/banta/python/tav
Importing and Using bbta in Your Project
Once the build completes, you can import the generated module directly from the _out directory or install it into your site-packages.
Direct Import from Build Directory
After building, import the two sub-modules (ta for indicators, tav for helper vectors) directly from the output folder:
from _out import ta, tav
# Calculate Simple Moving Average
prices = [101.5, 102.3, 103.7, 104.2, 105.0]
sma = ta.SMA(prices, period=3)
print("SMA:", sma)
Working with Multi-Output Indicators
Functions returning multiple series—like MACD—return fixed-size tuples because gopy expects single return values. In python/ta/index.go, these are wrapped to return arrays:
# MACD returns (macd_line, signal_line)
macd, signal = ta.MACD(prices, fast=12, slow=26, smooth=9)
print("MACD:", macd)
print("Signal:", signal)
Integration with NumPy and Pandas
The returned objects are plain Python list[float] (or tuples), so they integrate seamlessly with scientific Python stacks:
import numpy as np
import pandas as pd
# Convert to NumPy array
np_prices = np.array(prices)
# Use with pandas DataFrame
df = pd.DataFrame({"close": np_prices})
df["rsi"] = ta.RSI(df["close"].tolist(), period=14)
# Calculate HL2 using tav helpers
high = [110, 112, 113, 115]
low = [105, 107, 108, 109]
df["hl2"] = tav.HL2(high, low)
print(df)
Architecture of the Python Bindings
Understanding the binding architecture helps you debug integration issues or extend the wrappers.
Wrapper File Structure
The integration relies on two thin wrapper files that adapt Go functions to gopy conventions:
python/ta/index.go: Wraps all indicators fromgithub.com/banbox/banta(e.g.,SMA,RSI,MACD)python/tav/index.go: Wraps vector helpers fromgithub.com/banbox/banta/tav(e.g.,HL2, typical price calculations)
These wrappers translate Go's multiple return values into single values or fixed-size arrays that gopy can export to Python.
Return Value Handling
Because gopy only exports functions with a single return value or an error pair, multi-output Go functions (which normally return multiple *Series pointers) are wrapped to return fixed-size arrays. For example, the MACD implementation in python/ta/index.go returns [2]Series instead of two separate values, which Python receives as a tuple.
Packaging for Distribution (Optional)
If you need to distribute the bindings via PyPI or share them across teams without requiring Go toolchains on every machine, use the provided packaging script.
The repository includes setup_custom.py (located in the python/ directory) to build a redistributable wheel:
cd _out
python3 setup.py sdist bdist_wheel # Produces .tar.gz and .whl in dist/
twine upload dist/* # Upload to PyPI
The CI workflow defined in .github/workflows/build_wheels.yml automates this process for multiple platforms, building pre-compiled wheels so end users can pip install bbta without installing Go.
Summary
- BanTA Python bindings are generated via
gopyfrom wrapper files inpython/ta/index.goandpython/tav/index.go. - The build produces a native shared library (
_out/*.soor_out/*.pyd) that exposes thebbtamodule with submodulestaandtav. - Multi-output indicators like MACD return Python tuples because the Go wrappers use fixed-size arrays to comply with gopy's single-return requirement.
- The generated functions return plain Python lists, enabling seamless integration with NumPy and pandas without data conversion overhead.
- For production deployment, use
setup_custom.pyto build wheels and distribute via PyPI, eliminating the Go toolchain dependency for end users.
Frequently Asked Questions
What build tools are required to compile BanTA Python bindings?
You need pybindgen, setuptools, and wheel for the Python side, plus the Go compiler, goimports, and gopy for the Go side. These tools generate the CPython extension module that bridges Python calls to the Go implementation in github.com/banbox/banta.
How do I handle multi-output indicators like MACD in Python?
Multi-output functions are wrapped in python/ta/index.go to return fixed-size arrays (e.g., [2]Series) instead of multiple values. Python receives these as tuples, so you can unpack them directly: macd, signal = ta.MACD(prices, fast=12, slow=26, smooth=9).
Can I use BanTA bindings with NumPy and pandas?
Yes. All indicator functions return standard Python list[float] objects (or tuples of lists), which convert naturally to NumPy arrays and pandas Series. You can pass pandas columns directly using .tolist() or wrap the results in pd.Series() for DataFrame assignment.
Where are the wrapper functions defined in the source code?
The gopy-compatible wrappers live in two files: python/ta/index.go for core technical indicators (SMA, RSI, MACD) and python/tav/index.go for vector helpers (HL2, typical price). These files adapt the raw Go API from core.go to the calling conventions required by gopy-generated Python bindings.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →