ATR By Time Indicator

Get The Average True Range By Time of Day!

This indicator is designed to be used only on TradingView.


What is ATR By Time?

This indicator was inspired by my RVOL By Time indicator.

Instead of calculating the ATR by recent price data, it calculates an ATR value for each candle based on that candle’s time of day.

For example, if you set the Lookback setting on this indicator to 14, then instead of calculating the ATR based on the past 14 candles, it will calculate an ATR value based on the past 14 trading sessions for each candle.

This is extremely useful for day traders in particular as it allows you to gauge the average range of candles during certain times of day instead of only by the most recent price action.

The indicator will draw your stop loss value to the chart based on the following options:

  • Regular ATR
  • ATR By Time
  • Smallest ATR (Whichever is smallest between regular ATR vs. time ATR)
  • Largest ATR (Whichever is largest between regular ATR vs. time ATR)

This allows for tighter stops and larger position sizing during certain times of day for aggressive traders when set to Smallest ATR, or wider stop losses during more volatile periods of the day for conservative traders when set to Largest ATR.

It also draws a regular ATR value (optional) – so this is essentially an enhanced ATR indicator that gives you multiple readings on price volatility.

The script comes in two parts – an oscillator box for drawing the calculated values separate to your chart, and a chart companion script that draws the stop loss values over price action.


YouTube Video Guide


How It Works

This script uses a complex formula to calculate ATR values across distant historical bars.

Depending on the timeframe you select it will skip through historical bars to find previous bars from the same time of day. It collects these values then applies the traditional ATR formula to them.

The ATR value is determined by the maximum result of the following three calculations:

  • Current high minus the current low
  • The absolute value of the current high minus the previous close
  • The absolute value of the current low minus the previous close

Whichever of these three calculations comes out highest, that is your ATR for the given candle.

Once this value is calculated for historical bars, the ATR indicator’s reading is typically determined by a 14-period moving average of these individual ATR values. So the ATR reading you see on your screen is an average of the past 14 ATR values.

This means that as markets expand and contract this volatility reading will adapt to the change in candle price ranges.

The difference with the ATR By Time indicator’s calculation formula is that rather than referencing recent bars, it references bars based on their time of day.

For example, if you are on the 1-Hour chart and you check the ATR By Time value at 9:00AM with a Lookback period of 14, then the value you see will be the average of the ATR calculation of every 9:00AM 1-Hour candle over the past 14 trading sessions.

The gray candle in the background represents the average of the past X amount of trading sessions, whereas the colored part represents the ATR value of the current candle in relation to that.

You can also choose to enable the ATR moving average in the settings menu if you wish. This will give you a smoothed ATR reading by averaging the current session’s ATR value with previous sessions.

This versatility gives you a sophisticated reading on price volatility which is particularly helpful for day trade setups based around market opens or market closes when volatility tends to spike.

The regular ATR indicator will not account for this on the lower timeframes, but this indicator will!


Settings

ATR By Time Settings

Market:
You can choose from Forex, Crypto, Stocks and Futures. This setting is important – if you choose the wrong one the indicator will be inaccurate. This is because stocks have a different session length to forex, and forex has a different session length to crypto etc., which results in different price gaps that the script needs to account for.

Lookback Period:
This sets how many sessions the indicator will look back. For example, if you set this to 1, then it will show you today’s ATR relative to yesterday’s ATR.

Alert At ATR %:
This will enable alerts based on relative volatility. You can see this reading on the indicator, it is the very last numerical value in blue. Once you set this value, you need to create a new alert by pressing the + button on the alerts widget in the TradingView interface.

When the current candle’s ATR value exceeds the range % of the previous session’s value, the alert will be triggered. For example, if you set this value to 2 and the next candle is twice as large as its previous session’s counterpart, the alert will trigger.

Color Scheme:
This changes the color scheme of the indicator based on different interpretations of the ATR reading.

Heatmap

  • This color if range percent >= 0.25%
  • This color if range percent >= 0.50%
  • This color if range percent >= 0.75%
  • This color if range percent >= 1.00%
  • This color if range percent >= 2.00%

Traffic

  • This color if range percent >= 0.50%
  • This color if range percent >= 0.75%
  • This color if range percent >= 1.00%
  • This color if range percent >= 2.00%

Price

  • This color if candle closed bullish
  • This color if candle closed bearish

Trigger

  • This color if range percent >= specified range

RMA Length:
This sets the RMA length for averaging the session averages. Typically I prefer to keep this turned off, but if you want to experiment with “smoothing” the session averages, then that is what this feature is for.

