# RepaintsWeis Wave Volume Indicator for ThinkorSwim

Repaints

#### BenTen

Staff member
Staff
VIP
Here is the Weis Wave Volume indicator for ThinkorSwim converted from the Lazy Bear's version over at TradingView. In addition, I also found another indicator called Weis Wave Volume with ZigZag so I'll include that in this post as well.

### thinkScript Code (Lazy Bear)

Rich (BB code):
``````#
# @author LazyBear
# List of all my indicators: https://www.tradingview.com/v/4IneGo8h/
#
# study(" [LazyBear]", shorttitle="WWV_LB")
declare lower;
declare zerobase;

# trendDetectionLength=input(2)
input trendDetectionLength = 3;

# mov = close>close[1] ? 1 : close<close[1] ? -1 : 0
def mov = If(close > close[1], 1, If(close < close[1], -1, 0));

# trend= (mov != 0) and (mov != mov[1]) ? mov : nz(trend[1])
# might cause problems not using the nan if statement...
def trend = If((mov != 0) and (mov != mov[1]), mov, (trend[1])) ;
# isTrending = rising(close, trendDetectionLength) or falling(close, trendDetectionLength) //abs(close-close[1]) >= dif
def isTrending = IsAscending(close, trendDetectionLength) or IsDescending(close, trendDetectionLength);

# wave=(trend != nz(wave[1])) and isTrending ? trend : nz(wave[1])
# might be a problem not using the nan function here
def wave = If((trend != (wave[1])) and isTrending, trend , (wave[1]) );

# vol=wave==wave[1] ? (nz(vol[1])+volume) : volume
# might be a problem not using the nan function here
def vol = If(wave == wave[1] , ((vol[1]) + volume) , volume ) ;

# up=wave == 1 ? vol : 0
plot up = If(wave == 1 , vol , 0 );

# dn=showDistributionBelowZero ? (wave == 1 ? 0 : wave == -1 ? -vol : vol) : (wave == 1 ? 0 : vol)
# plot dn = If(wave == 1, 0, If(wave == -1, -vol, vol));
plot dn = If(wave == 1, 0, If(wave == -1, vol, vol));

# plot(up, style=histogram, color=green, linewidth=3)

# plot(dn, style=histogram, color=red, linewidth=3)

dn.setDefaultColor(color.red);
up.setDefaultColor(color.green);
dn.SetLineWeight(3);
up.SetLineWeight(3);
up.SetPaintingStrategy(PaintingStrategy.HISTOGRAM);
dn.SetPaintingStrategy(PaintingStrategy.HISTOGRAM);``````

### Weis Wave Zig Zag with Volume

Rich (BB code):
``````#
# Weis Wave
#

#Note: The Weis Wave indicator shows price waves associated with the Weis Wave Volume lower indicator.
#Note: The reversalAmount: Indicate the minimum amount price must reverse before an inflection point can be formed. This value should be set the same on the lower Weis Wave Volume indicator.

declare upper;

input price = hlc3;
input reversalAmount = 1.0;
input reversalMode = {default price, percent};
input displayMode = {default volume, barNumber, barTotal, none};

def mode = if  reversalMode ==  reversalMode.price then ZigZagTrendSign(price = price, reversalAmount=reversalAmount) else ZigZagTrendPercent(price = price, reversalAmount=reversalAmount);
def inflection = if reversalMode == reversalMode.price then if !isNan(ZigZagSign(price = price, reversalAmount=reversalAmount)) then 1 else 0 else if !isNan(ZigZagPercent(price = price, reversalAmount=reversalAmount)) then 1 else 0;
rec trend = if inflection==1 and mode ==-1 then 1 else if inflection==1 and mode==1 then -1 else trend[1];

plot wave =  if  reversalMode ==  reversalMode.price then ZigZagSign(price = price, reversalAmount=reversalAmount) else ZigZagPercent(price = price, reversalAmount=reversalAmount);
wave.EnableApproximation();
wave.AssignValueColor(if trend[1] == 1 then color.green else color.red);
wave.SetLineWeight(3);

rec upWaveVolume = if inflection == 1 and trend == 1 and close > open then volume else if inflection == 1 and trend == 1 and close <= open then 0 else if trend == 1 or (inflection == 1 and trend == -1 and close >= open) then upWaveVolume[1] + volume else 0;
rec downWaveVolume = if inflection == 1 and trend == -1  and close < open then volume else if inflection == 1 and trend == -1 and close >= open then 0 else if trend == -1 or (inflection == 1 and trend == 1 and close <= open) then downWaveVolume[1] + volume else 0;

rec barsUp = if inflection == 1 and trend == 1  and close > open then 1 else if inflection == 1 and trend == 1 and close <= open then 0 else if trend == 1 or (inflection == 1 and trend == -1 and close >= open) then barsUp[1] + 1 else 0;
rec barsDown =  if inflection == 1 and trend == -1  and close < open then 1 else if inflection == 1 and trend == -1 and close >= open then 0 else if trend == -1 or (inflection == 1 and trend == 1 and close <= open) then barsDown[1] + 1 else 0;

plot uCount = if (displayMode == displayMode.barNumber and barsUp) then barsUp else double.nan;
uCount.SetPaintingStrategy(paintingStrategy.VALUES_BELOW);
uCount.SetDefaultColor(color.dark_green);

plot dCount = if (displayMode == displayMode.barNumber and barsDown) then barsDown else double.nan;
dCount.SetPaintingStrategy(paintingStrategy.VALUES_ABOVE);
dCount.SetDefaultColor(color.red);

plot uCountTot =  if (displayMode == displayMode.barTotal and barsDown == 1 and barsUp==0) then barsUp[1] else double.nan;
uCountTot.SetPaintingStrategy(paintingStrategy.VALUES_ABOVE);
uCountTot.SetDefaultColor(color.dark_green);

plot dCountTot = if (displayMode == displayMode.barTotal and barsDown==0 and barsUp==1) then barsDown[1] else double.nan;
dCountTot.SetPaintingStrategy(paintingStrategy.VALUES_BELOW);
dCountTot.SetDefaultColor(color.red);

