Repaints Zero Lag Zig - Zag For ThinkOrSwim

Repaints
This was converted from TradingView. After a few enhancements I find it useful. I use it on 4 hour, D and W time frames. Let me know if you find it to be useful.

Code:
#////////////
#// Inputs //
#////////////

# "------ ZigZag settings ------"
input source = ohlc4;
def src = source;
input Length = 10;
input phase  = 50;
input power  = 2;
input color_up_and_down_moves = yes;
def   do_col =color_up_and_down_moves;


# "---------- Alerts ----------"
input Buy_Alert = yes;
def   do_buy_alert = Buy_Alert;
input Sell_Alert = yes;
def   do_sell_alert = Sell_Alert;

#///////////////
#// Functions //
#///////////////
#//{
#// definition of "Jurik Moving Average", by Everget
script nz{
    input x = close;
    input y = 0;
    plot result = if isnan(x) then y else x;
}

script rising{
    input src = close;
    input len = 5;
    plot result = if len == 1 then src > src[1] else fold i = 0 to len -1 with p = no while src[i] > getvalue(src, i+1) do getvalue(src,i+1) > getvalue(src, i+2);
}

script falling{
    input src = close;
    input len = 5;
    plot result = if len == 1 then src < src[1] else fold i = 0 to len -1 with p = no while src[i] < getvalue(src, i+1) do getvalue(src,i+1) < getvalue(src, i+2);
}

script fixnan{
    input source = close;
    def fix = if !isnan(source) then source else fix[1];
    plot result = fix;

}

script valuewhen{
    input condition = close;
    input source = close;
    input occ = 0;
    def   count = compoundValue(1,if condition and count[1] + 1 < occ then count[1] + 1 else if condition and count[1] + 1 >= occ then 0 else count[1],0) ;
    def   prevalue = if (count[1] + 1 >= occ) and condition then source else prevalue[1];
    def   value = if condition then prevalue[1] else value[1];
    plot  result = value;
   
}


script jma{
    input _src = close;
    input _length = 14;
    input _phase = 50;
    input _power = 2;
   
    def phaseRatio = if  _phase < -100 then 0.5 else if _phase > 100 then  2.5 else _phase / 100 + 1.5;
    def beta = 0.45 * (_length - 1) / (0.45 * (_length - 1) + 2);
    def alpha = power(beta, _power);
    def jma;
 
    def e0 = compoundValue(1,(1 - alpha) * _src + alpha * nz(e0[1]), 0.0);
    def e1 = compoundValue(1,(_src - e0) * (1 - beta) + beta * nz(e1[1]), 0.0);
    def e2 = compoundValue(1,(e0 + phaseRatio * e1 - nz(jma[1])) * power(1 - alpha, 2) +
       power(alpha, 2) * nz(e2[1]), 0.0);
    jma = compoundValue(1, e2 + nz(jma[1]), 0.0);
    plot result = jma;
   
}

#/////////////////
#// Main Script //
#/////////////////
#//{
#//calculate jma turning point
def jma_price   = jma(src, length, phase, power);
def turn_down   = rising(jma_price[1], 1) and !rising(jma_price, 1);
def turn_up     = falling(jma_price[1], 1) and !falling(jma_price, 1);

#pivot       = float(na)
def highest_1   = highest(high, 5);
def lowest_1    = lowest(low, 5);

def lastbar = isNaN(close[-1]) and !isNaN(close);

def pivot       = if turn_down then highest_1 else if turn_up   then  lowest_1 else double.nan;
def fixnan_1    = fixnan(pivot);

#pivot_color = do_col ? pivot < fixnan_1[1] ? color_dn : color_up : color.yellow

#def higheqfix = high == fixnan_1;
#def loweqfix = low == fixnan_1;
#def bar_index = barnumber();
#def pivot_bar  = compoundValue(1, if turn_down then valuewhen(higheqfix, bar_index, 0) else if turn_up   then  valuewhen( loweqfix, bar_index, 0) else double.nan, 0);

