Keltner Channel Strategy - Need help Coding

Lone Wolf

New member
Hi,

Does anybody know if I can scan using TOS for stocks where the body of the candle is COMPLETELY above or below the upper/lower Keltner Channel (using length 20, and 2.25 ATR)?

I see there are criteria for Bollinger bands there, but I am looking to scan for stocks where the body is completely outside the Keltner channel.

Let me know.

Thanks!
 
You can do that by setting up your scanner to something like this:

Here is an example: close crosses above the Upper Band.

aQwRD23.png
 
@Lone Wolf Here you go:

Code:
# KeltnerChannels
# TD Ameritrade IP Company, Inc. (c) 2007-2020
# Modified by BenTen at UseThinkScript.com
# Added paintbars

declare weak_volume_dependency;

input displace = 0;
input factor = 1.5;
input length = 20;
input price = close;
input averageType = AverageType.SIMPLE;
input trueRangeAverageType = AverageType.SIMPLE;

def shift = factor * MovingAverage(trueRangeAverageType, TrueRange(high, close, low), length);

def average = MovingAverage(averageType, price, length);

plot Avg = average[-displace];
Avg.SetDefaultColor(GetColor(1));

plot Upper_Band = average[-displace] + shift[-displace];
Upper_Band.SetDefaultColor(GetColor(8));

plot Lower_Band = average[-displace] - shift[-displace];
Lower_Band.SetDefaultColor(GetColor(5));

AssignPriceColor(if close > Upper_Band then color.green else if close < Lower_Band then color.red else color.white);
 
@ssimonn So you want to know when price crosses either of the "Keltner Channels"...???

Ruby:
plot kcx = if close crosses above KeltnerChannels()."Upper_Band" then 1
                 else if close crosses below KeltnerChannels()."Lower_Band" then -1
                 else Double.NaN;
 
Last edited:
You can do that by setting up your scanner to something like this:

Here is an example: close crosses above the Upper Band.

aQwRD23.png
Dear Ben: I use #4 thread that you post to scan for {close cross above Upper Keltner band}. However, after checking the scan results, The charts don't seem to fit the scan criteria. Could you help explain
VIj08iT.png

R2jp1ae.png

ctJVHLt.png
 
Last edited by a moderator:
Hello all ,no matter how many times I watch syntax code setup I cannot figure it out . I have been backtesting option setups with keltner channel TTM squeeze setup ,,I need help so with code to load into watchlist column , I would like a green indicator when daily close price is above ATR 3 (I think that’s the 87 ema) ,,corresponding red indicator when close price on daily is outside minus ATR 3 ,,,,,,my backtesting indicates once close is above ATR 3 the reversion towards mean ema 21 a put contract to be bought for 2 to 7 days ,,corresponding outside minus ATR 3 call to be bought fo4 same 2 to 7 days ,,,,thanks in advance
 
Here's code that does what you want. I made it so the value displayed in the column is a percentage of where price is relative to the Keltner channels so the column is sortable in a way that makes sense. 100 is at the 3rd ATR above. -100 is at the 3rd ATR below.

Be careful with this strategy, especially when going short. It's very common for stocks to pop higher than the 3rd ATR and gap up even more the next day. Depending on when you get in and your position size it could lead to a margin call, getting you out at a really bad time.

Some symbols will have a value of NaN (not a number) because they don't have enough periods of data for the averages used by Keltner to be calculated.

Above/Below Keltner watchlist column
Ruby:
input factor = 3;
input price = close;

def upper = reference KeltnerChannels(factor=factor).Upper_Band;
def lower = reference KeltnerChannels(factor=factor).Lower_Band;
def mid = reference KeltnerChannels(factor=factor).Avg;

plot p =
  if price > mid then Round((price - mid) / (upper - mid) * 100, 1)
  else if price < mid then Round((mid - price) / (mid - lower) * -100, 1)
  else 0
;

AssignBackgroundColor(if price > upper then Color.DARK_GREEN else if price < lower then Color.DARK_RED else Color.BLACK);
 
