Auto Trend Lines For ThinkOrSwim

Trader_Rich

Member
I came across this "auto trend" indicator (
) and while the auto trend lines are somewhat helpful, I'm finding that the vertical Confirmed Swing is great for further confirmation, and sometimes and early confirmation. Unfortunately every time a new Confirmed Swing appears, the old one goes away. Would anyone have any idea how to code it so that they Confirmed Swing vertical lines don't disappear?
Code:
#rcg_autotrendline


input price             = close;
input priceH            = high;    # swing high
input priceL            = low;     # swing low
input ATRreversalfactor = 5;
def ATR                 = reference ATR(length = 5);
def reversalAmount      = ATRreversalfactor * ATR;
input showlines         = yes;
input displace          = 1;
input only_confirmed    = yes;


#Assert(reversalAmount > 0, "'reversal amount' should be positive: " + reversalAmount);

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

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

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

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


#########################################
#########################################
#########################################
rec confirmed = if !isConf[1] and isConf then BarNumber() else confirmed[1];
def isconfirmed = BarNumber() < HighestAll(confirmed);
def use = (only_confirmed and isconfirmed) or !only_confirmed;

plot up = if signal[-1] > 0 and signal <= 0 and use then low else 0;
plot dn = if signal[-1] < 0 and signal >= 0 and use then high else 0;
up.SetDefaultColor(Color.CYAN);
dn.SetDefaultColor(Color.CYAN);
up.SetPaintingStrategy(PaintingStrategy.POINTS);
dn.SetPaintingStrategy(PaintingStrategy.POINTS);
up.Hide();
dn.Hide();


def p1 = low;
def p2 = high;
rec up_y1 = if up then p1 else up_y1[1];
rec up_y2 = if up_y1 != up_y1[1] then up_y1[1] else up_y2[1];
rec up_y3 = if up_y2 != up_y2[1] then up_y2[1] else up_y3[1];
rec up_y4 = if up_y3 != up_y3[1] then up_y3[1] else up_y4[1];
rec up_y5 = if up_y4 != up_y4[1] then up_y4[1] else up_y5[1];
rec up_x1 = if up then BarNumber() else up_x1[1];
rec up_x2 = if up_x1 != up_x1[1] then up_x1[1] else up_x2[1];
rec up_x3 = if up_x2 != up_x2[1] then up_x2[1] else up_x3[1];
rec up_x4 = if up_x3 != up_x3[1] then up_x3[1] else up_x4[1];
rec up_x5 = if up_x4 != up_x4[1] then up_x4[1] else up_x5[1];

rec dn_y1 = if dn then p2 else dn_y1[1];
rec dn_y2 = if dn_y1 != dn_y1[1] then dn_y1[1] else dn_y2[1];
rec dn_y3 = if dn_y2 != dn_y2[1] then dn_y2[1] else dn_y3[1];
rec dn_y4 = if dn_y3 != dn_y3[1] then dn_y3[1] else dn_y4[1];
rec dn_y5 = if dn_y4 != dn_y4[1] then dn_y4[1] else dn_y5[1];
rec dn_x1 = if dn then BarNumber() else dn_x1[1];
rec dn_x2 = if dn_x1 != dn_x1[1] then dn_x1[1] else dn_x2[1];
rec dn_x3 = if dn_x2 != dn_x2[1] then dn_x2[1] else dn_x3[1];
rec dn_x4 = if dn_x3 != dn_x3[1] then dn_x3[1] else dn_x4[1];
rec dn_x5 = if dn_x4 != dn_x4[1] then dn_x4[1] else dn_x5[1];

##Extra crap because you're a terrible scripter who didn't plan ahead
def up_y1a = HighestAll(if barNumber >= HighestAll(up_x1) then up_y1 else 0);
def up_y2a = HighestAll(if barNumber >= HighestAll(up_x1) then up_y2 else 0);
def up_y3a = HighestAll(if barNumber >= HighestAll(up_x1) then up_y3 else 0);
def up_y4a = HighestAll(if barNumber >= HighestAll(up_x1) then up_y4 else 0);
def up_y5a = HighestAll(if barNumber >= HighestAll(up_x1) then up_y5 else 0);
def up_x1a = HighestAll(up_x1);
def up_x2a = HighestAll(up_x2);
def up_x3a = HighestAll(up_x3);
def up_x4a = HighestAll(up_x4);
def up_x5a = HighestAll(up_x5);