#///////////
#// Plots //
#///////////
#//{
#plot(pivot, linewidth = 2, color = pivot_color, offset = -2, transp = 0)

def colcond = if isNaN(pivot) then colcond[1] else if pivot < fixnan_1[1] then no else yes;

plot pivot_zigzag = if lastbar then close else pivot[-2];
pivot_zigzag.setLineWeight(2);
pivot_zigzag.enableApproximation();
pivot_zigzag.defineColor("Down", color.red);
pivot_zigzag.defineColor("Up", createColor(0, 230, 118));
pivot_zigzag.assignValueColor(if do_col then (if colcond[-1] then pivot_zigzag.color("Down") else pivot_zigzag.color("Up")) else color.yellOW);


plot top = if turn_down then fixnan_1 else double.nan;
top.setpaintingStrategy(paintingStrategy.ARROW_DOWN);
top.setdefaultColor(color.red);
top.setLineWeight(3);

plot bottom = if turn_up then fixnan_1 else double.nan;
bottom.setPaintingStrategy(paintingStrategy.ARROW_UP);
bottom.setdefaultColor(createColor(0, 230, 118));
bottom.setLineWeight(3);

#////////////
#// Alerts //
#////////////
#//{
def buyalert  = turn_up;
def sellalert = turn_down;


alert(buyalert and do_buy_alert, "Buy alert", alert.BAR, sound.Nosound);
   
alert(sellalert and do_sell_alert, "Sell Alert", alert.bar, sound.Nosound);

#-----------------------------------------------------------------------
#def pivotcount = compoundValue(1,if !isNAN(pivot) then pivotcount[1] + 1 else pivotcount[1],0);
def fixcount = compoundValue(1,if fixnan_1 != fixnan_1[1] then fixcount[1] + 1 else fixcount[1], 0);
def swingsum = compoundValue(1,if fixnan_1 != fixnan_1[1] then swingsum[1] + absValue(fixnan_1 - fixnan_1[1]) else swingsum[1], 0);
def swingavg = swingsum / fixcount;

def swingsumpercent = compoundValue(1,if fixnan_1 != fixnan_1[1] then swingsumpercent[1] + absValue(fixnan_1 - fixnan_1[1])/fixnan_1 else swingsumpercent[1], 0);
def swingavgpercent = swingsumpercent / fixcount;

#addlabel(yes, "Piv : " + pivotcount);
#addlabel(yes, "Swings : " + fixcount, color.blue);
#addlabel(yes, "Swing Avg : " + asDollars(swingavg), color.blue);
#addlabel(yes, "Swing Avg % : " + asPercent(swingavgpercent), color.blue);

#-------------------------------------------------------------------------
input show_percent_bubbles = yes;
def changepercent = if fixnan_1 != fixnan_1[1] then round((fixnan_1 - fixnan_1[1])/fixnan_1,2) else double.nan;
def ispivot = fixnan_1 != fixnan_1[1];
addchartBubble(show_percent_bubbles and ispivot[-2],pivot[-2], aspercent(changepercent[-2]), color.yellow, if changepercent[-2] > 0 then yes else no);

Here are the settings I use.

Source (O+H+L+C)/4

Length 19

Phase 72

Power 2

Use the dropdowns for the rest of the settings.

Any developers here can feel free to enhance or change this code to make it better.

I use this in conjunction with another TV to TS conversion (done by the same developer) called UT Bot. UT Bot provides Buy / Sell bubbles based on a fairly complex calculation.

If interested here is the Thread: https://usethinkscript.com/threads/ut-bot-for-thinkorswim.12640/

I think it's important to not rely on any one or two indicators, but rather to validate a potential trade with multiple indicators on multiple time frames before trading. Also be sure to paper trade before using real money.
 
Last edited:
This was converted from TradingView. After a few enhancements I find it useful. I use it on 4 hour, D and W time frames. Let me know if you find it to be useful.

Code:
#////////////
#// Inputs //
#////////////

