Cup and Handle Indicator for ThinkorSwim

Hi @RobertPayne! Wow, are we honored to have you stop by. Welcome to useThinkscript. I have quite a few RPayne studies in my notepad ++! I do understand that you have a site where you can capitalize on your knowledge of programming and thinkscript. What I do like about your site is that you do give and have given some of the simpler studies away. Thank you for that.

@BenTen is the proprietor of this site. I do not want to speak out of turn for him, but is there anything that we mere mortals can do with the script from Mr. Siligardos from TASC in 2011? Or Is that the same one that Tos has built in, that does not work?

We have several here that are trying to up their game and you would be the perfect person for some of us to learn from.
(btw, The crowd at the TSLounge seem to be stuck with this problem as well. There, now I have made them mad! :))

I have placed the Semi-Cup Formation script from TASC below. Would you be so kind as to look it over and let us know what, if anything, can be changed make it work?

Once again, we are honored that you have stopped by. Markos

Code:
# SemiCupFormation G Siligardos April 2011 TASC Magazine.
input price = close;
input minLength = 20;
input maxLength = 252;
input factor = 2.0;

script VariableSumMax {
    input price = close;
    input index1 = 0;
    input index2 = 0;
    input maxOffset = 0;
    def inf = 1 / 0;
    plot VSum = fold i = index1 to index2 with s do s + getValue(price, i,
maxOffset);
    plot VMax = fold i = index1 to index2 with m = -inf do Max(m, getValue(price,
i, maxOffset));
}

def LogPrice = log(price);
def DXPlus = Max(LogPrice - LogPrice[1], 0);
def DXMinus = Max(LogPrice[1] - LogPrice, 0);

def offset = fold i = MinLength to MaxLength + 1 with off = -1 do if off =
= -1 and getValue(price, i, MaxLength) > price * factor then i else off;
def HiLogPrice = if IsNaN(getValue(LogPrice, offset, MaxLength)) then LogPrice
else getValue(LogPrice, offset, MaxLength);
def LoLogPrice = -VariableSumMax(-LogPrice, 0, offset + 1, MaxLength).VMax;

def B2Offset = if offset < 0 then -1 else round(offset * 0.6, 0);
def B3Offset = if offset < 0 then -1 else round(offset * 0.4, 0);
def L2 = LoLogPrice * 0.6 + HiLogPrice * 0.4;
def L3 = LoLogPrice * 0.4 + HiLogPrice * 0.6;

def eps = 0.000000001;
def SumDXPlusB0toB2 = VariableSumMax(DXPlus, B2Offset + 1, offset + 1, MaxLength).VSum;
def SumDXMinusB0toB2 = VariableSumMax(DXMinus, B2Offset + 1, offset + 1, MaxLength).Vsum;
def DX1 = AbsValue(SumDXPlusB0toB2 - SumDXMinusB0toB2) / (SumDXPlusB0toB2 +
SumDXMinusB0toB2 + eps) * 100;

def SumDXPlusB2toB5 = VariableSumMax(DXPlus, 0, B2Offset + 1, MaxLength).VSum;
def SumDXMinusB2toB5 = VariableSumMax(DXMinus, 0, B2Offset + 1, MaxLength).VSum;
def DX2 = AbsValue(SumDXPlusB2toB5 - SumDXMinusB2toB5) / (SumDXPlusB2toB5 +
SumDXMinusB2toB5 + eps) * 100;

def HighestB2toB3 = VariableSumMax(LogPrice, B3Offset + 1, B2Offset + 1, MaxLength).VMax;
def HighestB3toB5 = VariableSumMax(LogPrice, 0, B3Offset + 1, MaxLength).VMax;

plot SemiCup = offset > 0 and DX1 > 25 and DX2 < 25 and HighestB2toB3 < L3 and
HighestB3toB5 < L2;
SemiCup.SetDefaultColor(GetColor(2));
SemiCup.SetPaintingStrategy(PaintingStrategy.BOOLEAN_POINTS);
SemiCup.SetLineWeight(3);
AddChartLabel(SemiCup, concat("Semi-Cup formation size: ", offset + 1), GetColor(2));

# SemiCupVisual
input price = close;
input length = 100;
def formation = IsNaN(price[-length]);
def t = length - sum(formation, length);
def inf = 1 / 0;
def Hi = HighestAll(if formation then price else -inf);
def Lo = LowestAll(if formation then price else inf);
def a = (Hi - Lo) / Power(length - 1, 10);

