How do I make an exit signal fire ONLY AFTER the entry signal has been triggered?

B-rad

New member
I have managed to learn some thinkscript basics and frankensteined some code together to create a profitable strategy when backtested. My issue is that when I change the backtest into a regular study (with indicators for entry and exit points) it seems that something is lost in translation.

The strategy is a simple one I found on a free youtube video from John Carter involving a regression to the mean, and I have now modified slightly. The three required conditions for an long entry are:
  • RSI below 30
  • Not in a TTM squeeze
  • and the current price below the lower bollinger band
With the long exit condition simply being the price closing above the upper bollinger band. I'm sure the code could be shorter if I knew how to reference other studies in TOS....

#bollingerbands
input price = close;
input displace = 0;
input length = 20;
input Num_Dev_Dn = -2.0;
input Num_Dev_up = 2.0;
input averageType = AverageType.SIMPLE;

def sDev = StDev(data = price[-displace], length = length);

def MidLine = MovingAverage(averageType, data = price[-displace], length = length);
def LowerBand = MidLine + Num_Dev_Dn * sDev;
def UpperBand = MidLine + Num_Dev_up * sDev;
#bollingerbandsEND


#RSI
input length2 = 14;
input over_Bought = 70;
input over_Sold = 30;
input price2 = close;
input averageType2 = AverageType.WILDERS;
input showBreakoutSignals = no;

def NetChgAvg = MovingAverage(averageType2, price2 - price2[1], length);
def TotChgAvg = MovingAverage(averageType2, AbsValue(price2 - price2[1]), length);
def ChgRatio = if TotChgAvg != 0 then NetChgAvg / TotChgAvg else 0;

def RSI = 50 * (ChgRatio + 1);
def OverSold = over_Sold;
def OverBought = over_Bought;
def UpSignal = if RSI crosses above OverSold then OverSold else Double.NaN;
def DownSignal = if RSI crosses below OverBought then OverBought else Double.NaN;
#RSI END

#ttmsqueeze start
input price3 = close;
input length3 = 20;
input Num_Dev_Dn3 = -2.0;
input Num_Dev_up3 = 2.0;
input averageType3 = AverageType.SIMPLE;
input displace3 = 0;
def sDev3 = StDev(data = price3[-displace], length = length3);
def MidLineBB = MovingAverage(averageType, data = price3[-displace3], length = length);
def LowerBandBB = MidLineBB + Num_Dev_Dn * sDev3;
def UpperBandBB = MidLineBB + Num_Dev_up * sDev3;
input factorhigh = 1.0;
input factormid = 1.5;
input factorlow = 2.0;
input trueRangeAverageType3 = AverageType.SIMPLE;
def shifthigh = factorhigh * MovingAverage(trueRangeAverageType3, TrueRange(high, close, low), length3);
def shiftMid = factormid * MovingAverage(trueRangeAverageType3, TrueRange(high, close, low), length);
def shiftlow = factorlow * MovingAverage(trueRangeAverageType3, TrueRange(high, close, low), length);
def average = MovingAverage(averageType, price3, length3);

def Avg = average[-displace];

def UpperBandKCLow = average[-displace] + shiftlow[-displace];
def LowerBandKCLow = average[-displace] - shiftlow[-displace];

def UpperBandKCMid = average[-displace] + shiftMid[-displace];
def LowerBandKCMid = average[-displace] - shiftMid[-displace];

def UpperBandKCHigh = average[-displace] + shifthigh[-displace];
def LowerBandKCHigh = average[-displace] - shifthigh[-displace];

def K = (Highest(high, length3) + Lowest(low, length3)) /
2 + ExpAverage(close, length3);
def momo = Inertia(price3 - K / 2, length3);

def pos = momo >= 0;
def neg = momo < 0;
def up = momo >= momo[1];
def dn = momo < momo[1];

def presqueeze = LowerBandBB > LowerBandKCLow and UpperBandBB < UpperBandKCLow;
def originalSqueeze = LowerBandBB > LowerBandKCMid and UpperBandBB < UpperBandKCMid;
def ExtrSqueeze = LowerBandBB > LowerBandKCHigh and UpperBandBB < UpperBandKCHigh;

