ATR Risk Control Indicator for ThinkorSwim

rlohmeyer

Active member
ATR Risk Control Indicator for ThinkorSwim

I have worked on this indicator quite a while and am now using it consistently on my daily charts for swing trading. You can see it in the image posted below. Based on the parameters you set for (1) the ATR risk set-up (Type of Average to use for the ATR, Length of average, and the percent of the Avg ATR to use for your stop) and (2) your Dollar Amount to Risk on the trade...The indicator will then calculate (1) the number of shares to purchase based on those parameters (2) the cost of those shares (3) and then place the stops over and under each bar to indicate the Long Entry stop OR the Short entry stop.

The image below the chart image shows what will show up on your chart once you enter a position.

And then the final image will shows the input section for your parameters. The code is below that. The indicator was inspired by Mobius ATR Trend indicator and the ToS APTR indicator.

I hope this indicator will help some better control risks of swing trades.

Regards,
Bob
lvTnube.png


This image is from an entry I made today for a long entry. It shows the shares I purchased. My entry price and my cost. The P/L label is from another indicator.
PWHugAb.png


Op5HyGU.png





Code:
# @rlohmeyer: Inspired by Mobius work on ATR Trend Indicator and TOS APTR indicator

# Declaration
declare upper;

#Inputs
input AvgType = AverageType.EXPONENTIAL;
input Length = 20;
input StopOffset = 1.00;
input DollarAmountRisk = 25.0;
input showStops = yes;

# Basic Definitions
def shares = GetQuantity();
def oneTick = .01;
def h = high;
def l = low;
def c = close;
def o = open;
def AP = Round(GetAveragePrice(), 2);
def OPL = GetOpenPL();
def na = double.NaN;

# Def Stops
def TR = TrueRange(h, c, l);
def atrr = Round(MovingAverage(AvgType, tr, Length) / oneTick, 2) * oneTick;
def offsetAmt = Round((atrr * StopOffset) / oneTick, 2) * oneTick;
def StopL = c - offsetAmt;
def StopS = c + offsetAmt;

# Plots
plot stopLongEntry = StopL;
plot stopShortEntry = StopS;
stopLongEntry.SetDefaultColor(Color.white);
stopLongEntry.SetPaintingStrategy(PaintingStrategy.DASHES);
stopLongEntry.HideBubble();
stopLongEntry.HideTitle();
stopShortEntry.SetDefaultColor (Color.white);
stopShortEntry.SetPaintingStrategy(PaintingStrategy.DASHES);
stopShortEntry.HideBubble();
stopShortEntry.HideTitle();


# Define Num of Shares by Stop Size and Dollar Amount Risk
def stopSize = Round(AbsValue(c - StopL), 2);
def stopSizeTicks = (stopSize / oneTick);
def oneShareRiskAmt = stopSizeTicks * oneTick;
def numberOfShares = RoundDown(((DollarAmountRisk / oneShareRiskAmt)), 0);

#Risk Label
def ATRP = Round(APTR(Length,AvgType),1);
def TRP =Round(APTR(1),1);
def EXP = AvgType == 1;
def SMPL = AvgType == 0;
def WGHT = AvgType == 2;
def WLDR = AvgType == 3;
def HULL = AvgType == 4;


AddLabel(yes,(if EXP then "EXP" else if SMPL then "SMPL" else if WGHT then "WGHT" else if WLDR then "WLDR" else "HULL") + "-" + Length + "-" +  (StopOffset * 100) + "%" + "-" + ATRP +"%"+"  Rsk|$" + DollarAmountRisk + "  Cst|$" + Round(numberOfShares * C, 0)+ "  Shares|" + numberOfShares , Color.ORANGE);


#Entry Label
def cost = Round(shares * AP, 0);
AddLabel (if AP>0 then yes else no," Shares:" + shares +  " Ent:$" + AP + " Cst:$" + Round(cost, 0) , if cost == 0 then color.light_gray else CreateColor(137, 178, 245));
 
Last edited by a moderator:
Bob, this is an absolute awesome concept. I love it. I'm looking to add labels like this but with the "low of the day" as the stop, and a "take profit" as some multiple of that risk. Is there anyway you can help me with this I wouldn't even know where to begin.
 