Use RMA On Session Average Line?
If set to true, this will apply the RMA to the purple average line but not the bars, which will give you the best of both worlds. You get to see the current range compared to the session average (the bars), in addition to the current session average compared to the RMA of the session averages.

What this does is essentially turn this indicator into a hybrid ATR indicator that uses session ranges for input instead of candle ranges for the purple line, but shows you the current candle range compared to the session average with the histogram of bars.

Use RMA On Session Average Bars?
If set to true, then this will apply the RMA with the given length to the bars AND the session line, turning this into an ATR indicator that uses average session ranges for input instead of candle ranges.

Convert ATR To Whole Numbers?
I recommend leaving this turned on by default unless the market you are using this indicator on behaves strangely (in which case, please contact me and I will try to fix it).

If you turn this off, then the size of the bars will shrink dramatically depending on the price range of the timeframe you are using it on. For example, since forex pairs use pips, if you were to turn this off on a pair with a range of say 0.0005, then you would barely see the bars get drawn as they would be tiny. With this feature on, a reading of 0.0005 becomes 5.0.

Draw Regular ATR?
This is optional. If turned on, then this indicator will draw the regular ATR over the top of the purple session average and the histogram of bars. That way you get the best of both worlds – the current ATR reading in relation to recent price action, as well as the current ATR reading in relation to the typical volatility to be expected during the given time of day.

Updates / Change Log

v1.1:

  • Added visual Stop Loss value (Green = Long Stop Price, Red = Short Stop Price)
  • Added option to calculate stop loss distance based on:
    • Regular ATR
    • ATR By Time
    • Smallest ATR (Whichever is smallest between regular ATR vs. time ATR)
    • Largest ATR (Whichever is largest between regular ATR vs time ATR)
  • Created Chart Companion Script


Main Source Code

// @version=4
// ATR By Time Indicator v1.0
// Created by Matthew J. Slabosz
// Last Updated: 8th September, 2020
// www.zenandtheartoftrading.com
study(title="ATR by Time", shorttitle="ATR By Time", precision=5)

// Get user input
type = input(title="Market", defval='Forex', type=input.string, options=['Stocks', 'Forex', 'Crypto', 'Futures'])
lookback = input(title="Lookback Sessions", type=input.integer, defval=5)
alertPercent = input(title="Alert At ATR %", type=input.float, defval=0.0)
barColorOption = input(title="Color Scheme", defval='Heatmap', type=input.string, options=['Price', 'Heatmap', 'Traffic', 'Trigger'])
rmaLength = input(title="RMA Length", defval=14, type=input.integer)
useRMA0 = input(title="Use RMA On Session Average Line?", defval=false, type=input.bool)
useRMA1 = input(title="Use RMA On Session Average Bars?", defval=false, type=input.bool)
convertToWhole = input(title="Convert ATR to Whole Numbers?", defval=true, type=input.bool)
drawATR = input(title="Draw Regular ATR?", defval=true, type=input.bool)
useStructure = input(title="Use Structure On Trailing Stop?", defval=true, type=input.bool)
lookbackStructure = input(title="Structure Lookback", type=input.integer, defval=7)
atrMultiplier = input(title="ATR Multiplier", type=input.float, defval=1.0, minval=0.1)
useType = input(title="Stop Type", defval='ATR By Time', type=input.string, options=['ATR By Time', 'Regular ATR', 'Smallest ATR', 'Largest ATR'])

// Get this instrument's decimal count for Whole Number conversion
decimals = abs(log(syminfo.mintick) / log(10))

// Get current regular ATR
atrValue = atr(rmaLength)
atr = atrValue

// Convert to whole numbers if necessary
if decimals == 8 and convertToWhole
    atr := atrValue * 10000000
if decimals == 7 and convertToWhole
    atr := atrValue * 1000000
if decimals == 6 and convertToWhole
    atr := atrValue * 100000
if decimals == 5 and convertToWhole
    atr := atrValue * 10000
if decimals == 4 and convertToWhole
    atr := atrValue * 1000
if decimals == 3 and convertToWhole
    atr := atrValue * 100
if decimals == 2 and convertToWhole
    atr := atrValue * 10

// Get current range value
currentRangePips = max(abs(high - low), max(abs(high - close[1]), abs(low - close[1])))

// Convert range into whole number
currentRange = currentRangePips
if decimals == 8 and convertToWhole
    currentRange := currentRangePips * 10000000
if decimals == 7 and convertToWhole
    currentRange := currentRangePips * 1000000
