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

Download files

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

Source Distribution

brokerkit_angelone-1.0.3.tar.gz (29.8 kB view details)

Uploaded Source

Built Distribution

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

brokerkit_angelone-1.0.3-py3-none-any.whl (33.1 kB view details)

Uploaded Python 3

File details

Details for the file brokerkit_angelone-1.0.3.tar.gz.

File metadata

  • Download URL: brokerkit_angelone-1.0.3.tar.gz
  • Upload date:
  • Size: 29.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.6

File hashes

Hashes for brokerkit_angelone-1.0.3.tar.gz
Algorithm Hash digest
SHA256 99ff5626c1fdcde4dbfe6bd902bc97c14a91161aa396dd14dbecc241a1c293c0
MD5 ee206fdf55081ed2f53aeb4512577df2
BLAKE2b-256 f22b13efc144e15f898667b642c863e9acb853217c78c1fca66304afebaf27cc

See more details on using hashes here.

File details

Details for the file brokerkit_angelone-1.0.3-py3-none-any.whl.

File metadata

File hashes

Hashes for brokerkit_angelone-1.0.3-py3-none-any.whl
Algorithm Hash digest
SHA256 7da000e678255ea1b54a6d7596deeeaf4e96e6bcaf0c61c3282d137fe95b78f4
MD5 51f9db3a201e881ecb65301369b24689
BLAKE2b-256 9b845609770f742a111ec3c374fdc6e79ce9de773c292ead2ed2cdd9f5652bed

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

1.0.3 This release

2 files

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