plot uVol = if (displayMode == displayMode.volume and barsDown == 1 and barsUp==0) then upWaveVolume[1] else double.nan;
uVol.SetPaintingStrategy(paintingStrategy.VALUES_ABOVE);
uVol.SetDefaultColor(color.dark_green);

plot dVol = if (displayMode == displayMode.volume and barsUp == 1 and barsDown==0) then downWaveVolume[1] else double.nan;
dVol.SetPaintingStrategy(paintingStrategy.VALUES_BELOW);
dVol.SetDefaultColor(color.red);``````

### Ord-Volume

Code:
``````#VM_Ord_Volume_v01
#by GrOwEx
#growex: and i've written a study that calculates average volume on a swing...
#growex: it is similar to Weis Wave
#growex: WeisWave indicator calculates total volume of swing and TimOrd's one
#calculate average volume on each candle

declare upper;

input price = close;
input reversalAmount = 1.0;
input showBubbles = no;
input showLabel = no;
input volumedivider = 1000;
Assert(reversalAmount > 0, "'reversal amount' should be positive: " + reversalAmount);

def barNumber = BarNumber();
def barCount = HighestAll(If(IsNaN(price), 0, barNumber));

def state = {default init, undefined, uptrend, downtrend};
def minMaxPrice;

if (GetValue(state, 1) == GetValue(state.init, 0)) {
minMaxPrice = price;
state = state.undefined;
} else if (GetValue(state, 1) == GetValue(state.undefined, 0)) {
if (price <= GetValue(minMaxPrice, 1) - reversalAmount) {
state = state.downtrend;
minMaxPrice = price;
} else if (price >= GetValue(minMaxPrice, 1) + reversalAmount) {
state = state.uptrend;
minMaxPrice = price;
} else {
state = state.undefined;
minMaxPrice = GetValue(minMaxPrice, 1);
}
} else if (GetValue(state, 1) == GetValue(state.uptrend, 0)) {
if (price <= GetValue(minMaxPrice, 1) - reversalAmount) {
state = state.downtrend;
minMaxPrice = price;
} else {
state = state.uptrend;
minMaxPrice = Max(price, GetValue(minMaxPrice, 1));
}
} else {
if (price >= GetValue(minMaxPrice, 1) + reversalAmount) {
state = state.uptrend;
minMaxPrice = price;
} else {
state = state.downtrend;
minMaxPrice = Min(price, GetValue(minMaxPrice, 1));
}
}

def isCalculated = GetValue(state, 0) != GetValue(state, 1) and barNumber >= 1;
def futureDepth =  barCount - barNumber;
def tmpLastPeriodBar;
if (isCalculated) {
if (futureDepth >= 1 and GetValue(state, 0) == GetValue(state, -1)) {
tmpLastPeriodBar = fold lastPeriodBarI = 2 to futureDepth + 1 with lastPeriodBarAcc = 1
while lastPeriodBarAcc > 0
do if (GetValue(state, 0) != GetValue(state, -lastPeriodBarI))
then -lastPeriodBarAcc
else lastPeriodBarAcc + 1;
} else {
tmpLastPeriodBar = 0;
}
} else {
tmpLastPeriodBar = Double.NaN;
}

def lastPeriodBar = if (!IsNaN(tmpLastPeriodBar)) then -AbsValue(tmpLastPeriodBar) else -futureDepth;

def currentPriceLevel;
def currentPoints;
if (state == state.uptrend and isCalculated) {
currentPriceLevel =
fold barWithMaxOnPeriodI = lastPeriodBar to 1 with barWithMaxOnPeriodAcc = minMaxPrice
do Max(barWithMaxOnPeriodAcc, GetValue(minMaxPrice, barWithMaxOnPeriodI));
currentPoints =
fold maxPointOnPeriodI = lastPeriodBar to 1 with maxPointOnPeriodAcc = Double.NaN
while IsNaN(maxPointOnPeriodAcc)
do if (GetValue(price, maxPointOnPeriodI) == currentPriceLevel)
then maxPointOnPeriodI
else maxPointOnPeriodAcc;
} else if (state == state.downtrend and isCalculated) {
currentPriceLevel =
fold barWithMinOnPeriodI = lastPeriodBar to 1 with barWithMinOnPeriodAcc = minMaxPrice
do Min(barWithMinOnPeriodAcc, GetValue(minMaxPrice, barWithMinOnPeriodI));
currentPoints =
fold minPointOnPeriodI = lastPeriodBar to 1 with minPointOnPeriodAcc = Double.NaN
while IsNaN(minPointOnPeriodAcc)
do if (GetValue(price, minPointOnPeriodI) == currentPriceLevel)
then minPointOnPeriodI
else minPointOnPeriodAcc;
} else if (!isCalculated and (state == state.uptrend or state == state.downtrend)) {
currentPriceLevel = GetValue(currentPriceLevel, 1);
currentPoints = GetValue(currentPoints, 1) + 1;
} else {
currentPoints = 1;
currentPriceLevel = GetValue(price, currentPoints);
}

plot "ZZ\$" = if (barNumber == barCount or barNumber == 1) then price else if (currentPoints == 0) then currentPriceLevel else Double.NaN;

def zzSave = if !IsNaN("ZZ\$") then price else GetValue(zzSave, 1);
def chg = price - GetValue(zzSave, 1);
def isUp = chg >= 0;
def isConf = AbsValue(chg) >= reversalAmount or (IsNaN(GetValue("ZZ\$", 1)) and GetValue(isConf, 1));