Last edited:
Hi Everyone! I'm looking for a lower indicator for Keltner Channels that would look like the WoodiesCCI indicator.

It would look something like this:

2tX5Ssx.jpg


So imagine the center line is the 21EMA and you would have the 1, 2, and 3 standard deviation as dash lines. The bars would represent the price action for that day.
So personally I think I would just have the day bars green and have the dash lines grey but if the day bar crossed the standard deviations those dashes for that day would turn red.

Is this possible or does some one have something similar or better?

Thank you in advance!
 
Here's code that does what you want. I made it so the value displayed in the column is a percentage of where price is relative to the Keltner channels so the column is sortable in a way that makes sense. 100 is at the 3rd ATR above. -100 is at the 3rd ATR below.

Be careful with this strategy, especially when going short. It's very common for stocks to pop higher than the 3rd ATR and gap up even more the next day. Depending on when you get in and your position size it could lead to a margin call, getting you out at a really bad time.

Some symbols will have a value of NaN (not a number) because they don't have enough periods of data for the averages used by Keltner to be calculated.

Above/Below Keltner watchlist column
Ruby:
input factor = 3;
input price = close;

def upper = reference KeltnerChannels(factor=factor).Upper_Band;
def lower = reference KeltnerChannels(factor=factor).Lower_Band;
def mid = reference KeltnerChannels(factor=factor).Avg;

plot p =
  if price > upper then Round((price - mid) / (upper - mid) * 100, 1)
  else if price > mid then Round((upper - price) / (upper - mid) * 100, 1)
  else if price < lower then Round((mid - price) / (mid - lower) * -100, 1)
  else if price < mid then Round((price - lower) / (mid - lower) * -100, 1)
  else 0
;

AssignBackgroundColor(if price > upper then Color.DARK_GREEN else if price < lower then Color.DARK_RED else Color.BLACK);
Thankyou for the help and the code ,loaded into my watchlist and its awesome ..using as a visual indicator in S&P 100 and theotrade options to trade . Will continue on backtesting ...plus I already use simpler trading keltner TTM squeeze chart ,,,thanks again
 
Thankyou for the help and the code

It's no problem. Sometimes I write this stuff just for an interesting code challenge and to help someone out. Sometimes it's those things but also something I think I might use. This one I might use at some point but probably not as an entry signal.
 
I have an effective TOS strategy built upon Keltner Channel Hi / Low reversals . This TOS script will plot a horizontal line @ price (close) and can be plugged right into my Keltner strategy. Using this "HorizontalLine" syntax as my starting point I want to add a horizontal line on expansion that extends to the right of both the upper and lower keltner thresholds as well.

<input LineOnExpansion = yes;
<def bar = if IsNaN(price) then if LineOnExpansion then bar[1] else Double.NaN else BarNumber();
<def ThisBar = HighestAll(bar);
<def barCount = if bar == ThisBar then price else Double.NaN;
<plot HorizontalLine = if ThisBar <= bar then HighestAll(barCount) else Double.NaN;
<HorizontalLine.SetStyle(Curve.LONG_DASH);
<HorizontalLine.SetDefaultColor(CreateColor(250, 75, 75));
<HorizontalLine.SetLineWeight(1);
<def NetChg = close - close[1];
<def PrctChg = (NetChg / close[1]) * 100;

Does anyone know how I can add an upper/lower horizontal line-on-expansion to the upper / lower Keltner channel plots?
 
I have an effective TOS strategy built upon Keltner Channel Hi / Low reversals . This TOS script will plot a horizontal line @ price (close) and can be plugged right into my Keltner strategy. Using this "HorizontalLine" syntax as my starting point I want to add a horizontal line on expansion that extends to the right of both the upper and lower keltner thresholds as well.

<input LineOnExpansion = yes;
<def bar = if IsNaN(price) then if LineOnExpansion then bar[1] else Double.NaN else BarNumber();
<def ThisBar = HighestAll(bar);
<def barCount = if bar == ThisBar then price else Double.NaN;
<plot HorizontalLine = if ThisBar <= bar then HighestAll(barCount) else Double.NaN;
<HorizontalLine.SetStyle(Curve.LONG_DASH);
<HorizontalLine.SetDefaultColor(CreateColor(250, 75, 75));
<HorizontalLine.SetLineWeight(1);
<def NetChg = close - close[1];
<def PrctChg = (NetChg / close[1]) * 100;