@Bflorez21 @Beltrame1

Based on @Bflorez21 request I worked on a Risk Control indicator that will allow you to set the stop at the bottom or top of a bar and use a Target Multiple of the close-low or high-close to go long or short based on your choice of direction for the trade, to Buy for a Long Trade or Sell for Short Trade. The example image below is from Fridays bar on the DIA etf, which can easily be traded Long or Short. The code is below that. I have improved the code so that you see the stops and targets for one bar only extended over the whole chart. Easier to plan your trade. The first image shows the stop at the low in red, the second image shows the stop at the high in red.

The image also shows a Label telling you Dollar Risk, Target Multiple (set at 2 but can be changed), Shares per Risk, and Cost
Wramk26.jpg


Code:
#@rlohmeyer
#code borrowed and modified from this forum in order to show 1 bar stop and target extended across chart


# Def Stops & Risk Shares

def h = high;
def l = low;
def c = close;
input oneTick = .01;
input DollarAmountRisk = 25;
input TargetMultiple = 2.00;
input TradeDirectionUp = yes;

#Up Plots
def stpu = if !IsNaN(c - l) and IsNaN(c - l[-1]) then l else stpu[1];
plot stopu = if TradeDirectionUp == 1 and isNaN(c - l[-400])then stpu[-400] else Double.NaN;
stopu.setdefaultcolor(color.red);
stopu.setpaintingstrategy(paintingStrategy.dashes);
stopu.hidetitle();

def tgu =((c-l)* TargetMultiple);
def tgtu = if !IsNaN(c + tgu) and IsNaN(c + tgu[-1]) then c + tgu else tgtu[1];
plot targetu = if TradeDirectionUp == 1 and isNaN(c + tgu [-400])then tgtu[-400] else Double.NaN;
targetu.setdefaultcolor(color.green);
targetu.setpaintingstrategy(paintingStrategy.dashes);
targetu.hidetitle();

#DownPlots
def stpd = if !IsNaN(h-c) and IsNaN(h-c[-1]) then h else stpd[1];
plot stopd = if TradeDirectionUp == 0 and isNaN(h-c[-400])then stpd[-400] else Double.NaN;
stopd.setdefaultcolor(color.red);
stopd.setpaintingstrategy(paintingStrategy.dashes);
stopd.hidetitle();

def tgd =((h-c)* TargetMultiple);
def tgtd = if !IsNaN(c - tgd) and IsNaN(c - tgd[-1]) then c - tgd else tgtd[1];
plot targetd= if TradeDirectionUp == 0 and isNaN(c - tgd [-400])then tgtd[-400] else Double.NaN;
targetd.setdefaultcolor(color.green);
targetd.setpaintingstrategy(paintingStrategy.dashes);
targetd.hidetitle();

def offsetAmtu = Round((c-l) / oneTick, 2) * oneTick;
def sharesu = Round(((DollarAmountRisk / offsetAmtu)), 0);
def offsetAmtd = Round((h-l) / oneTick, 2) * oneTick;
def sharesd = AbsValue(Round(((DollarAmountRisk / offsetAmtd)), 0));

AddLabel(yes, "DollarRisk|$" + DollarAmountRisk + "  TargetMultiple|" +  Round(TargetMultiple,2) + "  SharesPerRisk|" + (if TradeDirectionUp == 1 then Round(sharesu,0) else Round(sharesd,0))  + "  Cost|$" + Round(sharesu * c, 0), Color.ORANGE);
 
Sorry for the duplicity.

So far here is MRL and MRH
Ruby:
So far here is MRL and MRH

Code:
#
# HighLowLookback
#
# Study to show the highest high and lowest low after a given number of bars back.
#
# Author: Kory Gill, @korygill
#
# VERSION HISTORY (sortable date and time (your local time is fine), and your initials
# 20190710-2200-KG - created

# Inputs
#
input length = 13;

#
# Common Variables that may also reduce calls to server
#
def vClose = close;
def vLow = low;
def vHigh = high;
def nan = double.NaN;

