ATR By Time Indicator
Table of Contents
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

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