Library · Pine Script v6 · Library

TAIndicators

by MarcosACH· code credited to ActiveQuants

TAIndicators is a Pine Script library providing helper functions for technical analysis calculations.

View on GitHub

GitHub stars1on the repository
Pine versionv6current
Lines of code479
Settings0inputs
LicenceNone statedfile: MPL-2.0
Last update1 year ago9 Jul 2025

Add It to Your TradingView Chart

  1. 1Copy the scriptPress Copy script above, or the copy button on the code below.
  2. 2Open the Pine EditorOpen a TradingView chart and choose Pine Editor at the bottom of the screen.
  3. 3Paste over the templateCreate a new library, select all of the template text and paste. Press Save and give it a name.
  4. 4Publish or import itA library draws nothing. Publish it from the editor, then import its functions in your own scripts.

Source Code

479 lines of Pine Script v6 from TAIndicators/ta_indicators.pinescript, published under MPL-2.0 (file header). Keep the author's credit and licence lines when you reuse it.

ta_indicators.pinescript
// 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]

Overview

TAIndicators features flexible moving average functions supporting SMA, EMA, SMMA, WMA, and VWMA options, along with secondary smoothing methods and Bollinger Band calculations. Designed for modular integration into custom indicators and strategies, it simplifies processing technical indicators with built-in parameter validation.

Details

Published by

MarcosACH on GitHub

Code credit

ActiveQuants, as written in the script's header

Type

Library, Pine Script v6

Draws

Library (no plots)

Markets

Any symbol

Timeframes

Any timeframe

Risk Notes

No repainting, lookahead or stacked entries were found in its code or README. That says nothing about how well it works: test it first.

Topics

librariespinescripttradingvewtradingviewpinescript-libraries

Third-party code. ForexR did not write, test or endorse this script, and the summary above was generated automatically from its code and README. Indicators describe the past, and a strategy's backtest can look better than live trading, especially when a script repaints. Check it in the Strategy Tester and on a demo account before you rely on it.

Similar Pine Scripts

FunctionLinearRegression

by ricardosantos79
261 stars

This Pine Script v5 library provides functions to calculate and plot linear regression channels using sample point arrays. It evaluates paired X and Y arrays to calculate the regression slope, intercept, fitted values, maximum deviation, minimum deviation, and

Library v5 Trend
Updated 4 years ago · None stated GitHub repository of FunctionLinearRegression

PositionSizing

by iamrichardD
57 stars

This Pine Script v6 library calculates trade position sizes and provides risk management functions for external scripts. It computes position sizes from account equity, percentage risk, and stop-loss distance, and offers dynamic sizing adjustments based on vol

Library v6
Updated 1 year ago · Apache-2.0 GitHub repository of PositionSizing

Chart Patterns

by deepentropy
13 stars

Chart Patterns is a Pine Script v6 library designed to scan for and render technical chart patterns directly on the price chart. It defines custom user-defined types to configure scanning parameters, such as Zigzag pivot offsets, error ratios, flat ratios, and

Library v6 Repaints
Updated 6 months ago · MIT GitHub repository of Chart Patterns

AuthLib

by alboogycOdR
6 stars

AuthLib is a Pine Script utility library providing access control and state management structures for technical indicators. It checks callers against a hardcoded array of authorized TradingView usernames before executing operations. The library exports user-de

Library v5 SMC / ICT / price actionSessions & time
Updated 7 months ago · None stated GitHub repository of AuthLib

WebhookMessageLibrary

by TradersPost
6 stars

WebhookMessageLibrary is a helper library designed to construct structured JSON payload messages for automated trading integrations like TradersPost. It defines custom exported types and constants for trade actions, market sentiments, quantities, limit prices,

Library v5
Updated 1 year ago · None stated GitHub repository of WebhookMessageLibrary

PineDraw

by 345-strategies
5 stars

PineDraw is a Pine Script v6 library that provides object primitives for drawing and updating price levels on the chart. It enables indicators and strategies to maintain lines, boxes, and labels in place by updating existing objects instead of deleting and rec

Library v6 Support & resistance
Updated 2 days ago · MPL-2.0 GitHub repository of PineDraw

More libraries

Trade Your Charts With a Regulated Broker

Compare brokers that connect to TradingView, with spreads, minimum deposits and leverage side by side.

Compare brokers