Indicator: conversion of Volume-Weighted Price Z-Score

Viewing 3 posts - 1 through 3 (of 3 total)
  • Author
    Posts
  • #258730 quote
    regus
    Participant
    Veteran




    // This script is licensed under Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International

    // https://creativecommons.org/licenses/by-nc-sa/4.0/

    // © QuantAlgo


    //@version=6

    indicator(‘Volume-Weighted Price Z-Score [QuantAlgo]’, overlay = false)


    //              ╔════════════════════════════════╗              //

    //              ║      USER-DEFINED SETTINGS     ║              //

    //              ╚════════════════════════════════╝              //


    var string calculation_settings = ‘════════ Calculation Parameters ════════’

    var string visual_settings = ‘════════ Visualization Settings ════════’

    var string alert_settings = ‘════════ Alert Configuration ════════’


    tooltip_price_source = ‘The price data used for calculations. Close is most common for end-of-period analysis. High/Low can be used for extremes, HL2 for midpoint, HLC3 for typical price, or OHLC4 for complete bar representation. Each source provides different sensitivity to price movements.’

    tooltip_lookback = ‘Period for calculating the volume-weighted moving average and volatility baseline. Shorter periods (20-50) make the indicator more responsive to recent price changes, capturing short-term deviations quickly. Longer periods (100-200) provide more stable reference points, better for identifying major market dislocations. Match this to your trading timeframe.’

    tooltip_smoothing = ‘EMA smoothing applied to the final z-score to reduce noise and create cleaner signals. Lower values (1-3) preserve more detail and react faster but may show more false signals. Higher values (5-10) create smoother curves with fewer whipsaws but slower response. Set to 1 for no smoothing.’

    tooltip_preset = ‘Select a predefined configuration optimized for different analysis styles and market conditions.’

    tooltip_preset_details = ‘Default (100, 5): Balanced configuration suitable for swing trading and daily/4H analysis. Provides good balance between responsiveness and stability. Works well for identifying medium-term overbought/oversold conditions.nnFast Response (50, 3): Faster configuration for intraday trading and scalping. Shorter lookback period and minimal smoothing catch price deviations quickly. Best for 15min-1H charts where rapid mean reversion opportunities are important. Expect more frequent signals.nnSmooth Trend (200, 8): Stable configuration for position trading and long-term analysis. Extended lookback and heavy smoothing filter out noise to identify only major market extremes. Ideal for daily-weekly charts where you want high-confidence deviation signals with minimal false positives.’

    tooltip_extreme_threshold = ‘Z-score threshold for marking extreme deviation levels. Values above +threshold indicate extreme overvaluation, values below -threshold indicate extreme undervaluation. Standard values: 2.0 (95.4% confidence), 2.5 (98.8% confidence), 3.0 (99.7% confidence). Higher thresholds identify rarer, more extreme conditions.’

    tooltip_color_preset = ‘Pre-configured color schemes optimized for different chart themes and visual preferences. Each preset maintains strong contrast for clear identification of positive vs negative deviations.’

    tooltip_positive_color = ‘Color for positive z-score values (price above volume-weighted average). Represents conditions where the asset may be overvalued relative to its volume-weighted price. Typically shown in warm colors (red, orange) to indicate caution.’

    tooltip_negative_color = ‘Color for negative z-score values (price below volume-weighted average). Represents conditions where the asset may be undervalued relative to its volume-weighted price. Typically shown in cool colors (cyan, blue, green) to indicate potential buying opportunities.’

    tooltip_fill_transparency = ‘Transparency level for the gradient fill area between the z-score line and zero line. Higher values (70-95) create a more subtle, transparent background. Lower values (20-40) create a more solid, prominent fill that clearly highlights deviations. Set to 100 for completely transparent (no fill).’

    tooltip_bar_coloring = ‘Enable/disable coloring of indicator bars based on the z-score gradient color. When enabled, the background bars of the indicator pane are colored to match the current z-score deviation, providing additional visual context for positive vs negative deviations.’


    priceSource = input.source(close, ‘Price Source’, group = calculation_settings, tooltip = tooltip_price_source)

    lookbackPeriod = input.int(100, ‘Lookback Period’, group = calculation_settings, tooltip = tooltip_lookback)

    smoothingPeriod = input.int(5, ‘Smoothing Period’, minval = 1, group = calculation_settings, tooltip = tooltip_smoothing)


    presetConfig = input.string(‘Default’, ‘Preset Configuration’, options = [‘Default’, ‘Fast Response’, ‘Smooth Trend’], group = calculation_settings, tooltip = tooltip_preset + ‘nn’ + tooltip_preset_details)


    if presetConfig == ‘Fast Response’

        lookbackPeriod := 50

        smoothingPeriod := 3

        smoothingPeriod

    else if presetConfig == ‘Smooth Trend’

        lookbackPeriod := 200

        smoothingPeriod := 8

        smoothingPeriod


    extremeThreshold = input.float(2.5, ‘Extreme Threshold’, minval = 1.0, maxval = 4.0, step = 0.5, group = calculation_settings, tooltip = tooltip_extreme_threshold)


    colorPreset = input.string(‘Custom’, ‘Color Preset’, options = [‘Classic’, ‘Aqua’, ‘Cosmic’, ‘Ember’, ‘Neon’, ‘Custom’], group = visual_settings, tooltip = tooltip_color_preset)

    positiveColorInput = input.color(#ff0000, ‘Positive Deviation Color’, group = visual_settings, tooltip = tooltip_positive_color)

    negativeColorInput = input.color(#00ffaa, ‘Negative Deviation Color’, group = visual_settings, tooltip = tooltip_negative_color)

    fillTransparency = input.int(70, ‘Fill Transparency’, minval = 0, maxval = 100, group = visual_settings, tooltip = tooltip_fill_transparency)

    enableBarColoring = input.bool(true, ‘Enable Bar Coloring’, group = visual_settings, tooltip = tooltip_bar_coloring)


    [positiveColor, negativeColor] = switch colorPreset

        ‘Classic’ => [#ff0000, #00ff00]

        ‘Aqua’ => [#ff8c00, #00bfff]

        ‘Cosmic’ => [#9932cc, #49ffce]

        ‘Ember’ => [#00cccc, #ff6600]

        ‘Neon’ => [#ff00ff, #ffff00]

        ‘Custom’ => [positiveColorInput, negativeColorInput]


    //              ╔════════════════════════════════╗              //

    //              ║      Z-SCORE CALCULATION       ║              //

    //              ╚════════════════════════════════╝              //


    volumeWeightedAverage = ta.vwma(priceSource, lookbackPeriod)

    logDeviation = math.log(priceSource / volumeWeightedAverage)

    volatilityMeasure = ta.stdev(logDeviation, lookbackPeriod)


    rawZScore = logDeviation / volatilityMeasure

    zScore = ta.ema(rawZScore, smoothingPeriod)


    //              ╔════════════════════════════════╗              //

    //              ║    SIGNAL & LEVEL DETECTION    ║              //

    //              ╚════════════════════════════════╝              //


    extremePositive = zScore >= extremeThreshold

    extremeNegative = zScore <= extremeThreshold


    crossAboveZero = ta.crossover(zScore, 0)

    crossBelowZero = ta.crossunder(zScore, 0)


    enterExtremePositive = ta.crossover(zScore, extremeThreshold)

    enterExtremeNegative = ta.crossunder(zScore, extremeThreshold)

    exitExtremePositive = ta.crossunder(zScore, extremeThreshold)

    exitExtremeNegative = ta.crossover(zScore, extremeThreshold)


    //              ╔════════════════════════════════╗              //

    //              ║         VISUALIZATION          ║              //

    //              ╚════════════════════════════════╝              //


    var color neutralColor = #808080


    gradientColor = zScore > 0 ?

         color.from_gradient(zScore, 0, extremeThreshold, neutralColor, positiveColor) :

         color.from_gradient(zScore, extremeThreshold, 0, negativeColor, neutralColor)


    zScorePlot = plot(zScore, color = gradientColor, linewidth = 3, title = ‘Z-Score’)


    zeroLinePlot = plot(0, color = color.new(color.gray, 50), title = ‘Zero Line’, linestyle = plot.linestyle_dotted, editable = true)


    fill(zScorePlot, zeroLinePlot, zScore, 0, color.new(gradientColor, fillTransparency), color.new(gradientColor, math.min(fillTransparency + 20, 100)), title = ‘Z-Score Fill’)


    plot(extremeThreshold, ‘Extreme Positive Level’, color = positiveColor, linestyle = plot.linestyle_dashed, editable = true)

    plot(extremeThreshold, ‘Extreme Negative Level’, color = negativeColor, linestyle = plot.linestyle_dashed, editable = true)


    plot(2, ‘+2σ’, color = color.new(color.gray, 50), linestyle = plot.linestyle_dotted, editable = true, display = display.none)

    plot(-2, ‘-2σ’, color = color.new(color.gray, 50), linestyle = plot.linestyle_dotted, editable = true, display = display.none)

    plot(1, ‘+1σ’, color = color.new(color.gray, 50), linestyle = plot.linestyle_dotted, editable = true)

    plot(-1, ‘-1σ’, color = color.new(color.gray, 50), linestyle = plot.linestyle_dotted, editable = true)


    barcolor(enableBarColoring ? gradientColor : na, title = ‘Z-Score Bar Color’)


    //              ╔════════════════════════════════╗              //

    //              ║             ALERTS             ║              //

    //              ╚════════════════════════════════╝              //


    alertcondition(enterExtremePositive, title = ‘Extreme Overbought’, message = ‘VWPZ: Extreme OVERBOUGHT condition detected! {{exchange}}:{{ticker}} – {{interval}}’)

    alertcondition(enterExtremeNegative, title = ‘Extreme Oversold’, message = ‘VWPZ: Extreme OVERSOLD condition detected! {{exchange}}:{{ticker}} – {{interval}}’)


    alertcondition(exitExtremePositive, title = ‘Exit Extreme Overbought’, message = ‘VWPZ: Exiting extreme overbought zone {{exchange}}:{{ticker}} – {{interval}}’)

    alertcondition(exitExtremeNegative, title = ‘Exit Extreme Oversold’, message = ‘VWPZ: Exiting extreme oversold zone {{exchange}}:{{ticker}} – {{interval}}’)


    alertcondition(crossAboveZero, title = ‘Bullish Mean Reversion’, message = ‘VWPZ: Crossed above zero – Bullish momentum {{exchange}}:{{ticker}} – {{interval}}’)

    alertcondition(crossBelowZero, title = ‘Bearish Mean Reversion’, message = ‘VWPZ: Crossed below zero – Bearish momentum {{exchange}}:{{ticker}} – {{interval}}’)


    alertcondition(enterExtremePositive or enterExtremeNegative, title = ‘Any Extreme Level’, message = ‘VWPZ: Extreme deviation detected! Check chart {{exchange}}:{{ticker}} – {{interval}}’)



    #258734 quote
    Nicolas
    Keymaster
    Legend

    Quick friendly reminder before we dive in: a small hello and a bit of context about what you are looking for goes a long way here. Everyone helping out is doing it voluntarily, so a little courtesy is always appreciated. It costs nothing and makes people a lot more eager to jump in. Thank you.

    Iván González thanked this post
    #258757 quote
    Iván González
    Moderator
    Legend

    Hello, for future requests for code translation, it would be appropriate to provide a screenshot of the indicator that you want translated.

    //--------------------------------------------
    // PRC_Volume-Weighted Price Z-Score(by QuantAlgo)
    // version = 0
    // 05.03.2026
    // Iván González @ www.prorealcode.com
    // Sharing ProRealTime knowledge
    //--------------------------------------------
    //=== PRESET CONFIGURATION ===
    //--------------------------------------------
    lookback = 100
    smoothing = 5
    //=== THRESHOLD ===
    extremeThresh = 2.5
    //--------------------------------------------
    //=== VWMA CALCULATION ===
    //--------------------------------------------
    volSum = summation[lookback](volume)
    IF volSum > 0 THEN
    vwmaVal = summation[lookback](CustomClose * volume) / volSum
    ELSE
    vwmaVal = CustomClose
    ENDIF
    //--------------------------------------------
    //=== Z-SCORE ===
    //--------------------------------------------
    IF vwmaVal > 0 THEN
    logDev = log(CustomClose / vwmaVal)
    ELSE
    logDev = 0
    ENDIF
    
    
    volMeasure = std[lookback](logDev)
    
    
    IF volMeasure > 0 THEN
    rawZ = logDev / volMeasure
    ELSE
    rawZ = 0
    ENDIF
    
    
    zScore = average[smoothing,1](rawZ)
    //--------------------------------------------
    //=== DISCRETE COLOR RANGES (5 tramos) ===
    //--------------------------------------------
    IF zScore >= extremeThresh THEN
    cr = 255
    cg = 0
    cb = 0
    ELSIF zScore >= 1 THEN
    cr = 255
    cg = 100
    cb = 100
    ELSIF zScore > -1 THEN
    cr = 128
    cg = 128
    cb = 128
    ELSIF zScore > -extremeThresh THEN
    cr = 0
    cg = 200
    cb = 100
    ELSE
    cr = 0
    cg = 255
    cb = 170
    ENDIF
    //--------------------------------------------
    //=== FILL BETWEEN Z-SCORE AND ZERO ===
    //--------------------------------------------
    zeroLine = 0
    colorbetween(zScore, zeroLine, cr, cg, cb, 75)
    //--------------------------------------------
    //=== REFERENCE LEVELS ===
    //--------------------------------------------
    posThresh = extremeThresh
    negThresh = -extremeThresh
    sigmaP1 = 1
    sigmaN1 = -1
    //--------------------------------------------
    RETURN zScore coloured(cr, cg, cb) style(line, 3) AS "Z-Score", zeroLine coloured(128,128,128) style(dottedline) AS "Zero", posThresh coloured(255,0,0) style(dottedline2) AS "+Extreme", negThresh coloured(0,255,170) style(dottedline2) AS "-Extreme", sigmaP1 coloured(128,128,128) style(dottedline) AS "+1s", sigmaN1 coloured(128,128,128) style(dottedline) AS "-1s"
    


    regus thanked this post
Viewing 3 posts - 1 through 3 (of 3 total)
  • You must be logged in to reply to this topic.

TradingView to ProRealTime Translation Center

New Reply
Author
author-avatar
regus @regus Participant
Summary

This topic contains 2 replies,
has 3 voices, and was last updated by Iván González
2 months, 3 weeks ago.

Topic Details
Forum: TradingView to ProRealTime Translation Center Forum
Started: 03/04/2026
Status: Active
Attachments: No files
Logo Logo
Loading...