Momentum Keltner Channels for ThinkorSwim

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

Hey @Pensar, is there anyway you can edit the code and take out the actual keltner channels and leave the alerts? I find the alerts are more than accurate, they are almost precise. They work best for Orbs but anyways, I am a technical trader and the channels get in my way sometimes. Any help would be appreciated!

And while we're at it, if you can edit the code to remove the keltner channels, can you make an alert like a ring sound when an arrow pops up? TIA. I am actually starting my first coding class in a week. What you guys do has inspired me to learn. TIA
I did minor modification to show or hide the channel. Moreover, I included the label alone with count in the script.
# MomentumKeltnerChannels
# Pensar
# 06/06/2020
# Based on the FW_MOBO code by TOS user davidinc (aka Firstwave, aka David Elliott)
# Modified code to use Keltner Channels, changed code structure.
# Added colored price and user-adjustable global colors.

#Inputs
input length = 34;
input factor = 0.5;
input displace = 0;
input price = close;
input type = AverageType.SIMPLE;
input pricecolor = yes;
input fill = yes;
input ShowLines = yes;
input Label = yes;
input arrows = yes;
input alerts = no;
input sound = {default "Ding", "Bell", "Chimes", "NoSound", "Ring"};

#Variables
def nan = double.nan;
def shift = factor * MovingAverage(type, TrueRange(high, close, low), length);
def avg = MovingAverage(type, price, length);
def line1 = avg[-displace] - shift[-displace];
def line2 = avg[-displace] + shift[-displace];
def Chg = if(close > line2, 1, if(close < line1, -1, 0));
def Hold = CompoundValue(1,if(Hold[1] == Chg or Chg == 0, Hold[1], if(Chg == 1, 1, -1)), 0);
def ArUp = if !arrows or Hold[0] == Hold[1] then nan else if Hold[0] == 1 then line1 else nan;
def ArDn = if !arrows or Hold[0] == Hold[1] then nan else if Hold[0] == -1 then line2 else nan;
def LBUp = if fill and Hold[0] == 1 then line2 else nan;
def UBUp = if fill and Hold[0] == 1 then line1 else nan;
def LBDn = if fill and Hold[0] == -1 then line2 else nan;
def UBDn = if fill and Hold[0] == -1 then line1 else nan;
def AlertUp = alerts and Hold[1] == 1 and (Hold[1] <> Hold[2]);
def AlertDn = alerts and Hold[1] == -1 and (Hold[1] <> Hold[2]);

#Colors
DefineGlobalColor("Cloud Up", color.dark_green);
DefineGlobalColor("Cloud Dn", color.dark_red);
DefineGlobalColor("Channel Up", color.green);
DefineGlobalColor("Channel Down", color.red);
DefineGlobalColor("Price Up", color.green);
DefineGlobalColor("Price Neutral", color.gray);
DefineGlobalColor("Price Down", color.red);

#Plots
plot UB = if ShowLines then line1 else nan;
UB.SetLineWeight(1);
UB.AssignValueColor(if Hold[0] == 1 then GlobalColor("Channel Up")
else GlobalColor("Channel Down"));
plot LB = if ShowLines then line2 else nan;
LB.SetLineWeight(1);
LB.AssignValueColor(if Hold[0] == 1 then GlobalColor("Channel Up")
else GlobalColor("Channel Down"));
plot BOA = ArUp;
BOA.SetPaintingStrategy(PaintingStrategy.Arrow_Up);
BOA.SetDefaultColor(color.green);
BOA.SetLineWeight(2);
plot BDA = ArDn;
BDA.SetPaintingStrategy(PaintingStrategy.Arrow_Down);
BDA.SetDefaultColor(color.red);
BDA.SetLineWeight(2);

#Clouds
AddCloud(LBUp, UBUp, GlobalColor("Cloud Up"), GlobalColor("Cloud Dn"));
AddCloud(LBDn, UBDn, GlobalColor("Cloud Dn"), GlobalColor("Cloud Up"));

#Price Color
AssignPriceColor(if pricecolor then if close > line2 then GlobalColor("Price Up")
else if close < line1 then GlobalColor("Price Down")
else GlobalColor("Price Neutral")
else color.current);
# Labels
def n1 = Hold[0] == 1;
def n2 = Hold[0] == -1;
def count1 = if n1 and !n1[1] then 1 else count1[1]+1;
def count2 = if n2 and !n2[1] then 1 else count2[1]+1;

def n = if n1 then count1 else if n2 then count2 else double.nan;

AddLabel(Label,
if n1 then "👍(" + count1 + ")" else "👎(" + count2 + ")",
if n1 then color.green else color.red);

#Alerts
Alert(AlertUp, "BREAKOUT!", Alert.Bar, Sound);
Alert(AlertDn, "BREAKDOWN!", Alert.Bar, Sound);

# --- End code ---
 
@samer800 I tried to make this a MTF something is off could you take a look and make the right adjustments thanks


# MomentumKeltnerChannels
# Pensar
# 06/06/2020
# Based on the FW_MOBO code by TOS user davidinc (aka Firstwave, aka David Elliott)
# Modified code to use Keltner Channels, changed code structure.
# Added colored price and user-adjustable global colors.


#Inputs
input length = 34;
input factor = 0.5;
input displace = 0;
def price = close(period = Period);
input type = AverageType.SIMPLE;
input pricecolor = yes;
input fill = yes;
input arrows = yes;
input alerts = yes;
input sound = {default "Ding", "Bell", "Chimes", "NoSound", "Ring"};
input Period = aggregationPeriod.Day;

#Variables
def nan = double.nan;
def shift = factor * MovingAverage(type, TrueRange(high(period = Period), close(period = Period), low(period = Period)), length);
def avg = MovingAverage(type, price, length);
def line1 = avg[-displace] - shift[-displace];
def line2 = avg[-displace] + shift[-displace];
def Chg = if(close(period = Period) > line2, 1, if(close(period = Period) < line1, -1, 0));
def Hold = CompoundValue(1,if(Hold[1] == Chg or Chg == 0, Hold[1], if(Chg == 1, 1, -1)), 0);
def ArUp = if !arrows or Hold[0] == Hold[1] then nan else if Hold[0] == 1 then line1 else nan;
def ArDn = if !arrows or Hold[0] == Hold[1] then nan else if Hold[0] == -1 then line2 else nan;
def LBUp = if fill and Hold[0] == 1 then line2 else nan;
def UBUp = if fill and Hold[0] == 1 then line1 else nan;
def LBDn = if fill and Hold[0] == -1 then line2 else nan;
def UBDn = if fill and Hold[0] == -1 then line1 else nan;
def AlertUp = alerts and Hold[1] == 1 and (Hold[1] <> Hold[2]);
def AlertDn = alerts and Hold[1] == -1 and (Hold[1] <> Hold[2]);

#Colors
DefineGlobalColor("Cloud Up", color.dark_green);
DefineGlobalColor("Cloud Dn", color.dark_red);
DefineGlobalColor("Channel Up", color.green);
DefineGlobalColor("Channel Down", color.red);
DefineGlobalColor("Price Up", color.green);
DefineGlobalColor("Price Neutral", color.gray);
DefineGlobalColor("Price Down", color.red);

#Plots
plot UB = line1;
UB.SetLineWeight(1);
UB.AssignValueColor(if Hold[0] == 1 then GlobalColor("Channel Up")
else GlobalColor("Channel Down"));
plot LB = line2;
LB.SetLineWeight(1);
LB.AssignValueColor(if Hold[0] == 1 then GlobalColor("Channel Up")
else GlobalColor("Channel Down"));
plot BOA = ArUp;
BOA.SetPaintingStrategy(PaintingStrategy.Arrow_Up);
BOA.SetDefaultColor(color.green);
BOA.SetLineWeight(2);
plot BDA = ArDn;
BDA.SetPaintingStrategy(PaintingStrategy.Arrow_Down);
BDA.SetDefaultColor(color.red);
BDA.SetLineWeight(2);

#Clouds
AddCloud(LBUp, UBUp, GlobalColor("Cloud Up"), GlobalColor("Cloud Dn"));
AddCloud(LBDn, UBDn, GlobalColor("Cloud Dn"), GlobalColor("Cloud Up"));

#Price Color
AssignPriceColor(if pricecolor then if close > line2 then GlobalColor("Price Up")
else if close < line1 then GlobalColor("Price Down")
else GlobalColor("Price Neutral")
else color.current);

#Alerts
Alert(AlertUp, "BREAKOUT!", Alert.Bar, Sound);
Alert(AlertDn, "BREAKDOWN!", Alert.Bar, Sound);
 
