Referencing Lower Timeframes

This lesson demonstrates how to access lower timeframe data using Pine Script. Specifically, in today's tutorial we are going to use arrays to reference the past 10 day's worth of ATR values on the Weekly and Monthly charts - but this technique works on all timeframes.

Check out my other free lessons!

Source Code

// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © ZenAndTheArtOfTrading
// @version=5
indicator("PSMC - Lower Timeframe Dayta")

// Get user input
int i_Lookback = input.int(title="Lookback", defval=10)
string i_Period = input.timeframe(title="Lower Timeframe", defval="D")

// Define custom function for safely retrieving array values without index OOB errors
getArrayValue(float[] array, int idx) =>
    if array.size(array) > idx
        array.get(array, idx)
    else
        na

// Get ATR value expression (for passing to security() function)
float atrValue = ta.atr(14)
plot(atrValue, color=color.new(color.purple, 100))

// Get lower timeframe dayta
float[] LtfATR_Array = request.security_lower_tf(syminfo.tickerid, i_Period, atrValue)
float[] LtfClosingPrice_Array = request.security_lower_tf(syminfo.tickerid, i_Period, close)

// Define our merged ATR values array
var float[] ATR_Array = array.new_float(i_Lookback, 0)
var float[] ClosingPrice_Array = array.new_float(i_Lookback, 0)

// If current timeframe is the reference timeframe, we don't need to reference LTF data
if timeframe.period == i_Period
    for i = 0 to array.size(ATR_Array) - 1
        array.set(ATR_Array, i, atrValue[i]) // Set each array index with the corresponding historical value
        array.set(ClosingPrice_Array, i, close[i])
    array.reverse(ATR_Array) // Reverse array to be consistent with HTF array population handled below
    array.reverse(ClosingPrice_Array)
else // Populate our ATR array
    if array.size(LtfATR_Array) > 0
        for i = 0 to array.size(LtfATR_Array) - 1
            array.shift(ATR_Array) // Remove the array's first element
            array.push(ATR_Array, array.get(LtfATR_Array, i)) // Insert a new array element (FIFO)
            array.shift(ClosingPrice_Array) 
            array.push(ClosingPrice_Array, array.get(LtfClosingPrice_Array, i))

// Draw the past 10 days ATR values
plot(getArrayValue(ATR_Array, 0))
plot(getArrayValue(ATR_Array, 1))
plot(getArrayValue(ATR_Array, 2))
plot(getArrayValue(ATR_Array, 3))
plot(getArrayValue(ATR_Array, 4))
plot(getArrayValue(ATR_Array, 5))
plot(getArrayValue(ATR_Array, 6))
plot(getArrayValue(ATR_Array, 7))
plot(getArrayValue(ATR_Array, 8))
plot(getArrayValue(ATR_Array, 9))

// For debug purposes
string debugStr = ""
for i = 0 to array.size(ClosingPrice_Array) - 1
    debugStr := debugStr + str.tostring(getArrayValue(ClosingPrice_Array, i), "#.##") + ", "

var table debugDisplay = table.new(position.top_right, 1, 1)
if barstate.islast
    atrPercent = (getArrayValue(ATR_Array, array.size(ATR_Array) - 1) / getArrayValue(ClosingPrice_Array, array.size(ClosingPrice_Array) - 1)) * 100
    table.cell(debugDisplay, 0, 0, str.tostring(atrPercent), text_color=color.lime)
    //table.cell(debugDisplay, 0, 0, debugStr, text_color=color.lime)