# "------ ZigZag settings ------"
input source = ohlc4;
def src = source;
input Length = 10;
input phase  = 50;
input power  = 2;
input color_up_and_down_moves = yes;
def   do_col =color_up_and_down_moves;


# "---------- Alerts ----------"
input Buy_Alert = yes;
def   do_buy_alert = Buy_Alert;
input Sell_Alert = yes;
def   do_sell_alert = Sell_Alert;

#///////////////
#// Functions //
#///////////////
#//{
#// definition of "Jurik Moving Average", by Everget
script nz{
    input x = close;
    input y = 0;
    plot result = if isnan(x) then y else x;
}

script rising{
    input src = close;
    input len = 5;
    plot result = if len == 1 then src > src[1] else fold i = 0 to len -1 with p = no while src[i] > getvalue(src, i+1) do getvalue(src,i+1) > getvalue(src, i+2);
}

script falling{
    input src = close;
    input len = 5;
    plot result = if len == 1 then src < src[1] else fold i = 0 to len -1 with p = no while src[i] < getvalue(src, i+1) do getvalue(src,i+1) < getvalue(src, i+2);
}

script fixnan{
    input source = close;
    def fix = if !isnan(source) then source else fix[1];
    plot result = fix;

}

script valuewhen{
    input condition = close;
    input source = close;
    input occ = 0;
    def   count = compoundValue(1,if condition and count[1] + 1 < occ then count[1] + 1 else if condition and count[1] + 1 >= occ then 0 else count[1],0) ;
    def   prevalue = if (count[1] + 1 >= occ) and condition then source else prevalue[1];
    def   value = if condition then prevalue[1] else value[1];
    plot  result = value;
   
}


script jma{
    input _src = close;
    input _length = 14;
    input _phase = 50;
    input _power = 2;
   
    def phaseRatio = if  _phase < -100 then 0.5 else if _phase > 100 then  2.5 else _phase / 100 + 1.5;
    def beta = 0.45 * (_length - 1) / (0.45 * (_length - 1) + 2);
    def alpha = power(beta, _power);
    def jma;
 
    def e0 = compoundValue(1,(1 - alpha) * _src + alpha * nz(e0[1]), 0.0);
    def e1 = compoundValue(1,(_src - e0) * (1 - beta) + beta * nz(e1[1]), 0.0);
    def e2 = compoundValue(1,(e0 + phaseRatio * e1 - nz(jma[1])) * power(1 - alpha, 2) +
       power(alpha, 2) * nz(e2[1]), 0.0);
    jma = compoundValue(1, e2 + nz(jma[1]), 0.0);
    plot result = jma;
   
}

#/////////////////
#// Main Script //
#/////////////////
#//{
#//calculate jma turning point
def jma_price   = jma(src, length, phase, power);
def turn_down   = rising(jma_price[1], 1) and !rising(jma_price, 1);
def turn_up     = falling(jma_price[1], 1) and !falling(jma_price, 1);

#pivot       = float(na)
def highest_1   = highest(high, 5);
def lowest_1    = lowest(low, 5);

def lastbar = isNaN(close[-1]) and !isNaN(close);

def pivot       = if turn_down then highest_1 else if turn_up   then  lowest_1 else double.nan;
def fixnan_1    = fixnan(pivot);

#pivot_color = do_col ? pivot < fixnan_1[1] ? color_dn : color_up : color.yellow

#def higheqfix = high == fixnan_1;
#def loweqfix = low == fixnan_1;
#def bar_index = barnumber();
#def pivot_bar  = compoundValue(1, if turn_down then valuewhen(higheqfix, bar_index, 0) else if turn_up   then  valuewhen( loweqfix, bar_index, 0) else double.nan, 0);

#///////////
#// Plots //
#///////////
#//{
#plot(pivot, linewidth = 2, color = pivot_color, offset = -2, transp = 0)

def colcond = if isNaN(pivot) then colcond[1] else if pivot < fixnan_1[1] then no else yes;

