3 ATR Bands using Keltner Channels for ThinkorSwim

irishgold

Member
Have not seen this code on the site, I watched John Carter using these bands to restrict his trades. The code is based on the TOS Keltner Channel code. I think it has good value in trading levels. It's basically 6 keltner channels with std deviation of 1,2,3,-1,-2,-3

Rich (BB code):
# Indicator that presents ATR 1,2,3 above and below using Keltner channel formula
input displace = 0;
input factor1 = 1.0;
input factor2 = 2.0;
input factor3 = 3.0;
input length = 21;
input price = close;
input averageType = AverageType.SIMPLE;
input trueRangeAverageType = AverageType.SIMPLE;

def shift1 = factor1 * MovingAverage(trueRangeAverageType, TrueRange(high, close, low), length);
def shift2 = factor2 * MovingAverage(trueRangeAverageType, TrueRange(high, close, low), length);
def shift3 = factor3 * MovingAverage(trueRangeAverageType, TrueRange(high, close, low), length);

plot average = MovingAverage(averageType, price, length);
average.SetDefaultColor(GetColor(4));

plot Upper_Band1 = average[-displace] + shift1[-displace];
Upper_Band1 .SetDefaultColor(GetColor(6));
plot Upper_Band2  = average[-displace] + shift2[-displace];
Upper_Band2 .SetDefaultColor(GetColor(0));
plot Upper_Band3 = average[-displace] + shift3[-displace];
Upper_Band3.SetDefaultColor(GetColor(5));

plot Lower_Band1 = average[-displace] - shift1[-displace];
Lower_Band1 .SetDefaultColor(GetColor(6));
plot Lower_Band2  = average[-displace] - shift2[-displace];
Lower_Band2 .SetDefaultColor(GetColor(0));
plot Lower_Band3 = average[-displace] - shift3[-displace];
Lower_Band3.SetDefaultColor(GetColor(5));
 

Topas

New member
VIP
any idea how to take advantage of these lines ....? As much i understood ... it should bounce from the line , but thats not the case ... lots of time it does keep going and bounce
 

irishgold

Member
It's just another tool to measure when price is reaching a range that the instrument is trading in. As you reach the upper 3 ATR level it's probably not a good time to get in and if already in to get out. On Thinkorswim you have expected moves so it is something of that nature.
Here's a good explanation of the Keltner channels: https://bullishbears.com/keltner-channels/
 

henry1224

Active member
VIP
Have not seen this code on the site, I watched John Carter using these bands to restrict his trades. The code is based on the TOS Keltner Channel code. I think it has good value in trading levels. It's basically 6 keltner channels with std deviation of 1,2,3,-1,-2,-3

Rich (BB code):
# Indicator that presents ATR 1,2,3 above and below using Keltner channel formula
input displace = 0;
input factor1 = 1.0;
input factor2 = 2.0;
input factor3 = 3.0;
input length = 21;
input price = close;
input averageType = AverageType.SIMPLE;
input trueRangeAverageType = AverageType.SIMPLE;

def shift1 = factor1 * MovingAverage(trueRangeAverageType, TrueRange(high, close, low), length);
def shift2 = factor2 * MovingAverage(trueRangeAverageType, TrueRange(high, close, low), length);
def shift3 = factor3 * MovingAverage(trueRangeAverageType, TrueRange(high, close, low), length);

plot average = MovingAverage(averageType, price, length);
average.SetDefaultColor(GetColor(4));

plot Upper_Band1 = average[-displace] + shift1[-displace];
Upper_Band1 .SetDefaultColor(GetColor(6));
plot Upper_Band2  = average[-displace] + shift2[-displace];
Upper_Band2 .SetDefaultColor(GetColor(0));
plot Upper_Band3 = average[-displace] + shift3[-displace];
Upper_Band3.SetDefaultColor(GetColor(5));