if decimals == 6 and convertToWhole
    currentRange := currentRangePips * 100000
if decimals == 5 and convertToWhole
    currentRange := currentRangePips * 10000
if decimals == 4 and convertToWhole
    currentRange := currentRangePips * 1000
if decimals == 3 and convertToWhole
    currentRange := currentRangePips * 100
if decimals == 2 and convertToWhole
    currentRange := currentRangePips * 10

// Get price data
totalRange = close - close
for i = 1 to lookback by 1
    if type == "Forex"
        totalRange := totalRange + (timeframe.period == "1" ? 0 : 
           timeframe.period == "3" ? 0 : timeframe.period == "5" ? 
           max(abs(high[i * 288] - low[i * 288]), max(abs(high[i * 288] - close[i * 288 + 1]), abs(low[i * 288] - close[i * 288 + 1]))) : 
           timeframe.period == "15" ? 
           max(abs(high[i * 96] - low[i * 96]), max(abs(high[i * 96] - close[i * 96 + 1]), abs(low[i * 96] - close[i * 96 + 1]))) : 
           timeframe.period == "30" ? 
           max(abs(high[i * 48] - low[i * 13]), max(abs(high[i * 48] - close[i * 48 + 1]), abs(low[i * 48] - close[i * 48 + 1]))) : 
           timeframe.period == "45" ? 
           max(abs(high[i * 32] - low[i * 32]), max(abs(high[i * 32] - close[i * 32 + 1]), abs(low[i * 32] - close[i * 32 + 1]))) : 
           timeframe.period == "60" ? 
           max(abs(high[i * 24] - low[i * 24]), max(abs(high[i * 24] - close[i * 24 + 1]), abs(low[i * 24] - close[i * 24 + 1]))) : 
           timeframe.period == "120" ? 
           max(abs(high[i * 12] - low[i * 12]), max(abs(high[i * 12] - close[i * 12 + 1]), abs(low[i * 12] - close[i * 12 + 1]))) : 
           timeframe.period == "180" ? 
           max(abs(high[i * 8] - low[i * 3]), max(abs(high[i * 8] - close[i * 8 + 1]), abs(low[i * 8] - close[i * 8 + 1]))) : 
           timeframe.period == "240" ? 
           max(abs(high[i * 6] - low[i * 6]), max(abs(high[i * 6] - close[i * 6 + 1]), abs(low[i * 6] - close[i * 6 + 1]))) : 
           timeframe.period == "D" ? 
           max(abs(high[i * 5] - low[i * 5]), max(abs(high[i * 5] - close[i * 5 + 1]), abs(low[i * 5] - close[i * 5 + 1]))) : 
           timeframe.period == "W" ? 
           max(abs(high[i * 4] - low[i * 4]), max(abs(high[i * 4] - close[i * 4 + 1]), abs(low[i * 4] - close[i * 4 + 1]))) : 
           0)
        totalRange
    if type == "Crypto"
        totalRange := totalRange + (timeframe.period == "1" ? 0 : 
           timeframe.period == "3" ? 0 : timeframe.period == "5" ? 
           max(abs(high[i * 288] - low[i * 288]), max(abs(high[i * 288] - close[i * 288 + 1]), abs(low[i * 288] - close[i * 288 + 1]))) : 
           timeframe.period == "15" ? 
           max(abs(high[i * 96] - low[i * 96]), max(abs(high[i * 96] - close[i * 96 + 1]), abs(low[i * 96] - close[i * 96 + 1]))) : 
           timeframe.period == "30" ? 
           max(abs(high[i * 48] - low[i * 13]), max(abs(high[i * 48] - close[i * 48 + 1]), abs(low[i * 48] - close[i * 48 + 1]))) : 
           timeframe.period == "45" ? 
           max(abs(high[i * 32] - low[i * 32]), max(abs(high[i * 32] - close[i * 32 + 1]), abs(low[i * 32] - close[i * 32 + 1]))) : 
           timeframe.period == "60" ? 
           max(abs(high[i * 24] - low[i * 24]), max(abs(high[i * 24] - close[i * 24 + 1]), abs(low[i * 24] - close[i * 24 + 1]))) : 
           timeframe.period == "120" ? 
           max(abs(high[i * 12] - low[i * 12]), max(abs(high[i * 12] - close[i * 12 + 1]), abs(low[i * 12] - close[i * 12 + 1]))) : 
           timeframe.period == "180" ? 
           max(abs(high[i * 8] - low[i * 3]), max(abs(high[i * 8] - close[i * 8 + 1]), abs(low[i * 8] - close[i * 8 + 1]))) : 
           timeframe.period == "240" ? 
           max(abs(high[i * 6] - low[i * 6]), max(abs(high[i * 6] - close[i * 6 + 1]), abs(low[i * 6] - close[i * 6 + 1]))) : 
           timeframe.period == "D" ? 
           max(abs(high[i * 7] - low[i * 7]), max(abs(high[i * 7] - close[i * 7 + 1]), abs(low[i * 7] - close[i * 7 + 1]))) : 
           timeframe.period == "W" ? 
           max(abs(high[i * 4] - low[i * 4]), max(abs(high[i * 4] - close[i * 4 + 1]), abs(low[i * 4] - close[i * 4 + 1]))) : 
           0)
        totalRange
    if type == "Stocks"
        totalRange := totalRange + (timeframe.period == "1" ? 0 : 
           timeframe.period == "3" ? 0 : timeframe.period == "5" ? 
           max(abs(high[i * 78] - low[i * 78]), max(abs(high[i * 78] - close[i * 78 + 1]), abs(low[i * 78] - close[i * 78 + 1]))) : 
           timeframe.period == "15" ? 
           max(abs(high[i * 26] - low[i * 26]), max(abs(high[i * 26] - close[i * 26 + 1]), abs(low[i * 26] - close[i * 26 + 1]))) : 
           timeframe.period == "30" ? 
           max(abs(high[i * 13] - low[i * 13]), max(abs(high[i * 13] - close[i * 13 + 1]), abs(low[i * 13] - close[i * 13 + 1]))) : 
           timeframe.period == "45" ? 
           max(abs(high[i * 9] - low[i * 9]), max(abs(high[i * 9] - close[i * 9 + 1]), abs(low[i * 9] - close[i * 9 + 1]))) : 
           timeframe.period == "60" ? 
           max(abs(high[i * 7] - low[i * 7]), max(abs(high[i * 7] - close[i * 7 + 1]), abs(low[i * 7] - close[i * 7 + 1]))) : 
           timeframe.period == "120" ? 
           max(abs(high[i * 4] - low[i * 4]), max(abs(high[i * 4] - close[i * 4 + 1]), abs(low[i * 4] - close[i * 4 + 1]))) : 
           timeframe.period == "180" ? 
           max(abs(high[i * 3] - low[i * 3]), max(abs(high[i * 3] - close[i * 3 + 1]), abs(low[i * 3] - close[i * 3 + 1]))) : 
           timeframe.period == "240" ? 
           max(abs(high[i * 2] - low[i * 2]), max(abs(high[i * 2] - close[i * 2 + 1]), abs(low[i * 2] - close[i * 2 + 1]))) : 
           timeframe.period == "D" ? 
           max(abs(high[i * 5] - low[i * 5]), max(abs(high[i * 5] - close[i * 5 + 1]), abs(low[i * 5] - close[i * 5 + 1]))) : 
           timeframe.period == "W" ? 
           max(abs(high[i * 4] - low[i * 4]), max(abs(high[i * 4] - close[i * 4 + 1]), abs(low[i * 4] - close[i * 4 + 1]))) : 
           0)
        totalRange
    if type == "Futures"
        totalRange := totalRange + (timeframe.period == "1" ? 0 : 
           timeframe.period == "3" ? 0 : timeframe.period == "5" ? 
           max(abs(high[i * 273] - low[i * 273]), max(abs(high[i * 273] - close[i * 273 + 1]), abs(low[i * 273] - close[i * 273 + 1]))) : 
           timeframe.period == "15" ? 
           max(abs(high[i * 91] - low[i * 91]), max(abs(high[i * 91] - close[i * 91 + 1]), abs(low[i * 91] - close[i * 91 + 1]))) : 
           timeframe.period == "30" ? 
           max(abs(high[i * 46] - low[i * 13]), max(abs(high[i * 46] - close[i * 46 + 1]), abs(low[i * 46] - close[i * 46 + 1]))) : 
           timeframe.period == "45" ? 
           max(abs(high[i * 32] - low[i * 31]), max(abs(high[i * 31] - close[i * 31 + 1]), abs(low[i * 31] - close[i * 31 + 1]))) : 
           timeframe.period == "60" ? 
           max(abs(high[i * 24] - low[i * 23]), max(abs(high[i * 23] - close[i * 23 + 1]), abs(low[i * 23] - close[i * 23 + 1]))) : 
           timeframe.period == "120" ? 
           max(abs(high[i * 12] - low[i * 12]), max(abs(high[i * 12] - close[i * 12 + 1]), abs(low[i * 12] - close[i * 12 + 1]))) : 
           timeframe.period == "180" ? 
           max(abs(high[i * 8] - low[i * 3]), max(abs(high[i * 8] - close[i * 8 + 1]), abs(low[i * 8] - close[i * 8 + 1]))) : 
           timeframe.period == "240" ? 
           max(abs(high[i * 6] - low[i * 6]), max(abs(high[i * 6] - close[i * 6 + 1]), abs(low[i * 6] - close[i * 6 + 1]))) : 
           timeframe.period == "D" ? 
           max(abs(high[i * 4] - low[i * 4]), max(abs(high[i * 4] - close[i * 4 + 1]), abs(low[i * 4] - close[i * 4 + 1]))) : 
           timeframe.period == "W" ? 
           max(abs(high[i * 4] - low[i * 4]), max(abs(high[i * 4] - close[i * 4 + 1]), abs(low[i * 4] - close[i * 4 + 1]))) : 
           0)
        totalRange

