Skip to main content

A Zerodha-Kite-Connect-shaped, Python SDK for Angel One SmartAPI: market data, historical OHLC, options chains/Greeks, portfolio, orders, and streaming.

Project description

angelone-connect

A production-grade, Zerodha-Kite-Connect-shaped Python SDK for Angel One's SmartAPI. It covers market data, historical OHLC, options chains/Greeks, portfolio, orders, and live streaming behind a clean, typed, provider-neutral interface — so a TradingBot can depend on this SDK's shapes and swap providers (Angel One today; Zerodha/Yahoo Finance/NSE adapters later) without touching call sites.

v2.0.0 is a ground-up rewrite, published under a new PyPI name (angelone-connect, previously smartapi_login). If you're upgrading from the old smartapi_login 1.x package, see Migrating from 1.x below — your old code keeps working via a deprecated compatibility shim, you just need to pip install angelone-connect and change your top-level import from smartapi_login to angelone_connect.

Install

pip install angelone-connect

Quick start

from angelone_connect import Config, SmartAPIClient

config = Config(
    api_key="YOUR_API_KEY",
    client_code="YOUR_CLIENT_CODE",
    password="YOUR_MPIN_OR_PASSWORD",
    totp_secret="YOUR_TOTP_SECRET",
)
client = SmartAPIClient(config)
client.login()

client.quote("NSE:INFY")                                      # full quote
client.ltp("NSE:INFY", "NSE:TCS")                             # {"NSE:INFY": 1500.0, ...}
client.historical_data("INFY", "day", "2024-01-01", "2024-06-01")
client.option_chain("NIFTY", expiry, spot_symbol="Nifty 50")
client.positions()
client.holdings()
client.margins()
client.orders()

Every method returns typed dataclasses (Quote, HistoricalCandle, OptionChain, Holding, Position, Order, ...) from angelone_connect.models, not raw dicts.

Equity symbols just work. Angel One's instrument master uses a "-EQ" series suffix for NSE equities ("RELIANCE-EQ") but a plain, un-suffixed symbol for the same stock on BSE ("RELIANCE"). You never need to know this: pass the bare company symbol ("RELIANCE", "TCS", "INFY") — with or without an "NSE:"/"BSE:" exchange prefix — to quote()/ltp()/ohlc()/historical_data()/place_order()/etc. and the SDK resolves NSE's -EQ listing first, falling back to BSE automatically if the stock isn't listed on NSE at all. Already-qualified symbols ("RELIANCE-EQ", option/future contract symbols, index names) still match exactly, so this never interferes with non-equity lookups.

Architecture

angelone_connect/
    auth/           session management: TOTP login, token refresh, thread safety
    instruments/    instrument master download/cache, symbol<->token, lot/tick size
    market/         quote() / ltp() / ohlc() — Angel One's getMarketData
    historical/     historical_data() with automatic chunking + week/month resampling
    options/        option_chain(), Greeks, PCR, max pain, ATM/ITM/OTM tagging
    derivatives/    OI build-up, put/call ratio, gainers/losers (real Angel One endpoints)
    portfolio/      holdings(), positions(), margins(), pnl(), allocation()
    orders/         place/modify/cancel orders, order book, trade book
    websocket/      SmartTicker — live tick streaming (LTP/quote/full modes)
    quant/          beta, alpha, ATR, volatility, drawdown, correlation — pure math over candles
    providers/      pluggable interfaces for data Angel One doesn't expose (see below)
    models/         typed dataclasses shared by every module
    utils/          retry with backoff, rate limiting, structured logging, parsing helpers
    cache/          thread-safe TTL cache (instrument master, quotes)
    exceptions.py   one exception hierarchy; SmartApi's raw exceptions are translated into it
    client.py       SmartAPIClient — the Zerodha-shaped facade over everything above

SmartAPIClient is the one class most consumers need; the per-domain modules underneath (client.market, client.options, client.portfolio, ...) are available directly if you want finer-grained control.

What's real vs. pluggable

Angel One's SmartAPI genuinely exposes: live quotes, historical OHLC, option Greeks, put/call ratio, OI build-up (long/short build-up, short covering, long unwinding), a gainers/losers scanner, holdings/positions/margins, orders, and WebSocket streaming. All of that is implemented for real in this SDK, backed by the actual SmartConnect methods (getMarketData, getCandleData, optionGreek, putCallRatio, oIBuildup, gainersLosers, holding, position, rmsLimit, placeOrder, ...).

Angel One does not expose fundamentals, macro indicators, news, broad FII/DII rupee flows, delivery %, block/bulk deals, or market breadth at all — there's no API to wrap. Those modules (angelone_connect.providers.*) ship as typed ABC interfaces you register a concrete adapter against:

from angelone_connect.providers import fundamentals

class MyYFinanceFundamentals(fundamentals.FundamentalsProvider):
    def fetch_fundamentals(self, symbol):
        ...  # wrap yfinance, NSE, or any source you like
    # ... implement the rest of the interface

fundamentals.set_provider(MyYFinanceFundamentals())
fundamentals.fetch_fundamentals("RELIANCE")  # now works

Until a provider is registered, calling these functions raises ProviderNotConfiguredError rather than returning fake data. The same pattern applies to providers.institutional, providers.macro, providers.news, and providers.market_breadth.

quant.risk (beta, alpha, correlation, ATR, historical/realized volatility, drawdown, rolling returns, Sharpe) is not a provider stub — it's pure math computed from candles you already fetch via historical_data(), so it's implemented for real with no external dependency.