plot Cup = if formation then Min(Hi, a * Power(t, 10) + 0.98 * Lo) else Double.NaN;
Cup.SetDefaultColor(GetColor(2));
 
Last edited:

Volatility Trading Range

VTR is a momentum indicator that shows if a stock is overbought or oversold based on its Weekly and Monthly average volatility trading range.

Download the indicator

Wow, are we honored to have you stop by. Welcome to useThinkscript. I have quite a few RPayne studies in my notepad ++!

Thank you for the warm welcome. It's always nice to hear that someone is finding my work useful. I see that BenTen has posted a few of my older indicators here.

is there anything that we mere mortals can do with the script from Mr. Siligardos from TASC in 2011?
Or Is that the same one that Tos has built in, that does not work?

I have placed the Semi-Cup Formation script from TASC below.
Would you be so kind as to look it over and let us know what, if anything, can be changed make it work?

Yes, it is the same that was published in TASC.

Very slightly modified version posted below that does work. It will work with the scanner if you set the MaxLength to 100 or less

b5oV8sl.png


8AdoNFq.png


Ruby:
#
# TD Ameritrade IP Company, Inc. (c) 2011-2019
# very slightly modified by Robert Payne

script VariableMax {
    input price = close;
    input min = 0;
    input max = 0;
    plot VMax = fold i = min to max with m = Double.NEGATIVE_INFINITY do Max(m, getValue(price, i));
}

script VariableMin {
    input price = close;
    input min = 0;
    input max = 0;
    plot VMin = fold i = min to max with m = Double.POSITIVE_INFINITY do Min(m, getValue(price, i));
}

script DX {
    input DXPlus = close;
    input DXMinus = close;
    input min = 0;
    input max = 0;

    def SumDXPlus = fold i = min to max with p do p + getValue(DXPlus, i);
    def SumDXMinus = fold j = min to max with m do m + getValue(DXMinus, j);
    plot DX = AbsValue(SumDXPlus - SumDXMinus) / (SumDXPlus + SumDXMinus + 0.000000001) * 100;
}

input price = close;
input minLength = 20;
input maxLength = 252;
input factor = 2.0;

assert(minLength > 0, "'min length' must be positive: " + minLength);
assert(factor >= 1, "'factor' must be greater than or equal to 1: " + factor);

def rawOffset = fold i = minLength to maxLength with off = -1 do if off == -1 and getValue(price, i) > price * factor then i else off;
def offset = if IsNaN(rawOffset) then -1 else rawOffset;

def logPrice = log(price);

def B2Offset = if offset < 0 then -1 else round(offset * 0.6, 0);

def DXPlus = Max(logPrice - logPrice[1], 0);
def DXMinus = Max(logPrice[1] - logPrice, 0);
def DX1 = DX(DXPlus, DXMinus, B2Offset + 1, offset + 1);
def DX2 = DX(DXPlus, DXMinus, 0, B2Offset + 1);

def B3Offset = if offset < 0 then -1 else round(offset * 0.4, 0);
def highestB2toB3 = VariableMax(logPrice, B3Offset + 1, B2Offset + 1);
def highestB3toB5 = VariableMax(logPrice, 0, B3Offset + 1);

def hiLogPrice = if IsNaN(getValue(logPrice, offset)) then logPrice else getValue(logPrice, offset);
def loLogPrice = VariableMin(logPrice, 0, offset + 1);
def L2 = loLogPrice * 0.6 + hiLogPrice * 0.4;
def L3 = loLogPrice * 0.4 + hiLogPrice * 0.6;

plot SemiCup = offset > 0 and DX1 > 25 and DX2 < 25 and highestB2toB3 < L3 and highestB3toB5 < L2;

# find last cup
def curBar = barNumber();
def cupEnd = HighestAll(if SemiCup then curBar else Double.NaN);

def rawCupOffset = HighestAll(if cupEnd == curBar and SemiCup then offset else Double.NaN);
def cupOffset = if IsNaN(rawCupOffset) then 0 else rawCupOffset;

def cupHiLogPrice = HighestAll(if curBar == cupEnd then getValue(logPrice, cupOffset) else Double.NaN);
def cupLowLogPrice = HighestAll(if curBar == cupEnd then VariableMin(logPrice, 0, cupOffset + 1) else Double.NaN);

