Skip to main content

bandl

One Python client for market data — crypto, Indian equities & options.
Same call everywhere. Get a pandas DataFrame or typed bars in three lines.

PyPI Python License


from bandl import Bandl, Interval

df = Bandl().crypto.get_ohlcv_dataframe("BTC/USDT", Interval.D1)   # no API key needed

One client, one API. Switch markets by changing the symbol — not your code.

  • 🟢 Zero-config crypto — Binance & CoinDCX public data, no keys.
  • 🇮🇳 Indian equities & indicesRELIANCE, NIFTY 50, BANKNIFTY via Zerodha.
  • 📈 Options, incl. expired contracts — NSE/BSE F&O + MCX commodities via Dhan.
  • 🐼 pandas or typed modelsget_ohlcv_dataframe(...) or get_ohlcv(...) -> list[OHLCV].
  • ⏱️ Normalized everywhere — UTC timestamps, Decimal prices, one Interval enum.
  • 🤖 Agent-ready — a dedicated AGENTS.md reference for LLM tools.

bandl demo


Install

pip install bandl

Python 3.10+. Dev setup: pip install -e ".[dev]" (CONTRIBUTING.md).


60-second start

No API key required — crypto works out of the box:

from bandl import Bandl, Interval

client = Bandl()

df = client.crypto.get_ohlcv_dataframe("BTC/USDT", Interval.D1)
print(df.tail())
#            timestamp     open     high      low    close       volume
#  2025-01-10 00:00:00  94000.1  95200.0  92800.5  94850.2   12930.4451

Want a window? Pass start / end (UTC). Want raw bars instead of pandas? Call get_ohlcv(...) — same arguments, returns list[OHLCV].

from datetime import datetime, timedelta, timezone

end = datetime.now(timezone.utc)
start = end - timedelta(days=30)
bars = client.crypto.get_ohlcv("ETHUSDT", Interval.H1, start, end)
print(bars[-1].close, bars[-1].source)

One API, every market

Facet Provider Auth Example symbols
client.crypto binance None BTC/USDT, ETHUSDT
client.crypto coindcx None BTCUSDT, ETHUSDT
client.equity zerodha Kite key + token RELIANCE, NIFTY 50, BANKNIFTY
client.derivatives dhan Dhan id + JWT GOLDM26JUN145000CE, NIFTY26JAN24000PE

Every facet exposes the same two callsget_ohlcv(...) and get_ohlcv_dataframe(...). Pick a provider with source="...", or rely on each facet's default.


Recipes

Indian equities & indices (Zerodha)

Add your Kite Connect credentials once; the rest is identical to crypto. Symbol aliases (NIFTY 50NIFTY50) are handled for you.

from bandl import Bandl, BandlConfig, Interval, ProviderSettings

client = Bandl(BandlConfig(providers={
    "zerodha": ProviderSettings(api_key="kite_api_key", access_token="daily_token"),
}))

reliance = client.equity.get_ohlcv_dataframe("RELIANCE", Interval.D1, source="zerodha")
nifty    = client.equity.get_ohlcv_dataframe("NIFTY 50", Interval.D1, source="zerodha")

Options & derivatives (Dhan)

