Indicator: conversion of Volume-Weighted Price Z-Score

Viewing 3 posts - 1 through 3 (of 3 total)
  • Author
    Posts
  • #258730 quote
    regusregus
    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
    NicolasNicolas
    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álezIvá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.
ProRealAI ProRealAI New

Stuck on this ProBuilder code?

Describe what this topic is trying to build, in plain English, and ProRealAI writes the ProRealTime™ indicator, screener or system for you.

Available in 7 languages
Try ProRealAI

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álezIván González
6 months, 2 weeks ago.

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