def found = curBar >= cupEnd - cupOffset and curBar <= cupEnd;

# cup visualization
def hi = exp(cupHiLogPrice);
def lo = exp(cupLowLogPrice);
def t = curBar - cupEnd;
def dev = (hi - lo) * Power(t / cupOffset, 10);
plot Curve = if found then Min(hi, dev + 0.98 * lo) else Double.NaN;

AddLabel(cupOffset, "Semi-Cup formation size: " + (cupOffset + 1));
SemiCup.SetPaintingStrategy(PaintingStrategy.BOOLEAN_POINTS);
SemiCup.SetLineWeight(3);
SemiCup.SetLineWeight(3);
Curve.SetDefaultColor(GetColor(2));
 
Your contribution of the script code is absolutely awesome and very timely!! Just 5 min ago concluded a follow-up phone call with TOS and they confirmed the TOS SemiCupFormation study is indeed "broken" and is in their queue to be repaired. TOS further stated that there is no ECD for a fix which did not make me joyous. So thank you very much for a solution Mr. Payne. You get major props! RDM

PS_Have looked at your offerings. Per usual I have a suggestion / request to run by you at another time re C&H
 
Hi there, this is my first post. I've been lurking for sometime, and my availability has opened up for the next month. I'm doing a crash course in some books and studying with this extra time I have before I get busy again. A couple months back, I made a scanner for detecting stocks that may be good swing trade candidates, but let me tell you: I'm no expert. I will say that overall, the scanner works surprisingly well. Here's the overall concept of how it should work:

A stock has a strong uptrend, generally lasting days, weeks, and up to months. Followed by a sudden sell off, into support levels to which is trades flat. Within time, it begins to develop an uptrend. When using this scanner, you may see that majority of stocks are in an uptrend, in what appears as a Cup and Handle formation on the 30 day chart. I would say roughly 75-80% show some nice results. To make things more interesting, I take it another level further by filtering using the Sizzle Index. For example, at the time of this writing it pulls a ticker named AXTA and a Sizzle Index of 3.5, so in a sense I am leveraging the scanner by using the Sizzle Index and finding unusual option volume on stocks that are in an uptrend.

The scanner could be greatly improved, for my first post I would like to include the scanner here. Please feel free to make an edits you think that could be beneficial here. I have a feeling it could detect uptrends a little sooner. What's frustrating is that it seems to pull stocks that are "halfway through the uptrend", so to speak. Let me know what your thoughts are!

I'm also not quite sure if it will work for everyone if you don't have specific studies. I hope it works. Have a good evening!

I also wanted to say thank you to this forum, and all of the passionate individuals I see here posting code. It's been very helpful and very educating. Shout out to everyone!!
Screenshot (58).png

Scanner Link: https://tos.mx/KL9DGog

Edit: I should note, just because a stock may appear to be forming a Cup and Handle, doesn't exactly mean that it is. It doesn't exactly pull sure-fire winners, rather it pulls some stocks "worth taking a look at".
 
Last edited by a moderator:
Hi there, this is my first post. I've been lurking for sometime, and my availability has opened up for the next month. I'm doing a crash course in some books and studying with this extra time I have before I get busy again. A couple months back, I made a scanner for detecting stocks that may be good swing trade candidates, but let me tell you: I'm no expert. I will say that overall, the scanner works surprisingly well. Here's the overall concept of how it should work:

A stock has a strong uptrend, generally lasting days, weeks, and up to months. Followed by a sudden sell off, into support levels to which is trades flat. Within time, it begins to develop an uptrend. When using this scanner, you may see that majority of stocks are in an uptrend, in what appears as a Cup and Handle formation on the 30 day chart. I would say roughly 75-80% show some nice results. To make things more interesting, I take it another level further by filtering using the Sizzle Index. For example, at the time of this writing it pulls a ticker named AXTA and a Sizzle Index of 3.5, so in a sense I am leveraging the scanner by using the Sizzle Index and finding unusual option volume on stocks that are in an uptrend.

The scanner could be greatly improved, for my first post I would like to include the scanner here. Please feel free to make an edits you think that could be beneficial here. I have a feeling it could detect uptrends a little sooner. What's frustrating is that it seems to pull stocks that are "halfway through the uptrend", so to speak. Let me know what your thoughts are!

I'm also not quite sure if it will work for everyone if you don't have specific studies. I hope it works. Have a good evening!