rec v = if isUp then volume + v[1] else 0;
rec vd = if !isUp then volume + vd[1] else 0;
rec countup = if isUp then countup[1] + 1 else 0;
rec countdn = if !isUp then countdn[1] + 1 else 0;
def vline = countup;
def vdline = countdn;
def valueup = if v > v[-1] then Round(v / volumedivider, 2) else Double.NaN;
def valuedn = if vd > vd[-1] then Round(vd / volumedivider, 2) else Double.NaN;
def valuecountup = if vline > vline[-1] then vline else Double.NaN;
def valuecountdn = if vdline > vdline[-1] then vdline else Double.NaN;
#def avg =  Round(valueup / valuecountup, 2);
#plot ord_up = Round(valueup / valuecountup, 2);
#plot ord_dn = Round(valuedn / valuecountdn, 2);
#ord_dn.SetPaintingStrategy(PaintingStrategy.VALUES_BELOW);
#ord_up.SetPaintingStrategy(PaintingStrategy.VALUES_ABOVE);
"ZZ\$".EnableApproximation();
"ZZ\$".DefineColor("Up Trend", Color.UPTICK);
"ZZ\$".DefineColor("Down Trend", Color.DOWNTICK);
"ZZ\$".DefineColor("Undefined", Color.DARK_ORANGE);
"ZZ\$".AssignValueColor(if !isConf then "ZZ\$".Color("Undefined") else if isUp then "ZZ\$".Color("Up Trend") else "ZZ\$".Color("Down Trend"));
DefineGlobalColor("Unconfirmed", Color.DARK_ORANGE);
DefineGlobalColor("Up", Color.UPTICK);
DefineGlobalColor("Down", Color.DOWNTICK);
AddChartBubble(showBubbles and !IsNaN("ZZ\$") and barNumber != 1, price,
if v > v[-1] then Round(valueup / valuecountup, 2) else if vd > vd[-1] then Round(valuedn / valuecountdn, 2) else double.nan, if !isConf then GlobalColor("Unconfirmed") else if isUp then GlobalColor("Up") else GlobalColor("Down"), isUp);
AddLabel(showLabel and barNumber != 1, (if isConf then "Confirmed " else "Unconfirmed ") + "ZigZag: " + chg, if !isConf then GlobalColor("Unconfirmed") else if isUp then GlobalColor("Up") else GlobalColor("Down"));``````

Last edited:
It does not plot in, is idea why ? i tried couple of times ... can you post shareable link plz

Last edited:
@Topas I see what happen there. Go to Settings > Equities and make sure you enable "Show volume subgraph".

Last edited:
I have this Wise wave volume code. Looks more accurate with the upper study

Code:
``````declare lower;

def price = hlc3;

input reversalAmount = 1.5;

input reversalMode = {price, default percent};

def mode = if reversalMode == reversalMode.price then ZigZagTrendSign(price = price, reversalAmount = reversalAmount) else ZigZagTrendPercent(price = price, reversalAmount = reversalAmount);

def inflection = if reversalMode == reversalMode.price then if !IsNaN(ZigZagSign(price = price, reversalAmount = reversalAmount)) then 1 else 0 else if !IsNaN(ZigZagPercent(price = price, reversalAmount = reversalAmount)) then 1 else 0;

rec trend = if inflection == 1 and mode == -1 then 1 else if inflection == 1 and mode == 1 then -1 else trend[1];

rec upWaveVolume = if inflection == 1 and trend == 1 and close > open then volume else if inflection == 1 and trend == 1 and close <= open then 0 else if trend == 1 or (inflection == 1 and trend == -1 and close >= open) then upWaveVolume[1] + volume else 0;

rec downWaveVolume = if inflection == 1 and trend == -1 and close < open then volume else if inflection == 1 and trend == -1 and close >= open then 0 else if trend == -1 or (inflection == 1 and trend == 1 and close <= open) then downWaveVolume[1] + volume else 0;

plot upvol = upWaveVolume;

upvol.SetDefaultColor(color.dark_green);

upvol.SetPaintingStrategy(PaintingStrategy.Histogram);

upvol.SetLineWeight(5);

plot dnvol = downWaveVolume;

dnvol.SetDefaultColor( Color.DownTICK);

dnvol.SetPaintingStrategy(PaintingStrategy.Histogram);

dnvol.SetLineWeight(5);``````

Last edited by a moderator:
This WeisWave looks interesting - I would appreciate if @BenTen et al. who are familiar with Thinkscript could explain a bit about what this script is doing. I haven't seen some of these commands / functions before.

@asragov Based on what @Johnny Cash posted, the code seems to have ZigZag function in it. I suspect the volume bar will repaint.

Same question as @thevelvetrock asked. Can somebody edit the zigzag code so that the volume number format can be changed? Reading 8/9 digit numbers is not very convenient. It would be nice to be able to round up the values, like David does in his webinars.

The indicator sums up the volume in the wave and displays the amount at the swing extremum. On very liquid instruments, the values are gigantic (8-9-10 digits), which is very uncomfortable to analyse.

So, this is the question. How to add a field that allows rounding out the output values?

Code is below. Thank you!

Code:
``````#
# Weis Wave
#

#Note: The Weis Wave indicator shows price waves associated with the Weis Wave Volume lower indicator.
#Note: The reversalAmount: Indicate the minimum amount price must reverse before an inflection point can be formed. This value should be set the same on the lower Weis Wave Volume indicator.

declare upper;

input price = hlc3;
input reversalAmount = 1.0;
input reversalMode = {default price, percent};
input displayMode = {default volume, barNumber, barTotal, none};

def mode = if  reversalMode ==  reversalMode.price then ZigZagTrendSign(price = price, reversalAmount=reversalAmount) else ZigZagTrendPercent(price = price, reversalAmount=reversalAmount);
def inflection = if reversalMode == reversalMode.price then if !isNan(ZigZagSign(price = price, reversalAmount=reversalAmount)) then 1 else 0 else if !isNan(ZigZagPercent(price = price, reversalAmount=reversalAmount)) then 1 else 0;
rec trend = if inflection==1 and mode ==-1 then 1 else if inflection==1 and mode==1 then -1 else trend[1];

plot wave =  if  reversalMode ==  reversalMode.price then ZigZagSign(price = price, reversalAmount=reversalAmount) else ZigZagPercent(price = price, reversalAmount=reversalAmount);
wave.EnableApproximation();
wave.AssignValueColor(if trend[1] == 1 then color.green else color.red);
wave.SetLineWeight(3);

rec upWaveVolume = if inflection == 1 and trend == 1 and close > open then volume else if inflection == 1 and trend == 1 and close <= open then 0 else if trend == 1 or (inflection == 1 and trend == -1 and close >= open) then upWaveVolume[1] + volume else 0;
rec downWaveVolume = if inflection == 1 and trend == -1  and close < open then volume else if inflection == 1 and trend == -1 and close >= open then 0 else if trend == -1 or (inflection == 1 and trend == 1 and close <= open) then downWaveVolume[1] + volume else 0;