Options

from datetime import date

expiries = client.expiry_list("NIFTY")
chain = client.option_chain("NIFTY", expiries[0], spot_symbol="Nifty 50", spot_exchange="NSE")

chain.pcr            # OI-based put/call ratio for this expiry
chain.max_pain        # strike minimizing aggregate option-writer payout
chain.atm_strike
for call in chain.calls:
    call.strike, call.ltp, call.open_interest, call.moneyness, call.greeks.delta

spot_symbol matters: Angel One's instrument master doesn't use the same string for an index's option-chain grouping ("NIFTY") and its tradable spot quote (often "Nifty 50"). Use client.instruments.search("NIFTY") to find the exact spot symbol for your account before relying on ATM tagging in production. If it can't be resolved, spot_price/atm_strike/moneyness come back as None rather than a guess.

Streaming

ticker = client.ticker()
ticker.on_ticks = lambda ticks: print(ticks)
ticker.connect(threaded=True)
ticker.subscribe([("NSE", "3045"), ("NFO", "50001")], mode="full")

Reconnection, resubscription, and heartbeats are handled by Angel One's own SmartWebSocketV2 under the hood.

Quant / risk

from angelone_connect.quant import risk

candles = client.historical_data("INFY", "day", "2023-01-01", "2024-01-01")
benchmark = client.historical_data("NIFTY 50", "day", "2023-01-01", "2024-01-01", exchange="NSE")

risk.beta(candles, benchmark)
risk.atr(candles, period=14)
risk.historical_volatility(candles, window=21)
risk.max_drawdown(candles)
risk.risk_metrics(candles, benchmark=benchmark)   # bundles the above + Sharpe

Also available as client.get_volatility_snapshot(symbol, benchmark_symbol=...).

Reliability

  • Retries: every call to Angel One is wrapped with exponential backoff + jitter (Config.retry), and a TokenExpiredError triggers an automatic session refresh before retrying — see angelone_connect.utils.retry and angelone_connect._base.BaseAPI._call.
  • Rate limiting: a thread-safe token-bucket limiter (Config.rate_limit) throttles calls before they hit Angel One's per-endpoint ceilings.
  • Caching: the instrument master is downloaded once and cached for Config.instrument_cache_ttl seconds (default 24h); override per-deployment.
  • Exceptions: every error surfaces as a angelone_connect.exceptions.SmartAPIError subclass (AuthenticationError, TokenExpiredError, RateLimitError, OrderError, InstrumentNotFoundError, ...) — SmartApi's raw smartExceptions are translated automatically.
  • Thread safety: SessionManager guards token state with per-connection locks so multiple modules can share one session across threads.

Migrating from 1.x

The old SmartAPIHelper class still works, via a deprecated shim (angelone_connect.legacy.SmartAPIHelper) that forwards onto SmartAPIClient:

from angelone_connect import SmartAPIHelper  # emits a DeprecationWarning

api = SmartAPIHelper()
api.login(api_key_hist="...", api_key_trading="...", uid="...", mpin="...", totp="...")
api.get_ltp("WIPRO")
api.get_ohlc("BANKNIFTY", "FIVE_MINUTE", "2024-01-01", "2024-02-01")  # still returns a DataFrame

New code should use SmartAPIClient directly — it's the same session under the hood, plus options/portfolio/orders/streaming/quant modules the 1.x helper never had. get_tradingsymbols(), mentioned in older docs, was never actually implemented in 1.x and has been dropped rather than carried forward broken.

Testing

pip install -e ".[dev]"
pytest

The test suite is fully mocked (no live Angel One credentials or network calls required) — it patches SmartConnect/SmartWebSocketV2 and instrument-master HTTP responses to verify request construction, response normalization, retry/refresh behavior, rate limiting, and the option-chain/quant math.

Disclaimer

This is an independent, community-maintained SDK. It is not affiliated with or endorsed by Angel One or Zerodha. Angel One's SmartAPI field names and per-endpoint rate/history limits are sparsely documented and can change; this SDK parses responses defensively (falling back to None rather than crashing on a missing/renamed field) but you should still verify behavior against your own account before trading with it.

Project details


Download files

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

Source Distribution

angelone_connect-2.0.1.tar.gz (67.5 kB view details)

Uploaded Source

Built Distribution

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

angelone_connect-2.0.1-py3-none-any.whl (67.8 kB view details)

Uploaded Python 3

File details

Details for the file angelone_connect-2.0.1.tar.gz.

File metadata

  • Download URL: angelone_connect-2.0.1.tar.gz
  • Upload date:
  • Size: 67.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.0.1 CPython/3.13.2

File hashes

Hashes for angelone_connect-2.0.1.tar.gz
Algorithm Hash digest
SHA256 7295361b6c28a88692bc8531c9da3ed0881a4f2ae427503cafd696eec1535e49
MD5 be56f1ca2adbe2ca40c21c8104bc2c7e
BLAKE2b-256 b5c89758c0029ab13de61219dfda5495789832b7da91bbdfc864b8bc97493081

See more details on using hashes here.

File details

Details for the file angelone_connect-2.0.1-py3-none-any.whl.

File metadata

File hashes

Hashes for angelone_connect-2.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 f4938735bc99f6389e5c23c0aede152bbd1f9859fbfb1de0ddc97da4b025d250
MD5 d21651327cf0376233f04134f7e41bc9
BLAKE2b-256 e67202628e8756bec7159a0dad8b4e0af95c35b079792a08fc2f7ebaa9823ab6

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page