def PosUp = pos and up;
def PosDn = pos and dn;
def NegDn = neg and dn;
def NegUp = neg and up;
def squeezeline = 0;
def momentum = momo;
#ttmsqueezeEND
Def longEntryPoint = if !presqueeze and !originalsqueeze and !extrsqueeze and (price <= lowerband) and (price > oversold) then 1 else 0;

Def longExitPoint = price >= upperband;

plot Longentry = if longentrypoint and !longentrypoint[1] then 1 else 0;
Longentry.SetPaintingStrategy(PaintingStrategy.ARROW_UP);

Plot Longexit = if longexitpoint then 1 else 0;
Longentry.SetPaintingStrategy(PaintingStrategy.ARROW_UP);
BEap56p.png


Note how the down arrows are referencing every instance where price is above the upper bollinger band whereas -below in strategies- they only fire after an entry point is signaled.

EVACmKq.png


I have had this same issue with other code on different strategies as well. I don't know, maybe I should have paid more attention to my high school geometry teacher when she was taking about 'If and only if' logical statements..... Any ideas?
 

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

I have managed to learn some thinkscript basics and frankensteined some code together to create a profitable strategy when backtested. My issue is that when I change the backtest into a regular study (with indicators for entry and exit points) it seems that something is lost in translation.

The strategy is a simple one I found on a free youtube video from John Carter involving a regression to the mean, and I have now modified slightly. The three required conditions for an long entry are:
  • RSI below 30
  • Not in a TTM squeeze
  • and the current price below the lower bollinger band
With the long exit condition simply being the price closing above the upper bollinger band. I'm sure the code could be shorter if I knew how to reference other studies in TOS....


BEap56p.png


Note how the down arrows are referencing every instance where price is above the upper bollinger band whereas -below in strategies- they only fire after an entry point is signaled.

EVACmKq.png


I have had this same issue with other code on different strategies as well. I don't know, maybe I should have paid more attention to my high school geometry teacher when she was taking about 'If and only if' logical statements..... Any ideas?

B-rad,

You mentioned "RSI below 30, Not in a TTM squeeze, and the current price below the lower bollinger band".

In the code it says "Def longEntryPoint = if !presqueeze and !originalsqueeze and !extrsqueeze and (price <= lowerband) and (price > oversold) then 1 else 0;"

Should it have (RSI < oversold) in there?
 
your code has no down arrows and it doesn't have addorders().
so it doesn't match the 2 images.
we can't answer the question why, when we don't know the code used to produce the 2 images.
we can guess that the formulas are different.


read this page to learn about accessing data from other studies.
https://tlc.thinkorswim.com/center/reference/thinkScript/Reserved-Words/reference

reference <StudyName>(parameter1=value1,.., parameterN=valueN ).<PlotName>


example
def z = BollingerBands( price = open, length = 30).upperband

notice the desired plot value on the end.
this passes some parameters to the bollingerbands study,
for it to calc the upperband value,
which is passed back and assigned to z.
if a parameter is not specified then the default value is used.

look up somd TD studies and read the pages. they list the inputs and outputs ( plots).
https://tlc.thinkorswim.com/center/reference/Tech-Indicators/studies-library/A-B/BollingerBands
 
@B-rad Perhaps the easiest method would be to assign a state variable to track when in either a long or short trade... The state variable could be set with 1, -1, and 0, or 1, -1, and Double.NaN... Food for thought... There are examples of state variable logic here in these forums, in the Thinkscript Learning Center, and in Jim Shindlers Thinkscript Collection...
@rad14733 Could you by chance include a specific reference from the thinkscript collection or perhaps a hyperlink to the forum you referring to? I used control + F on the Jim Shindler page, and it didn't have any hits under the term 'state variables', same with the thinkscript learning center. are state variables under the 'If-statements' section?

You are overestimating my experience with coding here. It feels like I asked you the question, 'What is the definition of a planet?' and then you handed me a 500 page text book on astrophysics and told me to read all of it.
 
Last edited:
B-rad,

You mentioned "RSI below 30, Not in a TTM squeeze, and the current price below the lower bollinger band".

In the code it says "Def longEntryPoint = if !presqueeze and !originalsqueeze and !extrsqueeze and (price <= lowerband) and (price > oversold) then 1 else 0;"

Should it have (RSI < oversold) in there?
@traderLK I assumed the 'oversold' variable was sighting the RSI study. In my code it has 'def OverSold = over_Sold;' and then 'over_Sold = 30'
Are you saying that it is an invalid reference?
 