rec barsUp = if inflection == 1 and trend == 1  and close > open then 1 else if inflection == 1 and trend == 1 and close <= open then 0 else if trend == 1 or (inflection == 1 and trend == -1 and close >= open) then barsUp[1] + 1 else 0;
rec barsDown =  if inflection == 1 and trend == -1  and close < open then 1 else if inflection == 1 and trend == -1 and close >= open then 0 else if trend == -1 or (inflection == 1 and trend == 1 and close <= open) then barsDown[1] + 1 else 0;

plot uCount = if (displayMode == displayMode.barNumber and barsUp) then barsUp else double.nan;
uCount.SetPaintingStrategy(paintingStrategy.VALUES_BELOW);
uCount.SetDefaultColor(color.dark_green);

plot dCount = if (displayMode == displayMode.barNumber and barsDown) then barsDown else double.nan;
dCount.SetPaintingStrategy(paintingStrategy.VALUES_ABOVE);
dCount.SetDefaultColor(color.red);

plot uCountTot =  if (displayMode == displayMode.barTotal and barsDown == 1 and barsUp==0) then barsUp[1] else double.nan;
uCountTot.SetPaintingStrategy(paintingStrategy.VALUES_ABOVE);
uCountTot.SetDefaultColor(color.dark_green);

plot dCountTot = if (displayMode == displayMode.barTotal and barsDown==0 and barsUp==1) then barsDown[1] else double.nan;
dCountTot.SetPaintingStrategy(paintingStrategy.VALUES_BELOW);
dCountTot.SetDefaultColor(color.red);

plot uVol = if (displayMode == displayMode.volume and barsDown == 1 and barsUp==0) then upWaveVolume[1] else double.nan;
uVol.SetPaintingStrategy(paintingStrategy.VALUES_ABOVE);
uVol.SetDefaultColor(color.dark_green);

plot dVol = if (displayMode == displayMode.volume and barsUp == 1 and barsDown==0) then downWaveVolume[1] else double.nan;
dVol.SetPaintingStrategy(paintingStrategy.VALUES_BELOW);
dVol.SetDefaultColor(color.red);``````

@ShinJ
To round the volumes printed on the Weis Wave chart by 100,000; replace the last six lines of the program with the following:

Code:
``````plot uVol = if (displayMode == displayMode.volume and barsDown == 1 and barsUp==0) then Round("number" = upWaveVolume[1] / 100000, "numberOfDigits" = 1)  else double.nan;
uVol.SetPaintingStrategy(paintingStrategy.VALUES_ABOVE);
uVol.SetDefaultColor(color.dark_green);

plot dVol = if (displayMode == displayMode.volume and barsUp == 1 and barsDown==0) then Round("number" = downWaveVolume[1] / 100000, "numberOfDigits" = 1) else double.nan;
dVol.SetPaintingStrategy(paintingStrategy.VALUES_BELOW);
dVol.SetDefaultColor(color.red);``````

For not "very liquid instruments", this will result in zero being displayed. Hope this helps.

Last edited:
@option_trader I'm seeing ZigZag being included in that script, be careful as it will repaint. That being said, not sure if it will be compatible with the mobile app.

Is it possible within thinkscript to calculate the percentage change in average volume between prior high or prior low pivots? i.e. in ShinJ's post, the last pivot high of 615 would have a calculation of (615-519)/519 * 100 so an increase of 18%.... and the 519 value would have the calc between 519 and 548.. and the low pivot points would have a similar concept to it..

https://n.b5z.net/i/u/10144154/f/Ord Articles/PriceVolume.pdf

Last edited by a moderator:
Is it possible within thinkscript to calculate the percentage change in average volume between prior high or prior low pivots? i.e. in ShinJ's post, the last pivot high of 615 would have a calculation of (615-519)/519 * 100 so an increase of 18%.... and the 519 value would have the calc between 519 and 548.. and the low pivot points would have a similar concept to it..

https://n.b5z.net/i/u/10144154/f/Ord Articles/PriceVolume.pdf
@eluciano530 There is not any code similar to your request available on the forum

Last edited:
I have this Wise wave volume code. Looks more accurate with the upper study

Code:
``````declare lower;

def price = hlc3;

input reversalAmount = 1.5;

input reversalMode = {price, default percent};

def mode = if reversalMode == reversalMode.price then ZigZagTrendSign(price = price, reversalAmount = reversalAmount) else ZigZagTrendPercent(price = price, reversalAmount = reversalAmount);

def inflection = if reversalMode == reversalMode.price then if !IsNaN(ZigZagSign(price = price, reversalAmount = reversalAmount)) then 1 else 0 else if !IsNaN(ZigZagPercent(price = price, reversalAmount = reversalAmount)) then 1 else 0;

rec trend = if inflection == 1 and mode == -1 then 1 else if inflection == 1 and mode == 1 then -1 else trend[1];

rec upWaveVolume = if inflection == 1 and trend == 1 and close > open then volume else if inflection == 1 and trend == 1 and close <= open then 0 else if trend == 1 or (inflection == 1 and trend == -1 and close >= open) then upWaveVolume[1] + volume else 0;

rec downWaveVolume = if inflection == 1 and trend == -1 and close < open then volume else if inflection == 1 and trend == -1 and close >= open then 0 else if trend == -1 or (inflection == 1 and trend == 1 and close <= open) then downWaveVolume[1] + volume else 0;

plot upvol = upWaveVolume;

upvol.SetDefaultColor(color.dark_green);

upvol.SetPaintingStrategy(PaintingStrategy.Histogram);

upvol.SetLineWeight(5);

plot dnvol = downWaveVolume;

dnvol.SetDefaultColor( Color.DownTICK);

dnvol.SetPaintingStrategy(PaintingStrategy.Histogram);

dnvol.SetLineWeight(5);``````
Thank you for sharing .. Great Indicator, is there a way to stop it from re-painting?

Made a self-adjusting version that changes the % percent parameter based on ATR, so you dont have to change settings every time you switch symbols to keep it accurate. Add it to studies and just leave it alone and you're good to go (unless you wanna change the ATR length)