// Convert average range to whole number
avgRangePips = totalRange / lookback
rma_1 = rma(avgRangePips, rmaLength)
avgRangePips := useRMA1 ? rma_1 : avgRangePips
avgRange = avgRangePips

atrV = atr(rmaLength)
longStopRegATR = (useStructure ? lowest(low, lookbackStructure) : close) - atrV * atrMultiplier
shortStopRegATR = (useStructure ? highest(high, lookbackStructure) : close) + atrV * atrMultiplier
longStopByTime = (useStructure ? lowest(low, lookbackStructure) : close) - avgRangePips * atrMultiplier
shortStopByTime = (useStructure ? highest(high, lookbackStructure) : close) + avgRangePips * atrMultiplier
longStop = longStopRegATR
shortStop = shortStopRegATR

if useType == "ATR By Time"
    longStop := longStopByTime
    shortStop := shortStopByTime
if useType == "Smallest ATR"
    longStop := longStopByTime > longStopRegATR ? longStopByTime : longStopRegATR
    shortStop := shortStopByTime < shortStopRegATR ? shortStopByTime : shortStopRegATR
if useType == "Largest ATR"
    longStop := longStopByTime < longStopRegATR ? longStopByTime : longStopRegATR
    shortStop := shortStopByTime > shortStopRegATR ? shortStopByTime : shortStopRegATR

