Skip to content

Volatility ​

Volatility indicators measure the degree of price variation in financial instruments. They help traders assess market uncertainty, risk levels, and potential breakout conditions. Tradeboard provides a comprehensive collection of volatility indicators optimized for performance and accuracy.

Import Statement ​

python
from tradeboard import ta
from tradeboard 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 ​

python
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 ​

python
# 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 ​

python
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 ​

python
# 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 ​

python
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 ​

python
# 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 ​

python
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 ​

python
# 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 ​

python
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 ​

python
# 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 ​

python
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 ​

python
# 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 Vigor Index (RVI) ​

ta.rvi is the Relative Vigor Index. It compares the close-open range with the high-low range to gauge the conviction behind a move, and returns the RVI line together with its signal line.

WARNING

ta.rvi needs four price series (open, high, low, close) and returns a tuple. It is not the Relative Volatility Index: that variant is not exposed on the ta object.

Usage ​

python
rvi_line, rvi_signal = ta.rvi(open_prices, high, low, close, period=10)

Parameters ​

  • open_prices (array-like): Opening prices
  • high (array-like): High prices
  • low (array-like): Low prices
  • close (array-like): Closing prices
  • period (int, default=10): Lookback period

Returns ​

  • tuple: (rvi, signal) in the same format as input

Example ​

python
# Calculate RVI and its signal line
rvi, rvi_signal = ta.rvi(df['open'], df['high'], df['low'], df['close'])
df['RVI'] = rvi
df['RVI_Signal'] = rvi_signal

# Custom period
rvi_custom, rvi_signal_custom = ta.rvi(df['open'], df['high'], df['low'], df['close'], period=14)
df['RVI_Custom'] = rvi_custom

print(df[['close', 'RVI', 'RVI_Signal', 'RVI_Custom']].tail())

Ultimate Oscillator ​

Ultimate Oscillator combines short, medium, and long-term price action into one oscillator, incorporating volatility analysis.

Usage ​

python
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 ​

python
# 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 ​

python
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 ​

python
# 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 ​

python
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 ​

python
# 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 ​

python
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 ​

python
# 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 ​

python
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 ​

python
# 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 ​

python
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 ​

python
# 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 ​

python
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 ​

python
# 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 ​

python
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 ​

python
# 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 ​

python
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 ​

python
# 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 ​

python
from tradeboard 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'], df['RVI_Signal'] = ta.rvi(df['open'], df['high'], df['low'], 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 ​

  1. Volatility Breakouts: Use BB Width and Mass Index to identify low volatility periods before breakouts
  2. Risk Management: Use ATR and NATR for position sizing and stop-loss placement
  3. Overbought/Oversold: Use BB %B and Bollinger Bandwidth to identify extreme price levels
  4. Trend Strength: Higher volatility often accompanies strong trends
  5. Market Regime: Compare different volatility measures to understand market conditions

Performance Tips ​

  1. Efficient Calculations: Use vectorized operations for multiple timeframes
  2. Memory Management: Calculate only needed indicators to save memory
  3. Parameter Optimization: Test different periods for your specific market and timeframe
  4. Combination Analysis: Use multiple volatility indicators together for confirmation