Code:
``````declare lower;

def price = hlc3;

input atrlength = 20;
input atraverageType = AverageType.Exponential;

def ATR = MovingAverage(atraverageType, TrueRange(high, close, low), atrlength);

def atrperc = (atr/close )* 100;

def reversalAmount = atrperc;

input reversalMode = {price, default percent};

def mode = if reversalMode == reversalMode.price then ZigZagTrendSign(price = price, reversalAmount = reversalAmount) else ZigZagTrendPercent(price = price, reversalAmount = reversalAmount);

def inflection = if reversalMode == reversalMode.price then if !IsNaN(ZigZagSign(price = price, reversalAmount = reversalAmount)) then 1 else 0 else if !IsNaN(ZigZagPercent(price = price, reversalAmount = reversalAmount)) then 1 else 0;

rec trend = if inflection == 1 and mode == -1 then 1 else if inflection == 1 and mode == 1 then -1 else trend[1];

rec upWaveVolume = if inflection == 1 and trend == 1 and close > open then volume else if inflection == 1 and trend == 1 and close <= open then 0 else if trend == 1 or (inflection == 1 and trend == -1 and close >= open) then upWaveVolume[1] + volume else 0;

rec downWaveVolume = if inflection == 1 and trend == -1 and close < open then volume else if inflection == 1 and trend == -1 and close >= open then 0 else if trend == -1 or (inflection == 1 and trend == 1 and close <= open) then downWaveVolume[1] + volume else 0;

plot upvol = upWaveVolume;

upvol.SetDefaultColor(color.dark_green);

upvol.SetPaintingStrategy(PaintingStrategy.Histogram);

upvol.SetLineWeight(5);

plot dnvol = downWaveVolume;

dnvol.SetDefaultColor( Color.DownTICK);

dnvol.SetPaintingStrategy(PaintingStrategy.Histogram);

dnvol.SetLineWeight(5);

addlabel(yes, "ATR(" + ATRLENGTH+ "): " + aspercent(ATRPERC/100), COLOR.LIGHT_GRAY);``````

Last edited:
Could you add Candle Painting upper?

Not tested:
Ruby:
``````AssignPriceColor(
if up then color.green else
if dn then color.red else color.gray);``````

Could you add Candle Painting upper?
Code:
``````declare lower;

def price = hlc3;

input atrlength = 20;
input atraverageType = AverageType.Exponential;
input reversalMode = {price, default percent};

input colorbars = no;

def ATR = MovingAverage(atraverageType, TrueRange(high, close, low), atrlength);

def atrperc = (atr/close )* 100;

def reversalAmount = atrperc;

def mode = if reversalMode == reversalMode.price then ZigZagTrendSign(price = price, reversalAmount = reversalAmount) else ZigZagTrendPercent(price = price, reversalAmount = reversalAmount);

def inflection = if reversalMode == reversalMode.price then if !IsNaN(ZigZagSign(price = price, reversalAmount = reversalAmount)) then 1 else 0 else if !IsNaN(ZigZagPercent(price = price, reversalAmount = reversalAmount)) then 1 else 0;

rec trend = if inflection == 1 and mode == -1 then 1 else if inflection == 1 and mode == 1 then -1 else trend[1];

rec upWaveVolume = if inflection == 1 and trend == 1 and close > open then volume else if inflection == 1 and trend == 1 and close <= open then 0 else if trend == 1 or (inflection == 1 and trend == -1 and close >= open) then upWaveVolume[1] + volume else 0;

rec downWaveVolume = if inflection == 1 and trend == -1 and close < open then volume else if inflection == 1 and trend == -1 and close >= open then 0 else if trend == -1 or (inflection == 1 and trend == 1 and close <= open) then downWaveVolume[1] + volume else 0;

plot upvol = upWaveVolume;

upvol.SetDefaultColor(color.dark_green);

upvol.SetPaintingStrategy(PaintingStrategy.Histogram);

upvol.SetLineWeight(5);

plot dnvol = downWaveVolume;

dnvol.SetDefaultColor( Color.DownTICK);

dnvol.SetPaintingStrategy(PaintingStrategy.Histogram);

dnvol.SetLineWeight(5);

assignpricecolor(if colorbars and upvol then color.dark_Green else if colorbars and dnvol then color.downtick else color.current);

addlabel(yes, "ATR(" + ATRLENGTH+ "): " + aspercent(ATRPERC/100), COLOR.LIGHT_GRAY);``````

Hi Johnny Cash, Can you please show me how to scan for Upvol and Dnvol for weis wave volume study? Thanks.

Here is the Weis Wave Volume indicator for ThinkorSwim converted from the Lazy Bear's version over at TradingView. In addition, I also found another indicator called Weis Wave Volume with ZigZag so I'll include that in this post as well.

### thinkScript Code (Lazy Bear)

Rich (BB code):
``````#
# @author LazyBear
# List of all my indicators: https://www.tradingview.com/v/4IneGo8h/
#
# study(" [LazyBear]", shorttitle="WWV_LB")
declare lower;
declare zerobase;

# trendDetectionLength=input(2)
input trendDetectionLength = 3;

# mov = close>close[1] ? 1 : close<close[1] ? -1 : 0
def mov = If(close > close[1], 1, If(close < close[1], -1, 0));

# trend= (mov != 0) and (mov != mov[1]) ? mov : nz(trend[1])
# might cause problems not using the nan if statement...
def trend = If((mov != 0) and (mov != mov[1]), mov, (trend[1])) ;
# isTrending = rising(close, trendDetectionLength) or falling(close, trendDetectionLength) //abs(close-close[1]) >= dif
def isTrending = IsAscending(close, trendDetectionLength) or IsDescending(close, trendDetectionLength);

# wave=(trend != nz(wave[1])) and isTrending ? trend : nz(wave[1])
# might be a problem not using the nan function here
def wave = If((trend != (wave[1])) and isTrending, trend , (wave[1]) );

# vol=wave==wave[1] ? (nz(vol[1])+volume) : volume
# might be a problem not using the nan function here
def vol = If(wave == wave[1] , ((vol[1]) + volume) , volume ) ;