// Convert to whole numbers
if decimals == 8 and convertToWhole
    avgRange := avgRangePips * 10000000
if decimals == 7 and convertToWhole
    avgRange := avgRangePips * 1000000
if decimals == 6 and convertToWhole
    avgRange := avgRangePips * 100000
if decimals == 5 and convertToWhole
    avgRange := avgRangePips * 10000
if decimals == 4 and convertToWhole
    avgRange := avgRangePips * 1000
if decimals == 3 and convertToWhole
    avgRange := avgRangePips * 100
if decimals == 2 and convertToWhole
    avgRange := avgRangePips * 10

// Calculate ATR percentage
rangePercent = currentRange / avgRange

// Determine if this candle exceeds the average
alert = currentRange > avgRange and alertPercent == 0.0 or 
   alertPercent != 0.0 and currentRange > alertPercent

// Determine ATR bar color
barColor = color.gray

// Heatmap Color Scheme
if barColorOption == "Heatmap" and rangePercent >= 0.25
    barColor := #005000
if barColorOption == "Heatmap" and rangePercent >= 0.50
    barColor := #007000
if barColorOption == "Heatmap" and rangePercent >= 0.75
    barColor := #009900
if barColorOption == "Heatmap" and rangePercent >= 1.0
    barColor := #00dd00
if barColorOption == "Heatmap" and rangePercent >= 2.0
    barColor := #00ff00

// Traffic Light Color Scheme
if barColorOption == "Traffic" and rangePercent >= 0.5
    barColor := #ff1d00
if barColorOption == "Traffic" and rangePercent >= 0.75
    barColor := #ff7f00
if barColorOption == "Traffic" and rangePercent >= 1.0
    barColor := #008000
if barColorOption == "Traffic" and rangePercent >= 2.0
    barColor := #00ff00

// Trigger Color Scheme
if barColorOption == "Trigger"
    barColor := alert ? color.teal : color.gray
// Colored Scheme
if barColorOption == "Price" and close >= open
    barColor := #5cbcb3
if barColorOption == "Price" and close < open
    barColor := #f37e7c
// Colored Scheme
if alertPercent != 0.0 and rangePercent >= alertPercent
    barColor := color.teal

