Skip to main content

brokerkit-angelone

BrokerKit's Angel One adapter — wraps the official smartapi-python SDK behind BrokerKit's broker-agnostic interfaces (auth, instruments, orders, portfolio, market data, historical candles, streaming), plus two Angel-only extras: charges and analytics.

pip install brokerkit-core brokerkit-angelone

Angel One is a live-execution account and a second free data source: unlike Groww, Dhan and Zerodha, its market and historical data need no paid subscription. That makes it, alongside Fyers, one of the two brokers here where the data side works out of the box.

Prerequisites

  1. Create an app at smartapi.angelone.in → you get the api_key.
  2. Enable TOTP on the Angel account (Profile → Settings → TOTP) and note the secret.
  3. Your client_code (e.g. A123456) and your MPIN — API login uses the MPIN, not the web password.
  4. Static IP registration for order placement (SEBI rule). Reads work without it. Angel has no sandbox, so there is no way around this for writes.

Quick start

import asyncio
import os

from brokerkit import Exchange, Segment, create_broker


async def main():
    broker = await create_broker(
        "angelone",
        api_key=os.environ["ANGEL_API_KEY"],
        client_code=os.environ["ANGEL_CLIENT_CODE"],
        mpin=os.environ["ANGEL_MPIN"],
        totp_secret=os.environ["ANGEL_TOTP_SECRET"],
    )

    instruments = await broker.instruments.fetch_instruments()
    reliance = next(
        i for i in instruments
        if i.symbol == "RELIANCE-EQ"
        and i.exchange == Exchange.NSE
        and i.segment == Segment.CASH
    )

    quote = await broker.market.get_quote(reliance)
    print(quote.last_price, quote.volume)

    await broker.close()


asyncio.run(main())

All four credentials are required — there is deliberately no token passthrough here (see below).

The auth quirk worth understanding

Angel is the only broker in BrokerKit with a real refresh-token endpoint (generateToken(refreshToken)), so the daily refresh needs no TOTP re-entry. There is a reason it ships one:

Angel's JWT expires on a wall-clock boundary, not after a fixed duration. Two tokens minted at different times both carried an identical expiry of 00:00:00 IST — meaning a morning login lasts most of a day and an 11:30 PM login lasts half an hour. The adapter therefore decodes the token's own exp claim rather than assuming any validity window; an assumed 24 hours made dead tokens look fresh and every call failed AG8001.

The feed token from the same login response is a genuine rolling 24 hours — the two tokens have different expiry semantics.

This is also why there is no access_token passthrough in this adapter, unlike Fyers/Upstox/Dhan. Those earn theirs (Dhan rate-limits token generation, Upstox needs a daily browser login). Angel's login is headless and takes about a second, and its JWT dies quickly, so a pasted token is stale almost immediately — it was a pure footgun.

Extras

broker.charges

Implements the core ChargesProvider via Angel's estimateCharges.

from decimal import Decimal
from brokerkit.enums import Product, TransactionType

charges = await broker.charges.get_brokerage(
    reliance, quantity=10, product=Product.CNC,
    transaction_type=TransactionType.BUY, price=Decimal("1400"),
)

broker.analytics

Angel-specific market analytics, kept adapter-local (deliberately not forced into Upstox's MarketInformationProvider, whose twelve methods don't map onto these):

await broker.analytics.put_call_ratio()
await broker.analytics.gainers_losers(datatype="PercPriceGainers", expirytype="NEAR")
await broker.analytics.option_greek(name="NIFTY", expiry=expiry)
await broker.analytics.oi_buildup(expirytype="NEAR", datatype="Long Built Up")
await broker.analytics.nse_intraday()
await broker.analytics.bse_intraday()

These return Angel's raw data payload rather than typed models — their shapes are auth-gated and not yet live-verified, and typing them from docs alone would risk silently wrong parsing.

Adapter notes

  • Both strike and tick_size in the master are in paise — the adapter divides by 100. Verified against real rows (a NIFTY 30000-PE carries strike="3000000").
  • The master has no ISIN column, so Instrument.isin is always None. ISIN does appear per-holding on the portfolio response. For cross-broker joins use exchange_token — it matches Fyers, Dhan, Groww and Zerodha exactly.
  • No server-side option-chain endpoint. get_option_chain is assembled: filter the master for the underlying's contracts at that expiry, trim to the nearest strikes around spot, quote them, then best-effort merge greeks from the separate optionGreek endpoint — degrading to greeks=None rather than failing the whole chain. expiry_list(underlying) is provided as an adapter extra.
  • variety is a separate axis from order type. Stop-loss orders go as variety STOPLOSS, everything else NORMAL, and both modify and cancel need the original variety — so both pre-fetch the order-book entry.
  • Depth is zero-padded to 5 levels by Angel; the adapter drops padding rows rather than reporting an ask of ₹0. Equity opnInterest is junk, so Quote.open_interest is nulled outside F&O and commodities.
  • Tick.minute_ohlc is always None — Angel's feed has no server-computed minute candle. Aggregate ticks yourself.
  • The SDK doesn't declare its own dependencies (logzero, websocket-client), so this package declares them; it also makes a blocking network call at import time and writes a logs/ directory into the working directory. Both are unavoidable SDK side effects, documented rather than worked around.

Verification status

Live-verified against a real account: auth, instruments, LTP/OHLC/full quote, historical at daily/15m/1m, expiry list, the whole assembled option-chain path, portfolio, and order list. Angel's free data means none of the Groww/Dhan/Zerodha subscription walls apply.

Not yet verified live: streaming, the analytics extras, charges through the provider, and all order writes (SEBI static IP, with no Angel sandbox to sidestep it).

License

MIT © 2026 Aditya Vishwakarma

Metadata

Release files for brokerkit-angelone 1.0.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for brokerkit-angelone 1.0.3
File Size Uploaded Provenance Actions
brokerkit_angelone-1.0.3.tar.gz 29.8 kB Without provenance Details for brokerkit_angelone-1.0.3.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for brokerkit-angelone 1.0.3
File Interpreter ABI Platform Actions
brokerkit_angelone-1.0.3-py3-none-any.whl Python 3 none any Details for brokerkit_angelone-1.0.3-py3-none-any.whl

Total release size: 62.9 kB

Release files / brokerkit_angelone-1.0.3.tar.gz

Download URL brokerkit_angelone-1.0.3.tar.gz
Size 29.8 kB
Tags Source
SHA-256 checksum
How to use checksums
99ff5626c1fdcde4dbfe6bd902bc97c14a91161aa396dd14dbecc241a1c293c0
BLAKE2b-256 checksum
How to use checksums
f22b13efc144e15f898667b642c863e9acb853217c78c1fca66304afebaf27cc
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.6

Release files / brokerkit_angelone-1.0.3-py3-none-any.whl

Download URL brokerkit_angelone-1.0.3-py3-none-any.whl
Size 33.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
7da000e678255ea1b54a6d7596deeeaf4e96e6bcaf0c61c3282d137fe95b78f4
BLAKE2b-256 checksum
How to use checksums
9b845609770f742a111ec3c374fdc6e79ce9de773c292ead2ed2cdd9f5652bed
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.6

Security for brokerkit-angelone 1.0.3

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

1.0.3 This release

2 release files No provenance

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