Last edited:
your code has no down arrows and it doesn't have addorders().
so it doesn't match the 2 images.
we can't answer the question why, when we don't know the code used to produce the 2 images.
we can guess that the formulas are different.


read this page to learn about accessing data from other studies.
https://tlc.thinkorswim.com/center/reference/thinkScript/Reserved-Words/reference

reference <StudyName>(parameter1=value1,.., parameterN=valueN ).<PlotName>


example
def z = BollingerBands( price = open, length = 30).upperband

notice the desired plot value on the end.
this passes some parameters to the bollingerbands study,
for it to calc the upperband value,
which is passed back and assigned to z.
if a parameter is not specified then the default value is used.

look up somd TD studies and read the pages. they list the inputs and outputs ( plots).
https://tlc.thinkorswim.com/center/reference/Tech-Indicators/studies-library/A-B/BollingerBands

@halcyonguy The only difference between the strategy picture I posted and the study photo was that I deleted the 'addorder' command and then replaced the 'def' of longentry with 'plot' longentry. I didn't think it was that significant. Do most people retain the 'addorder' in studies and not strategies?

As for the down arrows, I simply corrected that in the 'edit properties' section of the study rather than the 'edit source' area. I have been doing that with 'boolean vs numerical' as well. You will have to forgive my ignorance, everything I have learned about TOS, trading and Thinkscript has been entirely from youtube videos.

Thanks for the links, I will try to shorten the code by referencing other studies.
 

@halcyonguy The only difference between the strategy picture I posted and the study photo was that I deleted the 'addorder' command and then replaced the 'def' of longentry with 'plot' longentry. I didn't think it was that significant. Do most people retain the 'addorder' in studies and not strategies?

As for the down arrows, I simply corrected that in the 'edit properties' section of the study rather than the 'edit source' area. I have been doing that with 'boolean vs numerical' as well. You will have to forgive my ignorance, everything I have learned about TOS, trading and Thinkscript has been entirely from youtube videos.

Thanks for the links, I will try to shorten the code by referencing other studies.
my point was, the study didn't create those images, so it is confusing. in your first post, you didn't state that you changed the program.

.... corrected that in the 'edit properties' section .... if that works for you , great. i have never done that. if a study doesn't work as i want, i change the code. what happens if you unload the study, then later load it again? you will have to remember what settings you changed.
 
@traderLK I assumed the 'oversold' variable was sighting the RSI study. In my code it has 'def OverSold = over_Sold;' and then 'over_Sold = 30'
Are you saying that it is an invalid reference?

what traderlk was saying is you have the wrong variable and the wrong sign in the formula

your rule , RSI below 30 (oversold = 30)

your formula has a section that doesn't match your rule
(price > oversold)

price instead of RSI
' > instead of <

Def longEntryPoint = if !presqueeze and !originalsqueeze and !extrsqueeze and (price <= lowerband) and (price > oversold) then 1 else 0;

it should be
(RSI < oversold)

Def longEntryPoint = if !presqueeze and !originalsqueeze and !extrsqueeze and (price <= lowerband) and (RSI < oversold) then 1 else 0;
 
my point was, the study didn't create those images, so it is confusing. in your first post, you didn't state that you changed the program.

.... corrected that in the 'edit properties' section .... if that works for you , great. i have never done that. if a study doesn't work as i want, i change the code. what happens if you unload the study, then later load it again? you will have to remember what settings you changed.

@halcyonguy

I guess the question becomes, what code should I include so I don't have to keep editing it under the properties section?
 
what traderlk was saying is you have the wrong variable and the wrong sign in the formula

your rule , RSI below 30 (oversold = 30)

your formula has a section that doesn't match your rule
(price > oversold)

price instead of RSI
' > instead of <

Def longEntryPoint = if !presqueeze and !originalsqueeze and !extrsqueeze and (price <= lowerband) and (price > oversold) then 1 else 0;

it should be
(RSI < oversold)

Def longEntryPoint = if !presqueeze and !originalsqueeze and !extrsqueeze and (price <= lowerband) and (RSI < oversold) then 1 else 0;
Got it thanks
 

Similar threads

Not the exact question you're looking for?

Start a new thread and receive assistance from our community.

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