Kalman Volume Filter
Updated
April 29, 2024
TradingView

For free use on the TradingView platform

Settings:

  • Users can adjust various parameters to customize the indicator according to their preferences:
  • Volume Length: Defines the length of the volume period used in calculations.
  • Stabilization Coefficient (k): Determines the level of noise reduction in the signals.
  • Signal Line Length: Sets the length of the signal line used for identifying trends.
  • Overbought & Oversold Zone Level: Specifies the threshold levels for identifying overbought and oversold conditions.
  • Source: Allows users to select the price source for volume calculations.

Volume Zone Oscillator (VZO):

  • Calculates a volume-based oscillator indicating the direction and intensity of volume movements.
  • Utilizes a volume direction measurement over a specified period to compute the oscillator value.
  • Normalizes the oscillator value to improve comparability across different securities or timeframes.

// VOLUME ZONE OSCILLATOR
VZO(get_src, length) =>
    Volume_Direction    = get_src > get_src[2] ? volume : -volume
    VZO_volume          = ta.hma(Volume_Direction, length)
    Total_volume        = ta.hma(volume, length)
    VZO  = VZO_volume / (Total_volume)
    VZO := (VZO - 0) / ta.stdev(VZO, 200)
    VZO

Kalman Filter:

  • Applies a Kalman filter to smooth out the VZO values and reduce noise.
  • Utilizes a stabilization coefficient (k) to control the degree of smoothing.
  • Generates a filtered output representing the underlying volume trend.

// KALMAN FILTER
series float M_n     = 0.0                           //   - the resulting value of the current calculation
series float A_n     = VZO                       //   - the initial value of the current measurement
series float M_n_1   = nz(M_n[1])            //   - the resulting value of the previous calculation
float k              = input.float(0.06)  //  - stabilization coefficient

// Kalman Filter Formula
kalm(k)=>
    k * A_n + (1 - k) * M_n_1

Volume Visualization:

  • Displays the volume histogram, with color intensity indicating the strength of volume movements.
  • Adjusts bar colors based on volume bursts to highlight significant changes in volume.

Overbought and Oversold Zones:

Marks overbought and oversold levels on the chart to assist in identifying potential reversal points.

Plotting:

  • Plots the Kalman Volume Filter line and a signal line for visual analysis.
  • Utilizes different colors and fills to distinguish between rising and falling trends.
  • Highlights specific events such as local buy or sell signals, as well as overbought or oversold conditions.

This indicator provides traders with a comprehensive view of volume dynamics, trend direction, and potential market turning points, aiding in informed decision-making during trading activities.


// This Pine Script™ code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © ChartPrime

//@version=5
indicator("Kalman Volume Filter [ChartPrime]", overlay = false)

// 𝙐𝙎𝙀𝙍 𝙄𝙉𝙋𝙐𝙏𝙎
int VZO_length            = input.int(70, "Volume Length", group = "Settings")

float k                   = input.float(0.06,
                                         title = "Stabilization Coefficient",
                                         step = 0.001,
                                         maxval = 0.1,
                                         minval = 0.01,
                                         group = "Settings",
                                         tooltip = "The lower coefficient 
                                         the less noise the longer signals"
                                         ) //  - stabilization coefficient

int sig_length            = input.int(10, "Signal Line Length",maxval = 15, group = "Settings")
float ob_os_z             = input.float(0.6, "Overbought & Oversold Zone Level", step = 0.1, group = "Settings")

series float get_src      = input.source(close, "Source", group = "Settings") 

color colorUp             = input.color(color.aqua, "Color Up", group = "Visual")
color colorDn             = input.color(color.red,  "Color Dn", group = "Visual")


// 𝙄𝙉𝘿𝙄𝘾𝘼𝙏𝙊𝙍 𝘾𝘼𝙇𝘾𝙐𝙇𝘼𝙏𝙄𝙊𝙉𝙎