// Draw data
plot(avgRange, style=plot.style_columns, color=color.gray, title="Average Range Bars", transp=50, linewidth=1)
plot(currentRange, style=plot.style_columns, color=barColor, title="Current Range Bars", transp=0, linewidth=1)
rma_2 = rma(avgRange, rmaLength)
plot(useRMA0 ? rma_2 : avgRange, style=plot.style_line, color=color.purple, title="Average Range Line", transp=0, linewidth=1)
plot(drawATR ? atr : na, style=plot.style_line, color=#ff6d00, title="Regular ATR Line", transp=0)
plot(rangePercent, style=plot.style_line, color=color.blue, title="Percentage", transp=100)
plot(longStop, color=color.green, title="Long Stop Price", display=display.none, transp=0)
plot(shortStop, color=color.red, title="Short Stop Price", display=display.none, transp=0)

// Send out an alert if this candle meets our conditions
alertcondition(alert, title="ART Alert!", message="Average Range signal for {{ticker}}")


Companion Source Code:

// @version=4
// ATR+ Stop Loss Indicator v1.0
// Created by Matthew J. Slabosz
// Last Updated: 8th September, 2020
// www.zenandtheartoftrading.com
study("ATR By Time [Chart]", "ATR By Time Stop", overlay=true)

// Get inputs
type = input(title="Market", defval='Forex', type=input.string, options=['Stocks', 'Forex', 'Crypto', 'Futures'])
lookback = input(title="Lookback Sessions", type=input.integer, defval=5)
atrLength = input(title="ATR Length", type=input.integer, defval=14, minval=1)
useRMA = input(title="Use RMA?", type=input.bool, defval=false)
rmaLength = input(title="RMA Length", defval=14, type=input.integer)
useStructure = input(title="Use Structure?", type=input.bool, defval=true)
lookbackStructure = input(title="How Far To Look Back For High/Lows", type=input.integer, defval=7, minval=1)
atrMultiplier = input(title="ATR Multiplier", type=input.float, defval=1.0, minval=0.1)
useType = input(title="Stop Type", defval='ATR By Time', type=input.string, options=['ATR By Time', 'Regular ATR', 'Smallest ATR', 'Largest ATR'])

// Get order/tick volume data
totalRange = close - close
for i = 1 to lookback by 1
    if type == "Forex"
        totalRange := totalRange + (timeframe.period == "1" ? 0 : 
           timeframe.period == "3" ? 0 : timeframe.period == "5" ? 
           max(abs(high[i * 288] - low[i * 288]), max(abs(high[i * 288] - close[i * 288 + 1]), abs(low[i * 288] - close[i * 288 + 1]))) : 
           timeframe.period == "15" ? 
           max(abs(high[i * 96] - low[i * 96]), max(abs(high[i * 96] - close[i * 96 + 1]), abs(low[i * 96] - close[i * 96 + 1]))) : 
           timeframe.period == "30" ? 
           max(abs(high[i * 48] - low[i * 13]), max(abs(high[i * 48] - close[i * 48 + 1]), abs(low[i * 48] - close[i * 48 + 1]))) : 
           timeframe.period == "45" ? 
           max(abs(high[i * 32] - low[i * 32]), max(abs(high[i * 32] - close[i * 32 + 1]), abs(low[i * 32] - close[i * 32 + 1]))) : 
           timeframe.period == "60" ? 
           max(abs(high[i * 24] - low[i * 24]), max(abs(high[i * 24] - close[i * 24 + 1]), abs(low[i * 24] - close[i * 24 + 1]))) : 
           timeframe.period == "120" ? 
           max(abs(high[i * 12] - low[i * 12]), max(abs(high[i * 12] - close[i * 12 + 1]), abs(low[i * 12] - close[i * 12 + 1]))) : 
           timeframe.period == "180" ? 
           max(abs(high[i * 8] - low[i * 3]), max(abs(high[i * 8] - close[i * 8 + 1]), abs(low[i * 8] - close[i * 8 + 1]))) : 
           timeframe.period == "240" ? 
           max(abs(high[i * 6] - low[i * 6]), max(abs(high[i * 6] - close[i * 6 + 1]), abs(low[i * 6] - close[i * 6 + 1]))) : 
           timeframe.period == "D" ? 
           max(abs(high[i * 5] - low[i * 5]), max(abs(high[i * 5] - close[i * 5 + 1]), abs(low[i * 5] - close[i * 5 + 1]))) : 
           timeframe.period == "W" ? 
           max(abs(high[i * 4] - low[i * 4]), max(abs(high[i * 4] - close[i * 4 + 1]), abs(low[i * 4] - close[i * 4 + 1]))) : 
           0)
    if type == "Crypto"
        totalRange := totalRange + (timeframe.period == "1" ? 0 : 
           timeframe.period == "3" ? 0 : timeframe.period == "5" ? 
           max(abs(high[i * 288] - low[i * 288]), max(abs(high[i * 288] - close[i * 288 + 1]), abs(low[i * 288] - close[i * 288 + 1]))) : 
           timeframe.period == "15" ? 
           max(abs(high[i * 96] - low[i * 96]), max(abs(high[i * 96] - close[i * 96 + 1]), abs(low[i * 96] - close[i * 96 + 1]))) : 
           timeframe.period == "30" ? 
           max(abs(high[i * 48] - low[i * 13]), max(abs(high[i * 48] - close[i * 48 + 1]), abs(low[i * 48] - close[i * 48 + 1]))) : 
           timeframe.period == "45" ? 
           max(abs(high[i * 32] - low[i * 32]), max(abs(high[i * 32] - close[i * 32 + 1]), abs(low[i * 32] - close[i * 32 + 1]))) : 
           timeframe.period == "60" ? 
           max(abs(high[i * 24] - low[i * 24]), max(abs(high[i * 24] - close[i * 24 + 1]), abs(low[i * 24] - close[i * 24 + 1]))) : 
           timeframe.period == "120" ? 
           max(abs(high[i * 12] - low[i * 12]), max(abs(high[i * 12] - close[i * 12 + 1]), abs(low[i * 12] - close[i * 12 + 1]))) : 
           timeframe.period == "180" ? 
           max(abs(high[i * 8] - low[i * 3]), max(abs(high[i * 8] - close[i * 8 + 1]), abs(low[i * 8] - close[i * 8 + 1]))) : 
           timeframe.period == "240" ? 
           max(abs(high[i * 6] - low[i * 6]), max(abs(high[i * 6] - close[i * 6 + 1]), abs(low[i * 6] - close[i * 6 + 1]))) : 
           timeframe.period == "D" ? 
           max(abs(high[i * 7] - low[i * 7]), max(abs(high[i * 7] - close[i * 7 + 1]), abs(low[i * 7] - close[i * 7 + 1]))) : 
           timeframe.period == "W" ? 
           max(abs(high[i * 4] - low[i * 4]), max(abs(high[i * 4] - close[i * 4 + 1]), abs(low[i * 4] - close[i * 4 + 1]))) : 
           0)
    if type == "Stocks"
        totalRange := totalRange + (timeframe.period == "1" ? 0 : 
           timeframe.period == "3" ? 0 : timeframe.period == "5" ? 
           max(abs(high[i * 78] - low[i * 78]), max(abs(high[i * 78] - close[i * 78 + 1]), abs(low[i * 78] - close[i * 78 + 1]))) : 
           timeframe.period == "15" ? 
           max(abs(high[i * 26] - low[i * 26]), max(abs(high[i * 26] - close[i * 26 + 1]), abs(low[i * 26] - close[i * 26 + 1]))) : 
           timeframe.period == "30" ? 
           max(abs(high[i * 13] - low[i * 13]), max(abs(high[i * 13] - close[i * 13 + 1]), abs(low[i * 13] - close[i * 13 + 1]))) : 
           timeframe.period == "45" ? 
           max(abs(high[i * 9] - low[i * 9]), max(abs(high[i * 9] - close[i * 9 + 1]), abs(low[i * 9] - close[i * 9 + 1]))) : 
           timeframe.period == "60" ? 
           max(abs(high[i * 7] - low[i * 7]), max(abs(high[i * 7] - close[i * 7 + 1]), abs(low[i * 7] - close[i * 7 + 1]))) : 
           timeframe.period == "120" ? 
           max(abs(high[i * 4] - low[i * 4]), max(abs(high[i * 4] - close[i * 4 + 1]), abs(low[i * 4] - close[i * 4 + 1]))) : 
           timeframe.period == "180" ? 
           max(abs(high[i * 3] - low[i * 3]), max(abs(high[i * 3] - close[i * 3 + 1]), abs(low[i * 3] - close[i * 3 + 1]))) : 
           timeframe.period == "240" ? 
           max(abs(high[i * 2] - low[i * 2]), max(abs(high[i * 2] - close[i * 2 + 1]), abs(low[i * 2] - close[i * 2 + 1]))) : 
           timeframe.period == "D" ? 
           max(abs(high[i * 5] - low[i * 5]), max(abs(high[i * 5] - close[i * 5 + 1]), abs(low[i * 5] - close[i * 5 + 1]))) : 
           timeframe.period == "W" ? 
           max(abs(high[i * 4] - low[i * 4]), max(abs(high[i * 4] - close[i * 4 + 1]), abs(low[i * 4] - close[i * 4 + 1]))) : 
           0)
    if type == "Futures"
        totalRange := totalRange + (timeframe.period == "1" ? 0 : 
           timeframe.period == "3" ? 0 : timeframe.period == "5" ? 
           max(abs(high[i * 273] - low[i * 273]), max(abs(high[i * 273] - close[i * 273 + 1]), abs(low[i * 273] - close[i * 273 + 1]))) : 
           timeframe.period == "15" ? 
           max(abs(high[i * 91] - low[i * 91]), max(abs(high[i * 91] - close[i * 91 + 1]), abs(low[i * 91] - close[i * 91 + 1]))) : 
           timeframe.period == "30" ? 
           max(abs(high[i * 46] - low[i * 13]), max(abs(high[i * 46] - close[i * 46 + 1]), abs(low[i * 46] - close[i * 46 + 1]))) : 
           timeframe.period == "45" ? 
           max(abs(high[i * 32] - low[i * 31]), max(abs(high[i * 31] - close[i * 31 + 1]), abs(low[i * 31] - close[i * 31 + 1]))) : 
           timeframe.period == "60" ? 
           max(abs(high[i * 24] - low[i * 23]), max(abs(high[i * 23] - close[i * 23 + 1]), abs(low[i * 23] - close[i * 23 + 1]))) : 
           timeframe.period == "120" ? 
           max(abs(high[i * 12] - low[i * 12]), max(abs(high[i * 12] - close[i * 12 + 1]), abs(low[i * 12] - close[i * 12 + 1]))) : 
           timeframe.period == "180" ? 
           max(abs(high[i * 8] - low[i * 3]), max(abs(high[i * 8] - close[i * 8 + 1]), abs(low[i * 8] - close[i * 8 + 1]))) : 
           timeframe.period == "240" ? 
           max(abs(high[i * 6] - low[i * 6]), max(abs(high[i * 6] - close[i * 6 + 1]), abs(low[i * 6] - close[i * 6 + 1]))) : 
           timeframe.period == "D" ? 
           max(abs(high[i * 4] - low[i * 4]), max(abs(high[i * 4] - close[i * 4 + 1]), abs(low[i * 4] - close[i * 4 + 1]))) : 
           timeframe.period == "W" ? 
           max(abs(high[i * 4] - low[i * 4]), max(abs(high[i * 4] - close[i * 4 + 1]), abs(low[i * 4] - close[i * 4 + 1]))) : 
           0)

// Convert average range to whole number
avgRangePips = totalRange / lookback
rma_1 = rma(avgRangePips, rmaLength)
avgRangePips := useRMA ? rma_1 : avgRangePips

// Calculate stop loss
atr = atr(atrLength)
longStopRegATR = (useStructure ? lowest(low, lookbackStructure) : close) - atr * atrMultiplier
shortStopRegATR = (useStructure ? highest(high, lookbackStructure) : close) + atr * atrMultiplier
longStopByTime = (useStructure ? lowest(low, lookbackStructure) : close) - avgRangePips * atrMultiplier
shortStopByTime = (useStructure ? highest(high, lookbackStructure) : close) + avgRangePips * atrMultiplier
longStop = longStopRegATR
shortStop = shortStopRegATR

if useType == "ATR By Time"
    longStop := longStopByTime
    shortStop := shortStopByTime
if useType == "Smallest ATR"
    longStop := longStopByTime > longStopRegATR ? longStopByTime : longStopRegATR
    shortStop := shortStopByTime < shortStopRegATR ? shortStopByTime : shortStopRegATR
if useType == "Largest ATR"
    longStop := longStopByTime < longStopRegATR ? longStopByTime : longStopRegATR
    shortStop := shortStopByTime > shortStopRegATR ? shortStopByTime : shortStopRegATR

// Plot data
plot(atr, color=color.blue, title="ATR", transp=100)
plot(longStop, color=color.green, style=plot.style_linebr, title="Long Trailing Stop", transp=0)
plot(shortStop, color=color.red, style=plot.style_linebr, title="Short Trailing Stop", transp=0)

Last Updated: 8th September, 2020


Free Premium Charts!

5 1 vote
Article Rating
Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments