Weis Wave Volume Indicator for ThinkorSwim

BenTen

Administrative
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.

xTVRW5O.png


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: I've read a book by Tim Ord....about price and volume
#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
#adapted from ZigZagSign study.
#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:

Topas

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

 
Last edited:

BenTen

Administrative
Staff member
Staff
VIP
@Topas I see what happen there. Go to Settings > Equities and make sure you enable "Show volume subgraph".

7DiCT5J.png


 
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:

asragov

Member
2019 Donor
VIP
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.
 

ShinJ

New member
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!

X4uC5AT.png


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);
 

MerryDay

Administrative
Staff member
Staff
VIP
@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:

BenTen

Administrative
Staff member
Staff
VIP
@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.
 

eluciano530

New member
VIP
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..

the pdf link describes more about using percent changes
https://n.b5z.net/i/u/10144154/f/Ord Articles/PriceVolume.pdf
 
Last edited by a moderator:

MerryDay

Administrative
Staff member
Staff
VIP
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..

the pdf link describes more about using percent changes
https://n.b5z.net/i/u/10144154/f/Ord Articles/PriceVolume.pdf
@eluciano530 There is any code similar to your request available on the forum :(
  • And you could try the TOS chat lounge, some posters have been successful there.
gOqETY2.png
 

Similar threads

Top