#
# Logic
#
def currentBarNumber = if !IsNaN(vClose) then BarNumber() else nan;
def lastBarNumber = HighestAll(currentBarNumber);
def lookbackBar = lastBarNumber - length + 1;
def doPlot = if currentBarNumber >= lookbackBar then 1 else 0;

def mostRecentHigh = CompoundValue(1, if doPlot && vHigh > mostRecentHigh[1] then vHigh else mostRecentHigh[1],double.NEGATIVE_INFINITY);
def highBarNumber = CompoundValue(1, if doPlot && vHIgh > mostRecentHigh[1] then currentBarNumber else highBarNumber[1],0);
plot mrh = if currentBarNumber >= HighestAll(highBarNumber) then mostRecentHigh else nan;
mrh.SetDefaultColor(Color.GREEN);

def mostRecentLow = CompoundValue(1, if doPlot && vLow < mostRecentLow[1] then vLow else mostRecentLow[1],double.POSITIVE_INFINITY);
def lowBarNumber = CompoundValue(1, if doPlot && vLow < mostRecentLow[1] then currentBarNumber else lowBarNumber[1],0);
plot mrl = if currentBarNumber >= HighestAll(lowBarNumber) then mostRecentLow else nan;
mrl.SetDefaultColor(Color.RED);

#
# Visualizations
#
AddChartBubble(
currentBarNumber == HighestAll(highBarNumber),
vHigh,
"HIGH",
Color.WHITE,
yes);

AddChartBubble(
currentBarNumber == HighestAll(lowBarNumber),
vLow,
"LOW",
Color.WHITE,
no);

AddChartBubble(
currentBarNumber == lookbackBar,
(vHigh+vLow)/2,
length+"\nBar",
Color.GRAY,
yes);

plot bbH = if currentBarNumber == lookbackBar then vHigh + TickSize()*1 else nan;
bbH.SetPaintingStrategy(PaintingStrategy.SQUARES);
bbH.SetDefaultColor(Color.MAGENTA);
bbH.SetLineWeight(5);
bbH.HideBubble();

plot bbL = if currentBarNumber == lookbackBar then vLow - TickSize()*1 else nan;
bbL.SetPaintingStrategy(PaintingStrategy.SQUARES);
bbL.SetDefaultColor(Color.MAGENTA);
bbL.SetLineWeight(5);
bbL.HideBubble();

#
# Labels
#
AddLabel(yes,
"mostRecentHigh: " + mostRecentHigh,
Color.Gray);

AddLabel(yes,
"mostRecentLow: " + mostRecentLow,
Color.Gray);
 
Last edited by a moderator:
@rlohmeyer
Sorry to ask for a change to the script ( this is by far my favorite script) but there is an issue I'm running into and was wondering if you can help me with it.

So the way I trade is that I either buy on a break out candle or sometimes (probably more often buy the pull back after a break out when the moving averages catch up and I use the original break out bar as my stop.

If you're willing to is there a way you can change the script from looking at the low of day to an "input" so that I can change the price level. I understand this would take away the automation that is so convenient and require me to change the setting each time before I place a trade, but I think this would make it the most useable for the most amount of people and their different trading styles. I don't know if its possible to have a permanent line that's drag and drop able but ideally that would be a perfect worlds answer to this issue.

I tried to make the change myself by changing the definition of "L" but I kept getting an error message. Thanks and sorry for the request
 
Last edited by a moderator:
@QUIKTDR1
I have several modified risk control systems (that improve on the coding in the first post) that "follow" the present price, (and does not leave past ones for each bar) so I can post one based on: 1. Average True Range 2. Average Bar Range 3. Average Close to Open the next day (which I favor for an overnight trade that calculates an average risk of price movement till the open)...this I will use for a directional risk trade if I feel the price will open either higher or lower). I can post any of these. You could then modify the code for your purposes, and post the results for this thread.


@Bflorez21
I will look at your question when I get a chance.
 