# up=wave == 1 ? vol : 0
plot up = If(wave == 1 , vol , 0 );

# dn=showDistributionBelowZero ? (wave == 1 ? 0 : wave == -1 ? -vol : vol) : (wave == 1 ? 0 : vol)
# plot dn = If(wave == 1, 0, If(wave == -1, -vol, vol));
plot dn = If(wave == 1, 0, If(wave == -1, vol, vol));

# plot(up, style=histogram, color=green, linewidth=3)

# plot(dn, style=histogram, color=red, linewidth=3)

dn.setDefaultColor(color.red);
up.setDefaultColor(color.green);
dn.SetLineWeight(3);
up.SetLineWeight(3);
up.SetPaintingStrategy(PaintingStrategy.HISTOGRAM);
dn.SetPaintingStrategy(PaintingStrategy.HISTOGRAM);``````

### Weis Wave Zig Zag with Volume

Rich (BB code):
``````#
# Weis Wave
#

#Note: The Weis Wave indicator shows price waves associated with the Weis Wave Volume lower indicator.
#Note: The reversalAmount: Indicate the minimum amount price must reverse before an inflection point can be formed. This value should be set the same on the lower Weis Wave Volume indicator.

declare upper;

input price = hlc3;
input reversalAmount = 1.0;
input reversalMode = {default price, percent};
input displayMode = {default volume, barNumber, barTotal, none};

def mode = if  reversalMode ==  reversalMode.price then ZigZagTrendSign(price = price, reversalAmount=reversalAmount) else ZigZagTrendPercent(price = price, reversalAmount=reversalAmount);
def inflection = if reversalMode == reversalMode.price then if !isNan(ZigZagSign(price = price, reversalAmount=reversalAmount)) then 1 else 0 else if !isNan(ZigZagPercent(price = price, reversalAmount=reversalAmount)) then 1 else 0;
rec trend = if inflection==1 and mode ==-1 then 1 else if inflection==1 and mode==1 then -1 else trend[1];

plot wave =  if  reversalMode ==  reversalMode.price then ZigZagSign(price = price, reversalAmount=reversalAmount) else ZigZagPercent(price = price, reversalAmount=reversalAmount);
wave.EnableApproximation();
wave.AssignValueColor(if trend[1] == 1 then color.green else color.red);
wave.SetLineWeight(3);

rec upWaveVolume = if inflection == 1 and trend == 1 and close > open then volume else if inflection == 1 and trend == 1 and close <= open then 0 else if trend == 1 or (inflection == 1 and trend == -1 and close >= open) then upWaveVolume[1] + volume else 0;
rec downWaveVolume = if inflection == 1 and trend == -1  and close < open then volume else if inflection == 1 and trend == -1 and close >= open then 0 else if trend == -1 or (inflection == 1 and trend == 1 and close <= open) then downWaveVolume[1] + volume else 0;

rec barsUp = if inflection == 1 and trend == 1  and close > open then 1 else if inflection == 1 and trend == 1 and close <= open then 0 else if trend == 1 or (inflection == 1 and trend == -1 and close >= open) then barsUp[1] + 1 else 0;
rec barsDown =  if inflection == 1 and trend == -1  and close < open then 1 else if inflection == 1 and trend == -1 and close >= open then 0 else if trend == -1 or (inflection == 1 and trend == 1 and close <= open) then barsDown[1] + 1 else 0;

plot uCount = if (displayMode == displayMode.barNumber and barsUp) then barsUp else double.nan;
uCount.SetPaintingStrategy(paintingStrategy.VALUES_BELOW);
uCount.SetDefaultColor(color.dark_green);

plot dCount = if (displayMode == displayMode.barNumber and barsDown) then barsDown else double.nan;
dCount.SetPaintingStrategy(paintingStrategy.VALUES_ABOVE);
dCount.SetDefaultColor(color.red);

plot uCountTot =  if (displayMode == displayMode.barTotal and barsDown == 1 and barsUp==0) then barsUp[1] else double.nan;
uCountTot.SetPaintingStrategy(paintingStrategy.VALUES_ABOVE);
uCountTot.SetDefaultColor(color.dark_green);

plot dCountTot = if (displayMode == displayMode.barTotal and barsDown==0 and barsUp==1) then barsDown[1] else double.nan;
dCountTot.SetPaintingStrategy(paintingStrategy.VALUES_BELOW);
dCountTot.SetDefaultColor(color.red);

plot uVol = if (displayMode == displayMode.volume and barsDown == 1 and barsUp==0) then upWaveVolume[1] else double.nan;
uVol.SetPaintingStrategy(paintingStrategy.VALUES_ABOVE);
uVol.SetDefaultColor(color.dark_green);

plot dVol = if (displayMode == displayMode.volume and barsUp == 1 and barsDown==0) then downWaveVolume[1] else double.nan;
dVol.SetPaintingStrategy(paintingStrategy.VALUES_BELOW);
dVol.SetDefaultColor(color.red);``````

### Ord-Volume

Code:
``````#VM_Ord_Volume_v01
#by GrOwEx
#growex: and i've written a study that calculates average volume on a swing...
#growex: it is similar to Weis Wave
#growex: WeisWave indicator calculates total volume of swing and TimOrd's one
#calculate average volume on each candle

declare upper;

input price = close;
input reversalAmount = 1.0;
input showBubbles = no;
input showLabel = no;
input volumedivider = 1000;
Assert(reversalAmount > 0, "'reversal amount' should be positive: " + reversalAmount);

def barNumber = BarNumber();
def barCount = HighestAll(If(IsNaN(price), 0, barNumber));

def state = {default init, undefined, uptrend, downtrend};
def minMaxPrice;

