// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © millerrh
//@version=5
// Revision 2 - Optimizing the code for improved speed (with some help from @RozaniGhani-RG), allowing the user to control which timeframes to look at,
// and moving indicator to table so I can use a mutable variable to indicate which timeframe the user selected.
// Revision 3 - More speed optimization to limit the # of security calls. Allow for abiilty for user to reposition the table.
// Revision 4 - Added ability to choose between close or high for pivot.
// This indicator identifies trends in multiple higher timeframes and shows them in a widget off to the right of the chart.
// It's meant to be used as an alternative filter for "trading with the trend." Typically people use moving averages of varying lengths for this
// (i.e. if over 200 MA it's an uptrend, etc.), but I wanted to see if it might be more effective to see if the higher timeframes were actually
// trending or not in a certain direction.
// For the purposes of this indicator, an uptrend is defined as higher highs and higher lows. So if currently in a downtrend and the highs are broken,
// the indicator will flip to an uptrend because now we have a higher high. Vice versa for downtrends.
// The user can choose the lookback period for defining these highs/lows (the pivot points). A smaller lookback number will give you more frequent pivot points.
// The user can toggle on visibility of all historical pivot points to make sure the frequency and placement of the swing highs/lows is to their liking.
// The user can show the support/resistance lines of those most recent swing high/low points on the multiple timeframes as well.
// When these lines are breached, that is when the trends change, so you can see if you are close to changing any longer term trends.
indicator('MTF Trend Table', overlay=true)
// == USER INPUT ==
tableLocation = input.string(defval='Top', options=['Top', 'Bottom'], title='Info Table Location', group='Display',
tooltip='Place information table on the top of the pane or the bottom of the pane.')
lookback = input.int(defval=3, title='Pivot Lookback Period', group='Pivot Points',
tooltip='Looks for pivot points within this number of bars both left and right.')
pivotType = input.string(defval = "High/Low", title = "Pivot Type", options = ["High/Low","Close"], group = 'Pivot Points',
tooltip = 'Choose whether the high/low or close is used for pivot points and trend calcuations.')
showPivotPoints = input.bool(title='Show Historical Pivot Points?', defval=false, group='Pivot Points',
tooltip='Toggle this on to see the historical pivot points that were used. Change the Lookback Period to adjust the
frequency of these points. The pivot points are only shown for the current chart timeframe - to see the Daily pivot pionts, use the Daily timeframe, etc.')
oneSet = input.timeframe(defval='240', title='First Timeframe', group='Higher Timeframe Levels',
tooltip='Allows you to set different time frames for looking at the trend. Important: Does not work for lower timeframes than the current
chart timeframe.')
twoSet = input.timeframe(defval='D', title='Second Timeframe', group='Higher Timeframe Levels')
threeSet = input.timeframe(defval='W', title='Third Timeframe', group='Higher Timeframe Levels')
fourSet = input.timeframe(defval='M', title='Fourth Timeframe', group='Higher Timeframe Levels')
showMTFLevels = input.bool(title='Show Multiple Timeframe S/R Levels?', defval=true, group='Higher Timeframe Levels',
tooltip='Displays the pivot highs and lows of higher timeframes to use as support/resistance levels. When these levels break,
the trend will change on these higher timeframes.')
oneColorS = input.color(color.new(color.orange, 50), title='1st Timeframe Support', group='Higher Timeframe Levels', inline='MTF1')
oneColorR = input.color(color.new(color.orange, 50), title=' Resistance', group='Higher Timeframe Levels', inline='MTF1')
twoColorS = input.color(color.new(color.blue, 50), title='2nd Timeframe Support', group='Higher Timeframe Levels', inline='MTF2')
twoColorR = input.color(color.new(color.blue, 50), title=' Resistance', group='Higher Timeframe Levels', inline='MTF2')
threeColorS = input.color(color.new(color.white, 50), title='3rd Timeframe Support', group='Higher Timeframe Levels', inline='MTF3')
threeColorR = input.color(color.new(color.white, 50), title=' Resistance', group='Higher Timeframe Levels', inline='MTF3')
fourColorS = input.color(color.new(color.red, 50), title='4th Timeframe Support', group='Higher Timeframe Levels', inline='MTF4')
fourColorR = input.color(color.new(color.red, 50), title=' Resistance', group='Higher Timeframe Levels', inline='MTF4')
levelWidth = input.int(defval=1, title='Line Width (pixels)', group='Higher Timeframe Levels')
// == DEFINE FUNCTIONS FOR USE IN MULTIPLE TIMEFRAMES (USING A TUPLE TO AVOID SO MANY SECURITY CALLS) ==
f_getHTF() =>
var float ph = na, float pl = na, float highLevel = na, float lowLevel = na
if pivotType == "Close"
ph := ta.pivothigh(close, lookback, lookback)
pl := ta.pivotlow(close, lookback, lookback)
highLevel := ta.valuewhen(ph, close[lookback], 0)
lowLevel := ta.valuewhen(pl, close[lookback], 0)
else
ph := ta.pivothigh(high, lookback, lookback)
pl := ta.pivotlow(low, lookback, lookback)
highLevel := ta.valuewhen(ph, high[lookback], 0)
lowLevel := ta.valuewhen(pl, low[lookback], 0)
barsSinceHigh = ta.barssince(ph) + lookback
barsSinceLow = ta.barssince(pl) + lookback
timeSinceHigh = time[barsSinceHigh]
timeSinceLow = time[barsSinceLow]
[ph, pl, highLevel, lowLevel, barsSinceHigh, barsSinceLow, timeSinceHigh, timeSinceLow]
[ph_01, pl_01, hL_01, lL_01, bsSH_01, bsSL_01, tSH_01, tSL_01] = request.security(syminfo.tickerid, oneSet, f_getHTF())
[ph_02, pl_02, hL_02, lL_02, bsSH_02, bsSL_02, tSH_02, tSL_02] = request.security(syminfo.tickerid, twoSet, f_getHTF())
[ph_03, pl_03, hL_03, lL_03, bsSH_03, bsSL_03, tSH_03, tSL_03] = request.security(syminfo.tickerid, threeSet, f_getHTF())
[ph_04, pl_04, hL_04, lL_04, bsSH_04, bsSL_04, tSH_04, tSL_04] = request.security(syminfo.tickerid, fourSet, f_getHTF())
// Check to ensure boxes are all higher timeframe than the chart to remove glyph and gray out box if that's the case
tfInMinutes(simple string tf = "") =>
float chartTf =
timeframe.multiplier * (
timeframe.isseconds ? 1. / 60 :
timeframe.isminutes ? 1. :
timeframe.isdaily ? 60. * 24 :
timeframe.isweekly ? 60. * 24 * 7 :
timeframe.ismonthly ? 60. * 24 * 30.4375 : na)
float result = tf == "" ? chartTf : request.security(syminfo.tickerid, tf, chartTf)
float chartTFInMinutes = tfInMinutes()
bool TF1Check = tfInMinutes(oneSet) < chartTFInMinutes
bool TF2Check = tfInMinutes(twoSet) < chartTFInMinutes
bool TF3Check = tfInMinutes(threeSet) < chartTFInMinutes
bool TF4Check = tfInMinutes(fourSet) < chartTFInMinutes
// Current timeframe pivots
var float phC = na, float plC = na
if pivotType == "High/Low"
phC := ta.pivothigh(high, lookback, lookback)
plC := ta.pivotlow(low, lookback, lookback)
else
phC := ta.pivothigh(close, lookback, lookback)
plC := ta.pivotlow(close, lookback, lookback)
// Plot historical pivot points for debugging and configuring the lookback period.
plot(showPivotPoints ? phC : na, style=plot.style_cross, linewidth=3, color=color.new(color.yellow, 50), offset=-lookback)
plot(showPivotPoints ? plC : na, style=plot.style_cross, linewidth=3, color=color.new(color.yellow, 50), offset=-lookback)
// == PLOT SUPPORT/RESISTANCE LINES ON THE HIGHER TIMEFRAMES ==
// Use a function to define the lines
f_line(x1, y1, y2, _color) =>
var line id = na
line.delete(id)
id := line.new(x1, y1, time, y2, xloc.bar_time, extend.right, _color, width=levelWidth)
id
// 1st Timeframe
highLine1 = TF1Check ? na : showMTFLevels ? f_line(tSH_01, hL_01, hL_01, oneColorR) : na
lowLine1 = TF1Check ? na : showMTFLevels ? f_line(tSL_01, lL_01, lL_01, oneColorS) : na
// 2nd Timeframe
highLine2 = TF2Check ? na : showMTFLevels ? f_line(tSH_02, hL_02, hL_02, twoColorR) : na
lowLine2 = TF2Check ? na : showMTFLevels ? f_line(tSL_02, lL_02, lL_02, twoColorS) : na
// 3rd Timeframe
highLine3 = TF3Check ? na : showMTFLevels ? f_line(tSH_03, hL_03, hL_03, threeColorR) : na
lowLine3 = TF3Check ? na : showMTFLevels ? f_line(tSL_03, lL_03, lL_03, threeColorS) : na
// 4th Timeframe
highLine4 = TF3Check ? na : showMTFLevels ? f_line(tSH_04, hL_04, hL_04, fourColorR) : na
lowLine4 = TF3Check ? na : showMTFLevels ? f_line(tSL_04, lL_04, lL_04, fourColorS) : na
// == TREND CALCULATIONS (USING A TUPLE TO CONSOLIDATE REPETATIVE CODE AND GENERATE MULTIPE VARIABLES WITH ONE FUNCTION ==
f_signal(highLevel, lowLevel) =>
uptrendSignal = high > highLevel
downtrendSignal = low < lowLevel
inUptrend = bool(na)
inDowntrend = bool(na)
inUptrend := uptrendSignal[1] ? true : downtrendSignal[1] ? false : inUptrend[1]
inDowntrend := not inUptrend
[uptrendSignal, downtrendSignal, inUptrend, inDowntrend]
[uptrendSignal1, downtrendSignal1, inUptrend1, inDowntrend1] = f_signal(hL_01, lL_01) // 1st Timeframe
[uptrendSignal2, downtrendSignal2, inUptrend2, inDowntrend2] = f_signal(hL_02, lL_02) // 2nd Timeframe
[uptrendSignal3, downtrendSignal3, inUptrend3, inDowntrend3] = f_signal(hL_03, lL_03) // 3rd Timeframe
[uptrendSignal4, downtrendSignal4, inUptrend4, inDowntrend4] = f_signal(hL_04, lL_04) // 3rd Timeframe
// == TREND TABLE PLOTTING ==
tablePos = tableLocation == 'Top' ? position.top_right : position.bottom_right
var table trendTable = table.new(tablePos, 4, 1, border_width=3)
upColor = color.rgb(38, 166, 154)
downColor = color.rgb(240, 83, 80)
tfColor = color.new(#999999, 0)
f_fillCell(_column, _row, _cellText, _c_color) =>
table.cell(trendTable, _column, _row, _cellText, bgcolor=color.new(_c_color, 70), text_color=_c_color, width=6)
// Define glyphs
glyph1 = TF1Check ? na : inUptrend1 ? '▲ ': '▼ '
glyph2 = TF2Check ? na : inUptrend2 ? '▲ ': '▼ '
glyph3 = TF3Check ? na : inUptrend3 ? '▲ ': '▼ '
glyph4 = TF4Check ? na : inUptrend3 ? '▲ ': '▼ '
if barstate.islast
f_fillCell(0, 0, glyph1 + oneSet, TF1Check ? tfColor : inUptrend1 ? upColor : downColor)
f_fillCell(1, 0, glyph2 + twoSet, TF2Check ? tfColor : inUptrend2 ? upColor : downColor)
f_fillCell(2, 0, glyph3 + threeSet, TF3Check ? tfColor : inUptrend3 ? upColor : downColor)
f_fillCell(3, 0, glyph4 + fourSet, TF4Check ? tfColor : inUptrend4 ? upColor : downColor)
// CREATE PRICE AND TIMEFRAME LABEL
// THIS DOES NOT SEEM TO BE WORKING!!! NEED TO FIGURE OUT WHY.
// lbl_txt1H = str.tostring(hL_01) + "(" + str.tostring(oneSet) + ")"
// var label label1H = na
// label1H := TF1Check ? na : showMTFLevels ? label.new(bar_index, close, text=lbl_txt1H, yloc=yloc.price, style=label.style_none, textcolor=color.new(color.orange, 50)) : na
// label.set_y(id=label1H, y=hL_01)
// label.delete(label1H)
// lbl_txt1L = str.tostring(lL_01) + "(" + str.tostring(oneSet) + ")"
// var label label1L = na
// label1L := TF1Check ? na : showMTFLevels ? label.new(bar_index, close, text=lbl_txt1L, yloc=yloc.price, style=label.style_none, textcolor=color.new(color.orange, 50)) : na
// label.set_y(id=label1L, y=lL_01)
// label.delete(label1L)
// lbl_txt2H = str.tostring(hL_02) + "(" + str.tostring(twoSet) + ")"
// var label label2H = na
// label2H := TF2Check ? na : showMTFLevels ? label.new(bar_index, close, text=lbl_txt2H, yloc=yloc.price, style=label.style_none, textcolor=color.new(color.orange, 50)) : na
// label.set_y(id=label2H, y=hL_02)
// label.delete(label2H)
// lbl_txt2L = str.tostring(lL_02) + "(" + str.tostring(twoSet) + ")"
// var label label2L = na
// label2L := TF2Check ? na : showMTFLevels ? label.new(bar_index, close, text=lbl_txt2L, yloc=yloc.price, style=label.style_none, textcolor=color.new(color.orange, 50)) : na
// label.set_y(id=label2L, y=lL_02)
// label.delete(label2L)
// lbl_txt3H = str.tostring(hL_03) + "(" + str.tostring(threeSet) + ")"
// var label label3H = na
// label3H := TF3Check ? na : showMTFLevels ? label.new(bar_index, close, text=lbl_txt3H, yloc=yloc.price, style=label.style_none, textcolor=color.new(color.orange, 50)) : na
// label.set_y(id=label3H, y=hL_03)
// label.delete(label3H)
// lbl_txt3L = str.tostring(lL_03) + "(" + str.tostring(threeSet) + ")"
// var label label3L = na
// label3L := TF3Check ? na : showMTFLevels ? label.new(bar_index, close, text=lbl_txt3L, yloc=yloc.price, style=label.style_none, textcolor=color.new(color.orange, 50)) : na
// label.set_y(id=label3L, y=lL_03)
// label.delete(label3L)