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

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page