if (GetValue(state, 1) == GetValue(state.init, 0)) {
minMaxPrice = price;
state = state.undefined;
} else if (GetValue(state, 1) == GetValue(state.undefined, 0)) {
if (price <= GetValue(minMaxPrice, 1) - reversalAmount) {
state = state.downtrend;
minMaxPrice = price;
} else if (price >= GetValue(minMaxPrice, 1) + reversalAmount) {
state = state.uptrend;
minMaxPrice = price;
} else {
state = state.undefined;
minMaxPrice = GetValue(minMaxPrice, 1);
}
} else if (GetValue(state, 1) == GetValue(state.uptrend, 0)) {
if (price <= GetValue(minMaxPrice, 1) - reversalAmount) {
state = state.downtrend;
minMaxPrice = price;
} else {
state = state.uptrend;
minMaxPrice = Max(price, GetValue(minMaxPrice, 1));
}
} else {
if (price >= GetValue(minMaxPrice, 1) + reversalAmount) {
state = state.uptrend;
minMaxPrice = price;
} else {
state = state.downtrend;
minMaxPrice = Min(price, GetValue(minMaxPrice, 1));
}
}

def isCalculated = GetValue(state, 0) != GetValue(state, 1) and barNumber >= 1;
def futureDepth =  barCount - barNumber;
def tmpLastPeriodBar;
if (isCalculated) {
if (futureDepth >= 1 and GetValue(state, 0) == GetValue(state, -1)) {
tmpLastPeriodBar = fold lastPeriodBarI = 2 to futureDepth + 1 with lastPeriodBarAcc = 1
while lastPeriodBarAcc > 0
do if (GetValue(state, 0) != GetValue(state, -lastPeriodBarI))
then -lastPeriodBarAcc
else lastPeriodBarAcc + 1;
} else {
tmpLastPeriodBar = 0;
}
} else {
tmpLastPeriodBar = Double.NaN;
}

def lastPeriodBar = if (!IsNaN(tmpLastPeriodBar)) then -AbsValue(tmpLastPeriodBar) else -futureDepth;

def currentPriceLevel;
def currentPoints;
if (state == state.uptrend and isCalculated) {
currentPriceLevel =
fold barWithMaxOnPeriodI = lastPeriodBar to 1 with barWithMaxOnPeriodAcc = minMaxPrice
do Max(barWithMaxOnPeriodAcc, GetValue(minMaxPrice, barWithMaxOnPeriodI));
currentPoints =
fold maxPointOnPeriodI = lastPeriodBar to 1 with maxPointOnPeriodAcc = Double.NaN
while IsNaN(maxPointOnPeriodAcc)
do if (GetValue(price, maxPointOnPeriodI) == currentPriceLevel)
then maxPointOnPeriodI
else maxPointOnPeriodAcc;
} else if (state == state.downtrend and isCalculated) {
currentPriceLevel =
fold barWithMinOnPeriodI = lastPeriodBar to 1 with barWithMinOnPeriodAcc = minMaxPrice
do Min(barWithMinOnPeriodAcc, GetValue(minMaxPrice, barWithMinOnPeriodI));
currentPoints =
fold minPointOnPeriodI = lastPeriodBar to 1 with minPointOnPeriodAcc = Double.NaN
while IsNaN(minPointOnPeriodAcc)
do if (GetValue(price, minPointOnPeriodI) == currentPriceLevel)
then minPointOnPeriodI
else minPointOnPeriodAcc;
} else if (!isCalculated and (state == state.uptrend or state == state.downtrend)) {
currentPriceLevel = GetValue(currentPriceLevel, 1);
currentPoints = GetValue(currentPoints, 1) + 1;
} else {
currentPoints = 1;
currentPriceLevel = GetValue(price, currentPoints);
}

plot "ZZ\$" = if (barNumber == barCount or barNumber == 1) then price else if (currentPoints == 0) then currentPriceLevel else Double.NaN;

def zzSave = if !IsNaN("ZZ\$") then price else GetValue(zzSave, 1);
def chg = price - GetValue(zzSave, 1);
def isUp = chg >= 0;
def isConf = AbsValue(chg) >= reversalAmount or (IsNaN(GetValue("ZZ\$", 1)) and GetValue(isConf, 1));

rec v = if isUp then volume + v[1] else 0;
rec vd = if !isUp then volume + vd[1] else 0;
rec countup = if isUp then countup[1] + 1 else 0;
rec countdn = if !isUp then countdn[1] + 1 else 0;
def vline = countup;
def vdline = countdn;
def valueup = if v > v[-1] then Round(v / volumedivider, 2) else Double.NaN;
def valuedn = if vd > vd[-1] then Round(vd / volumedivider, 2) else Double.NaN;
def valuecountup = if vline > vline[-1] then vline else Double.NaN;
def valuecountdn = if vdline > vdline[-1] then vdline else Double.NaN;
#def avg =  Round(valueup / valuecountup, 2);
#plot ord_up = Round(valueup / valuecountup, 2);
#plot ord_dn = Round(valuedn / valuecountdn, 2);
#ord_dn.SetPaintingStrategy(PaintingStrategy.VALUES_BELOW);
#ord_up.SetPaintingStrategy(PaintingStrategy.VALUES_ABOVE);
"ZZ\$".EnableApproximation();
"ZZ\$".DefineColor("Up Trend", Color.UPTICK);
"ZZ\$".DefineColor("Down Trend", Color.DOWNTICK);
"ZZ\$".DefineColor("Undefined", Color.DARK_ORANGE);
"ZZ\$".AssignValueColor(if !isConf then "ZZ\$".Color("Undefined") else if isUp then "ZZ\$".Color("Up Trend") else "ZZ\$".Color("Down Trend"));
DefineGlobalColor("Unconfirmed", Color.DARK_ORANGE);
DefineGlobalColor("Up", Color.UPTICK);
DefineGlobalColor("Down", Color.DOWNTICK);
AddChartBubble(showBubbles and !IsNaN("ZZ\$") and barNumber != 1, price,
if v > v[-1] then Round(valueup / valuecountup, 2) else if vd > vd[-1] then Round(valuedn / valuecountdn, 2) else double.nan, if !isConf then GlobalColor("Unconfirmed") else if isUp then GlobalColor("Up") else GlobalColor("Down"), isUp);
AddLabel(showLabel and barNumber != 1, (if isConf then "Confirmed " else "Unconfirmed ") + "ZigZag: " + chg, if !isConf then GlobalColor("Unconfirmed") else if isUp then GlobalColor("Up") else GlobalColor("Down"));``````
Hi Ben, is it possible to scan for upwavevolume or downwavevolume in the weis wave study?
I see the following error when I try