@Bflorez21
Here is your quote as to the perfect way for you. " I don't know if its possible to have a permanent line that's drag and drop able but ideally that would be a perfect worlds answer to this issue." You can set up trades on your chart very easily that will be automatically triggered based on the specific price level you want to get in, and can have both a stop and a target attached to the order. These are called OCO orders. These can be set up on your chart anywhere, and can be moved by drag and drop anywhere you want. Youtube has quite a number of videos on how to set these up. My indicator was to calculate the number of shares per the amount of risk. The calculations require using the high, low, close, open of a bar or a combination of these in order to place the lines that stretch across the chart, thus the Indicator lines cannot be dragged on a chart. They move on their own or stay in place based on using these particular calculations. But a price input alone, without some relationship to say the high or low the bar, would not work to draw the lines. That is why when you fooled with the "low" in the code, you got an error. The code requires the low to draw the lines.

Regards,
Bob
 
ATR Risk Control Indicator for ThinkorSwim

I have worked on this indicator quite a while and am now using it consistently on my daily charts for swing trading. You can see it in the image posted below. Based on the parameters you set for (1) the ATR risk set-up (Type of Average to use for the ATR, Length of average, and the percent of the Avg ATR to use for your stop) and (2) your Dollar Amount to Risk on the trade...The indicator will then calculate (1) the number of shares to purchase based on those parameters (2) the cost of those shares (3) and then place the stops over and under each bar to indicate the Long Entry stop OR the Short entry stop.

The image below the chart image shows what will show up on your chart once you enter a position.

And then the final image will shows the input section for your parameters. The code is below that. The indicator was inspired by Mobius ATR Trend indicator and the ToS APTR indicator.

I hope this indicator will help some better control risks of swing trades.

Regards,
Bob
lvTnube.png


This image is from an entry I made today for a long entry. It shows the shares I purchased. My entry price and my cost. The P/L label is from another indicator.
PWHugAb.png


Op5HyGU.png





Code:
# @rlohmeyer: Inspired by Mobius work on ATR Trend Indicator and TOS APTR indicator

# Declaration
declare upper;

#Inputs
input AvgType = AverageType.EXPONENTIAL;
input Length = 20;
input StopOffset = 1.00;
input DollarAmountRisk = 25.0;
input showStops = yes;

# Basic Definitions
def shares = GetQuantity();
def oneTick = .01;
def h = high;
def l = low;
def c = close;
def o = open;
def AP = Round(GetAveragePrice(), 2);
def OPL = GetOpenPL();
def na = double.NaN;

# Def Stops
def TR = TrueRange(h, c, l);
def atrr = Round(MovingAverage(AvgType, tr, Length) / oneTick, 2) * oneTick;
def offsetAmt = Round((atrr * StopOffset) / oneTick, 2) * oneTick;
def StopL = c - offsetAmt;
def StopS = c + offsetAmt;

# Plots
plot stopLongEntry = StopL;
plot stopShortEntry = StopS;
stopLongEntry.SetDefaultColor(Color.white);
stopLongEntry.SetPaintingStrategy(PaintingStrategy.DASHES);
stopLongEntry.HideBubble();
stopLongEntry.HideTitle();
stopShortEntry.SetDefaultColor (Color.white);
stopShortEntry.SetPaintingStrategy(PaintingStrategy.DASHES);
stopShortEntry.HideBubble();
stopShortEntry.HideTitle();


# Define Num of Shares by Stop Size and Dollar Amount Risk
def stopSize = Round(AbsValue(c - StopL), 2);
def stopSizeTicks = (stopSize / oneTick);
def oneShareRiskAmt = stopSizeTicks * oneTick;
def numberOfShares = RoundDown(((DollarAmountRisk / oneShareRiskAmt)), 0);

#Risk Label
def ATRP = Round(APTR(Length,AvgType),1);
def TRP =Round(APTR(1),1);
def EXP = AvgType == 1;
def SMPL = AvgType == 0;
def WGHT = AvgType == 2;
def WLDR = AvgType == 3;
def HULL = AvgType == 4;


AddLabel(yes,(if EXP then "EXP" else if SMPL then "SMPL" else if WGHT then "WGHT" else if WLDR then "WLDR" else "HULL") + "-" + Length + "-" +  (StopOffset * 100) + "%" + "-" + ATRP +"%"+"  Rsk|$" + DollarAmountRisk + "  Cst|$" + Round(numberOfShares * C, 0)+ "  Shares|" + numberOfShares , Color.ORANGE);