// VOLUME ZONE OSCILLATOR
VZO(get_src, length) =>
    Volume_Direction    = get_src > get_src[2] ? volume : -volume
    VZO_volume          = ta.hma(Volume_Direction, length)
    Total_volume        = ta.hma(volume, length)
    VZO  = VZO_volume / (Total_volume)
    VZO := (VZO - 0) / ta.stdev(VZO, 200)
    VZO

VZO = VZO(get_src, VZO_length)

// KALMAN FILTER
series float M_n     = 0.0                        //   - the resulting value of the current calculation
series float A_n     = VZO                       //   - the initial value of the current measurement
series float M_n_1   = nz(M_n[1])               //   - the resulting value of the previous calculation

// Kalman Filter Formula
kalm(k)=>
    k * A_n + (1 - k) * M_n_1

// KALMAN VOLUME FILTER
M_n := kalm(k)

// Signal Line
M_n_ = ta.sma(M_n, sig_length)



// 𝙑𝙄𝙎𝙐𝘼𝙇𝙄𝙕𝘼𝙏𝙄𝙊𝙉
// Volume Histogram
volume_ = ((volume - 0) / ta.stdev(volume, 200))/10
volume_ := volume_ > 0.8 ? 0 : volume_

color_vol = color.from_gradient(volume_, 0.1, 0.45, chart.fg_color, colorUp)

plot(volume_, style = plot.style_columns, color = color.new(color_vol, 85))
plot(volume_*-1, style = plot.style_columns, color = color.new(color_vol, 85))

// Bar color based on Volume Bursts
barcolor(color_vol)

// Overbought and Oversold Zones
p3 = plot(2, color = color.new(colorDn, 90))
p4 = plot(ob_os_z, display = display.none)
p5 = plot(-2, color = color.new(colorUp, 90))
p6 = plot(-ob_os_z, display = display.none)

fill(plot1 = p3,
     plot2 = p4,
     top_value =  2,
     bottom_value =  ob_os_z, 
     top_color = na,
     bottom_color = color.new(colorDn, 70)
     )

fill(plot1 = p5,
     plot2 = p6,
     top_value =  -ob_os_z,
     bottom_value = -2, 
     top_color = color.new(colorUp, 70),
     bottom_color = na
     )

// Plot Of Kalman Volume Filter
p1 = plot(M_n, 
     color = M_n > M_n_ ? colorUp : colorDn, 
     linewidth = 1
         )

p2 = plot(M_n_, 
     color = M_n > M_n_ ? color.new(colorUp,60) : color.new(colorDn,60), 
     linewidth = 1
         )

fill(plot1 = p1,
      plot2 = p2,
      top_value =  M_n,
      bottom_value =  M_n_, 
      top_color = M_n > M_n_ ? colorUp : colorDn,
      bottom_color =  M_n > M_n_ ? na : #880e4f00
      )



// 𝙎𝙄𝙂𝙉𝘼𝙇𝙎 
plotchar(series = ta.crossover(M_n, M_n_) and M_n > -ob_os_z and M_n < ob_os_z ? M_n : na, 
     title = "Local Buy",
      char = "⦿",
      location = location.absolute,
       color = colorUp, 
       size = size.tiny,
       offset = -1
       )

plotchar(series = ta.crossunder(M_n, M_n_) and M_n > -ob_os_z and M_n < ob_os_z ? M_n : na, 
     title = "Local Sell",
      char = "⦿",
      location = location.absolute,
       color = colorDn, 
       size = size.tiny,
       offset = -1
       )

plotchar(series = ta.crossover(M_n, M_n_) and M_n < -ob_os_z ? M_n : na, 
     title = "Oversold Buy",
      char = "⬙",
      location = location.absolute,
       color = color.new(colorUp, 10), 
       size = size.small,
       offset = -1
       )

plotchar(series = ta.crossunder(M_n, M_n_) and M_n > ob_os_z ? M_n : na, 
     title = "Overbought Sell",
      char = "◈",
      location = location.absolute,
       color = color.new(colorDn, 10), 
       size = size.small,
       offset = -1
       )

// Mid Line
hline(0, color = #787b8662)

Get access to our Exclusive
premium indicators