I also wanted to say thank you to this forum, and all of the passionate individuals I see here posting code. It's been very helpful and very educating. Shout out to everyone!!

https://tos.mx/KL9DGog

Edit: I should note, just because a stock may appear to be forming a Cup and Handle, doesn't exactly mean that it is. It doesn't exactly pull sure-fire winners, rather it pulls some stocks "worth taking a look at".
@tropicalfartbreeze What a great add to the community, I have looking for such as scanner in a long time. You are definitely God sent. Btw, I changed my TF to daily and it delivered some really great setups. I like it when the handle surfs either the 10 or 20 MA, and anticipate the breakout. Thanks
 
Hi I have a question r bout the semi cup formation if I can create a scan and watchlist if so how thanks
 
# Scan SemiCup from Mobius V02.10.02.2021
Caveat: Scan will time-out on attempts to scan the Universe of Stocks! There HAS to be some filters to narrow down the pool of stocks being scanned. The example below, has the standard filters on price, market cap, volume but you can use any filters that fit your strategy.
Shared Scanner Link: http://tos.mx/x1Dbpp2
FfwftTx.png

This scanner code MUST be cut&pasted into the scanner! It will timeout if saved as a study as referenced in the scanner.
Ruby:
# Scan SemiCup
# Mobius
# V02.10.02.2021 Note: Corrects script fuctions and getValue() functions

script VariableMax
    {
     input price = close;
     input min = 0;
     input max = 0;
     plot VMax = fold i = min to max
                 with m = Double.NEGATIVE_INFINITY
                 do Max(m, getValue(price, i));
    }
script VariableMin
    {
     input price = close;
     input min = 0;
     input max = 0;
     plot VMin = fold i = min to max
                 with m = Double.POSITIVE_INFINITY
                 do Min(m, getValue(price, i));
    }
script DX
    {
     input DXPlus = close;
     input DXMinus = close;
     input min = 0;
     input max = 0;
     def SumDXPlus = fold i = min to max
                     with p
                     do p + getValue(DXPlus, i);
     def SumDXMinus = fold j = min to max
                      with m
                      do m + getValue(DXMinus, j);
     plot DX = AbsValue(SumDXPlus - SumDXMinus) / (SumDXPlus + SumDXMinus + 0.000000001) * 100;
    }

input price = close;
input minLength = 20;
input maxLength = 252;
input factor = 2.0;

assert(minLength > 0, "'min length' must be positive: " + minLength);
assert(factor >= 1, "'factor' must be greater than or equal to 1: " + factor);

def rawOffset = fold i = minLength to maxLength
                with off = -1
                do if off == -1 and getValue(price, i) > price * factor
                   then i
                   else off;
def offset = if IsNaN(rawOffset)
             then -1
             else rawOffset;
def logPrice = log(price);
def B2Offset = if offset < 0
               then -1
               else round(offset * 0.6, 0);
def DXPlus = Max(logPrice - logPrice[1], 0);
def DXMinus = Max(logPrice[1] - logPrice, 0);
def DX1 = DX(DXPlus, DXMinus, B2Offset + 1, offset + 1);
def DX2 = DX(DXPlus, DXMinus, 0, B2Offset + 1);
def B3Offset = if offset < 0
               then -1
               else round(offset * 0.4, 0);
def highestB2toB3 = VariableMax(logPrice, B3Offset + 1, B2Offset + 1);
def highestB3toB5 = VariableMax(logPrice, 0, B3Offset + 1);
def hiLogPrice = if IsNaN(getValue(logPrice, offset))
                 then logPrice
                 else getValue(logPrice, offset);
def loLogPrice = VariableMin(logPrice, 0, offset + 1);
def L2 = loLogPrice * 0.6 + hiLogPrice * 0.4;
def L3 = loLogPrice * 0.4 + hiLogPrice * 0.6;

# NOTE: For a chart study the following line of code should be changed to a plot statement.
def SemiCup = offset > 0 and DX1 > 25 and DX2 < 25 and highestB2toB3 < L3 and highestB3toB5 < L2;

# find last cup
def curBar = barNumber();
def cupEnd = HighestAll(if SemiCup
                        then curBar
                        else Double.NaN);
def rawCupOffset = HighestAll(if cupEnd == curBar and SemiCup
                              then offset
                              else Double.NaN);
def cupOffset = if IsNaN(rawCupOffset)
                then 0
                else rawCupOffset;
def cupHiLogPrice = HighestAll(if curBar == cupEnd
                               then getValue(logPrice, cupOffset)
                               else Double.NaN);
def cupLowLogPrice = HighestAll(if curBar == cupEnd
                                then VariableMin(logPrice, 0, cupOffset + 1)
                                else Double.NaN);
def found = curBar >= cupEnd - cupOffset and curBar <= cupEnd;
def hi = exp(cupHiLogPrice);
def lo = exp(cupLowLogPrice);
def t = curBar - cupEnd;
def dev = (hi - lo) * Power(t / cupOffset, 10);
plot Curve = if found
             then Min(hi, dev + 0.98 * lo)
             else Double.NaN;
# End Code: Corrected SemiCup Formation
a1.png
 
Last edited:
Is it possible to modify the script to identify the complete cup and handle rather than the semi formation? That way we could identify the reversal to the upside and look for a breakout (Mark Minervini method)
 
Last edited:
If you want to use this as a chart study, simply change "def SemiCup" to "plot SemiCup" ... this is the line below the comment that says "# NOTE: For a chart study the following line of code should be changed to a plot statement." ... Create a new chart study and re-paste the scanner code and making the mentioned change.
 
Is it possible to modify the script to identify the complete cup and handle rather than the semi formation? That way we could identify the reversal to the upside and look for a breakout (Mark Minervini method)
Not currently
 
Hello, thanks everyone for all the great work and help you provide. However, after reading everything i'm still confused as to what link would be the appropriate to use to scan for possible Cup and Handle patterns.

I see Robert Payne share a code on this thread: https://usethinkscript.com/threads/cup-and-handle-indicator-for-thinkorswim.405/post-5123 which i copied into TOS, but it wont let me close/save the thinkscript so i can use it...so im unable to to use the scan. Can someone please share the scan link of that code? I know nothing about coding FYI :(

Also, is Robert scanner different from the one @MerryDay copied here? https://usethinkscript.com/threads/cup-and-handle-indicator-for-thinkorswim.405/post-77743

Thanks all for the help in advance
 
Hi @RobertPayne! Wow, are we honored to have you stop by. Welcome to useThinkscript. I have quite a few RPayne studies in my notepad ++! I do understand that you have a site where you can capitalize on your knowledge of programming and thinkscript. What I do like about your site is that you do give and have given some of the simpler studies away. Thank you for that.

@BenTen is the proprietor of this site. I do not want to speak out of turn for him, but is there anything that we mere mortals can do with the script from Mr. Siligardos from TASC in 2011? Or Is that the same one that Tos has built in, that does not work?

We have several here that are trying to up their game and you would be the perfect person for some of us to learn from.
(btw, The crowd at the TSLounge seem to be stuck with this problem as well. There, now I have made them mad! :))

I have placed the Semi-Cup Formation script from TASC below. Would you be so kind as to look it over and let us know what, if anything, can be changed make it work?

Once again, we are honored that you have stopped by. Markos

Code:
# SemiCupFormation G Siligardos April 2011 TASC Magazine.
input price = close;
input minLength = 20;
input maxLength = 252;
input factor = 2.0;

script VariableSumMax {
    input price = close;
    input index1 = 0;
    input index2 = 0;
    input maxOffset = 0;
    def inf = 1 / 0;
    plot VSum = fold i = index1 to index2 with s do s + getValue(price, i,
maxOffset);
    plot VMax = fold i = index1 to index2 with m = -inf do Max(m, getValue(price,
i, maxOffset));
}

def LogPrice = log(price);
def DXPlus = Max(LogPrice - LogPrice[1], 0);
def DXMinus = Max(LogPrice[1] - LogPrice, 0);

def offset = fold i = MinLength to MaxLength + 1 with off = -1 do if off =
= -1 and getValue(price, i, MaxLength) > price * factor then i else off;
def HiLogPrice = if IsNaN(getValue(LogPrice, offset, MaxLength)) then LogPrice
else getValue(LogPrice, offset, MaxLength);
def LoLogPrice = -VariableSumMax(-LogPrice, 0, offset + 1, MaxLength).VMax;

def B2Offset = if offset < 0 then -1 else round(offset * 0.6, 0);
def B3Offset = if offset < 0 then -1 else round(offset * 0.4, 0);
def L2 = LoLogPrice * 0.6 + HiLogPrice * 0.4;
def L3 = LoLogPrice * 0.4 + HiLogPrice * 0.6;

