Volatility
Volatility indicators measure the degree of price variation in financial instruments. They help traders assess market uncertainty, risk levels, and potential breakout conditions. OpenAlgo provides a comprehensive collection of volatility indicators optimized for performance and accuracy.
Import Statement
from openalgo import ta
from openalgo import api
# Initialize API client
client = api(api_key='your_api_key_here', host='http://127.0.0.1:5000')
# Get sample data
df = client.history(symbol="SBIN", exchange="NSE", interval="5m",
start_date="2025-04-01", end_date="2025-04-08")
Available Volatility Indicators
Average True Range (ATR)
ATR measures market volatility by decomposing the entire range of an asset price for that period. It's one of the most widely used volatility indicators.
Usage
atr_result = ta.atr(high, low, close, period=14)
Parameters
- high (array-like): High prices
- low (array-like): Low prices
- close (array-like): Closing prices
- period (int, default=14): Number of periods for ATR calculation
Returns
- array: ATR values in the same format as input
Example
# Calculate 14-period ATR
atr_14 = ta.atr(df['high'], df['low'], df['close'], period=14)
df['ATR_14'] = atr_14
# Calculate 21-period ATR
atr_21 = ta.atr(df['high'], df['low'], df['close'], period=21)
df['ATR_21'] = atr_21
print(df[['close', 'ATR_14', 'ATR_21']].tail())
Bollinger Bands
Bollinger Bands consist of a middle band (SMA) and two outer bands that are standard deviations away from the middle band, used to identify overbought and oversold conditions.
Usage
upper, middle, lower = ta.bbands(data, period=20, std_dev=2.0)
Parameters
- data (array-like): Price data (typically closing prices)
- period (int, default=20): Number of periods for moving average and standard deviation
- std_dev (float, default=2.0): Number of standard deviations for the bands
Returns
- tuple: (upper_band, middle_band, lower_band) arrays
Example
# Calculate Bollinger Bands
bb_upper, bb_middle, bb_lower = ta.bbands(df['close'], period=20, std_dev=2.0)
df['BB_Upper'] = bb_upper
df['BB_Middle'] = bb_middle
df['BB_Lower'] = bb_lower
# Calculate tighter bands
bb_upper_tight, bb_middle_tight, bb_lower_tight = ta.bbands(df['close'], period=20, std_dev=1.5)
df['BB_Upper_Tight'] = bb_upper_tight
df['BB_Lower_Tight'] = bb_lower_tight
print(df[['close', 'BB_Upper', 'BB_Middle', 'BB_Lower']].tail())
Keltner Channel
Keltner Channels are volatility-based envelopes set above and below an exponential moving average, using ATR to set channel distance.
Usage
upper, middle, lower = ta.keltner(high, low, close, ema_period=20, atr_period=10, multiplier=2.0)
Parameters
- high (array-like): High prices
- low (array-like): Low prices
- close (array-like): Closing prices
- ema_period (int, default=20): Period for the EMA calculation
- atr_period (int, default=10): Period for the ATR calculation
- multiplier (float, default=2.0): Multiplier for the ATR
Returns
- tuple: (upper_channel, middle_line, lower_channel) arrays
Example
# Calculate Keltner Channel
kc_upper, kc_middle, kc_lower = ta.keltner(df['high'], df['low'], df['close'])
df['KC_Upper'] = kc_upper
df['KC_Middle'] = kc_middle
df['KC_Lower'] = kc_lower
# Custom parameters
kc_upper_custom, kc_middle_custom, kc_lower_custom = ta.keltner(
df['high'], df['low'], df['close'],
ema_period=14, atr_period=14, multiplier=1.5
)
print(df[['close', 'KC_Upper', 'KC_Middle', 'KC_Lower']].tail())
Donchian Channel
Donchian Channels are formed by taking the highest high and lowest low of the last n periods, providing dynamic support and resistance levels.
Usage
upper, middle, lower = ta.donchian(high, low, period=20)
Parameters
- high (array-like): High prices
- low (array-like): Low prices
- period (int, default=20): Number of periods for the channel calculation
Returns
- tuple: (upper_channel, middle_line, lower_channel) arrays
Example
# Calculate Donchian Channel
dc_upper, dc_middle, dc_lower = ta.donchian(df['high'], df['low'], period=20)
df['DC_Upper'] = dc_upper
df['DC_Middle'] = dc_middle
df['DC_Lower'] = dc_lower
# Different periods
dc_upper_10, dc_middle_10, dc_lower_10 = ta.donchian(df['high'], df['low'], period=10)
df['DC_Upper_10'] = dc_upper_10
df['DC_Lower_10'] = dc_lower_10
print(df[['high', 'low', 'DC_Upper', 'DC_Middle', 'DC_Lower']].tail())
Chaikin Volatility
Chaikin Volatility measures the rate of change of the trading range, indicating periods of increasing or decreasing volatility.
Usage
cv_result = ta.chaikin(high, low, ema_period=10, roc_period=10)
Parameters
- high (array-like): High prices
- low (array-like): Low prices
- ema_period (int, default=10): Period for EMA of high-low range
- roc_period (int, default=10): Period for rate of change calculation
Returns
- array: Chaikin Volatility values
Example
# Calculate Chaikin Volatility
cv = ta.chaikin(df['high'], df['low'])
df['Chaikin_Volatility'] = cv
# Custom parameters
cv_custom = ta.chaikin(df['high'], df['low'], ema_period=14, roc_period=14)
df['CV_Custom'] = cv_custom
print(df[['close', 'Chaikin_Volatility', 'CV_Custom']].tail())
Normalized Average True Range (NATR)
NATR is ATR expressed as a percentage of closing price, making it useful for comparing volatility across different price levels.
Usage
natr_result = ta.natr(high, low, close, period=14)
Parameters
- high (array-like): High prices
- low (array-like): Low prices
- close (array-like): Closing prices
- period (int, default=14): Period for ATR calculation
Returns
- array: NATR values (percentage)
Example
# Calculate NATR
natr = ta.natr(df['high'], df['low'], df['close'], period=14)
df['NATR'] = natr
# Different period
natr_21 = ta.natr(df['high'], df['low'], df['close'], period=21)
df['NATR_21'] = natr_21
print(df[['close', 'NATR', 'NATR_21']].tail())
Relative Volatility Index (RVI)
RVI applies the RSI calculation to standard deviation instead of price changes, measuring volatility momentum.
Usage
rvi_result = ta.rvi(data, stdev_period=10, rsi_period=14)
Parameters
- data (array-like): Price data (typically closing prices)
- stdev_period (int, default=10): Period for standard deviation calculation
- rsi_period (int, default=14): Period for RSI calculation
Returns
- array: RVI values (0-100 range)
Example
# Calculate RVI
rvi = ta.rvi(df['close'])
df['RVI'] = rvi
# Custom parameters
rvi_custom = ta.rvi(df['close'], stdev_period=14, rsi_period=21)
df['RVI_Custom'] = rvi_custom
print(df[['close', 'RVI', 'RVI_Custom']].tail())
Ultimate Oscillator
Ultimate Oscillator combines short, medium, and long-term price action into one oscillator, incorporating volatility analysis.
Usage
uo_result = ta.ultimate_oscillator(high, low, close, period1=7, period2=14, period3=28)
Parameters
- high (array-like): High prices
- low (array-like): Low prices
- close (array-like): Closing prices
- period1 (int, default=7): Short period
- period2 (int, default=14): Medium period
- period3 (int, default=28): Long period
Returns
- array: Ultimate Oscillator values (0-100 range)
Example
# Calculate Ultimate Oscillator
uo = ta.ultimate_oscillator(df['high'], df['low'], df['close'])
df['Ultimate_Oscillator'] = uo
# Custom periods
uo_custom = ta.ultimate_oscillator(df['high'], df['low'], df['close'],
period1=5, period2=10, period3=20)
df['UO_Custom'] = uo_custom
print(df[['close', 'Ultimate_Oscillator', 'UO_Custom']].tail())
True Range
True Range measures volatility that accounts for gaps between periods.
Usage
tr_result = ta.true_range(high, low, close)
Parameters
- high (array-like): High prices
- low (array-like): Low prices
- close (array-like): Closing prices
Returns
- array: True Range values
Example
# Calculate True Range
tr = ta.true_range(df['high'], df['low'], df['close'])
df['True_Range'] = tr
print(df[['high', 'low', 'close', 'True_Range']].tail())
Mass Index
Mass Index uses the high-low range to identify trend reversals based on range expansion.
Usage
mass_result = ta.massindex(high, low, length=10)
Parameters
- high (array-like): High prices
- low (array-like): Low prices
- length (int, default=10): Period for sum calculation
Returns
- array: Mass Index values
Example
# Calculate Mass Index
mass = ta.massindex(df['high'], df['low'])
df['Mass_Index'] = mass
# Different period
mass_14 = ta.massindex(df['high'], df['low'], length=14)
df['Mass_Index_14'] = mass_14
print(df[['close', 'Mass_Index', 'Mass_Index_14']].tail())
Bollinger Bands %B
%B shows where price is in relation to the Bollinger Bands, with 1 indicating price at upper band and 0 at lower band.
Usage
percent_b = ta.bbpercent(data, period=20, std_dev=2.0)
Parameters
- data (array-like): Price data (typically closing prices)
- period (int, default=20): Period for moving average and standard deviation
- std_dev (float, default=2.0): Number of standard deviations for the bands
Returns
- array: %B values
Example
# Calculate Bollinger Bands %B
bb_percent = ta.bbpercent(df['close'])
df['BB_Percent_B'] = bb_percent
# Custom parameters
bb_percent_tight = ta.bbpercent(df['close'], period=14, std_dev=1.5)
df['BB_Percent_B_Tight'] = bb_percent_tight
print(df[['close', 'BB_Percent_B', 'BB_Percent_B_Tight']].tail())
Bollinger Bandwidth
Bollinger Bandwidth measures the width of the Bollinger Bands, useful for identifying volatility squeezes.
Usage
bandwidth = ta.bbwidth(data, period=20, std_dev=2.0)
Parameters
- data (array-like): Price data (typically closing prices)
- period (int, default=20): Period for moving average and standard deviation
- std_dev (float, default=2.0): Number of standard deviations for the bands
Returns
- array: Bandwidth values
Example
# Calculate Bollinger Bandwidth
bb_width = ta.bbwidth(df['close'])
df['BB_Bandwidth'] = bb_width
# Different standard deviation
bb_width_tight = ta.bbwidth(df['close'], std_dev=1.5)
df['BB_Bandwidth_Tight'] = bb_width_tight
print(df[['close', 'BB_Bandwidth', 'BB_Bandwidth_Tight']].tail())
Chandelier Exit
Chandelier Exit is a trailing stop-loss technique that follows price action using highest/lowest values and ATR.
Usage
long_exit, short_exit = ta.chandelier_exit(high, low, close, period=22, multiplier=3.0)
Parameters
- high (array-like): High prices
- low (array-like): Low prices
- close (array-like): Closing prices
- period (int, default=22): Period for highest/lowest and ATR calculation
- multiplier (float, default=3.0): ATR multiplier
Returns
- tuple: (long_exit, short_exit) arrays
Example
# Calculate Chandelier Exit
ce_long, ce_short = ta.chandelier_exit(df['high'], df['low'], df['close'])
df['CE_Long_Exit'] = ce_long
df['CE_Short_Exit'] = ce_short
# Custom parameters
ce_long_custom, ce_short_custom = ta.chandelier_exit(
df['high'], df['low'], df['close'], period=14, multiplier=2.0
)
df['CE_Long_Custom'] = ce_long_custom
df['CE_Short_Custom'] = ce_short_custom
print(df[['close', 'CE_Long_Exit', 'CE_Short_Exit']].tail())
Historical Volatility
Historical Volatility measures the standard deviation of logarithmic returns over a specified period.
Usage
hv_result = ta.hv(close, length=10, annual=365, per=1)
Parameters
- close (array-like): Closing prices
- length (int, default=10): Period for volatility calculation
- annual (int, default=365): Annual periods for scaling
- per (int, default=1): Timeframe periods (1 for daily/intraday, 7 for weekly+)
Returns
- array: Historical volatility values (annualized percentages)
Example
# Calculate Historical Volatility
hv = ta.hv(df['close'], length=20)
df['Historical_Volatility'] = hv
# Different periods
hv_10 = ta.hv(df['close'], length=10)
hv_30 = ta.hv(df['close'], length=30)
df['HV_10'] = hv_10
df['HV_30'] = hv_30
print(df[['close', 'Historical_Volatility', 'HV_10', 'HV_30']].tail())
Ulcer Index
Ulcer Index measures downside risk by calculating the depth and duration of drawdowns from recent highs.
Usage
ui_result = ta.ulcerindex(data, length=14, smooth_length=14, signal_length=52,
signal_type="SMA", return_signal=False)
Parameters
- data (array-like): Price data (typically closing prices)
- length (int, default=14): Period for highest calculation
- smooth_length (int, default=14): Period for smoothing squared drawdowns
- signal_length (int, default=52): Period for signal line calculation
- signal_type (str, default="SMA"): Signal smoothing type ("SMA" or "EMA")
- return_signal (bool, default=False): Whether to return signal line
Returns
- array or tuple: Ulcer Index values (and signal if return_signal=True)
Example
# Calculate Ulcer Index
ui = ta.ulcerindex(df['close'])
df['Ulcer_Index'] = ui
# With signal line
ui_with_signal, ui_signal = ta.ulcerindex(df['close'], return_signal=True)
df['UI_Signal'] = ui_signal
# Custom parameters
ui_custom = ta.ulcerindex(df['close'], length=21, smooth_length=21)
df['UI_Custom'] = ui_custom
print(df[['close', 'Ulcer_Index', 'UI_Signal', 'UI_Custom']].tail())
STARC Bands
STARC Bands use a Simple Moving Average and Average True Range to create volatility-based bands.
Usage
upper, middle, lower = ta.starc(high, low, close, ma_period=5, atr_period=15, multiplier=1.33)
Parameters
- high (array-like): High prices
- low (array-like): Low prices
- close (array-like): Closing prices
- ma_period (int, default=5): Period for SMA calculation
- atr_period (int, default=15): Period for ATR calculation
- multiplier (float, default=1.33): ATR multiplier
Returns
- tuple: (upper_band, middle_line, lower_band) arrays
Example
# Calculate STARC Bands
starc_upper, starc_middle, starc_lower = ta.starc(df['high'], df['low'], df['close'])
df['STARC_Upper'] = starc_upper
df['STARC_Middle'] = starc_middle
df['STARC_Lower'] = starc_lower
# Custom parameters
starc_upper_custom, starc_middle_custom, starc_lower_custom = ta.starc(
df['high'], df['low'], df['close'],
ma_period=10, atr_period=20, multiplier=2.0
)
print(df[['close', 'STARC_Upper', 'STARC_Middle', 'STARC_Lower']].tail())
Complete Example: Volatility Analysis
from openalgo import ta, api
import pandas as pd
# Initialize API and get data
client = api(api_key='your_api_key_here', host='http://127.0.0.1:5000')
df = client.history(symbol="SBIN", exchange="NSE", interval="5m",
start_date="2025-04-01", end_date="2025-04-08")
# Calculate multiple volatility indicators
df['ATR'] = ta.atr(df['high'], df['low'], df['close'], period=14)
df['NATR'] = ta.natr(df['high'], df['low'], df['close'], period=14)
# Bollinger Bands
bb_upper, bb_middle, bb_lower = ta.bbands(df['close'], period=20, std_dev=2.0)
df['BB_Upper'] = bb_upper
df['BB_Middle'] = bb_middle
df['BB_Lower'] = bb_lower
df['BB_Width'] = ta.bbwidth(df['close'], period=20, std_dev=2.0)
df['BB_Percent_B'] = ta.bbpercent(df['close'], period=20, std_dev=2.0)
# Keltner Channel
kc_upper, kc_middle, kc_lower = ta.keltner(df['high'], df['low'], df['close'])
df['KC_Upper'] = kc_upper
df['KC_Middle'] = kc_middle
df['KC_Lower'] = kc_lower
# Donchian Channel
dc_upper, dc_middle, dc_lower = ta.donchian(df['high'], df['low'], period=20)
df['DC_Upper'] = dc_upper
df['DC_Middle'] = dc_middle
df['DC_Lower'] = dc_lower
# Advanced volatility indicators
df['RVI'] = ta.rvi(df['close'])
df['Historical_Vol'] = ta.hv(df['close'], length=20)
df['Ulcer_Index'] = ta.ulcerindex(df['close'])
df['Mass_Index'] = ta.massindex(df['high'], df['low'])
# Chandelier Exit levels
ce_long, ce_short = ta.chandelier_exit(df['high'], df['low'], df['close'])
df['CE_Long'] = ce_long
df['CE_Short'] = ce_short
# Volatility analysis
print("=== Volatility Analysis ===")
print(f"Average ATR: {df['ATR'].mean():.2f}")
print(f"Average NATR: {df['NATR'].mean():.2f}%")
print(f"Average Historical Volatility: {df['Historical_Vol'].mean():.2f}%")
print(f"Average BB Width: {df['BB_Width'].mean():.4f}")
# Recent values
print("\n=== Recent Volatility Indicators ===")
recent_data = df[['close', 'ATR', 'NATR', 'BB_Width', 'RVI', 'Historical_Vol']].tail()
print(recent_data)
# Volatility squeeze detection (BB Width < KC Width equivalent)
df['Squeeze'] = (df['BB_Upper'] - df['BB_Lower']) < (df['KC_Upper'] - df['KC_Lower'])
print(f"\nVolatility Squeeze periods: {df['Squeeze'].sum()} out of {len(df)} periods")
Common Use Cases
- Volatility Breakouts: Use BB Width and Mass Index to identify low volatility periods before breakouts
- Risk Management: Use ATR and NATR for position sizing and stop-loss placement
- Overbought/Oversold: Use BB %B and RVI to identify extreme price levels
- Trend Strength: Higher volatility often accompanies strong trends
- Market Regime: Compare different volatility measures to understand market conditions
Performance Tips
- Efficient Calculations: Use vectorized operations for multiple timeframes
- Memory Management: Calculate only needed indicators to save memory
- Parameter Optimization: Test different periods for your specific market and timeframe
- Combination Analysis: Use multiple volatility indicators together for confirmation