com.devexperts.tos.thinkscript.runtime.TooComplexException: The complexity of the expression suggests that it may not be reliable with real-time data.

can you please show how to scan for upwavevolume or downwavevolume? Thanks,

Hi Johnny Cash, Can you please show me how to scan for Upvol and Dnvol for weis wave volume study? Thanks.

Hi Ben, is it possible to scan for upwavevolume or downwavevolume in the weis wave study?
I see the following error when I try

com.devexperts.tos.thinkscript.runtime.TooComplexException: The complexity of the expression suggests that it may not be reliable with real-time data.

can you please show how to scan for upwavevolume or downwavevolume? Thanks,
yea that means the calculation is too complex to be able to scan with. Nothing can be done bout that

Same question as @thevelvetrock asked. Can somebody edit the zigzag code so that the volume number format can be changed? Reading 8/9 digit numbers is not very convenient. It would be nice to be able to round up the values, like David does in his webinars.

The indicator sums up the volume in the wave and displays the amount at the swing extremum. On very liquid instruments, the values are gigantic (8-9-10 digits), which is very uncomfortable to analyse.

So, this is the question. How to add a field that allows rounding out the output values?

Code is below. Thank you!

Code:
``````#
# Weis Wave
#

#Note: The Weis Wave indicator shows price waves associated with the Weis Wave Volume lower indicator.
#Note: The reversalAmount: Indicate the minimum amount price must reverse before an inflection point can be formed. This value should be set the same on the lower Weis Wave Volume indicator.

declare upper;

input price = hlc3;
input reversalAmount = 1.0;
input reversalMode = {default price, percent};
input displayMode = {default volume, barNumber, barTotal, none};

def mode = if  reversalMode ==  reversalMode.price then ZigZagTrendSign(price = price, reversalAmount=reversalAmount) else ZigZagTrendPercent(price = price, reversalAmount=reversalAmount);
def inflection = if reversalMode == reversalMode.price then if !isNan(ZigZagSign(price = price, reversalAmount=reversalAmount)) then 1 else 0 else if !isNan(ZigZagPercent(price = price, reversalAmount=reversalAmount)) then 1 else 0;
rec trend = if inflection==1 and mode ==-1 then 1 else if inflection==1 and mode==1 then -1 else trend[1];

plot wave =  if  reversalMode ==  reversalMode.price then ZigZagSign(price = price, reversalAmount=reversalAmount) else ZigZagPercent(price = price, reversalAmount=reversalAmount);
wave.EnableApproximation();
wave.AssignValueColor(if trend[1] == 1 then color.green else color.red);
wave.SetLineWeight(3);

rec upWaveVolume = if inflection == 1 and trend == 1 and close > open then volume else if inflection == 1 and trend == 1 and close <= open then 0 else if trend == 1 or (inflection == 1 and trend == -1 and close >= open) then upWaveVolume[1] + volume else 0;
rec downWaveVolume = if inflection == 1 and trend == -1  and close < open then volume else if inflection == 1 and trend == -1 and close >= open then 0 else if trend == -1 or (inflection == 1 and trend == 1 and close <= open) then downWaveVolume[1] + volume else 0;

rec barsUp = if inflection == 1 and trend == 1  and close > open then 1 else if inflection == 1 and trend == 1 and close <= open then 0 else if trend == 1 or (inflection == 1 and trend == -1 and close >= open) then barsUp[1] + 1 else 0;
rec barsDown =  if inflection == 1 and trend == -1  and close < open then 1 else if inflection == 1 and trend == -1 and close >= open then 0 else if trend == -1 or (inflection == 1 and trend == 1 and close <= open) then barsDown[1] + 1 else 0;

plot uCount = if (displayMode == displayMode.barNumber and barsUp) then barsUp else double.nan;
uCount.SetPaintingStrategy(paintingStrategy.VALUES_BELOW);
uCount.SetDefaultColor(color.dark_green);

plot dCount = if (displayMode == displayMode.barNumber and barsDown) then barsDown else double.nan;
dCount.SetPaintingStrategy(paintingStrategy.VALUES_ABOVE);
dCount.SetDefaultColor(color.red);

plot uCountTot =  if (displayMode == displayMode.barTotal and barsDown == 1 and barsUp==0) then barsUp[1] else double.nan;
uCountTot.SetPaintingStrategy(paintingStrategy.VALUES_ABOVE);
uCountTot.SetDefaultColor(color.dark_green);

plot dCountTot = if (displayMode == displayMode.barTotal and barsDown==0 and barsUp==1) then barsDown[1] else double.nan;
dCountTot.SetPaintingStrategy(paintingStrategy.VALUES_BELOW);
dCountTot.SetDefaultColor(color.red);

plot uVol = if (displayMode == displayMode.volume and barsDown == 1 and barsUp==0) then upWaveVolume[1] else double.nan;
uVol.SetPaintingStrategy(paintingStrategy.VALUES_ABOVE);
uVol.SetDefaultColor(color.dark_green);

plot dVol = if (displayMode == displayMode.volume and barsUp == 1 and barsDown==0) then downWaveVolume[1] else double.nan;
dVol.SetPaintingStrategy(paintingStrategy.VALUES_BELOW);
dVol.SetDefaultColor(color.red);``````
Question: does the volume number on thee reversal bars indicate how much volume is needed for a reversal? If not, what does it mean? I'm having a hard time understanding. Thanks in advance.

87k+ Posts
401 Online

## The Market Trading Game Changer

Join 2,500+ subscribers inside the useThinkScript VIP Membership Club
• Exclusive indicators
• Proven strategies & setups
• Private Discord community
• Exclusive members-only content
• 1 full year of unlimited support

What is useThinkScript?

useThinkScript is the #1 community of stock market investors using indicators and other tools to power their trading strategies. Traders of all skill levels use our forums to learn about scripting and indicators, help each other, and discover new ways to gain an edge in the markets.

How do I get started?

We get it. Our forum can be intimidating, if not overwhelming. With thousands of topics, tens of thousands of posts, our community has created an incredibly deep knowledge base for stock traders. No one can ever exhaust every resource provided on our site.

If you are new, or just looking for guidance, here are some helpful links to get you started.

What are the benefits of VIP Membership?