OpenAlgo Indicator Expert Skill
Environment
- Python with openalgo, pandas, numpy, plotly, dash, streamlit, numba
- Data sources: OpenAlgo (Indian markets via
client.history(), client.quotes(), client.depth()), yfinance (US/Global)
- Real-time: OpenAlgo WebSocket (
client.connect(), subscribe_ltp, subscribe_quote, subscribe_depth)
- Indicators: openalgo.ta (ALWAYS β 100+ Numba-optimized indicators)
- Charts: Plotly with
template="plotly_dark"
- Dashboards: Plotly Dash with
dash-bootstrap-components OR Streamlit with st.plotly_chart()
- Custom indicators: Numba
@njit(cache=True, nogil=True) + NumPy
- API keys loaded from single root
.env via python-dotenv + find_dotenv() β never hardcode keys
- Scripts go in appropriate directories (charts/, dashboards/, custom_indicators/, scanners/) created on-demand
- Never use icons/emojis in code or logger output
Critical Rules
- ALWAYS use openalgo.ta for ALL technical indicators. Never reimplement what already exists in the library.
- Data normalization: Always convert DataFrame index to datetime, sort, and strip timezone after fetching.
- Signal cleaning: Always use
ta.exrem() after generating raw buy/sell signals. Always .fillna(False) before exrem.
- Plotly dark theme: All charts use
template="plotly_dark" with xaxis type="category" for candlesticks.
- Numba for custom indicators: Use
@njit(cache=True, nogil=True) β never fastmath=True (breaks NaN handling).
- Input flexibility: openalgo.ta accepts numpy arrays, pandas Series, or lists. Output matches input type.
- WebSocket feeds: Use
client.connect(), client.subscribe_ltp() / subscribe_quote() / subscribe_depth() for real-time data.
- Environment: Load
.env from project root via find_dotenv() β never hardcode API keys.
- Market detection: If symbol looks Indian (SBIN, RELIANCE, NIFTY), use OpenAlgo. If US (AAPL, MSFT), use yfinance.
- Always explain chart outputs in plain language so traders understand what the indicator shows.
Data Source Priority
| Market |
Data Source |
Method |
Example Symbols |
| India (equity) |
OpenAlgo |
client.history() |
SBIN, RELIANCE, INFY |
| India (index) |
OpenAlgo |
client.history(exchange="NSE_INDEX") |
NIFTY, BANKNIFTY |
| India (F&O) |
OpenAlgo |
client.history(exchange="NFO") |
NIFTY30DEC25FUT |
| US/Global |
yfinance |
yf.download() |
AAPL, MSFT, SPY |
OpenAlgo API Methods for Data
| Method |
Purpose |
Returns |
client.history(symbol, exchange, interval, start_date, end_date) |
OHLCV candles |
DataFrame (timestamp, open, high, low, close, volume) |
client.quotes(symbol, exchange) |
Real-time snapshot |
Dict (open, high, low, ltp, bid, ask, prev_close, volume) |
client.multiquotes(symbols=[...]) |
Multi-symbol quotes |
List of quote dicts |
client.depth(symbol, exchange) |
Market depth (L5) |
Dict (bids, asks, ohlc, volume, oi) |
client.intervals() |
Available intervals |
Dict (minutes, hours, days, weeks, months) |
client.connect() |
WebSocket connect |
None (sets up WS connection) |
client.subscribe_ltp(instruments, callback) |
Live LTP stream |
Callback with {symbol, exchange, ltp} |
client.subscribe_quote(instruments, callback) |
Live quote stream |
Callback with {symbol, exchange, ohlc, ltp, volume} |
client.subscribe_depth(instruments, callback) |
Live depth stream |
Callback with {symbol, exchange, bids, asks} |
Indicator Library Reference
All indicators accessed via from openalgo import ta:
Trend (20)
ta.sma, ta.ema, ta.wma, ta.dema, ta.tema, ta.hma, ta.vwma, ta.alma, ta.kama, ta.zlema, ta.t3, ta.frama, ta.supertrend, ta.ichimoku, ta.chande_kroll_stop, ta.trima, ta.mcginley, ta.vidya, ta.alligator, ta.ma_envelopes
Momentum (9)
ta.rsi, ta.macd, ta.stochastic, ta.cci, ta.williams_r, ta.bop, ta.elder_ray, ta.fisher, ta.crsi
Volatility (16)
ta.atr, ta.bbands, ta.keltner, ta.donchian, ta.chaikin_volatility, ta.natr, ta.rvi, ta.ultimate_oscillator, ta.true_range, ta.massindex, ta.bb_percent, ta.bb_width, ta.chandelier_exit, ta.historical_volatility, ta.ulcer_index, ta.starc
Volume (14)
ta.obv, ta.obv_smoothed, ta.vwap, ta.mfi, ta.adl, ta.cmf, ta.emv, ta.force_index, ta.nvi, ta.pvi, ta.volosc, ta.vroc, ta.kvo, ta.pvt
Oscillators (20+)
ta.cmo, ta.trix, ta.uo_oscillator, ta.awesome_oscillator, ta.accelerator_oscillator, ta.ppo, ta.po, ta.dpo, ta.aroon_oscillator, ta.stoch_rsi, ta.rvi_oscillator, ta.cho, ta.chop, ta.kst, ta.tsi, ta.vortex, ta.gator_oscillator, ta.stc, ta.coppock, ta.roc
Statistical (9)
ta.linreg, ta.lrslope, ta.correlation, ta.beta, ta.variance, ta.tsf, ta.median, ta.mode, ta.median_bands
Hybrid (6+)
ta.adx, ta.dmi, ta.aroon, ta.pivot_points, ta.sar, ta.williams_fractals, ta.rwi
Utilities
ta.crossover, ta.crossunder, ta.cross, ta.highest, ta.lowest, ta.change, ta.roc, ta.stdev, ta.exrem, ta.flip, ta.valuewhen, ta.rising, ta.falling
Modular Rule Files
Detailed reference for each topic is in rules/:
| Rule File |
Topic |
| indicator-catalog |
Complete 100+ indicator reference with signatures and parameters |
| data-fetching |
OpenAlgo history/quotes/depth, yfinance, data normalization |
| plotting |
Plotly candlestick, overlay, subplot, multi-panel charts |
| custom-indicators |
Building custom indicators with Numba + NumPy |
| websocket-feeds |
Real-time LTP/Quote/Depth streaming via WebSocket |
| numba-optimization |
Numba JIT patterns, cache, nogil, NaN handling |
| dashboard-patterns |
Plotly Dash web applications with callbacks |
| streamlit-patterns |
Streamlit web applications with sidebar, metrics, plotly charts |
| multi-timeframe |
Multi-timeframe indicator analysis |
| signal-generation |
Signal generation, cleaning, crossover/crossunder |
| indicator-combinations |
Combining indicators for confluence analysis |
| symbol-format |
OpenAlgo symbol format, exchange codes, index symbols |
Chart Templates (in rules/assets/)
| Template |
Path |
Description |
| EMA Chart |
assets/ema_chart/chart.py |
EMA overlay on candlestick |
| RSI Chart |
assets/rsi_chart/chart.py |
RSI with overbought/oversold zones |
| MACD Chart |
assets/macd_chart/chart.py |
MACD line, signal, histogram |
| Supertrend |
assets/supertrend_chart/chart.py |
Supertrend overlay with direction coloring |
| Bollinger |
assets/bollinger_chart/chart.py |
Bollinger Bands with squeeze detection |
| Multi-Indicator |
assets/multi_indicator/chart.py |
Candlestick + EMA + RSI + MACD + Volume |
| Basic Dashboard |
assets/dashboard_basic/app.py |
Single-symbol Plotly Dash app |
| Multi Dashboard |
assets/dashboard_multi/app.py |
Multi-symbol multi-timeframe dashboard |
| Streamlit Basic |
assets/streamlit_basic/app.py |
Single-symbol Streamlit app |
| Streamlit Multi |
assets/streamlit_multi/app.py |
Multi-timeframe Streamlit app |
| Custom Indicator |
assets/custom_indicator/template.py |
Numba custom indicator template |
| Live Feed |
assets/live_feed/template.py |
WebSocket real-time indicator |
| Scanner |
assets/scanner/template.py |
Multi-symbol indicator scanner |
Quick Template: Standard Indicator Chart Script
import os
from datetime import datetime, timedelta
from pathlib import Path
import numpy as np
import pandas as pd
import plotly.graph_objects as go
from plotly.subplots import make_subplots
from dotenv import find_dotenv, load_dotenv
from openalgo import api, ta
script_dir = Path(__file__).resolve().parent
load_dotenv(find_dotenv(), override=False)
SYMBOL = "SBIN"
EXCHANGE = "NSE"
INTERVAL = "D"
client = api(
api_key=os.getenv("OPENALGO_API_KEY"),
host=os.getenv("OPENALGO_HOST", "http://127.0.0.1:5000"),
)
end_date = datetime.now().date()
start_date = end_date - timedelta(days=365)
df = client.history(
symbol=SYMBOL, exchange=EXCHANGE, interval=INTERVAL,
start_date=start_date.strftime("%Y-%m-%d"),
end_date=end_date.strftime("%Y-%m-%d"),
)
if "timestamp" in df.columns:
df["timestamp"] = pd.to_datetime(df["timestamp"])
df = df.set_index("timestamp")
else:
df.index = pd.to_datetime(df.index)
df = df.sort_index()
if df.index.tz is not None:
df.index = df.index.tz_convert(None)
close = df["close"]
high = df["high"]
low = df["low"]
volume = df["volume"]
ema_20 = ta.ema(close, 20)
rsi_14 = ta.rsi(close, 14)
fig = make_subplots(
rows=2, cols=1, shared_xaxes=True,
row_heights=[0.7, 0.3], vertical_spacing=0.03,
subplot_titles=[f"{SYMBOL} Price + EMA(20)"