Skip to content

feat(trading): Dhan + Shoonya Indian broker connectors (paper-capped)#181

Merged
warren618 merged 1 commit into
mainfrom
fix/in-broker-connectors-paper-capped
Jun 5, 2026
Merged

feat(trading): Dhan + Shoonya Indian broker connectors (paper-capped)#181
warren618 merged 1 commit into
mainfrom
fix/in-broker-connectors-paper-capped

Conversation

@warren618

Copy link
Copy Markdown
Collaborator

Summary

Adds two broker_sdk connectors for the Indian equity and F&O markets (NSE/BSE) — Dhan (dhanhq) and Shoonya / Finvasia (NorenRestApiPy) — following the connector-first architecture. Read access + locally simulated paper-account order placement.

This is a maintainer follow-up to #174 that lands the contribution with the paper/live boundary made structural.

Why capped to paper + read-only

Both brokers expose no sandbox and no runtime paper/live discriminator — a single token / TOTP login reaches the same real account, and "paper" is purely a local simulation flag. That is exactly the case the project already caps at paper + read-only for Longbridge, because every connector that places live orders earns it with a broker-provided discriminator (Tiger 17-digit account · Alpaca host+key separation · OKX demo flag · Binance testnet host · Futu trd_env). Dhan/Shoonya can't provide one, so they follow the Longbridge precedent.

Concretely, vs. the original #174 submission:

  • Structural cap. place_order / cancel_order refuse any non-paper config at the first line, so a flipped profile override can never reach a live order. No *-live-trade profile is registered — three profiles each (paper-sdk read-only · paper-trade local-sim · live-sdk-readonly read-only), mirroring Longbridge.
  • Removed a crash. The original live path set an invalid asset class (in_equity, not a member of AssetClass) that raised ValueError for every order through the gate; that mapping is dropped.
  • Wired the classifier. DHAN_TOOL_CLASS / SHOONYA_TOOL_CLASS are now registered in the live classifier registry (they were defined but never imported).
  • Hardening. Order ops pinned WRITE; secrets redacted; pyotp made an optional dependency with a clean error; Shoonya sessions cached per user_id to avoid cross-account reuse; dead code removed.

What you get

Real-time NSE/BSE data, account/position/order reads (paper + live read-only), and local paper-strategy simulation. Live order placement stays off by construction; if either broker ships a real sandbox/demo endpoint later, a discriminator can be added and the cap lifted cleanly.

Tests

pytest2998 passed, 2 skipped (CI-equivalent run). New coverage in test_sdk_connectors.py:

  • profile registration for both connectors
  • non-paper config is fail-closed in place_order / cancel_order
  • paper config simulates locally
  • order ops resolve WRITE through the shared classifier + registry
  • secret redaction
  • regression guard: no-discriminator brokers (Longbridge, Dhan, Shoonya) never expose a *-live-trade profile

Original connector work by @panditvirchandra77-lgtm (#174).

…ped)

Two broker_sdk connectors for the Indian equity and F&O markets (NSE/BSE):
Dhan (dhanhq) and Shoonya / Finvasia (NorenRestApiPy). Read access plus
locally simulated paper-account order placement.

Both brokers expose no sandbox and no runtime paper/live discriminator — a
single token / TOTP login reaches the same real account — so, following the
Longbridge precedent, the order path is structurally capped at paper:

- place_order / cancel_order refuse any non-paper config at the first line, so
  a flipped `profile` override can never reach a live order;
- no live order-placing profile is registered (paper-sdk read-only,
  paper-trade local-sim, live-sdk-readonly read-only — three profiles each,
  mirroring Longbridge);
- DHAN/SHOONYA tool-class maps wired into the live classifier registry;
- order ops pinned WRITE; secrets redacted; pyotp made an optional dependency;
  Shoonya sessions cached per user_id to avoid cross-account reuse.

Tests cover profile registration, the non-paper fail-closed guard, paper
simulation, WRITE-pinned order ops, secret redaction, and a regression guard
that these no-discriminator brokers never expose a *-live-trade profile.

Maintainer follow-up to PR #174: the original submission shipped live order
placement with no structural paper/live discriminator (and an invalid asset
class that crashed the live path); this revision caps both connectors to
paper + read-only to keep the paper/live boundary structural, never an
agent-flippable config flag.

Co-authored-by: Haozhe Wu <haozhe_wu@connect.hku.hk>
@warren618 warren618 merged commit a4f0fc1 into main Jun 5, 2026
1 check passed
@warren618 warren618 deleted the fix/in-broker-connectors-paper-capped branch June 5, 2026 07:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

1 participant