plot pivot_zigzag = if lastbar then close else pivot[-2];
pivot_zigzag.setLineWeight(2);
pivot_zigzag.enableApproximation();
pivot_zigzag.defineColor("Down", color.red);
pivot_zigzag.defineColor("Up", createColor(0, 230, 118));
pivot_zigzag.assignValueColor(if do_col then (if colcond[-1] then pivot_zigzag.color("Down") else pivot_zigzag.color("Up")) else color.yellOW);


plot top = if turn_down then fixnan_1 else double.nan;
top.setpaintingStrategy(paintingStrategy.ARROW_DOWN);
top.setdefaultColor(color.red);
top.setLineWeight(3);

plot bottom = if turn_up then fixnan_1 else double.nan;
bottom.setPaintingStrategy(paintingStrategy.ARROW_UP);
bottom.setdefaultColor(createColor(0, 230, 118));
bottom.setLineWeight(3);

#////////////
#// Alerts //
#////////////
#//{
def buyalert  = turn_up;
def sellalert = turn_down;


alert(buyalert and do_buy_alert, "Buy alert", alert.BAR, sound.Nosound);
   
alert(sellalert and do_sell_alert, "Sell Alert", alert.bar, sound.Nosound);

#-----------------------------------------------------------------------
#def pivotcount = compoundValue(1,if !isNAN(pivot) then pivotcount[1] + 1 else pivotcount[1],0);
def fixcount = compoundValue(1,if fixnan_1 != fixnan_1[1] then fixcount[1] + 1 else fixcount[1], 0);
def swingsum = compoundValue(1,if fixnan_1 != fixnan_1[1] then swingsum[1] + absValue(fixnan_1 - fixnan_1[1]) else swingsum[1], 0);
def swingavg = swingsum / fixcount;

def swingsumpercent = compoundValue(1,if fixnan_1 != fixnan_1[1] then swingsumpercent[1] + absValue(fixnan_1 - fixnan_1[1])/fixnan_1 else swingsumpercent[1], 0);
def swingavgpercent = swingsumpercent / fixcount;

#addlabel(yes, "Piv : " + pivotcount);
#addlabel(yes, "Swings : " + fixcount, color.blue);
#addlabel(yes, "Swing Avg : " + asDollars(swingavg), color.blue);
#addlabel(yes, "Swing Avg % : " + asPercent(swingavgpercent), color.blue);

#-------------------------------------------------------------------------
input show_percent_bubbles = yes;
def changepercent = if fixnan_1 != fixnan_1[1] then round((fixnan_1 - fixnan_1[1])/fixnan_1,2) else double.nan;
def ispivot = fixnan_1 != fixnan_1[1];
addchartBubble(show_percent_bubbles and ispivot[-2],pivot[-2], aspercent(changepercent[-2]), color.yellow, if changepercent[-2] > 0 then yes else no);

Here are the settings I use.

Source (O+H+L+C)/4

Length 19

Phase 72

Power 2

Use the dropdowns for the rest of the settings.
Can you help to add addchartbubble for high low price instead of changepercent? Thanks,
 
I am not a Thinkscript programmer. But there are many excellent developers here, and maybe they can enhance it.
 
This was converted from TradingView. After a few enhancements I find it useful. I use it on 4 hour, D and W time frames. Let me know if you find it to be useful.

Code:
#////////////
#// Inputs //
#////////////

# "------ ZigZag settings ------"
input source = ohlc4;
def src = source;
input Length = 10;
input phase  = 50;
input power  = 2;
input color_up_and_down_moves = yes;
def   do_col =color_up_and_down_moves;


# "---------- Alerts ----------"
input Buy_Alert = yes;
def   do_buy_alert = Buy_Alert;
input Sell_Alert = yes;
def   do_sell_alert = Sell_Alert;

#///////////////
#// Functions //
#///////////////
#//{
#// definition of "Jurik Moving Average", by Everget
script nz{
    input x = close;
    input y = 0;
    plot result = if isnan(x) then y else x;
}