Last edited by a moderator:
@samer800 I tried to make this a MTF something is off could you take a look and make the right adjustments thanks


# MomentumKeltnerChannels
# Pensar
# 06/06/2020
# Based on the FW_MOBO code by TOS user davidinc (aka Firstwave, aka David Elliott)
# Modified code to use Keltner Channels, changed code structure.
# Added colored price and user-adjustable global colors.


#Inputs
input length = 34;
input factor = 0.5;
input displace = 0;
input price = close(period = Period);
input type = AverageType.SIMPLE;
input pricecolor = yes;
input fill = yes;
input arrows = yes;
input alerts = yes;
input sound = {default "Ding", "Bell", "Chimes", "NoSound", "Ring"};
input Period = aggregationPeriod.Day;

#Variables
def nan = double.nan;
def shift = factor * MovingAverage(type, TrueRange(high(period = Period), close(period = Period), low(period = Period)), length);
def avg = MovingAverage(type, price, length);
def line1 = avg[-displace] - shift[-displace];
def line2 = avg[-displace] + shift[-displace];
def Chg = if(close(period = Period) > line2, 1, if(close(period = Period) < line1, -1, 0));
def Hold = CompoundValue(1,if(Hold[1] == Chg or Chg == 0, Hold[1], if(Chg == 1, 1, -1)), 0);
def ArUp = if !arrows or Hold[0] == Hold[1] then nan else if Hold[0] == 1 then line1 else nan;
def ArDn = if !arrows or Hold[0] == Hold[1] then nan else if Hold[0] == -1 then line2 else nan;
def LBUp = if fill and Hold[0] == 1 then line2 else nan;
def UBUp = if fill and Hold[0] == 1 then line1 else nan;
def LBDn = if fill and Hold[0] == -1 then line2 else nan;
def UBDn = if fill and Hold[0] == -1 then line1 else nan;
def AlertUp = alerts and Hold[1] == 1 and (Hold[1] <> Hold[2]);
def AlertDn = alerts and Hold[1] == -1 and (Hold[1] <> Hold[2]);

#Colors
DefineGlobalColor("Cloud Up", color.dark_green);
DefineGlobalColor("Cloud Dn", color.dark_red);
DefineGlobalColor("Channel Up", color.green);
DefineGlobalColor("Channel Down", color.red);
DefineGlobalColor("Price Up", color.green);
DefineGlobalColor("Price Neutral", color.gray);
DefineGlobalColor("Price Down", color.red);

#Plots
plot UB = line1;
UB.SetLineWeight(1);
UB.AssignValueColor(if Hold[0] == 1 then GlobalColor("Channel Up")
else GlobalColor("Channel Down"));
plot LB = line2;
LB.SetLineWeight(1);
LB.AssignValueColor(if Hold[0] == 1 then GlobalColor("Channel Up")
else GlobalColor("Channel Down"));
plot BOA = ArUp;
BOA.SetPaintingStrategy(PaintingStrategy.Arrow_Up);
BOA.SetDefaultColor(color.green);
BOA.SetLineWeight(2);
plot BDA = ArDn;
BDA.SetPaintingStrategy(PaintingStrategy.Arrow_Down);
BDA.SetDefaultColor(color.red);
BDA.SetLineWeight(2);

#Clouds
AddCloud(LBUp, UBUp, GlobalColor("Cloud Up"), GlobalColor("Cloud Dn"));
AddCloud(LBDn, UBDn, GlobalColor("Cloud Dn"), GlobalColor("Cloud Up"));

#Price Color
AssignPriceColor(if pricecolor then if close > line2 then GlobalColor("Price Up")
else if close < line1 then GlobalColor("Price Down")
else GlobalColor("Price Neutral")
else color.current);

#Alerts
Alert(AlertUp, "BREAKOUT!", Alert.Bar, Sound);
Alert(AlertDn, "BREAKDOWN!", Alert.Bar, Sound);
@Trading51
ALL the close, high, low needed to be changed. Your script above has been fixed
 
I have found the the Momentum Keltner Channels study and scan can be a very accurate and effective way to find stocks that are ready for a move. If anyone else uses this please comment on your results. It is very useful, in my opinion. The scan produces potential movers, and the study arrows are great. Give it a try.

