ta_indicators.pinescript
Copy
// This Pine Script™ code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © ActiveQuants
// Created by ActiveQuants
// Last updated: June 17, 2025
//@version=6
// @description This library provides a collection of functions for calculating various technical analysis indicators.
library(title = "TAIndicators", overlay = true)
import TradingView/ta/10
// MA
// @function Calculates a moving average of a given type, with optional smoothing.
// @param maType The type of moving average to calculate. Valid options are: 'SMA', 'SMA + Bollinger Bands', 'EMA', 'SMMA (RMA)', 'WMA', 'VWMA'.
// @param source The source data for the moving average (e.g., `close`).
// @param length The lookback period for the moving average.
// @param smoothingType (Optional) The type of moving average to use for smoothing. Valid options are: 'SMA', 'SMA + Bollinger Bands', 'EMA', 'SMMA (RMA)', 'WMA', 'VWMA', 'None'. Defaults to 'None'.
// @param smoothingLength (Optional) The lookback period for the smoothing moving average. Required if `smoothingType` is not 'None'.
// @param bbMult (Optional) The multiplier for the Bollinger Bands calculation. Required if `smoothingType` is 'SMA + Bollinger Bands'.
// @returns An array containing the MA value, the smoothed MA, and the upper and lower Bollinger Bands (`[float, float, float, float]`). If `smoothingType` is not 'SMA + Bollinger Bands', the upper and lower band values will be `na`.
export ma(string maType, float source, int length, string smoothingType = "None", int smoothingLength = na, float bbMult = na) =>
if not array.from("SMA", "SMA + Bollinger Bands", "EMA", "SMMA (RMA)", "WMA", "VWMA").includes(maType)
runtime.error("Please input a valid <maType> parameter value on the ma() function. It should be one of the following ones: ['SMA', 'SMA + Bollinger Bands', 'EMA', 'SMMA (RMA)', 'WMA', 'VWMA']")
if not array.from("SMA", "SMA + Bollinger Bands", "EMA", "SMMA (RMA)", "WMA", "VWMA", "None").includes(smoothingType)
runtime.error("Please input a valid <smoothingType> parameter value on the ma() function. It should be one of the following ones: ['SMA', 'SMA + Bollinger Bands', 'EMA', 'SMMA (RMA)', 'WMA', 'VWMA', 'None']")
float sma = ta.sma(source, length)
float ema = ta.ema(source, length)
float rma = ta.rma(source, length)
float wma = ta.wma(source, length)
float vwma = ta.vwma(source, length)
float ma = switch maType
"SMA" => sma
"SMA + Bollinger Bands" => sma
"EMA" => ema
"SMMA (RMA)" => rma
"WMA" => wma
"VWMA" => vwma
float smoothedMa = na
float smoothedMaSma = ta.sma(ma, smoothingLength)
float smoothedMaEma = ta.ema(ma, smoothingLength)
float smoothedMaRma = ta.rma(ma, smoothingLength)
float smoothedMaWma = ta.wma(ma, smoothingLength)
float smoothedMaVwma = ta.vwma(ma, smoothingLength)
float maStdDev = ta.stdev(ma, smoothingLength)
float upperBb = na
float lowerBb = na
if smoothingType != "None"
if na(smoothingLength)
runtime.error("Please specify the <smoothingLength> parameter value on the ma() function.")
if na(bbMult) and smoothingType == "SMA + Bollinger Bands"
runtime.error("Please specify the <bbMult> parameter value on the ma() function.")
smoothedMa := switch smoothingType
"SMA" => smoothedMaSma
"SMA + Bollinger Bands" => smoothedMaSma
"EMA" => smoothedMaEma
"SMMA (RMA)" => smoothedMaRma
"WMA" => smoothedMaWma
"VWMA" => smoothedMaVwma
if smoothingType == "SMA + Bollinger Bands"
upperBb := smoothedMa + maStdDev * bbMult
lowerBb := smoothedMa - maStdDev * bbMult
[ma, smoothedMa, upperBb, lowerBb]
// RSI
// @function Calculates the Relative Strength Index (RSI), with optional smoothing, Bollinger Bands, and divergence detection.
// @param source The source data for the RSI (e.g., `close`).
// @param length The lookback period for the RSI calculation.
// @param smoothingType (Optional) The type of moving average to use for smoothing the RSI. Valid options are: 'SMA', 'SMA + Bollinger Bands', 'EMA', 'SMMA (RMA)', 'WMA', 'VWMA', 'None'. Defaults to 'None'.
// @param smoothingLength (Optional) The lookback period for the smoothing moving average. Required if `smoothingType` is not 'None'.
// @param bbMult (Optional) The multiplier for the Bollinger Bands calculation. Required if `smoothingType` is 'SMA + Bollinger Bands'.
// @param calculateDivergence (Optional) Whether to calculate bullish and bearish divergences. Defaults to `false`.
// @param divergenceLookbackLeft (Optional) The left lookback period for divergence detection. Required if `calculateDivergence` is `true`.
// @param divergenceLookbackRight (Optional) The right lookback period for divergence detection. Required if `calculateDivergence` is `true`.
// @returns An array containing the RSI value, the smoothed RSI, the upper and lower Bollinger Bands, a boolean indicating bullish divergence, a boolean indicating bearish divergence, a boolean indicating a pivot low, and a boolean indicating a pivot high (`[float, float, float, float, bool, bool, bool, bool]`). If `smoothingType` is not 'SMA + Bollinger Bands', the upper and lower band values will be `na`.
export rsi(float source, int length, string smoothingType = "None", int smoothingLength = na, float bbMult = na, bool calculateDivergence = false, int divergenceLookbackLeft = na, int divergenceLookbackRight = na) =>
if not array.from("SMA", "SMA + Bollinger Bands", "EMA", "SMMA (RMA)", "WMA", "VWMA", "None").includes(smoothingType)
runtime.error("Please input a valid <smoothingType> parameter value on the rsi() function. It should be one of the following ones: ['SMA', 'SMA + Bollinger Bands', 'EMA', 'SMMA (RMA)', 'WMA', 'VWMA', 'None']")
float rsi = ta.rsi(source, length)
if smoothingType != "None"
if na(smoothingLength)
runtime.error("Please specify the <smoothingLength> parameter value on the rsi() function.")
if na(bbMult)
runtime.error("Please specify the <bbMult> parameter value on the rsi() function.")
float smoothedRsiSma = ta.sma(rsi, smoothingLength)
float smoothedRsiEma = ta.ema(rsi, smoothingLength)
float smoothedRsiRma = ta.rma(rsi, smoothingLength)
float smoothedRsiWma = ta.wma(rsi, smoothingLength)
float smoothedRsiVwma = ta.vwma(rsi, smoothingLength)
float smoothedRsi = switch smoothingType
"SMA" => smoothedRsiSma
"SMA + Bollinger Bands" => smoothedRsiSma
"EMA" => smoothedRsiEma
"SMMA (RMA)" => smoothedRsiRma
"WMA" => smoothedRsiWma
"VWMA" => smoothedRsiVwma
float rsiStdDev = ta.stdev(rsi, smoothingLength)
float upperBb = na
float lowerBb = na
if smoothingType == "SMA + Bollinger Bands"
upperBb := smoothedRsi + rsiStdDev * bbMult
lowerBb := smoothedRsi - rsiStdDev * bbMult
if calculateDivergence
if na(divergenceLookbackLeft)
runtime.error("Please specify the <divergenceLookbackLeft> parameter value on the rsi() function.")
if na(divergenceLookbackRight)
runtime.error("Please specify the <divergenceLookbackRight> parameter value on the rsi() function.")
// Divergence
int rangeUpper = 60
int rangeLower = 5
float rsiLBR = rsi[divergenceLookbackRight]
bool plFound = not na(ta.pivotlow(rsi, divergenceLookbackLeft, divergenceLookbackRight))
bool phFound = not na(ta.pivothigh(rsi, divergenceLookbackLeft, divergenceLookbackRight))
// Bullish
int barsBull = ta.barssince(plFound[1])
bool inRangeBull = rangeLower <= barsBull and barsBull <= rangeUpper
bool rsiHL = rsiLBR > ta.valuewhen(plFound, rsiLBR, 1) and inRangeBull
float lowLBR = low[divergenceLookbackRight]
bool priceLL = lowLBR < ta.valuewhen(plFound, lowLBR, 1)
// Bearish
int barsBear = ta.barssince(phFound[1])
bool inRangeBear = rangeLower <= barsBear and barsBear <= rangeUpper
bool rsiLH = rsiLBR < ta.valuewhen(phFound, rsiLBR, 1) and inRangeBear
float highLBR = high[divergenceLookbackRight]
bool priceHH = highLBR > ta.valuewhen(phFound, highLBR, 1)
bool bullDivergence = priceLL and rsiHL and plFound
bool bearDivergence = priceHH and rsiLH and phFound
[rsi, smoothedRsi, upperBb, lowerBb, bullDivergence, bearDivergence, plFound, phFound]
// MACD
// @function Calculates the Moving Average Convergence Divergence (MACD) indicator.
// @param maType The type of moving average to use for the fast and slow MAs. Valid options are: 'SMA', 'SMA + Bollinger Bands', 'EMA', 'SMMA (RMA)', 'WMA', 'VWMA'.
// @param source The source data for the MACD calculation (e.g., `close`).
// @param fastLength The lookback period for the fast moving average.
// @param slowLength The lookback period for the slow moving average.
// @param signalLength The lookback period for the signal line moving average.
// @param signalMaType The type of moving average to use for the signal line. Valid options are: 'SMA', 'SMA + Bollinger Bands', 'EMA', 'SMMA (RMA)', 'WMA', 'VWMA', 'None'.
// @returns An array containing the MACD line, the signal line, and the histogram (`[float, float, float]`).
export macd(string maType, float source, int fastLength, int slowLength, int signalLength, string signalMaType) =>
if not array.from("SMA", "SMA + Bollinger Bands", "EMA", "SMMA (RMA)", "WMA", "VWMA").includes(maType)
runtime.error("Please input a valid <maType> parameter value on the macd() function. It should be one of the following ones: ['SMA', 'SMA + Bollinger Bands', 'EMA', 'SMMA (RMA)', 'WMA', 'VWMA']")
if not array.from("SMA", "SMA + Bollinger Bands", "EMA", "SMMA (RMA)", "WMA", "VWMA", "None").includes(signalMaType)
runtime.error("Please input a valid <signalMaType> parameter value on the macd() function. It should be one of the following ones: ['SMA', 'SMA + Bollinger Bands', 'EMA', 'SMMA (RMA)', 'WMA', 'VWMA', 'None']")
float fastSma = ta.sma(source, fastLength)
float fastEma = ta.ema(source, fastLength)
float fastRma = ta.rma(source, fastLength)
float fastWma = ta.wma(source, fastLength)
float fastVwma = ta.vwma(source, fastLength)
float slowSma = ta.sma(source, slowLength)
float slowEma = ta.ema(source, slowLength)
float slowRma = ta.rma(source, slowLength)
float slowWma = ta.wma(source, slowLength)
float slowVwma = ta.vwma(source, slowLength)
float fastMa = switch maType
"SMA" => fastSma
"SMA + Bollinger Bands" => fastSma
"EMA" => fastEma
"SMMA (RMA)" => fastRma
"WMA" => fastWma
"VWMA" => fastVwma
float slowMa = switch maType
"SMA" => slowSma
"SMA + Bollinger Bands" => slowSma
"EMA" => slowEma
"SMMA (RMA)" => slowRma
"WMA" => slowWma
"VWMA" => slowVwma
float macd = fastMa - slowMa
float macdSignalSma = ta.sma(macd, signalLength)
float macdSignalEma = ta.ema(macd, signalLength)
float macdSignalRma = ta.rma(macd, signalLength)
float macdSignalWma = ta.wma(macd, signalLength)
float macdSignalVwma = ta.vwma(macd, signalLength)
float macdSignal = switch signalMaType
"SMA" => macdSignalSma
"SMA + Bollinger Bands" => macdSignalSma
"EMA" => macdSignalEma
"SMMA (RMA)" => macdSignalRma
"WMA" => macdSignalWma
"VWMA" => macdSignalVwma
float macdHist = macd - macdSignal
[macd, macdSignal, macdHist]
// ATR
// @function Calculates the Average True Range (ATR) with an optional Bollinger Bands overlay.
// @param length The lookback period for the ATR calculation.
// @param smoothingType The type of smoothing to apply to the True Range. Valid options are: 'SMA', 'SMA + Bollinger Bands', 'EMA', 'SMMA (RMA)', 'WMA', 'VWMA'.
// @param bbMult (Optional) The multiplier for the Bollinger Bands. Required if `smoothingType` is 'SMA + Bollinger Bands'.
// @returns An array containing the ATR value, and the upper and lower Bollinger Bands (`[float, float, float]`). If `smoothingType` is not 'SMA + Bollinger Bands', the upper and lower band values will be `na`.
export atr(int length, string smoothingType, float bbMult = na) =>
if not array.from("SMA", "SMA + Bollinger Bands", "EMA", "SMMA (RMA)", "WMA", "VWMA").includes(smoothingType)
runtime.error("Please input a valid <smoothingType> parameter value on the atr() function. It should be one of the following ones: ['SMA', 'SMA + Bollinger Bands', 'EMA', 'SMMA (RMA)', 'WMA', 'VWMA']")
float atrSma = ta.sma(ta.tr(true), length)
float atrEma = ta.ema(ta.tr(true), length)
float atrRma = ta.rma(ta.tr(true), length)
float atrWma = ta.wma(ta.tr(true), length)
float atrVwma = ta.vwma(ta.tr(true), length)
float atr = switch smoothingType
"SMA" => atrSma
"SMA + Bollinger Bands" => atrSma
"EMA" => atrEma
"SMMA (RMA)" => atrRma
"WMA" => atrWma
"VWMA" => atrVwma
float trStdDev = ta.stdev(ta.tr(true), length)
float upperBb = na
float lowerBb = na
if smoothingType == "SMA + Bollinger Bands"
if na(bbMult)
runtime.error("Please specify the <bbMult> parameter value on the atr() function.")
upperBb := atr + trStdDev * bbMult
lowerBb := atr - trStdDev * bbMult
[atr, upperBb, lowerBb]
// VWAP
// @function Calculates the Volume Weighted Average Price (VWAP) with multiple, configurable bands.
// @param anchor The anchor period for the VWAP calculation. Valid options are: 'Earnings', 'Dividends', 'Splits', 'Session', 'Week', 'Month', 'Quarter', 'Year', 'Decade', 'Century'.
// @param source The source price for the VWAP calculation.
// @param calcMode The calculation mode for the bands. Valid options are: 'Standard Deviation', 'Percentage'.
// @param hideOnDWM A boolean to hide the indicator on daily, weekly, or monthly timeframes.
// @param bandMult1 The multiplier for the first set of bands.
// @param bandMult2 The multiplier for the second set of bands.
// @param bandMult3 The multiplier for the third set of bands.
// @returns An array containing the VWAP value, and the upper and lower values for the three bands (`[float, float, float, float, float, float, float]`).
export vwap(string anchor, float source, string calcMode, bool hideOnDWM, float bandMult1, float bandMult2, float bandMult3) =>
if not array.from("Earnings", "Dividends", "Splits", "Session", "Week", "Month", "Quarter", "Year", "Decade", "Century").includes(anchor)
runtime.error("Please input a valid <anchor> parameter value on the vwap() function. It should be one of the following ones: ['Earnings', 'Dividends', 'Splits', 'Session', 'Week', 'Month', 'Quarter', 'Year', 'Decade', 'Century']")
if not array.from("Standard Deviation", "Percentage").includes(calcMode)
runtime.error("Please input a valid <calcMode> parameter value on the vwap() function. It should be one of the following ones: ['Standard Deviation', 'Percentage']")
float cumVolume = ta.cum(volume)
if barstate.islast and cumVolume == 0
runtime.error("No volume is provided by the data vendor.")
float newEarnings = request.earnings(syminfo.tickerid, earnings.actual, barmerge.gaps_on, barmerge.lookahead_on, ignore_invalid_symbol = true)
float newDividends = request.dividends(syminfo.tickerid, dividends.gross, barmerge.gaps_on, barmerge.lookahead_on, ignore_invalid_symbol = true)
float newSplit = request.splits(syminfo.tickerid, splits.denominator, barmerge.gaps_on, barmerge.lookahead_on, ignore_invalid_symbol = true)
bool isNewPeriod = switch anchor
"Earnings" => not na(newEarnings)
"Dividends" => not na(newDividends)
"Splits" => not na(newSplit)
"Session" => timeframe.change("D")
"Week" => timeframe.change("W")
"Month" => timeframe.change("M")
"Quarter" => timeframe.change("3M")
"Year" => timeframe.change("12M")
"Decade" => timeframe.change("12M") and year % 10 == 0
"Century" => timeframe.change("12M") and year % 100 == 0
=> false
bool isEdsAnchor = anchor == "Earnings" or anchor == "Dividends" or anchor == "Splits"
if na(source[1]) and not isEdsAnchor
isNewPeriod := true
float upperBand1 = na
float lowerBand1 = na
float upperBand2 = na
float lowerBand2 = na
float upperBand3 = na
float lowerBand3 = na
[vwap, stdevUpper, _] = ta.vwap(source, isNewPeriod, 1)
if not (hideOnDWM and timeframe.isdwm)
float stdevAbs = stdevUpper - vwap
float bandBasis = calcMode == "Standard Deviation" ? stdevAbs : vwap / 100
upperBand1 := vwap + bandBasis * bandMult1
lowerBand1 := vwap - bandBasis * bandMult1
upperBand2 := vwap + bandBasis * bandMult2
lowerBand2 := vwap - bandBasis * bandMult2
upperBand3 := vwap + bandBasis * bandMult3
lowerBand3 := vwap - bandBasis * bandMult3
[vwap, upperBand1, lowerBand1, upperBand2, lowerBand2, upperBand3, lowerBand3]
// ADX
// @function Calculates the Average Directional Index (ADX).
// @param length The lookback period for the ADX line.
// @param diLength The lookback period for the Directional Movement Index (DMI).
// @returns The ADX value (`float`).
export adx(int length, int diLength) =>
float up = ta.change(high)
float down = -ta.change(low)
float plusDM = na(up) ? na : (up > down and up > 0 ? up : 0)
float minusDM = na(down) ? na : (down > up and down > 0 ? down : 0)
float trueRange = ta.rma(ta.tr, diLength)
float plus = fixnan(100 * ta.rma(plusDM, diLength) / trueRange)
float minus = fixnan(100 * ta.rma(minusDM, diLength) / trueRange)
float sum = plus + minus
float adx = 100 * ta.rma(math.abs(plus - minus) / (sum == 0 ? 1 : sum), length)
adx
// Cumulative Volume Delta
// @function Calculates the Cumulative Volume Delta (CVD) based on a lower timeframe.
// @param anchor The anchor period for the CVD calculation (e.g., 'Session', 'Week').
// @param useCustomTimeframe A boolean to determine if a custom lower timeframe should be used.
// @param lowerTimeframe The custom lower timeframe to use if `useCustomTimeframe` is `true`.
// @returns An array containing the open, high, low, and close values of the volume delta for the specified lower timeframe (`[float, float, float, float]`).
export cvd(string anchor, bool useCustomTimeframe, string lowerTimeframe) =>
float cumVolume = ta.cum(volume)
if barstate.islast and cumVolume == 0
runtime.error("No volume is provided by the data vendor.")
var string lt = switch
useCustomTimeframe => lowerTimeframe
timeframe.isseconds => "1S"
timeframe.isintraday => "1"
timeframe.isdaily => "5"
=> "60"
[openVolume, highVolume, lowVolume, closeVolume] = ta.requestVolumeDelta(lt, anchor)
// Bollinger Bands
// @function Calculates Bollinger Bands.
// @param source The source data for the bands (e.g., `close`).
// @param length The lookback period for the moving average and standard deviation.
// @param mult The standard deviation multiplier.
// @param maType The type of moving average to use for the basis line. Valid options are: 'SMA', 'EMA', 'SMMA (RMA)', 'WMA', 'VWMA'.
// @returns An array containing the basis line, the upper band, and the lower band (`[float, float, float]`).
export bb(float source, int length, float mult, string maType) =>
if not array.from("SMA", "EMA", "SMMA (RMA)", "WMA", "VWMA").includes(maType)
runtime.error("Please input a valid <maType> parameter value on the bb() function. It should be one of the following ones: ['SMA', 'EMA', 'SMMA (RMA)', 'WMA', 'VWMA']")
float sma = ta.sma(source, length)
float ema = ta.ema(source, length)
float rma = ta.rma(source, length)
float wma = ta.wma(source, length)
float vwma = ta.vwma(source, length)
float basis = switch maType
"SMA" => sma
"EMA" => ema
"SMMA (RMA)" => rma
"WMA" => wma
"VWMA" => vwma
float stdDev = mult * ta.stdev(source, length)
float upper = basis + stdDev
float lower = basis - stdDev
[basis, upper, lower]
// Keltner Channels
// @function Calculates Keltner Channels.
// @param source The source data for the basis moving average.
// @param length The lookback period for the basis moving average.
// @param mult The multiplier for the channel bands.
// @param maType The type of moving average for the basis line. Valid options are: 'SMA', 'EMA', 'SMMA (RMA)', 'WMA', 'VWMA'.
// @param bandsStyle The style of the bands. Valid options are: 'Average True Range', 'True Range', 'Range'.
// @param atrLength The lookback period for the Average True Range calculation.
// @returns An array containing the basis line, the upper channel, and the lower channel (`[float, float, float]`).
export kc(float source, int length, float mult, string maType, string bandsStyle, int atrLength) =>
if not array.from("SMA", "EMA", "SMMA (RMA)", "WMA", "VWMA").includes(maType)
runtime.error("Please input a valid <maType> parameter value on the kc() function. It should be one of the following ones: ['SMA', 'EMA', 'SMMA (RMA)', 'WMA', 'VWMA']")
if not array.from("Average True Range", "True Range", "Range").includes(bandsStyle)
runtime.error("Please input a valid <bandsStyle> parameter value on the kc() function. It should be one of the following ones: ['Average True Range', 'True Range', 'Range']")
float sma = ta.sma(source, length)
float ema = ta.ema(source, length)
float rma = ta.rma(source, length)
float wma = ta.wma(source, length)
float vwma = ta.vwma(source, length)
float basis = switch maType
"SMA" => sma
"EMA" => ema
"SMMA (RMA)" => rma
"WMA" => wma
"VWMA" => vwma
float atr = ta.atr(atrLength)
float tr = ta.tr(true)
float rangeRma = ta.rma(high - low, length)
float rangeMa = switch bandsStyle
"Average True Range" => atr
"True Range" => tr
=> rangeRma
float upper = basis + rangeMa * mult
float lower = basis - rangeMa * mult
[basis, upper, lower]
// OBV
// @function Calculates the On-Balance Volume (OBV) indicator, with optional smoothing and Bollinger Bands.
// @param smoothingType (Optional) The type of moving average to use for smoothing. Valid options are: 'SMA', 'SMA + Bollinger Bands', 'EMA', 'SMMA (RMA)', 'WMA', 'VWMA', 'None'. Defaults to 'None'.
// @param smoothingLength (Optional) The lookback period for the smoothing moving average. Required if `smoothingType` is not 'None'.
// @param bbMult (Optional) The multiplier for the Bollinger Bands calculation. Required if `smoothingType` is 'SMA + Bollinger Bands'.
// @returns An array containing the OBV value, the smoothed OBV, and the upper and lower Bollinger Bands (`[float, float, float, float]`). If `smoothingType` is not 'SMA + Bollinger Bands', the upper and lower band values will be `na`.
export obv(string smoothingType = "None", int smoothingLength = na, int bbMult = na) =>
if not array.from("SMA", "SMA + Bollinger Bands", "EMA", "SMMA (RMA)", "WMA", "VWMA", "None").includes(smoothingType)
runtime.error("Please input a valid <smoothingType> parameter value on the obv() function. It should be one of the following ones: ['SMA', 'SMA + Bollinger Bands', 'EMA', 'SMMA (RMA)', 'WMA', 'VWMA', 'None']")
float cumVolume = ta.cum(volume)
if barstate.islast and cumVolume == 0
runtime.error("No volume is provided by the data vendor.")
float obv = ta.obv
float smoothedObv = na
float obvStdDev = ta.stdev(obv, smoothingLength)
float upperBb = na
float lowerBb = na
float sma = ta.sma(obv, smoothingLength)
float ema = ta.ema(obv, smoothingLength)
float rma = ta.rma(obv, smoothingLength)
float wma = ta.wma(obv, smoothingLength)
float vwma = ta.vwma(obv, smoothingLength)
if smoothingType != "None"
if na(smoothingLength)
runtime.error("Please specify the <smoothingLength> parameter value on the obv() function.")
if na(bbMult) and smoothingType == "SMA + Bollinger Bands"
runtime.error("Please specify the <bbMult> parameter value on the obv() function.")
smoothedObv := switch smoothingType
"SMA" => sma
"SMA + Bollinger Bands" => sma
"EMA" => ema
"SMMA (RMA)" => rma
"WMA" => wma
"VWMA" => vwma
if smoothingType == "SMA + Bollinger Bands"
upperBb := smoothedObv + obvStdDev * bbMult
lowerBb := smoothedObv - obvStdDev * bbMult
[obv, smoothedObv, upperBb, lowerBb]
Show all 479 lines