client.derivatives serves option OHLCV across NSE/BSE F&O and MCX commodities — with open_interest on every bar. Give it a symbol string (auto-resolved against Dhan's scrip master) or a structured OptionContract.

from datetime import date, datetime, timezone
from decimal import Decimal
from bandl import Bandl, BandlConfig, Interval, ProviderSettings
from bandl.models.market import OptionContract, OptionType

client = Bandl(BandlConfig(providers={
    "dhan": ProviderSettings(api_key="dhan_client_id", access_token="dhan_jwt"),
}))

# 1) Symbol string — easiest
df = client.derivatives.get_ohlcv_dataframe(
    "GOLDM26JUL145000CE", Interval.M5, source="dhan", exchange="MCX",
)

# 2) Structured contract — explicit & unambiguous
contract = OptionContract(
    underlying="GOLDM", expiry=date(2026, 7, 29),
    strike=Decimal("145000"), option_type=OptionType.CALL, exchange="MCX",
)
bars = client.derivatives.get_ohlcv(contract, Interval.M1, source="dhan")

# What expiries exist for an underlying?
expiries = client.derivatives.list_expiries("GOLDM", source="dhan", exchange="MCX")

Need expired contracts? Most APIs drop them. bandl still fetches their minute candles — pass the native instrument_id once (look it up via Dhan, or the bundled examples/dhan_expired_probe.py):

bars = client.derivatives.get_ohlcv(
    "GOLDM26JUN143500CE", Interval.M1,
    datetime(2026, 6, 26, tzinfo=timezone.utc),
    datetime(2026, 6, 27, tzinfo=timezone.utc),
    source="dhan", exchange="MCX", instrument_id="570800",
)

Typed bars instead of pandas

from bandl import OHLCV

bars: list[OHLCV] = client.crypto.get_ohlcv("BTCUSDT", Interval.H1)
bars[-1].close      # Decimal — no float rounding
bars[-1].timestamp  # tz-aware UTC datetime

List tradable symbols

client.list_symbols(source="binance", search="BTC", limit=20)
client.list_symbols(source="zerodha", exchange="NSE",
                    instrument_types=("EQ",), search="RELI", limit=10)

Intervals & timezones

One enum maps to every provider's native interval. Timestamps come back UTC.

from bandl import Interval
Interval.M1, Interval.M5, Interval.H1, Interval.D1   # 1m / 5m / 1h / 1d

df["timestamp"] = df["timestamp"].dt.tz_convert("Asia/Kolkata")  # → IST for display

Configuration

from bandl import BandlConfig, ProviderSettings

config = BandlConfig(
    providers={
        "zerodha": ProviderSettings(api_key="...", access_token="..."),
        "dhan":    ProviderSettings(api_key="client_id", access_token="jwt"),
    },
    timeout_seconds=30,
    default_crypto_provider="binance",       # client.crypto default
    default_equity_provider="zerodha",       # client.equity default
    default_derivatives_provider="dhan",     # client.derivatives default
)
Provider api_key access_token Notes
zerodha Kite API key daily token Tokens expire daily — regenerate after login. 403 ⇒ expired/wrong token or no historical-API access.
dhan client id JWT JWT generated in the Dhan web/app. Expired contracts leave the scrip master — fetch by instrument_id.
binance / coindcx Public OHLCV needs no keys.

Binance HTTP 451? Binance blocks some regions/cloud IPs (US, Colab). Use source="coindcx" — same symbols, no key — or set default_crypto_provider="coindcx".

CoinDCX empty DataFrame? Its public feed can lag by months. A start/end entirely after the feed raises DataNotAvailableError with the available span; pick an overlapping window.


More

Account history — orders, fills & PnL via client.account
fills  = client.account.get_fills(start, end, source="coindcx")
pnl    = client.account.get_pnl(start, end, source="zerodha", prefer="auto")
bundle = client.account.export_analysis_bundle(start, end)

Full guide: docs/ACCOUNT_HISTORY.md.

Futures 24h leaders — rolling ticker stats
from bandl import AssetType

tickers = client.crypto.get_24hr_tickers(source="coindcx", asset_type=AssetType.CRYPTO_PERP)
Runnable demos
cp examples/.env.example .env      # add ZERODHA_* / DHAN_* to test authed providers
python examples/main.py
python examples/dhan_options.py
python examples/futures_24hr_leaders.py --source coindcx

For AI agents

AGENTS.md is a purpose-built reference (provider matrix, recipes, errors) for LLM coding tools. It is not shipped in the PyPI wheel — point your agent at the GitHub link:

https://github.com/stockalgo/bandl/blob/master/AGENTS.md

Pin a tag (e.g. .../blob/v0.4.0/AGENTS.md) for a fixed version. See agents/README.md.


Docs & development

pytest tests/bandl/
ruff check lib/bandl tests/bandl

Roadmap

  • Live streams / WebSockets
  • More brokers & deeper commodity history
  • Richer SymbolInfo and fundamentals

Contributing

PRs welcome — read CONTRIBUTING.md and CODE_OF_CONDUCT.md first.

License

MIT

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

bandl-0.6.0.tar.gz (62.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

bandl-0.6.0-py3-none-any.whl (83.4 kB view details)

Uploaded Python 3

File details

Details for the file bandl-0.6.0.tar.gz.

File metadata

  • Download URL: bandl-0.6.0.tar.gz
  • Upload date:
  • Size: 62.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for bandl-0.6.0.tar.gz
Algorithm Hash digest
SHA256 f011511d27142f1d7f1abe90fdb41fba6335c1573b3d9bfb08da3af94d2cc686
MD5 e97c57230ae392d47ebe97c561ee9c47
BLAKE2b-256 d488bad5f522a37fd5c677c6f3ba4298ac6b8fe67ed65725f69f974a2382d613

See more details on using hashes here.

Provenance

The following attestation bundles were made for bandl-0.6.0.tar.gz:

Publisher: publish.yml on stockalgo/bandl

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file bandl-0.6.0-py3-none-any.whl.

File metadata

  • Download URL: bandl-0.6.0-py3-none-any.whl
  • Upload date:
  • Size: 83.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for bandl-0.6.0-py3-none-any.whl
Algorithm Hash digest
SHA256 65550fcf993bf1d34800fed9932ebaaa167d8de76e34e818a834cdf47b908a93
MD5 da007db70c7588f8f6a4b4483a938a38
BLAKE2b-256 b275d520cb6413e7281e2156c88581adede48132ee4fcc29fe146af940788ec3

See more details on using hashes here.

Provenance

The following attestation bundles were made for bandl-0.6.0-py3-none-any.whl:

Publisher: publish.yml on stockalgo/bandl

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

0.6.0 This release

2 files

0.5.0

2 files

0.4.0

2 files

0.3.0

2 files

0.2.0

2 files

0.1.0

2 files

0.0.1

1 file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page