plot Lower_Band1 = average[-displace] - shift1[-displace];
Lower_Band1 .SetDefaultColor(GetColor(6));
plot Lower_Band2  = average[-displace] - shift2[-displace];
Lower_Band2 .SetDefaultColor(GetColor(0));
plot Lower_Band3 = average[-displace] - shift3[-displace];
Lower_Band3.SetDefaultColor(GetColor(5));
add this to get colored bands

AddCloud(Upper_Band1, Lower_Band1, Color.LIME, CreateColor(175, 250, 175), no);
AddCloud(Upper_Band3, Upper_Band2, Color.PINK, CreateColor(175, 250, 175), no);
AddCloud(Lower_Band2, Lower_Band3, Color.PINK, CreateColor(175, 250, 175), no);
 

rad14733

Well-known member
VIP
@mark0482 That indicator appears to be The same as TTM_Squeeze_Pro_Clouds without the clouds... It is, essentially, Bollinger Bands with three sets of Keltner Channels... I have a similar chart running all the time but with the clouds enabled...
 

Jonas99

Active member
VIP
I believe they are 1.0, 1.5, and 2.0 ATR... Those are the TTM_Squeeze_Pro settings and what I used when I wrote my code before ever seeing John Carters...
I am in his class, that's all we talk about daily. 3ATR is the buy or sell point where 1ATR is the mean reversion target. I am looking for some help if the Keltner Channel can be scripted for the last 20 bars only, as not to clutter the chart. Sort of like an Anchored ATR channel that floating with 2ATR and 3ATR levels. @rad14733
 

rad14733

Well-known member
VIP
I am in his class, that's all we talk about daily. 3ATR is the buy or sell point where 1ATR is the mean reversion target. I am looking for some help if the Keltner Channel can be scripted for the last 20 bars only, as not to clutter the chart. Sort of like an Anchored ATR channel that floating with 2ATR and 3ATR levels. @rad14733

Ahhh... Different indicator altogether, without Bollinger Bands...

I haven't played much with partial displays but @XeoNoX and @SleepyZ have posted code on how to go about it as I recall...
 

SleepyZ

Active member
Ahhh... Different indicator altogether, without Bollinger Bands...

I haven't played much with partial displays but @XeoNoX and @SleepyZ have posted code on how to go about it as I recall...

Here is an old version of Keltner Channel that I did that is modified to just display the KC for display_xbars input
Code:
#KeltnerChannel_Limited_Display
#20210606 Sleepyz Usethinkscript request
#KC limited plot to last display_xbars input

input display_xbars = 20;
input factor1  = 1.0;
input factor2  = 2.0;
input factor3  = 3.0;
input length   =  20;
input price    = close;
input trlength = 20;

input Avgtype_ma  = AverageType.SIMPLE;
input Avgtype_tr  = AverageType.EXPONENTIAL;
def tr = MovingAverage(Avgtype_tr, TrueRange(high, close, low), trlength);

#Display limited to last xbars
def lastbar  = if IsNaN(close[-1]) and !IsNaN(close) then BarNumber() else Double.NaN;
plot Average = if BarNumber() < HighestAll(lastbar - display_xbars)
               then Double.NaN
               else MovingAverage(Avgtype_ma, price, length);
###########

plot Upper_Band  = Average + tr * factor1;
plot Lower_Band  = Average - tr * factor1;
plot Upper_Band2 = Average + tr * factor2;
plot Lower_Band2 = Average - tr * factor2;
plot Upper_Band3 = Average + tr * factor3;
plot Lower_Band3 = Average - tr * factor3;