def dn_y1a = HighestAll(if barNumber >= HighestAll(dn_x1) then dn_y1 else 0);
def dn_y2a = HighestAll(if barNumber >= HighestAll(dn_x1) then dn_y2 else 0);
def dn_y3a = HighestAll(if barNumber >= HighestAll(dn_x1) then dn_y3 else 0);
def dn_y4a = HighestAll(if barNumber >= HighestAll(dn_x1) then dn_y4 else 0);
def dn_y5a = HighestAll(if barNumber >= HighestAll(dn_x1) then dn_y5 else 0);
def dn_x1a = HighestAll(dn_x1);
def dn_x2a = HighestAll(dn_x2);
def dn_x3a = HighestAll(dn_x3);
def dn_x4a = HighestAll(dn_x4);
def dn_x5a = HighestAll(dn_x5);


#1's and 2's switched in script
script trend {
    input x1 = 0;
    input x2 = 0;
    input y1 = 0;
    input y2 = 0;

    def slope = (y2 - y1) / (x2 - x1);
    def diff = BarNumber() - HighestAll(x1);
    def last = BarNumber() >= HighestAll(x1);
    plot line = if last then (slope * diff) + y1 else Double.NaN;
}

def ATR1 = Average(TrueRange(high, close, low), 5) * 1.5;


plot up1 = if HighestAll(close + ATR1 < trend(up_x2a, up_x1a, up_y2a, up_y1a))
                == 0 then
                trend(up_x2a, up_x1a, up_y2a, up_y1a) else
                if HighestAll(close + ATR1 > trend(up_x2a, up_x1a, up_y2a, up_y1a))
                == 0 then
                trend(up_x2a, up_x1a, up_y2a, up_y1a) else
                Double.NaN;

plot up2 = if HighestAll(close + ATR1 < trend(up_x3a, up_x1a, up_y3a, up_y1a))
                == 0 then
                trend(up_x3a, up_x1a, up_y3a, up_y1a) else
                if HighestAll(close + ATR1 > trend(up_x3a, up_x2a, up_y3a, up_y2a))
                == 0 then
                trend(up_x3a, up_x2a, up_y3a, up_y2a) else
                Double.NaN;
plot up3 = if HighestAll(close + ATR1 < trend(up_x4a, up_x1a, up_y4a, up_y1a))
                == 0 then
                trend(up_x4a, up_x1a, up_y4a, up_y1a) else
                if HighestAll(close + ATR1 > trend(up_x4a, up_x3a, up_y4a, up_y3a))
                == 0 then
                trend(up_x4a, up_x3a, up_y4a, up_y3a) else
                Double.NaN;
plot up4 = if HighestAll(close + ATR1 < trend(up_x5a, up_x1a, up_y5a, up_y1a))
                == 0 then
                trend(up_x5a, up_x1a, up_y5a, up_y1a) else
                if HighestAll(close + ATR1 > trend(up_x5a, up_x4a, up_y5a, up_y4a))
                == 0 then
                trend(up_x5a, up_x4a, up_y5a, up_y4a) else
                Double.NaN;

plot dn1 = if HighestAll(close - ATR1 > trend(dn_x2a, dn_x1a, dn_y2a, dn_y1a))
                == 0 then
                trend(dn_x2a, dn_x1a, dn_y2a, dn_y1a) else
                if HighestAll(close + ATR1 > trend(dn_x2a, dn_x1a, dn_y2a, dn_y1a))
                == 0 then
                trend(dn_x2a, dn_x1a, dn_y2a, dn_y1a) else
                Double.NaN;
