# Can we add 14 ATR to ZigZag indicator?

#### Miket

##### Member
Hello,

Can you take the zigzag tos indicator so that it will automatically update using the following equations answer as the reversal amount?

Take the 14 period APTR of the stock and multiply it by 2.5 to get the reversal amount.

I see a lock on the code so I don't really know what this means. However, this is a pretty good mechanical system for swing trading.

#### greentonic

##### New member
Code:
``````def   price               = close;

def   priceH              = high;    # swing high

def   priceL              = low;     # swing low

input ATRreversalfactor   = 3.0;#Hint ATRreversalfactor: 3 is standard, adjust

input ATRlength           = 5;#Hint ATRlength: 5 is standard, adjust to whatever

input zigzagpercent       = 0.80;#LAR original is 0.2, but modified in testing

input zigzagamount        = .15;

def ATR                   = reference ATR(length = ATRlength);

def reversalAmount        = if (close * zigzagpercent / 100) > Max

(zigzagamount < ATRreversalfactor * ATR, zigzagamount) then

(close * zigzagpercent / 100) else if zigzagamount < ATRreversalfactor * ATR then

ATRreversalfactor * ATR else zigzagamount;

input showSupplyDemand    = {Off, default Arrow, Pivot};

input showArrows          = yes; #orignal by LAR was no

input useAlerts           = no; #orignal by LAR was no

#Original TOS ZigZag code Modified by Linus

def barNumber = BarNumber();

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

rec state = {default init, undefined, uptrend, downtrend};

rec 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 = priceL;

} else if (price >= GetValue(minMaxPrice, 1) + reversalAmount) {

state = state.uptrend;

minMaxPrice = priceH;

} 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 = priceL;

} else {

state = state.uptrend;

minMaxPrice = Max(priceH, GetValue(minMaxPrice, 1));

}

} else {

if (price >= GetValue(minMaxPrice, 1) + reversalAmount) {

state = state.uptrend;

minMaxPrice = priceH;

} else {

state = state.downtrend;

minMaxPrice = Min(priceL, 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;

rec currentPriceLevel;

rec 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(priceH, 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(priceL, 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 if state ==

state.uptrend then priceH else priceL else if (currentPoints == 0) then

currentPriceLevel else Double.NaN;

rec zzSave =  if !IsNaN("ZZ\$") then if (barNumber == barCount or barNumber == 1)

then if IsNaN(barNumber[-1]) and  state == state.uptrend then priceH else priceL

else currentPriceLevel else GetValue(zzSave, 1);

def chg = (if barNumber == barCount and currentPoints < 0 then priceH else if

barNumber == barCount and currentPoints > 0 then priceL else currentPriceLevel)

- GetValue(zzSave, 1);

def isUp = chg >= 0;

rec isConf = AbsValue(chg) >= reversalAmount or (IsNaN(GetValue("ZZ\$", 1)) and

GetValue(isConf, 1));

"ZZ\$".EnableApproximation();

"ZZ\$".DefineColor("Up Trend", Color.GREEN);

"ZZ\$".DefineColor("Down Trend", Color.RED);

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

"ZZ\$".SetLineWeight(2);

DefineGlobalColor("Unconfirmed", Color.DARK_ORANGE);

DefineGlobalColor("Up", Color.GREEN);

DefineGlobalColor("Down", Color.RED);

#Arrows

def zzL = if !IsNaN("ZZ\$") and state == state.downtrend then priceL else

GetValue(zzL, 1);

def zzH = if !IsNaN("ZZ\$") and state == state.uptrend then priceH else GetValue

(zzH, 1);

def dir = CompoundValue(1, if zzL != zzL[1] then 1 else if zzH != zzH[1] then -1

else dir[1], 0);

def signal = CompoundValue(1,

if dir > 0 and low > zzL then

if signal[1] <= 0 then 1 else signal[1]

else if dir < 0 and high < zzH then

if signal[1] >= 0 then -1 else signal[1]

else signal[1]

, 0);

plot U1 = showArrows and signal > 0 and signal[1] <= 0;

U1.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_UP);

U1.SetDefaultColor(Color.GREEN);

U1.SetLineWeight(4);

plot D1 = showArrows and signal < 0 and signal[1] >= 0;

D1.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_DOWN);

D1.SetDefaultColor(Color.RED);

D1.SetLineWeight(4);

#Supply Demand Areas

def idx = if showSupplyDemand == showSupplyDemand.Pivot then 1 else 0;

def rLow;

def rHigh;

if barNumber() == 1 {

rLow = Double.NaN;

rHigh = Double.NaN;

} else if signal crosses 0 {

rLow = low[idx];

rHigh = high[idx];

} else {

rLow = rLow[1];

rHigh = rHigh[1];

}

plot HighLine = if showSupplyDemand and !IsNaN(close) then rHigh else

Double.NaN;

HighLine.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);

HighLine.AssignValueColor(if signal > 0 then Color.GREEN else Color.RED);

plot LowLine = if showSupplyDemand and !IsNaN(close) then rLow else Double.NaN;

LowLine.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);

LowLine.AssignValueColor(if signal > 0 then Color.GREEN else Color.RED);

def hlUp = if signal > 0 then HighLine else Double.NaN;

def hlDn = if signal < 0 then HighLine else Double.NaN;