Skip to main content

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

  1. Enable TOTP on the account first — web.dhan.co → DhanHQ APIs → Setup TOTP. Without it, token generation fails.
  2. Your client_id and login pin.
  3. Static IP registration for order placement (SEBI rule). Reads work without it.
  4. 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.
  5. 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_size in 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 returns DH-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.volume populates — Ticker mode carries no volume.
  • Tick.minute_ohlc is always None — 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)

Source distribution for brokerkit-dhan 1.0.3
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)

Table of built distributions (wheels) for brokerkit-dhan 1.0.3
File Interpreter ABI Platform Actions
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.

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