plot dn2 = if HighestAll(close - ATR1 < trend(dn_x3a, dn_x1a, dn_y3a, dn_y1a))
                == 0 then
                trend(dn_x3a, dn_x1a, dn_y3a, dn_y1a) else
                if HighestAll(close - ATR < trend(dn_x3a, dn_x2a, dn_y3a, dn_y2a))
                == 0 then
                trend(dn_x3a, dn_x2a, dn_y3a, dn_y2a) else
                Double.NaN;
plot dn3 = if HighestAll(close - ATR1 > trend(dn_x4a, dn_x1a, dn_y4a, dn_y1a))
                == 0 then
                trend(dn_x4a, dn_x1a, dn_y4a, dn_y1a) else
                if HighestAll(close - ATR1 < trend(dn_x4a, dn_x3a, dn_y4a, dn_y3a))
                == 0 then
                trend(dn_x4a, dn_x3a, dn_y4a, dn_y3a)
                else Double.NaN;
plot dn4 = if HighestAll(close - ATR1 > trend(dn_x5a, dn_x1a, dn_y5a, dn_y1a))
                == 0 then
                trend(dn_x5a, dn_x1a, dn_y5a, dn_y1a) else
                if HighestAll(close - ATR1 > trend(dn_x5a, dn_x4a, dn_y5a, dn_y4a))
                == 0 then
                trend(dn_x5a, dn_x4a, dn_y5a, dn_y4a) else
                Double.NaN;


up1.SetDefaultColor(Color.GREEN);
up2.SetDefaultColor(Color.GREEN);
up3.SetDefaultColor(Color.GREEN);
up4.SetDefaultColor(Color.GREEN);

dn1.SetDefaultColor(Color.RED);
dn2.SetDefaultColor(Color.RED);
dn3.SetDefaultColor(Color.RED);
dn4.SetDefaultColor(Color.RED);

up2.SetLineWeight(2);
up3.SetLineWeight(3);
up4.SetLineWeight(4);
dn2.SetLineWeight(2);
dn3.SetLineWeight(3);
dn4.SetLineWeight(4);


AddVerticalLine(BarNumber() == HighestAll(confirmed), "Conifirmed Swing", Color.WHITE, Curve.LONG_DASH);
##########################################
##########################################
##########################################



#"ZZ$".EnableApproximation();
#"ZZ$".DefineColor("Up Trend", Color.UPTICK);
#"ZZ$".DefineColor("Down Trend", Color.DOWNTICK);
#"ZZ$".DefineColor("Undefined", Color.WHITE);
#"ZZ$".AssignValueColor(if !isConf then "ZZ$".Color("Undefined") else if isUp then #"ZZ$".Color("Up Trend") else "ZZ$".Color("Down Trend"));
Screenshot (86).png
 
Last edited by a moderator:
@Trader_Rich Thank you for sharing these auto trend lines with the community! I also think auto trend lines can be somewhat helpful.

I see a potential problem with your request. By definition all studies that utilize the function "highest all" / "lowest all" in a recursive fashion are repainting indicators by the simple fact that highest and lowest are constantly moving targets. Therefore, as the new confirmed swing repaints, the last one disappears.

The way that other swing high / swing low studies get around this is they let the confirmed swing point continually repaint and trigger until the next high or low at that point they leave the last artifact in place. But this is misleading because all the false confirmed swings disappear, leaving the one perfect signal from the last cycle. There isn't anyway to leave a trail of all the signals to paint a true picture.
 
How do you know which was the swing is confirming? Up or down?
If it crosses above the vertical Confirming Line then it is confirming up otherwise down.
Even with the confirming line, this is a repainting indicator. The confirming line can still move or disappear.
Never use any indicator in isolation.
 
If it crosses above the vertical Confirming Line then it is confirming up otherwise down.
Even with the confirming line, this is a repainting indicator. The confirming line can still move or disappear.
Never use any indicator in isolation.
i wish there was a up or down arrow showing if it crossed up or down because the line disappears after it crosses... kinda confusing lol
 

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
189 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