script rising{
    input src = close;
    input len = 5;
    plot result = if len == 1 then src > src[1] else fold i = 0 to len -1 with p = no while src[i] > getvalue(src, i+1) do getvalue(src,i+1) > getvalue(src, i+2);
}

script falling{
    input src = close;
    input len = 5;
    plot result = if len == 1 then src < src[1] else fold i = 0 to len -1 with p = no while src[i] < getvalue(src, i+1) do getvalue(src,i+1) < getvalue(src, i+2);
}

script fixnan{
    input source = close;
    def fix = if !isnan(source) then source else fix[1];
    plot result = fix;

}

script valuewhen{
    input condition = close;
    input source = close;
    input occ = 0;
    def   count = compoundValue(1,if condition and count[1] + 1 < occ then count[1] + 1 else if condition and count[1] + 1 >= occ then 0 else count[1],0) ;
    def   prevalue = if (count[1] + 1 >= occ) and condition then source else prevalue[1];
    def   value = if condition then prevalue[1] else value[1];
    plot  result = value;
  
}


script jma{
    input _src = close;
    input _length = 14;
    input _phase = 50;
    input _power = 2;
  
    def phaseRatio = if  _phase < -100 then 0.5 else if _phase > 100 then  2.5 else _phase / 100 + 1.5;
    def beta = 0.45 * (_length - 1) / (0.45 * (_length - 1) + 2);
    def alpha = power(beta, _power);
    def jma;
 
    def e0 = compoundValue(1,(1 - alpha) * _src + alpha * nz(e0[1]), 0.0);
    def e1 = compoundValue(1,(_src - e0) * (1 - beta) + beta * nz(e1[1]), 0.0);
    def e2 = compoundValue(1,(e0 + phaseRatio * e1 - nz(jma[1])) * power(1 - alpha, 2) +
       power(alpha, 2) * nz(e2[1]), 0.0);
    jma = compoundValue(1, e2 + nz(jma[1]), 0.0);
    plot result = jma;
  
}

#/////////////////
#// Main Script //
#/////////////////
#//{
#//calculate jma turning point
def jma_price   = jma(src, length, phase, power);
def turn_down   = rising(jma_price[1], 1) and !rising(jma_price, 1);
def turn_up     = falling(jma_price[1], 1) and !falling(jma_price, 1);

#pivot       = float(na)
def highest_1   = highest(high, 5);
def lowest_1    = lowest(low, 5);

def lastbar = isNaN(close[-1]) and !isNaN(close);

def pivot       = if turn_down then highest_1 else if turn_up   then  lowest_1 else double.nan;
def fixnan_1    = fixnan(pivot);

#pivot_color = do_col ? pivot < fixnan_1[1] ? color_dn : color_up : color.yellow

#def higheqfix = high == fixnan_1;
#def loweqfix = low == fixnan_1;
#def bar_index = barnumber();
#def pivot_bar  = compoundValue(1, if turn_down then valuewhen(higheqfix, bar_index, 0) else if turn_up   then  valuewhen( loweqfix, bar_index, 0) else double.nan, 0);

#///////////
#// Plots //
#///////////
#//{
#plot(pivot, linewidth = 2, color = pivot_color, offset = -2, transp = 0)

def colcond = if isNaN(pivot) then colcond[1] else if pivot < fixnan_1[1] then no else yes;

plot pivot_zigzag = if lastbar then close else pivot[-2];
pivot_zigzag.setLineWeight(2);
pivot_zigzag.enableApproximation();
pivot_zigzag.defineColor("Down", color.red);
pivot_zigzag.defineColor("Up", createColor(0, 230, 118));
pivot_zigzag.assignValueColor(if do_col then (if colcond[-1] then pivot_zigzag.color("Down") else pivot_zigzag.color("Up")) else color.yellOW);


plot top = if turn_down then fixnan_1 else double.nan;
top.setpaintingStrategy(paintingStrategy.ARROW_DOWN);
top.setdefaultColor(color.red);
top.setLineWeight(3);