def eps = 0.000000001;
def SumDXPlusB0toB2 = VariableSumMax(DXPlus, B2Offset + 1, offset + 1, MaxLength).VSum;
def SumDXMinusB0toB2 = VariableSumMax(DXMinus, B2Offset + 1, offset + 1, MaxLength).Vsum;
def DX1 = AbsValue(SumDXPlusB0toB2 - SumDXMinusB0toB2) / (SumDXPlusB0toB2 +
SumDXMinusB0toB2 + eps) * 100;

def SumDXPlusB2toB5 = VariableSumMax(DXPlus, 0, B2Offset + 1, MaxLength).VSum;
def SumDXMinusB2toB5 = VariableSumMax(DXMinus, 0, B2Offset + 1, MaxLength).VSum;
def DX2 = AbsValue(SumDXPlusB2toB5 - SumDXMinusB2toB5) / (SumDXPlusB2toB5 +
SumDXMinusB2toB5 + eps) * 100;

def HighestB2toB3 = VariableSumMax(LogPrice, B3Offset + 1, B2Offset + 1, MaxLength).VMax;
def HighestB3toB5 = VariableSumMax(LogPrice, 0, B3Offset + 1, MaxLength).VMax;

plot SemiCup = offset > 0 and DX1 > 25 and DX2 < 25 and HighestB2toB3 < L3 and
HighestB3toB5 < L2;
SemiCup.SetDefaultColor(GetColor(2));
SemiCup.SetPaintingStrategy(PaintingStrategy.BOOLEAN_POINTS);
SemiCup.SetLineWeight(3);
AddChartLabel(SemiCup, concat("Semi-Cup formation size: ", offset + 1), GetColor(2));

# SemiCupVisual
input price = close;
input length = 100;
def formation = IsNaN(price[-length]);
def t = length - sum(formation, length);
def inf = 1 / 0;
def Hi = HighestAll(if formation then price else -inf);
def Lo = LowestAll(if formation then price else inf);
def a = (Hi - Lo) / Power(length - 1, 10);

plot Cup = if formation then Min(Hi, a * Power(t, 10) + 0.98 * Lo) else Double.NaN;
Cup.SetDefaultColor(GetColor(2));
I see the following error:

identifier Already Used: i at 14:22
Expected double
Expected double at 32:5
Expected double at 33:5
Expected double at 37:5
Expected double at 38:5
Expected double at 42:5
Expected double at 43:5
 
Hello. I am the author of the cup and handle indicator for Thinkorswim that you have been discussing.



It is possible to automate the identification of, at least, some cup and handle patterns in Thinkorswim. This indicator, obviously, will not identify every possible cup and handle pattern, but it will, certainly, make the process of finding some of them much easier.



The patterns identified by my indicator do have a handle that show a moderate price decline. I chose not to draw the handle as declining because I wanted the breakout line to be obvious. However, if you look at the candles themselves, it is obvious that they do "show a moderate price decline".

mituoPA.png
Hi where is your code for this?
 
Thank you for the warm welcome. It's always nice to hear that someone is finding my work useful. I see that BenTen has posted a few of my older indicators here.



Yes, it is the same that was published in TASC.

Very slightly modified version posted below that does work. It will work with the scanner if you set the MaxLength to 100 or less

b5oV8sl.png


8AdoNFq.png


Ruby:
#
# TD Ameritrade IP Company, Inc. (c) 2011-2019
# very slightly modified by Robert Payne

script VariableMax {
    input price = close;
    input min = 0;
    input max = 0;
    plot VMax = fold i = min to max with m = Double.NEGATIVE_INFINITY do Max(m, getValue(price, i));
}

script VariableMin {
    input price = close;
    input min = 0;
    input max = 0;
    plot VMin = fold i = min to max with m = Double.POSITIVE_INFINITY do Min(m, getValue(price, i));
}

script DX {
    input DXPlus = close;
    input DXMinus = close;
    input min = 0;
    input max = 0;

    def SumDXPlus = fold i = min to max with p do p + getValue(DXPlus, i);
    def SumDXMinus = fold j = min to max with m do m + getValue(DXMinus, j);
    plot DX = AbsValue(SumDXPlus - SumDXMinus) / (SumDXPlus + SumDXMinus + 0.000000001) * 100;
}

input price = close;
input minLength = 20;
input maxLength = 252;
input factor = 2.0;

assert(minLength > 0, "'min length' must be positive: " + minLength);
assert(factor >= 1, "'factor' must be greater than or equal to 1: " + factor);

def rawOffset = fold i = minLength to maxLength with off = -1 do if off == -1 and getValue(price, i) > price * factor then i else off;
def offset = if IsNaN(rawOffset) then -1 else rawOffset;

def logPrice = log(price);

def B2Offset = if offset < 0 then -1 else round(offset * 0.6, 0);

def DXPlus = Max(logPrice - logPrice[1], 0);
def DXMinus = Max(logPrice[1] - logPrice, 0);
def DX1 = DX(DXPlus, DXMinus, B2Offset + 1, offset + 1);
def DX2 = DX(DXPlus, DXMinus, 0, B2Offset + 1);

def B3Offset = if offset < 0 then -1 else round(offset * 0.4, 0);
def highestB2toB3 = VariableMax(logPrice, B3Offset + 1, B2Offset + 1);
def highestB3toB5 = VariableMax(logPrice, 0, B3Offset + 1);

def hiLogPrice = if IsNaN(getValue(logPrice, offset)) then logPrice else getValue(logPrice, offset);
def loLogPrice = VariableMin(logPrice, 0, offset + 1);
def L2 = loLogPrice * 0.6 + hiLogPrice * 0.4;
def L3 = loLogPrice * 0.4 + hiLogPrice * 0.6;

plot SemiCup = offset > 0 and DX1 > 25 and DX2 < 25 and highestB2toB3 < L3 and highestB3toB5 < L2;

# find last cup
def curBar = barNumber();
def cupEnd = HighestAll(if SemiCup then curBar else Double.NaN);

def rawCupOffset = HighestAll(if cupEnd == curBar and SemiCup then offset else Double.NaN);
def cupOffset = if IsNaN(rawCupOffset) then 0 else rawCupOffset;

def cupHiLogPrice = HighestAll(if curBar == cupEnd then getValue(logPrice, cupOffset) else Double.NaN);
def cupLowLogPrice = HighestAll(if curBar == cupEnd then VariableMin(logPrice, 0, cupOffset + 1) else Double.NaN);

def found = curBar >= cupEnd - cupOffset and curBar <= cupEnd;

# cup visualization
def hi = exp(cupHiLogPrice);
def lo = exp(cupLowLogPrice);
def t = curBar - cupEnd;
def dev = (hi - lo) * Power(t / cupOffset, 10);
plot Curve = if found then Min(hi, dev + 0.98 * lo) else Double.NaN;

AddLabel(cupOffset, "Semi-Cup formation size: " + (cupOffset + 1));
SemiCup.SetPaintingStrategy(PaintingStrategy.BOOLEAN_POINTS);
SemiCup.SetLineWeight(3);
SemiCup.SetLineWeight(3);
Curve.SetDefaultColor(GetColor(2));

What time frame am I suppose to use? This study doesn't display anything.
 
Hello, thanks everyone for all the great work and help you provide. However, after reading everything i'm still confused as to what link would be the appropriate to use to scan for possible Cup and Handle patterns.

I see Robert Payne share a code on this thread: https://usethinkscript.com/threads/cup-and-handle-indicator-for-thinkorswim.405/post-5123 which i copied into TOS, but it wont let me close/save the thinkscript so i can use it...so im unable to to use the scan. Can someone please share the scan link of that code? I know nothing about coding FYI :(

Also, is Robert scanner different from the one @MerryDay copied here? https://usethinkscript.com/threads/cup-and-handle-indicator-for-thinkorswim.405/post-77743

Thanks all for the help in advance
I see the following error:

identifier Already Used: i at 14:22
Expected double
Expected double at 32:5
Expected double at 33:5
Expected double at 37:5
Expected double at 38:5
Expected double at 42:5
Expected double at 43:5
Hi where is your code for this?
What time frame am I suppose to use? This study doesn't display anything.

Yes, there is an issue with the Payne Scan the one posted here is the only working one available:
https://usethinkscript.com/threads/cup-and-handle-indicator-for-thinkorswim.405/post-77743
 
Last edited:

New Indicator: Buy the Dip

Check out our Buy the Dip indicator and see how it can help you find profitable swing trading ideas. Scanner, watchlist columns, and add-ons are included.

Download the indicator

Similar threads

Not the exact question you're looking for?

Start a new thread and receive assistance from our community.

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