def dir = if (Average) > (Average[1]) and Upper_Band > Upper_Band[1] and Lower_Band > Lower_Band[1] then 1 else if (Average) < (Average[1]) and Upper_Band < Upper_Band[1] and Lower_Band < Lower_Band[1] then 2 else 0;
Average.AssignValueColor(if dir == 1 then Color.GREEN  else if dir == 2 then Color.RED else Color.WHITE);
Upper_Band.AssignValueColor(if dir == 1 then Color.GREEN  else if dir == 2 then Color.RED else Color.WHITE);
Lower_Band.AssignValueColor(if dir == 1 then Color.GREEN  else if dir == 2 then Color.RED else Color.WHITE);
Upper_Band2.AssignValueColor(if dir == 1 then Color.GREEN  else if dir == 2 then Color.RED else Color.WHITE);
Lower_Band2.AssignValueColor(if dir == 1 then Color.GREEN  else if dir == 2 then Color.RED else Color.WHITE);
Upper_Band3.SetDefaultColor(Color.BLACK);
Lower_Band3.SetDefaultColor(Color.BLACK);
Upper_Band3.SetStyle(Curve.SHORT_DASH);
Lower_Band3.SetStyle(Curve.SHORT_DASH);

Average.HideBubble();
Upper_Band.HideBubble();
Lower_Band.HideBubble();
Upper_Band2.HideBubble();
Lower_Band2.HideBubble();
Upper_Band3.HideBubble();
Lower_Band3.HideBubble();

input showclouds = yes;
AddCloud(if showclouds and Round(low) <= Round(Lower_Band2) then Lower_Band2 else Double.NaN, Lower_Band3, Color.MAGENTA, color2 = Color.MAGENTA);
AddCloud(if showclouds and Round(high) >= Round(Upper_Band2) then Upper_Band2 else Double.NaN, Upper_Band3, Color.MAGENTA, color2 = Color.MAGENTA);

input usealerts = no;
Alert(usealerts and close crosses below Upper_Band2, "Close below UB", Alert.BAR, Sound.Ring);
Alert(usealerts and close crosses above Lower_Band2, "Close above LB", Alert.BAR, Sound.Ring);


input showclouds_ul = yes;
AddCloud(if showclouds_ul and dir == 1 then Upper_Band2 else Upper_Band, if dir == 1 then Upper_Band else Upper_Band2, Color.GREEN, Color.RED);

AddCloud(if showclouds_ul and dir == 2 then Lower_Band else Lower_Band2, if dir == 2 then Lower_Band2 else Lower_Band, Color.RED, Color.GREEN);

input showlabel = yes;
AddLabel(showlabel, if dir == 1 then "KC-All Up" else if dir == 2 then "KC-All Down" else "KC-Mixed", if dir == 1 then Color.GREEN else if dir == 2 then Color.RED else Color.WHITE);

AddLabel(showlabel, "KC-AVG", if Average > Average[1] then Color.GREEN else if Average < Average[1] then Color.RED else Color.WHITE);

AddLabel(showlabel, "KC-UB", if Upper_Band > Upper_Band[1] then Color.GREEN else if Upper_Band < Upper_Band[1] then Color.RED else Color.WHITE);

AddLabel(showlabel, "KC-LB", if Lower_Band > Lower_Band[1] then Color.GREEN else if Lower_Band < Lower_Band[1] then Color.RED else Color.WHITE);

def span = Upper_Band - Lower_Band;
AddLabel(showlabel, "U-L " + AsText(span), if Round(span) > Round(span[1]) then Color.GREEN else Color.RED);

input bubblemover = 5;
def bm = bubblemover + 1;
input bubblemoverupdown = 0;
input showbubble_avg_ub_lb = yes;
AddChartBubble(showbubble_avg_ub_lb and IsNaN(close[bubblemover]) and !IsNaN(close[bm]), Upper_Band[bm] + bubblemoverupdown * TickSize(), "UB " + AsText(Upper_Band[bm]), if Upper_Band[bm] > Upper_Band[bm + 1] then Color.GREEN else if Upper_Band[bm] < Upper_Band[bm + 1] then Color.RED else Color.WHITE);
AddChartBubble(showbubble_avg_ub_lb and IsNaN(close[bubblemover]) and !IsNaN(close[bm]), Lower_Band[bm] + bubblemoverupdown * TickSize(), "LB " + AsText(Lower_Band[bm]), if Lower_Band[bm] > Lower_Band[bm + 1] then Color.GREEN else if Lower_Band[bm] < Lower_Band[bm + 1] then Color.RED else Color.WHITE);

AddChartBubble(showbubble_avg_ub_lb and IsNaN(close[bubblemover]) and !IsNaN(close[bm]), Average[bm] + bubblemoverupdown * TickSize(), "AVG " +  AsText(Average[bm]), if Average[bm] > Average[bm + 1] then Color.GREEN else if Average[bm] < Average[bm + 1] then Color.RED else Color.WHITE);

input bubblemover_ul = 2;
def bm_ul = bubblemover_ul + 1;
input bubblemoverupdown_ul = 0;
input showbubble_ul = yes;
AddChartBubble(showbubble_ul and IsNaN(close[bubblemover_ul]) and !IsNaN(close[bm_ul]), close[bm_ul] + bubblemoverupdown_ul * TickSize(), "U-L\n" + AsText(Round(span[bm_ul])), if Round(span[bm_ul]) > Round(span[bm_ul + 1]) then Color.GREEN else if Round(span[bm_ul]) < Round(span[bm_ul + 1]) then Color.RED else Color.WHITE);
Capture.jpg
 

Jonas99

Active member
VIP
Here is an old version of Keltner Channel that I did that is modified to just display the KC for display_xbars input
@SleepyZ you are a genius! Thank you so very much! Could we just have the lines and without the cloud? and without the price bubbles. Just like your Anchored VWAP, simpler version of it.
 
Last edited:

SleepyZ

Active member
@SleepyZ you are a genius! Thank you so very much! Could we just have the lines and without the cloud? and without the price bubbles. Just like your Anchored VWAP, simpler version of it.

Here is simpler version
Code:
input display_xbars = 20;
input factor1  = 1.0;
input factor2  = 2.0;
input factor3  = 3.0;
input length   =  20;
input price    = close;
input trlength = 20;

input Avgtype_ma  = AverageType.SIMPLE;
input Avgtype_tr  = AverageType.EXPONENTIAL;
def tr = MovingAverage(Avgtype_tr, TrueRange(high, close, low), trlength);

#Display limited to last xbars
def lastbar  = if IsNaN(close[-1]) and !IsNaN(close) then BarNumber() else Double.NaN;
plot Average = if BarNumber() < HighestAll(lastbar - display_xbars)
               then Double.NaN
               else MovingAverage(Avgtype_ma, price, length);
###########

plot Upper_Band  = Average + tr * factor1;
plot Lower_Band  = Average - tr * factor1;
plot Upper_Band2 = Average + tr * factor2;
plot Lower_Band2 = Average - tr * factor2;
plot Upper_Band3 = Average + tr * factor3;
plot Lower_Band3 = Average - tr * factor3;

Average.setdefaultColor(color.yellow);
Upper_Band.setdefaultColor(color.green);
Lower_Band.setdefaultColor(color.red);
Upper_Band2.setdefaultColor(color.green);
Lower_Band2.setdefaultColor(color.red);
Upper_Band3.setdefaultColor(color.green);
Lower_Band3.setdefaultColor(color.red);

Average.HideBubble();
Upper_Band.HideBubble();
Lower_Band.HideBubble();
Upper_Band2.HideBubble();
Lower_Band2.HideBubble();
Upper_Band3.HideBubble();
Lower_Band3.HideBubble();
 

rad14733

Well-known member
VIP
@rad14733 what's your personal opinion of the TTM Squeeze Pro vs the traditional TTM Squeeze that's a defaulted indicator in ToS?
I guess I prefer TTM_Squeeze_Pro as it provides more information regarding the depth of the squeeze... Between the depth of squeeze and the momentum I feel it is a nice tool for anticipating momentum breakouts for scalping and day trading...

That being said, I also like Keltner Channels, whether standard, as smaller mobo bands, or with multiple ATR bands...
 

Similar threads

Top