https://usethinkscript.com/threads/momentum-keltner-channels-for-thinkorswim.2855/

The settings I use (FWIW) are: length=15, factor=.3, price= (H+L+ C)/3, type =weighted.

I do only Swing Trading, so your setting may need adjustment if you are a day trader.
 
Code:
# MomentumKeltnerChannels
# Pensar
# 06/06/2020
# Based on the FW_MOBO code by TOS user davidinc (aka Firstwave, aka David Elliott)
# Modified code to use Keltner Channels, changed code structure.
# Added colored price and user-adjustable global colors.

#Inputs
input length       =     34;
input factor       =     0.5;
input displace     =     0;
input price        =     close;
input type         =     AverageType.SIMPLE;
input pricecolor   =     yes;
input fill         =     yes;
input arrows       =     yes;
input alerts       =     yes;
input sound        =     {default "Ding", "Bell", "Chimes", "NoSound", "Ring"};

#Variables
def nan      =   double.nan;
def shift    =   factor * MovingAverage(type, TrueRange(high, close, low), length);
def avg      =   MovingAverage(type, price, length);
def line1    =   avg[-displace] - shift[-displace];
def line2    =   avg[-displace] + shift[-displace];
def Chg      =   if(close > line2, 1, if(close < line1, -1, 0));
def Hold     =   CompoundValue(1,if(Hold[1] == Chg or Chg == 0, Hold[1], if(Chg == 1, 1, -1)), 0);
def ArUp     =   if !arrows or Hold[0] == Hold[1] then nan else if Hold[0] == 1 then line1 else nan;
def ArDn     =   if !arrows or Hold[0] == Hold[1] then nan else if Hold[0] == -1 then line2 else nan;
def LBUp     =   if fill and Hold[0] == 1 then line2 else nan;
def UBUp     =   if fill and Hold[0] == 1 then line1 else nan;
def LBDn     =   if fill and Hold[0] == -1 then line2 else nan;
def UBDn     =   if fill and Hold[0] == -1 then line1 else nan;
def AlertUp  =   alerts and Hold[1] ==  1 and (Hold[1] <> Hold[2]);
def AlertDn  =   alerts and Hold[1] == -1 and (Hold[1] <> Hold[2]);

#Colors
DefineGlobalColor("Cloud Up", color.dark_green);
DefineGlobalColor("Cloud Dn", color.dark_red);
DefineGlobalColor("Channel Up", color.green);
DefineGlobalColor("Channel Down", color.red);
DefineGlobalColor("Price Up", color.green);
DefineGlobalColor("Price Neutral", color.gray);
DefineGlobalColor("Price Down", color.red);

#Plots
plot UB = line1;
     UB.SetLineWeight(1);
     UB.AssignValueColor(if Hold[0] == 1 then GlobalColor("Channel Up")
                         else GlobalColor("Channel Down"));
plot LB = line2;
     LB.SetLineWeight(1);
     LB.AssignValueColor(if Hold[0] == 1 then GlobalColor("Channel Up")
                         else GlobalColor("Channel Down"));
plot BOA = ArUp;
     BOA.SetPaintingStrategy(PaintingStrategy.Arrow_Up);
     BOA.SetDefaultColor(color.green);
     BOA.SetLineWeight(2);
plot BDA = ArDn;
     BDA.SetPaintingStrategy(PaintingStrategy.Arrow_Down);
     BDA.SetDefaultColor(color.red);
     BDA.SetLineWeight(2);

#Clouds
AddCloud(LBUp, UBUp, GlobalColor("Cloud Up"), GlobalColor("Cloud Dn"));
AddCloud(LBDn, UBDn, GlobalColor("Cloud Dn"), GlobalColor("Cloud Up"));

#Price Color
AssignPriceColor(if pricecolor then if close > line2 then GlobalColor("Price Up")
                 else if close < line1 then GlobalColor("Price Down")
                 else GlobalColor("Price Neutral")
                 else color.current);

#Alerts
Alert(AlertUp, "BREAKOUT!",  Alert.Bar, Sound);
Alert(AlertDn, "BREAKDOWN!", Alert.Bar, Sound);

# --- End code ---

View attachment 7328
Very nicely done, thank you !
 
Last edited by a moderator:

Similar threads

Not the exact question you're looking for?

Start a new thread and receive assistance from our community.

87k+ Posts
202 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