plot bottom = if turn_up then fixnan_1 else double.nan;
bottom.setPaintingStrategy(paintingStrategy.ARROW_UP);
bottom.setdefaultColor(createColor(0, 230, 118));
bottom.setLineWeight(3);

#////////////
#// Alerts //
#////////////
#//{
def buyalert  = turn_up;
def sellalert = turn_down;


alert(buyalert and do_buy_alert, "Buy alert", alert.BAR, sound.Nosound);
  
alert(sellalert and do_sell_alert, "Sell Alert", alert.bar, sound.Nosound);

#-----------------------------------------------------------------------
#def pivotcount = compoundValue(1,if !isNAN(pivot) then pivotcount[1] + 1 else pivotcount[1],0);
def fixcount = compoundValue(1,if fixnan_1 != fixnan_1[1] then fixcount[1] + 1 else fixcount[1], 0);
def swingsum = compoundValue(1,if fixnan_1 != fixnan_1[1] then swingsum[1] + absValue(fixnan_1 - fixnan_1[1]) else swingsum[1], 0);
def swingavg = swingsum / fixcount;

def swingsumpercent = compoundValue(1,if fixnan_1 != fixnan_1[1] then swingsumpercent[1] + absValue(fixnan_1 - fixnan_1[1])/fixnan_1 else swingsumpercent[1], 0);
def swingavgpercent = swingsumpercent / fixcount;

#addlabel(yes, "Piv : " + pivotcount);
#addlabel(yes, "Swings : " + fixcount, color.blue);
#addlabel(yes, "Swing Avg : " + asDollars(swingavg), color.blue);
#addlabel(yes, "Swing Avg % : " + asPercent(swingavgpercent), color.blue);

#-------------------------------------------------------------------------
input show_percent_bubbles = yes;
def changepercent = if fixnan_1 != fixnan_1[1] then round((fixnan_1 - fixnan_1[1])/fixnan_1,2) else double.nan;
def ispivot = fixnan_1 != fixnan_1[1];
addchartBubble(show_percent_bubbles and ispivot[-2],pivot[-2], aspercent(changepercent[-2]), color.yellow, if changepercent[-2] > 0 then yes else no);

Here are the settings I use.

Source (O+H+L+C)/4

Length 19

Phase 72

Power 2

Use the dropdowns for the rest of the settings.

Any developers here can feel free to enhance or change this code to make it better.

I use this in conjunction with another TV to TS conversion (done by the same developer) called UT Bot. UT Bot provides Buy / Sell bubbles based on a fairly complex calculation.

If interested here is the Thread: https://usethinkscript.com/threads/ut-bot-for-thinkorswim.12640/

I think it's important to not rely on any one or two indicators, but rather to validate a potential trade with multiple indicators on multiple time frames before trading. Also be sure to paper trade before using real money.
Thank you. I appreciate you sharing the code with us. According to what I saw today, your settings (length 19 and phase 72) appear to be producing better signals on the 1 minute time frame than the initial input values (length 14 and phase 50)
 

Join useThinkScript to post your question to a community of 21,000+ developers and traders.

Similar threads

Not the exact question you're looking for?

Start a new thread and receive assistance from our community.

87k+ Posts
429 Online
Create Post

Similar threads

Similar threads

The Market Trading Game Changer

Join 2,500+ subscribers inside the useThinkScript VIP Membership Club
  • Exclusive indicators
  • Proven strategies & setups
  • Private Discord community
  • ‘Buy The Dip’ signal alerts
  • Exclusive members-only content
  • Add-ons and resources
  • 1 full year of unlimited support

Frequently Asked Questions

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?
VIP members get exclusive access to these proven and tested premium indicators: Buy the Dip, Advanced Market Moves 2.0, Take Profit, and Volatility Trading Range. In addition, VIP members get access to over 50 VIP-only custom indicators, add-ons, and strategies, private VIP-only forums, private Discord channel to discuss trades and strategies in real-time, customer support, trade alerts, and much more. Learn all about VIP membership here.
How can I access the premium indicators?
To access the premium indicators, which are plug and play ready, sign up for VIP membership here.
Back
Top