#Entry Label
def cost = Round(shares * AP, 0);
AddLabel (if AP>0 then yes else no," Shares:" + shares +  " Ent:$" + AP + " Cst:$" + Round(cost, 0) , if cost == 0 then color.light_gray else CreateColor(137, 178, 245));
This is so helpful, but for an options trader, can this be motified to for contracts, based on contracts pricing and amounts??
 
@stone

Hi,
Thanks for the comment. If I were trying to figure out how to change the code in order to accommodate putting this indicator on an options chart, I would try to determine the time decay factor for one tick change in the price of the underlying to equal 1 tick change in options contract.

For the SPY, with near expiration options (say a few days on a weekly option contract) that are in the money, you get a pretty darn close relationship between a 1 tick change ($.01) in price of the SPY to $10 change in the options contract, based on the very short time to expiration and the intrinsic value of the option. I do not trade options as of this point, so this has not been an issue for me. Some others on this forum may be able to help you code for that. I would be interested in what you find out.
 
Last edited:
I love this script!
https://usethinkscript.com/threads/atr-risk-control-indicator-for-thinkorswim.6765/
Moving to my question:

Can this be changed to use with Forex trading? Obviously it's set to "shares" in which will not work for Forex. Thanks for any help
Code:
# @rlohmeyer: Inspired by Mobius work on ATR Trend Indicator and TOS APTR indicator
# Declaration
declare upper;

#Inputs
input AvgType = AverageType.EXPONENTIAL;
input Length = 20;
input StopOffset = 1.00;
input DollarAmountRisk = 25.0;
input showStops = yes;

# Basic Definitions
def shares = GetQuantity();
def oneTick = .01;
def h = high;
def l = low;
def c = close;
def o = open;
def AP = GetAveragePrice();
def OPL = GetOpenPL();
def na = double.NaN;

# Def Stops
def TR = TrueRange(h, c, l);
def atrr = Round(MovingAverage(AvgType, tr, Length) / oneTick, 2) * oneTick;
def offsetAmt = Round((atrr * StopOffset) / oneTick, 2) * oneTick;
def StopL = c - offsetAmt;
def StopS = c + offsetAmt;

# Plots
plot stopLongEntry = StopL;
plot stopShortEntry = StopS;
stopLongEntry.SetDefaultColor(Color.white);
stopLongEntry.SetPaintingStrategy(PaintingStrategy.DASHES);
stopLongEntry.HideBubble();
stopLongEntry.HideTitle();
stopShortEntry.SetDefaultColor (Color.white);
stopShortEntry.SetPaintingStrategy(PaintingStrategy.DASHES);
stopShortEntry.HideBubble();
stopShortEntry.HideTitle();


# Define Num of Shares by Stop Size and Dollar Amount Risk
def stopSize = Round(AbsValue(c - StopL), 2);
def stopSizeTicks = (stopSize / oneTick);
def oneShareRiskAmt = stopSizeTicks * oneTick;
def numberOfShares = RoundDown(((DollarAmountRisk / oneShareRiskAmt)), 0);

#Risk Label
def ATRP = Round(APTR(Length,AvgType),1);
def TRP =Round(APTR(1),1);
def EXP = AvgType == 1;
def SMPL = AvgType == 0;
def WGHT = AvgType == 2;
def WLDR = AvgType == 3;
def HULL = AvgType == 4;

AddLabel(yes,(if EXP then "EXP" else if SMPL then "SMPL" else if WGHT then "WGHT" else if WLDR then "WLDR" else "HULL") + "-" + Length + "-" + (StopOffset * 100) + "%" + "-" + ATRP +"%"+" Rsk|$" + DollarAmountRisk + " Cst|$" + Round(numberOfShares * C, 0)+ " Shrs| " +numberOfShares + " |**" , Color.ORANGE);


#Entry Label
def cost = Round(shares * AP, 2);
AddLabel (if AP>0 then yes else no,"Shrs|" + shares + " Cst|$" + cost + " Entry|$" + AP, if cost == 0 then color.light_gray else CreateColor(137, 178, 245));
@rlohmeyer
 
Last edited:

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