brokerkit-dhan
BrokerKit's Dhan adapter — wraps the official dhanhq SDK behind BrokerKit's broker-agnostic interfaces (auth, instruments, orders, portfolio, market data, historical candles, streaming), plus three Dhan-only extras: US equities, risk control and a sandbox.
pip install brokerkit-core brokerkit-dhan
This is the broadest-scope adapter in BrokerKit. Dhan is a second live-execution account, the only source of Global Stocks (US equity trading — no other broker here has it), and the source of real risk tooling.
Prerequisites
- Enable TOTP on the account first — web.dhan.co → DhanHQ APIs → Setup TOTP. Without it, token generation fails.
- Your
client_idand loginpin. - Static IP registration for order placement (SEBI rule). Reads work without it.
- Data API subscription — required for market data, historical candles, option chain and streaming. Without it those calls fail on subscription (historical returns a clean
DH-902), same posture as Groww. - US account activation, only if you want Global Stocks holdings/funds. Instruments and market status work without it.
Quick start
import asyncio
import os
from brokerkit import Exchange, Segment, create_broker
async def main():
broker = await create_broker(
"dhan",
client_id=os.environ["DHAN_CLIENT_ID"],
pin=os.environ["DHAN_PIN"],
totp_secret=os.environ["DHAN_TOTP_SECRET"],
# Strongly recommended — see below
access_token=os.environ.get("DHAN_ACCESS_TOKEN"),
)
instruments = await broker.instruments.fetch_instruments()
reliance = next(
i for i in instruments
if i.symbol == "RELIANCE"
and i.exchange == Exchange.NSE
and i.segment == Segment.CASH
)
print(await broker.portfolio.holdings())
await broker.close()
asyncio.run(main())
Use the access_token passthrough. Dhan rate-limits token generation to once every 2 minutes, so re-running a script repeatedly will hit "Token can be generated once every 2 minutes." Generate once, reuse it; pin + totp_secret are still used for the 24-hour refresh.
Extras
broker.global_stocks — US equities
Core models genuinely cannot represent this — core OrderRequest.quantity is an int but Global Stocks supports fractional shares, core Exchange has no US value, and prices are USD — so this has its own adapter-local models (GlobalInstrument, GlobalOrder, GlobalHolding, GlobalFundLimit, GlobalMarketStatus).
us = await broker.global_stocks.fetch_instruments() # ~11,458 US instruments
aapl = next(i for i in us if i.symbol == "AAPL")
print(aapl.security_id, aapl.exchange, aapl.fractional)
print(await broker.global_stocks.market_status())
Holdings and fund limits need US onboarding on the account (INX-1007 otherwise); instruments and market status do not.
broker.risk_control — kill switch + P&L auto-exit
await broker.risk_control.kill_switch_status()
await broker.risk_control.activate_kill_switch()
await broker.risk_control.get_pnl_exit()
Dhan's kill switch is account-wide (Upstox's is per-segment).
broker.sandbox_orders — order writes without the static-IP wall
Pass sandbox_access_token= (from developer.dhanhq.co) and broker.sandbox_orders gets wired. Dhan's sandbox covers a much broader surface than Upstox's — full order CRUD and reads.
It is deliberately a separate attribute from broker.orders, never merged, so a real order can never be confused with a sandbox one.
Adapter notes
tick_sizein the instrument master is in paise — the adapter divides by 100. Verified against real rows: a ₹1400 stock cannot have a ₹10 tick.- Both instrument CSVs are needed. The detailed CSV has ISIN and underlying but no trading symbol; the compact one has the symbol but neither of those. The adapter fetches both concurrently and joins them (195,524 instruments).
- Empty holdings arrive as a failure envelope, not
[]. Dhan returnsDH-1111 "No holdings available"as an error; the adapter translates it to an empty list. - Streaming uses Quote mode (17), not Ticker (15), specifically so
Tick.volumepopulates — Ticker mode carries no volume. Tick.minute_ohlcis alwaysNone— Dhan's feed carries day OHLC only, no server-computed minute candle. Aggregate ticks yourself.- Uses
dhanhq==2.3.0rc1, a pre-release, deliberately. It is the only version with Global Stocks at all, and diffing it against stable 2.2.0 from source showed it is purely additive — no changed or removed signatures.
Verification status
Live-verified: auth, instruments, portfolio, order list, Global Stocks instruments and market status, risk-control reads.
Blocked by account state rather than by code: market / historical / option chain / streaming need the paid Data API subscription (so their response parsing is written from docs and not yet live-confirmed); Global Stocks holdings and funds need US activation; real order writes need SEBI static IP or a sandbox token.
License
MIT © 2026 Aditya Vishwakarma
Metadata
Release files for brokerkit-dhan 1.0.3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| brokerkit_dhan-1.0.3.tar.gz | 27.7 kB | Without provenance | Details for brokerkit_dhan-1.0.3.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| brokerkit_dhan-1.0.3-py3-none-any.whl | Python 3 | none | any | Details for brokerkit_dhan-1.0.3-py3-none-any.whl |
Total release size: 58.5 kB
Release files / brokerkit_dhan-1.0.3.tar.gz
| Download URL | brokerkit_dhan-1.0.3.tar.gz |
|---|---|
| Size | 27.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
60aec75390538cd14e73482a933db9eb8bc3986e1c5e13340c2ae154f966c5e1
|
|
BLAKE2b-256 checksum How to use checksums |
121cefa2add008fce34600f70788fdb64d73d2cc5b4956563007ef974172be5a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.6
|
Release files / brokerkit_dhan-1.0.3-py3-none-any.whl
| Download URL | brokerkit_dhan-1.0.3-py3-none-any.whl |
|---|---|
| Size | 30.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
c054bee2ae2c72ee96ca382bd16194f050b2299955802d45bcb9ed2f279982c2
|
|
BLAKE2b-256 checksum How to use checksums |
e33b15f00f3fcdd85a998b146206c5b13accf9be28e1099588ef3d4b586ca9f8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.6
|
Security for brokerkit-dhan 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.