OpenAlgo — Trading Skill for Indian Markets
OpenAlgo is a broker-agnostic, self-hosted trading platform. One Python
SDK (pip install openalgo) talks to 30+ Indian brokers behind a unified
REST + WebSocket interface. This skill covers the complete SDK surface
plus production-ready helpers and examples for the seven core workflows
traders ask for:
- Order execution — equity, F&O, options-by-offset, multi-leg, basket, split, smart
- Custom execution algos — limit-order chasing, auto-modify, time/price triggered cancel
- Scanners —
multiquotes + history + filter pipelines
- Visualization — heatmaps, OI charts, seasonality, gainers/losers, PCR dashboards
- Backtesting — vectorbt glue with realistic Indian fees, NIFTY benchmark
- Charting — candles (category x-axis, no weekend gaps), depth ladder, option-chain OI, IV smile
- Real-time streaming — LTP / Quote / Depth WebSocket, reconnect loop, callback routing
Setup
pip install -U "openalgo[indicators]"
pip install -r requirements.txt # includes vectorbt, TA-Lib, plotly, duckdb, dotenv
cp .env.sample .env # fill in OPENALGO_API_KEY and host/ws URLs
Minimal init (every script in this skill starts the same way):
import os
from dotenv import find_dotenv, load_dotenv
from openalgo import api
load_dotenv(find_dotenv(), override=False)
client = api(
api_key=os.environ["OPENALGO_API_KEY"],
host=os.environ.get("OPENALGO_HOST", "http://127.0.0.1:5000"),
ws_url=os.environ.get("OPENALGO_WS_URL", "ws://127.0.0.1:8765"),
)
For repo-resident scripts prefer the shared helper:
from scripts.openalgo_client import get_client
client = get_client()
Safety Rules — Always Enforce
- Iterate in analyzer mode first. Toggle
client.analyzertoggle(mode=True) so the SDK simulates responses without hitting the broker. Switch off only after the strategy is reviewed.
- Confirm before live orders. Print a readable preview (symbol, side, qty, product, price, notional) and wait for user confirmation unless the user has explicitly authorized auto-execution for the current session.
- Default to
LIMIT over MARKET. Quote the symbol first and place a marketable-limit at LTP ± a few ticks. MARKET only when the user explicitly asks.
- Validate F&O lot-size multiples. Load the bundled
assets/LotSize.csv (or call client.symbol() for the current lotsize) and reject non-multiples before placement.
- Warn on notional > Rs 50,000. For F&O, use
lotsize × strike as a worst-case proxy when price is unknown.
- Never
CNC on F&O / commodity / currency. Only MIS (intraday) or NRML (overnight) for those segments. CNC is equity-delivery only.
- Never hardcode API keys. Always read from
.env via find_dotenv(). Reject scripts that contain literal 64-char hex keys.
- Multi-leg execution needs explicit per-leg confirmation when run live.
optionsmultiorder and basketorder route to the broker as separate orders that can partially fail — handle the results[] array, don't trust the top-level status.
- Rate limits matter. Order APIs are capped at 10/sec (smart orders 2/sec), data APIs at 50/sec. Use the retry-with-backoff helper in
scripts/orders.py rather than tight loops.
- WebSocket reconnect is the user's responsibility. Use the
subscribe() context manager in scripts/stream.py — it handles auth, heartbeat, and re-subscription on disconnect.
File-Output Convention
When this skill generates code for a specific action, write outputs
into a per-action subfolder, created on-demand (never pre-created):
openalgo_workspace/
├── execution/
│ ├── atm_straddle/ # straddle.py, run.log, trade_journal.csv
│ └── iron_condor/
├── execution_algos/
│ ├── limit_chaser_reliance/ # chaser.py, fills.csv
│ └── twap_slicer_sbin/
├── scanners/
│ ├── rsi_oversold/ # scan.py, results_2026-05-24.csv
│ └── breakout/
├── visualization/
│ └── sector_heatmap/ # heatmap.py, heatmap_2026-05-24.html
├── backtesting/
│ ├── supertrend_sbin/ # backtest.py, trades.csv, equity.html
│ └── ema_crossover_nifty50/
├── charting/
│ └── nifty_option_chain_oi/ # chart.py, oi_27jan26.html
└── streaming/
└── nifty_depth_stream/ # stream.py, ticks.parquet
Each subfolder is self-contained — script, generated data, plots, logs.
The user can rm -rf any folder without affecting others.
Constants — Order Surface
| Category |
Values |
| Exchange |
NSE BSE (equity); NFO BFO (F&O); CDS BCD (currency); MCX NCDEX NCO (commodity); NSE_INDEX BSE_INDEX MCX_INDEX GLOBAL_INDEX (quote-only) |
| Action |
BUY SELL |
| Product |
CNC (equity delivery only), MIS (intraday all segments), NRML (F&O / commodity overnight) |
| Price type |
MARKET, LIMIT, SL (stop-loss limit), SL-M (stop-loss market) |
| Validity |
DAY (default), IOC |
| Option offset |
ATM, ITM1..ITM20, OTM1..OTM20 (resolved against ATM strike by the SDK) |
| WS mode |
1 = LTP, 2 = Quote (OHLC+vol), 3 = Depth (with depth_level 5/20/30/50) |
| WS verbose |
0/False silent, 1/True connection logs, 2 all data updates |
Full grammar in references/order-constants.md and references/symbol-format.md. F&O lot sizes ship as a CSV at assets/LotSize.csv (see references/lot-sizes.md).
Symbol Format Quick-Reference
Equity: RELIANCE (just the base symbol)
Futures: NIFTY30JUN26FUT [base][DDMMMYY]FUT
Options: NIFTY30JUN2626500CE [base][DDMMMYY][strike][CE/PE]
Index quote-only symbols (no trading, use for quotes/history/ws):
NIFTY BANKNIFTY FINNIFTY MIDCPNIFTY NIFTYNXT50 SENSEX BANKEX (and 80+ more — see references/symbol-format.md)
Complete SDK Method Map
| Group |
Method |
Doc |
| Order placement |
placeorder |
order-management |
|
placesmartorder |
"" — position-aware sizing |
|
optionsorder |
"" — by offset (ATM/ITMn/OTMn) |
|
optionsmultiorder |
"" — multi-leg (iron condor, straddle, diagonal) |
|
basketorder |
"" — list of orders, results[] |
|
splitorder |
"" — slice large qty into N chunks |
| Order management |
modifyorder |
"" |
|
cancelorder |
"" |
|
cancelallorder |
"" |
|
closeposition |
"" — square off all |
| GTT (REST-only) |
placegttorder / modifygttorder / cancelgttorder / gttorderbook |
order-management |
| Order info |
orderstatus |
order-information |
|
openposition |
"" — for a specific symbol |
| Market data |
quotes |
market-data |
|
multiquotes |
"" — up to many symbols, used by scanners |
|
depth |
"" — full Level-2 book |
|
history |
"" — source="api" (broker) or source="db" (Historify DuckDB) |
|
intervals |
"" |
| Symbol services |
symbol |
symbol-services |
|
search |
"" — fuzzy lookup |
|
expiry |
"" — F&O expiry dates |
|
instruments |
"" — full master |
| Options analytics |
optionsymbol |
options-services |
|
optionchain |
"" — full CE/PE chain with OI |
|
syntheticfuture |
"" |
|
optiongreeks |
"" — delta/gamma/theta/vega/rho + IV |
| Account |
funds |
account-services |
|
margin |
"" — multi-leg margin calculator |
|
orderbook |
"" |
|
tradebook |
"" |
|
positionbook |
"" |
|
holdings |
"" |
| Calendar |
holidays(year) |
market-calendar |
|
timings(date) |
"" |
|
checkholiday(date) |
"" |
| Analyzer |
analyzerstatus / analyzertoggle(mode=True) |
analyzer-services |
| Alerts |
telegram(username, message) |
alerts |
|
whatsapp(text, to=..., image=..., document=...) |
"" |
| WebSocket |
connect() / disconnect() |
websocket-streaming |
|
subscribe_ltp / subscribe_quote / subscribe_depth (+ unsubscribe variants) |
"" |
|
get_quotes() — pulls latest cached snapshot |
"" |
| Indicators |
from openalgo import ta → ta.supertrend, ta.donchian, ta.ichimoku, ta.hma, ta.kama, ta.alma, ta.zlema, ta.vwma, ta.exrem, ta.crossover, ta.crossunder, ta.flip |
indicators |
The Python SDK doesn't expose every kwarg in its docstrings — when a parameter is missing or unclear, fall back to the per-endpoint REST docs at /Users/openalgo/test-zerodha/openalgo/docs/api/<group>/<endpoint>.md. That tree is parameter-complete.
Quick Template — Place an Order with Preview + Analyzer Safety
import os
from dotenv import find_dotenv, load_dotenv
from openalgo import api
load_dotenv(find_dotenv(), override=False)
client = api(
api_key=os.environ["OPENALGO_API_KEY"],
host=os.environ.get("OPENALGO_HOST", "http://127.0.0.1:5000"),
)
SYMBOL, EXCHANGE = "RELIANCE", "NSE"
ACTION, QTY, PRODUCT = "BUY", 1, "MIS"
# 1. Quote to anchor a marketable limit price (safer than MARKET)
q = client.quotes(symbol=SYMBOL, exchange=EXCHANGE)["data"]
limit_price = round(q["ltp"] * 1.001, 2) if ACTION == "BUY" else round(q["ltp"] * 0.999, 2)
notional = limit_price * QTY
print(f"--- Order Preview ---")
print(f" {ACTION} {QTY} {SYMBOL} @ LIMIT {limit_price} notional Rs {notional:,.2f}")
print(f" Product: {PRODUCT} LTP: {q['ltp']}")
if input("Proceed? [y/N] ").strip().lower() != "y":
raise SystemExit("aborted")
response = client.placeorder(
strategy=os.environ.get("OPENALGO_DEFAULT_STRATEGY", "python"),
symbol=SYMBOL,
exchange=EXCHANGE,
action=ACTION,
price_type="LIMIT",
product=PRODUCT,
quantity=str(QTY),
price=str(limit_price),
)
print("ORDER:", response)
Quick Template — Stream LTP with Reconnect
import os, time
from dotenv import find_dotenv, load_dotenv
from openalgo import api
load_dotenv(find_dotenv(), override=False)
client = api(
api_key=os.environ["OPENALGO_API_KEY"],
host=os.environ.get("OPENALGO_HOST", "http://127.0.0.1:5000"),
ws_url=os.environ.get("OPENALGO_WS_URL", "ws://127.0.0.1:8765"),
verbose=True,
)
instruments = [
{"exchange": "NSE_INDEX", "symbol": "NIFTY"},
{"exchange": "NSE", "symbol": "RELIANCE"},
]
def on_ltp(msg):
d = msg["data"]
print(f"{d['symbol']:<12} LTP {d['ltp']} @ {d['timestamp']}")
client.connect()
client.subscribe_ltp(instruments,
try:
while True:
time.sleep(1)
except KeyboardInterrupt:
client.unsubscribe_ltp(instruments)
client.disconnect()
Quick Template — History from Direct DuckDB (Historify)
client.history(..., source="db") routes through REST. For bulk
multi-symbol pulls or backtesting, hit the DuckDB file directly:
import os, duckdb, pandas as pd
from dotenv import find_dotenv, load_dotenv
load_dotenv(find_dotenv(), override=False)
DB = os.environ["HISTORIFY_DUCKDB_PATH"] # e.g. /srv/openalgo/db/historify.duckdb
con = duckdb.connect(DB, read_only=True)
# Historify schema: table `market_data` with epoch timestamps
df = con.execute("""
SELECT
symbol,
exchange,
to_timestamp(timestamp) AT TIME ZONE 'Asia/Kolkata' AS ts,
open, high, low, close, volume
FROM market_data
WHERE symbol = ?
AND exchange = ?
AND timestamp >= EXTRACT(EPOCH FROM TIMESTAMP '2024-01-01')
ORDER BY timestamp
""", ["SBIN", "NSE"]).fetchdf()
con.close()
df["ts"] = pd.to_datetime(df["ts"]).dt.tz_localize(None)
df = df.set_index("ts")
print(df.tail())
Full Historify usage, multi-symbol joins, and resampling alignment with
NSE 09:15 IST in references/duckdb-historify.md.
Indicator Rule (matches vectorbt-backtesting-skills)
- TA-Lib for the standard set:
EMA, SMA, RSI, MACD, ATR, BBANDS, ADX, STDDEV, MOM.
openalgo.ta for: supertrend, donchian, ichimoku, hma, kama, alma, zlema, vwma.
openalgo.ta for signal cleaning: exrem, crossover, crossunder, flip — always .fillna(False) before exrem.
Never use VectorBT's built-in indicators (vbt.MA.run etc.).
Helper Scripts (scripts/)
| File |
Purpose |
openalgo_client.py |
get_client() — bootstraps from .env with find_dotenv() |
symbols.py |
resolve_symbol, build_fut_symbol, build_opt_symbol, parse_opt_symbol |
lotsize.py |
load_lot_sizes(), nearest_lot(symbol, quantity), validate_fno_lot() |
orders.py |
preview_order, place_with_confirmation, retry_on_rate_limit |
execution.py |
LimitChaser (peg the touch), TWAPSlicer, IcebergSlicer, OrderManager |
option_analytics.py |
atm_strike, pcr, max_pain, iv_skew, payoff_diagram |
scanner.py |
Scanner — multi-symbol filter pipeline over multiquotes + history |
stream.py |
subscribe() context manager — auth, heartbeat, auto-reconnect |
plotting.py |
candlestick_no_gaps, oi_histogram, heatmap, depth_ladder |
duckdb_data.py |
load_ohlcv(symbol, ...) from Historify, multi-symbol bulk pull, resample |
fees.py |
Indian market cost model (equity / F&O / intraday / delivery) |
ta_helpers.py |
Ergonomic wrappers — TA-Lib + openalgo.ta combined |
trade_logger.py |
Persistent CSV/SQLite trade journal |
Examples Catalog (examples/)
| Folder |
Coverage |
01_execution/ |
Equity, ATM straddle, iron condor, basket rebalance, smart-order sizing, supertrend live, GTT OCO |
02_scanners/ |
Gainers/losers, breakout, RSI oversold, volume surge, OI change, pre-open gap |
03_visualization/ |
Sector heatmap, YTD heatmap, CAGR heatmap, seasonality, OI histogram, PCR dashboard |
04_backtesting/ |
EMA crossover, Supertrend, Opening Range Breakout, multi-symbol screener backtest |
05_charting/ |
Candlestick with indicators, option chain OI chart, max pain, IV smile, depth ladder |
06_streaming/ |
LTP, Quote, Depth (20-level), callback router, stream → Telegram alert, reconnect loop |
07_execution_algos/ |
Limit-order chaser, TWAP slicer, iceberg via splitorder, time-based cancel, price-based cancel-and-replace, conditional bracket |
Reference Files (references/)
| Need |
File |
| Order placement / modification / cancellation + GTT |
order-management.md |
| Order status & open positions |
order-information.md |
| Quotes, depth, history, intervals |
market-data.md |
| Symbol, search, expiry, instruments |
symbol-services.md |
| Option chain, Greeks, synthetic future, ATM/ITM/OTM offsets |
options-services.md |
| Funds, margin, books, holdings |
account-services.md |
| Holidays, timings, holiday check |
market-calendar.md |
| Sandbox / analyzer mode |
analyzer-services.md |
| WebSocket protocol, modes, depth_level, verbose |
websocket-streaming.md |
| Telegram + WhatsApp alerts |
alerts.md |
openalgo.ta complete reference |
indicators.md |
| Custom limit-order execution algos (chaser, TWAP, iceberg) |
execution-algos.md |
| Direct DuckDB access to Historify market data |
duckdb-historify.md |
| Equity / Futures / Options symbol grammar + index lists |
symbol-format.md |
| F&O lot sizes (Apr/May/Jun 2026 + how to update) |
lot-sizes.md |
| Constants (exchange, product, price type, action) |
order-constants.md |
| Rate limits & retry guidance |
rate-limits.md |
| Common multi-step recipes |
common-workflows.md |
| Error patterns & troubleshooting |
error-codes.md |
How to Pick Live vs Analyzer Mode
status = client.analyzerstatus()["data"]
if status["analyze_mode"]:
print(f"[ANALYZER] simulated mode — orders will not reach broker. logs: {status['total_logs']}")
else:
print("[LIVE] orders will execute on the broker")
While developing a new strategy: client.analyzertoggle(mode=True). When the user is satisfied: ask for explicit go-live confirmation, then client.analyzertoggle(mode=False).
Output Encoding Rules
- Never put emojis in generated code or log output. Plain ASCII only.
- Plotly charts use
template="plotly_dark" and candlesticks use xaxis_type="category" to skip weekend gaps.
- Trade journals / scan results write to CSV with a date-stamped filename inside the action's workspace folder.
- All datetime indexes are tz-naive after dropping
Asia/Kolkata (matches the vectorbt skill's convention so dataframes round-trip cleanly).
1---2name: openalgo3description: OpenAlgo agent skill — comprehensive coverage of the OpenAlgo Python SDK for Indian markets (NSE / BSE / NFO / BFO / CDS / BCD / MCX / NCO). Use when the user asks to place / modify / cancel orders, build a limit-order-chasing or custom execution algo, fetch quotes / depth / historical OHLCV (REST or direct DuckDB Historify), pull option chains with Greeks, calculate margin or funds, stream live LTP / Quote / Depth over WebSocket, build a scanner, render a heatmap / OI chart / candlestick, backtest a strategy with vectorbt, send Telegram / WhatsApp alerts, or toggle analyzer (sandbox) mode. Also triggers for general questions about programmatic trading on Indian exchanges when OpenAlgo is the user's platform.4---56# OpenAlgo — Trading Skill for Indian Markets78OpenAlgo is a broker-agnostic, self-hosted trading platform. One Python9SDK (`pip install openalgo`) talks to 30+ Indian brokers behind a unified10REST + WebSocket interface. This skill covers the complete SDK surface11plus production-ready helpers and examples for the seven core workflows12traders ask for:13141. **Order execution** — equity, F&O, options-by-offset, multi-leg, basket, split, smart152. **Custom execution algos** — limit-order chasing, auto-modify, time/price triggered cancel163. **Scanners** — `multiquotes` + history + filter pipelines174. **Visualization** — heatmaps, OI charts, seasonality, gainers/losers, PCR dashboards185. **Backtesting** — vectorbt glue with realistic Indian fees, NIFTY benchmark196. **Charting** — candles (category x-axis, no weekend gaps), depth ladder, option-chain OI, IV smile207. **Real-time streaming** — LTP / Quote / Depth WebSocket, reconnect loop, callback routing2122## Setup2324```bash25pip install -U "openalgo[indicators]"26pip install -r requirements.txt # includes vectorbt, TA-Lib, plotly, duckdb, dotenv27cp .env.sample .env # fill in OPENALGO_API_KEY and host/ws URLs28```2930Minimal init (every script in this skill starts the same way):3132```python33import os34from dotenv import find_dotenv, load_dotenv35from openalgo import api3637load_dotenv(find_dotenv(), override=False)3839client = api(40 api_key=os.environ["OPENALGO_API_KEY"],41 host=os.environ.get("OPENALGO_HOST", "http://127.0.0.1:5000"),42 ws_url=os.environ.get("OPENALGO_WS_URL", "ws://127.0.0.1:8765"),43)44```4546For repo-resident scripts prefer the shared helper:4748```python49from scripts.openalgo_client import get_client50client = get_client()51```5253## Safety Rules — Always Enforce54551. **Iterate in analyzer mode first.** Toggle `client.analyzertoggle(mode=True)` so the SDK simulates responses without hitting the broker. Switch off only after the strategy is reviewed.562. **Confirm before live orders.** Print a readable preview (symbol, side, qty, product, price, notional) and wait for user confirmation unless the user has explicitly authorized auto-execution for the current session.573. **Default to `LIMIT` over `MARKET`.** Quote the symbol first and place a marketable-limit at LTP ± a few ticks. MARKET only when the user explicitly asks.584. **Validate F&O lot-size multiples.** Load the bundled `assets/LotSize.csv` (or call `client.symbol()` for the current `lotsize`) and reject non-multiples before placement.595. **Warn on notional > Rs 50,000.** For F&O, use `lotsize × strike` as a worst-case proxy when price is unknown.606. **Never `CNC` on F&O / commodity / currency.** Only `MIS` (intraday) or `NRML` (overnight) for those segments. `CNC` is equity-delivery only.617. **Never hardcode API keys.** Always read from `.env` via `find_dotenv()`. Reject scripts that contain literal 64-char hex keys.628. **Multi-leg execution needs explicit per-leg confirmation** when run live. `optionsmultiorder` and `basketorder` route to the broker as separate orders that can partially fail — handle the `results[]` array, don't trust the top-level `status`.639. **Rate limits matter.** Order APIs are capped at 10/sec (smart orders 2/sec), data APIs at 50/sec. Use the retry-with-backoff helper in `scripts/orders.py` rather than tight loops.6410. **WebSocket reconnect is the user's responsibility.** Use the `subscribe()` context manager in `scripts/stream.py` — it handles auth, heartbeat, and re-subscription on disconnect.6566## File-Output Convention6768When this skill **generates** code for a specific action, write outputs69into a per-action subfolder, created on-demand (never pre-created):7071```72openalgo_workspace/73├── execution/74│ ├── atm_straddle/ # straddle.py, run.log, trade_journal.csv75│ └── iron_condor/76├── execution_algos/77│ ├── limit_chaser_reliance/ # chaser.py, fills.csv78│ └── twap_slicer_sbin/79├── scanners/80│ ├── rsi_oversold/ # scan.py, results_2026-05-24.csv81│ └── breakout/82├── visualization/83│ └── sector_heatmap/ # heatmap.py, heatmap_2026-05-24.html84├── backtesting/85│ ├── supertrend_sbin/ # backtest.py, trades.csv, equity.html86│ └── ema_crossover_nifty50/87├── charting/88│ └── nifty_option_chain_oi/ # chart.py, oi_27jan26.html89└── streaming/90 └── nifty_depth_stream/ # stream.py, ticks.parquet91```9293Each subfolder is self-contained — script, generated data, plots, logs.94The user can `rm -rf` any folder without affecting others.9596## Constants — Order Surface9798| Category | Values |99|----------|--------|100| **Exchange** | `NSE` `BSE` (equity); `NFO` `BFO` (F&O); `CDS` `BCD` (currency); `MCX` `NCDEX` `NCO` (commodity); `NSE_INDEX` `BSE_INDEX` `MCX_INDEX` `GLOBAL_INDEX` (quote-only) |101| **Action** | `BUY` `SELL` |102| **Product** | `CNC` (equity delivery only), `MIS` (intraday all segments), `NRML` (F&O / commodity overnight) |103| **Price type** | `MARKET`, `LIMIT`, `SL` (stop-loss limit), `SL-M` (stop-loss market) |104| **Validity** | `DAY` (default), `IOC` |105| **Option offset** | `ATM`, `ITM1`..`ITM20`, `OTM1`..`OTM20` (resolved against ATM strike by the SDK) |106| **WS mode** | `1` = LTP, `2` = Quote (OHLC+vol), `3` = Depth (with `depth_level` 5/20/30/50) |107| **WS verbose** | `0`/`False` silent, `1`/`True` connection logs, `2` all data updates |108109Full grammar in [references/order-constants.md](references/order-constants.md) and [references/symbol-format.md](references/symbol-format.md). F&O lot sizes ship as a CSV at `assets/LotSize.csv` (see [references/lot-sizes.md](references/lot-sizes.md)).110111## Symbol Format Quick-Reference112113```114Equity: RELIANCE (just the base symbol)115Futures: NIFTY30JUN26FUT [base][DDMMMYY]FUT116Options: NIFTY30JUN2626500CE [base][DDMMMYY][strike][CE/PE]117```118119Index quote-only symbols (no trading, use for `quotes`/`history`/`ws`):120`NIFTY` `BANKNIFTY` `FINNIFTY` `MIDCPNIFTY` `NIFTYNXT50` `SENSEX` `BANKEX` (and 80+ more — see [references/symbol-format.md](references/symbol-format.md))121122## Complete SDK Method Map123124| Group | Method | Doc |125|-------|--------|-----|126| **Order placement** | `placeorder` | [order-management](references/order-management.md) |127| | `placesmartorder` | "" — position-aware sizing |128| | `optionsorder` | "" — by `offset` (ATM/ITMn/OTMn) |129| | `optionsmultiorder` | "" — multi-leg (iron condor, straddle, diagonal) |130| | `basketorder` | "" — list of orders, results[] |131| | `splitorder` | "" — slice large qty into N chunks |132| **Order management** | `modifyorder` | "" |133| | `cancelorder` | "" |134| | `cancelallorder` | "" |135| | `closeposition` | "" — square off all |136| **GTT (REST-only)** | `placegttorder` / `modifygttorder` / `cancelgttorder` / `gttorderbook` | [order-management](references/order-management.md#gtt) |137| **Order info** | `orderstatus` | [order-information](references/order-information.md) |138| | `openposition` | "" — for a specific symbol |139| **Market data** | `quotes` | [market-data](references/market-data.md) |140| | `multiquotes` | "" — up to many symbols, used by scanners |141| | `depth` | "" — full Level-2 book |142| | `history` | "" — `source="api"` (broker) or `source="db"` (Historify DuckDB) |143| | `intervals` | "" |144| **Symbol services** | `symbol` | [symbol-services](references/symbol-services.md) |145| | `search` | "" — fuzzy lookup |146| | `expiry` | "" — F&O expiry dates |147| | `instruments` | "" — full master |148| **Options analytics** | `optionsymbol` | [options-services](references/options-services.md) |149| | `optionchain` | "" — full CE/PE chain with OI |150| | `syntheticfuture` | "" |151| | `optiongreeks` | "" — delta/gamma/theta/vega/rho + IV |152| **Account** | `funds` | [account-services](references/account-services.md) |153| | `margin` | "" — multi-leg margin calculator |154| | `orderbook` | "" |155| | `tradebook` | "" |156| | `positionbook` | "" |157| | `holdings` | "" |158| **Calendar** | `holidays(year)` | [market-calendar](references/market-calendar.md) |159| | `timings(date)` | "" |160| | `checkholiday(date)` | "" |161| **Analyzer** | `analyzerstatus` / `analyzertoggle(mode=True)` | [analyzer-services](references/analyzer-services.md) |162| **Alerts** | `telegram(username, message)` | [alerts](references/alerts.md) |163| | `whatsapp(text, to=..., image=..., document=...)` | "" |164| **WebSocket** | `connect()` / `disconnect()` | [websocket-streaming](references/websocket-streaming.md) |165| | `subscribe_ltp` / `subscribe_quote` / `subscribe_depth` (+ unsubscribe variants) | "" |166| | `get_quotes()` — pulls latest cached snapshot | "" |167| **Indicators** | `from openalgo import ta` → `ta.supertrend`, `ta.donchian`, `ta.ichimoku`, `ta.hma`, `ta.kama`, `ta.alma`, `ta.zlema`, `ta.vwma`, `ta.exrem`, `ta.crossover`, `ta.crossunder`, `ta.flip` | [indicators](references/indicators.md) |168169The Python SDK doesn't expose every kwarg in its docstrings — when a parameter is missing or unclear, fall back to the per-endpoint REST docs at `/Users/openalgo/test-zerodha/openalgo/docs/api/<group>/<endpoint>.md`. That tree is parameter-complete.170171## Quick Template — Place an Order with Preview + Analyzer Safety172173```python174import os175from dotenv import find_dotenv, load_dotenv176from openalgo import api177178load_dotenv(find_dotenv(), override=False)179client = api(180 api_key=os.environ["OPENALGO_API_KEY"],181 host=os.environ.get("OPENALGO_HOST", "http://127.0.0.1:5000"),182)183184SYMBOL, EXCHANGE = "RELIANCE", "NSE"185ACTION, QTY, PRODUCT = "BUY", 1, "MIS"186187# 1. Quote to anchor a marketable limit price (safer than MARKET)188q = client.quotes(symbol=SYMBOL, exchange=EXCHANGE)["data"]189limit_price = round(q["ltp"] * 1.001, 2) if ACTION == "BUY" else round(q["ltp"] * 0.999, 2)190notional = limit_price * QTY191192print(f"--- Order Preview ---")193print(f" {ACTION} {QTY} {SYMBOL} @ LIMIT {limit_price} notional Rs {notional:,.2f}")194print(f" Product: {PRODUCT} LTP: {q['ltp']}")195196if input("Proceed? [y/N] ").strip().lower() != "y":197 raise SystemExit("aborted")198199response = client.placeorder(200 strategy=os.environ.get("OPENALGO_DEFAULT_STRATEGY", "python"),201 symbol=SYMBOL,202 exchange=EXCHANGE,203 action=ACTION,204 price_type="LIMIT",205 product=PRODUCT,206 quantity=str(QTY),207 price=str(limit_price),208)209print("ORDER:", response)210```211212## Quick Template — Stream LTP with Reconnect213214```python215import os, time216from dotenv import find_dotenv, load_dotenv217from openalgo import api218219load_dotenv(find_dotenv(), override=False)220client = api(221 api_key=os.environ["OPENALGO_API_KEY"],222 host=os.environ.get("OPENALGO_HOST", "http://127.0.0.1:5000"),223 ws_url=os.environ.get("OPENALGO_WS_URL", "ws://127.0.0.1:8765"),224 verbose=True,225)226227instruments = [228 {"exchange": "NSE_INDEX", "symbol": "NIFTY"},229 {"exchange": "NSE", "symbol": "RELIANCE"},230]231232def on_ltp(msg):233 d = msg["data"]234 print(f"{d['symbol']:<12} LTP {d['ltp']} @ {d['timestamp']}")235236client.connect()237client.subscribe_ltp(instruments, on_data_received=on_ltp)238239try:240 while True:241 time.sleep(1)242except KeyboardInterrupt:243 client.unsubscribe_ltp(instruments)244 client.disconnect()245```246247## Quick Template — History from Direct DuckDB (Historify)248249`client.history(..., source="db")` routes through REST. For bulk250multi-symbol pulls or backtesting, hit the DuckDB file directly:251252```python253import os, duckdb, pandas as pd254from dotenv import find_dotenv, load_dotenv255256load_dotenv(find_dotenv(), override=False)257DB = os.environ["HISTORIFY_DUCKDB_PATH"] # e.g. /srv/openalgo/db/historify.duckdb258259con = duckdb.connect(DB, read_only=True)260261# Historify schema: table `market_data` with epoch timestamps262df = con.execute("""263 SELECT264 symbol,265 exchange,266 to_timestamp(timestamp) AT TIME ZONE 'Asia/Kolkata' AS ts,267 open, high, low, close, volume268 FROM market_data269 WHERE symbol = ?270 AND exchange = ?271 AND timestamp >= EXTRACT(EPOCH FROM TIMESTAMP '2024-01-01')272 ORDER BY timestamp273""", ["SBIN", "NSE"]).fetchdf()274con.close()275276df["ts"] = pd.to_datetime(df["ts"]).dt.tz_localize(None)277df = df.set_index("ts")278print(df.tail())279```280281Full Historify usage, multi-symbol joins, and resampling alignment with282NSE 09:15 IST in [references/duckdb-historify.md](references/duckdb-historify.md).283284## Indicator Rule (matches vectorbt-backtesting-skills)285286- **TA-Lib** for the standard set: `EMA`, `SMA`, `RSI`, `MACD`, `ATR`, `BBANDS`, `ADX`, `STDDEV`, `MOM`.287- **`openalgo.ta`** for: `supertrend`, `donchian`, `ichimoku`, `hma`, `kama`, `alma`, `zlema`, `vwma`.288- **`openalgo.ta`** for signal cleaning: `exrem`, `crossover`, `crossunder`, `flip` — always `.fillna(False)` before `exrem`.289290Never use VectorBT's built-in indicators (`vbt.MA.run` etc.).291292## Helper Scripts (`scripts/`)293294| File | Purpose |295|------|---------|296| `openalgo_client.py` | `get_client()` — bootstraps from `.env` with `find_dotenv()` |297| `symbols.py` | `resolve_symbol`, `build_fut_symbol`, `build_opt_symbol`, `parse_opt_symbol` |298| `lotsize.py` | `load_lot_sizes()`, `nearest_lot(symbol, quantity)`, `validate_fno_lot()` |299| `orders.py` | `preview_order`, `place_with_confirmation`, `retry_on_rate_limit` |300| `execution.py` | `LimitChaser` (peg the touch), `TWAPSlicer`, `IcebergSlicer`, `OrderManager` |301| `option_analytics.py` | `atm_strike`, `pcr`, `max_pain`, `iv_skew`, `payoff_diagram` |302| `scanner.py` | `Scanner` — multi-symbol filter pipeline over `multiquotes` + `history` |303| `stream.py` | `subscribe()` context manager — auth, heartbeat, auto-reconnect |304| `plotting.py` | `candlestick_no_gaps`, `oi_histogram`, `heatmap`, `depth_ladder` |305| `duckdb_data.py` | `load_ohlcv(symbol, ...)` from Historify, multi-symbol bulk pull, resample |306| `fees.py` | Indian market cost model (equity / F&O / intraday / delivery) |307| `ta_helpers.py` | Ergonomic wrappers — TA-Lib + `openalgo.ta` combined |308| `trade_logger.py` | Persistent CSV/SQLite trade journal |309310## Examples Catalog (`examples/`)311312| Folder | Coverage |313|--------|----------|314| `01_execution/` | Equity, ATM straddle, iron condor, basket rebalance, smart-order sizing, supertrend live, GTT OCO |315| `02_scanners/` | Gainers/losers, breakout, RSI oversold, volume surge, OI change, pre-open gap |316| `03_visualization/` | Sector heatmap, YTD heatmap, CAGR heatmap, seasonality, OI histogram, PCR dashboard |317| `04_backtesting/` | EMA crossover, Supertrend, Opening Range Breakout, multi-symbol screener backtest |318| `05_charting/` | Candlestick with indicators, option chain OI chart, max pain, IV smile, depth ladder |319| `06_streaming/` | LTP, Quote, Depth (20-level), callback router, stream → Telegram alert, reconnect loop |320| `07_execution_algos/` | **Limit-order chaser, TWAP slicer, iceberg via splitorder, time-based cancel, price-based cancel-and-replace, conditional bracket** |321322## Reference Files (`references/`)323324| Need | File |325|------|------|326| Order placement / modification / cancellation + GTT | [order-management.md](references/order-management.md) |327| Order status & open positions | [order-information.md](references/order-information.md) |328| Quotes, depth, history, intervals | [market-data.md](references/market-data.md) |329| Symbol, search, expiry, instruments | [symbol-services.md](references/symbol-services.md) |330| Option chain, Greeks, synthetic future, ATM/ITM/OTM offsets | [options-services.md](references/options-services.md) |331| Funds, margin, books, holdings | [account-services.md](references/account-services.md) |332| Holidays, timings, holiday check | [market-calendar.md](references/market-calendar.md) |333| Sandbox / analyzer mode | [analyzer-services.md](references/analyzer-services.md) |334| WebSocket protocol, modes, depth_level, verbose | [websocket-streaming.md](references/websocket-streaming.md) |335| Telegram + WhatsApp alerts | [alerts.md](references/alerts.md) |336| `openalgo.ta` complete reference | [indicators.md](references/indicators.md) |337| Custom limit-order execution algos (chaser, TWAP, iceberg) | [execution-algos.md](references/execution-algos.md) |338| Direct DuckDB access to Historify market data | [duckdb-historify.md](references/duckdb-historify.md) |339| Equity / Futures / Options symbol grammar + index lists | [symbol-format.md](references/symbol-format.md) |340| F&O lot sizes (Apr/May/Jun 2026 + how to update) | [lot-sizes.md](references/lot-sizes.md) |341| Constants (exchange, product, price type, action) | [order-constants.md](references/order-constants.md) |342| Rate limits & retry guidance | [rate-limits.md](references/rate-limits.md) |343| Common multi-step recipes | [common-workflows.md](references/common-workflows.md) |344| Error patterns & troubleshooting | [error-codes.md](references/error-codes.md) |345346## How to Pick Live vs Analyzer Mode347348```python349status = client.analyzerstatus()["data"]350if status["analyze_mode"]:351 print(f"[ANALYZER] simulated mode — orders will not reach broker. logs: {status['total_logs']}")352else:353 print("[LIVE] orders will execute on the broker")354```355356While developing a new strategy: `client.analyzertoggle(mode=True)`. When the user is satisfied: ask for explicit go-live confirmation, then `client.analyzertoggle(mode=False)`.357358## Output Encoding Rules359360- Never put emojis in generated code or log output. Plain ASCII only.361- Plotly charts use `template="plotly_dark"` and candlesticks use `xaxis_type="category"` to skip weekend gaps.362- Trade journals / scan results write to CSV with a date-stamped filename inside the action's workspace folder.363- All datetime indexes are tz-naive after dropping `Asia/Kolkata` (matches the vectorbt skill's convention so dataframes round-trip cleanly).