Does anyone know how I can add an upper/lower horizontal line-on-expansion to the upper / lower Keltner channel plots?
See if this is what you are requesting.

Screenshot-2021-08-21-110323.jpg
Ruby:
#
# TD Ameritrade IP Company, Inc. (c) 2007-2021
#

declare weak_volume_dependency;

input displace = 0;
input factor = 1.5;
input length = 20;
input price = close;
input averageType = AverageType.SIMPLE;
input trueRangeAverageType = AverageType.SIMPLE;

def shift = factor * MovingAverage(trueRangeAverageType, TrueRange(high, close, low), length);

def average = MovingAverage(averageType, price, length);

plot Avg = average[-displace];
Avg.SetDefaultColor(GetColor(1));

def ub = if isnan(close) then ub[1] else average[-displace] + shift[-displace]; 
plot Upper_Band = ub;
Upper_Band.SetDefaultColor(GetColor(8));

def ul = if isnan(close) then ul[1] else average[-displace] - shift[-displace];
plot Lower_Band = ul;
Lower_Band.SetDefaultColor(GetColor(5));
 
try this and see if it's what you're after. i have it set up to show the percentage proximity to the lower band, above or below. btw / might be some extraneous code in the thing but it shouldn't matter to the results. obviously, change the inputs to suit your needs.

in the screenshot, look at k%. it's showing that the price of ZM is about 6% below the 1.8 keltner band.

gH3qmDx.png


Code:
input atr_length = 10;
input factor = 1.8;
input length = 20;

def shift = factor * MovingAverage(AverageType.WILDERS, TrueRange(high, close, low), atr_length);

def average = MovingAverage(AverageType.EXPONENTIAL, close, length);

def Lower_Band = average - shift;

def Avg = average;

def Upper_Band = average + shift;

def signal = low - lower_band;

def difference = ((close - signal) / close * 100);

plot diff2 = round ((close - lower_band) / close * 100,0);

def t1 = low < lower_band;
def t2 = close <= lower_band;
def t3 = diff2;

AssignBackgroundColor( if t1 then color.dark_green else if t2 then color.green else if t1[1] then color.blue else if t2[2] then color.blue else color.black);

addlabel (yes, "" + t3, color.white);
 
Last edited:
@Lone Wolf Here you go:

Code:
# KeltnerChannels
# TD Ameritrade IP Company, Inc. (c) 2007-2020
# Modified by BenTen at UseThinkScript.com
# Added paintbars

declare weak_volume_dependency;

input displace = 0;
input factor = 1.5;
input length = 20;
input price = close;
input averageType = AverageType.SIMPLE;
input trueRangeAverageType = AverageType.SIMPLE;

def shift = factor * MovingAverage(trueRangeAverageType, TrueRange(high, close, low), length);

def average = MovingAverage(averageType, price, length);

plot Avg = average[-displace];
Avg.SetDefaultColor(GetColor(1));

plot Upper_Band = average[-displace] + shift[-displace];
Upper_Band.SetDefaultColor(GetColor(8));

plot Lower_Band = average[-displace] - shift[-displace];
Lower_Band.SetDefaultColor(GetColor(5));

AssignPriceColor(if close > Upper_Band then color.green else if close < Lower_Band then color.red else color.white);
Get an error when adding the scanner script - "Exactly one plot expected"
 
This should be easy for you all but I am having a hard to doing this. I want to show the column to show a 1 if both of the last 2 bars have closed above the Keltner Channel. Of course the same with below but that's just the opposite. Here is what I have. The issue is that it is still sometimes showing a 1 when clearly the last 2 bars are not above the band.

Code:
close from 2 bars ago is greater than KeltnerChannels("factor" = 2.0)."Upper_Band" and close from 1 bars ago is greater than KeltnerChannels("factor" = 2.0)."Upper_Band"
 

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