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, previouslysmartapi_login). If you're upgrading from the oldsmartapi_login1.x package, see Migrating from 1.x below — your old code keeps working via a deprecated compatibility shim, you just need topip install angelone-connectand change your top-level import fromsmartapi_logintoangelone_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 aTokenExpiredErrortriggers an automatic session refresh before retrying — seeangelone_connect.utils.retryandangelone_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_ttlseconds (default 24h); override per-deployment. - Exceptions: every error surfaces as a
angelone_connect.exceptions.SmartAPIErrorsubclass (AuthenticationError,TokenExpiredError,RateLimitError,OrderError,InstrumentNotFoundError, ...) — SmartApi's rawsmartExceptionsare translated automatically. - Thread safety:
SessionManagerguards 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
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7295361b6c28a88692bc8531c9da3ed0881a4f2ae427503cafd696eec1535e49
|
|
| MD5 |
be56f1ca2adbe2ca40c21c8104bc2c7e
|
|
| BLAKE2b-256 |
b5c89758c0029ab13de61219dfda5495789832b7da91bbdfc864b8bc97493081
|
File details
Details for the file angelone_connect-2.0.1-py3-none-any.whl.
File metadata
- Download URL: angelone_connect-2.0.1-py3-none-any.whl
- Upload date:
- Size: 67.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.0.1 CPython/3.13.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f4938735bc99f6389e5c23c0aede152bbd1f9859fbfb1de0ddc97da4b025d250
|
|
| MD5 |
d21651327cf0376233f04134f7e41bc9
|
|
| BLAKE2b-256 |
e67202628e8756bec7159a0dad8b4e0af95c35b079792a08fc2f7ebaa9823ab6
|