Skip to content

Instantly share code, notes, and snippets.

@faiyaz7283
Last active October 22, 2023 04:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save faiyaz7283/901046b7d902953eca34de0b797e8cca to your computer and use it in GitHub Desktop.
Save faiyaz7283/901046b7d902953eca34de0b797e8cca to your computer and use it in GitHub Desktop.
Watchlist heatmap for Trading View
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © faiyaz7283
//@version=5
indicator(title="Watchlist Heatmap", shorttitle="WL Heatmap", overlay=true)
// ::Imports:: {
import faiyaz7283/tools/9 as tools
import faiyaz7283/printer/6 as prnt
import faiyaz7283/multidata/7 as mltd
// }
// ::Inputs:: {
var section01 = 'POSITION, SIZE & COLORS'
//---------------------:
var displayLoc = input.string(defval = position.top_right, title = 'Display Location', options = [position.top_left,
position.top_center, position.top_right, position.middle_left, position.middle_center, position.middle_right,
position.bottom_left, position.bottom_center, position.bottom_right], group = section01)
var cellPad = input.int(defval = 1, title = 'Cell Spacing', minval = 0, maxval = 5, group = section01)
var orientation = input.string(defval = 'vertical', title = 'Orientation', options = ['horizontal', 'vertical'],
group = section01) == 'vertical' ? false : true
var grdUp = input.color(defval = #00FF00, title = '⬆ Max', inline = 'grdnt', group = section01)
var grdNeutral = input.color(defval = #fff9c4, title = '⮕ Neutral', inline = 'grdnt', group = section01)
var grdDown = input.color(defval = #FF0000, title = '⬇ Min', inline = 'grdnt', group = section01)
var headerColor = input.color(defval = #ffcc80, title = 'Header:\tColor', inline = 'hdrCl', group = section01)
var headerSize = input.string(defval=size.normal, title = 'Size', options = ['hide', size.auto, size.tiny, size.small,
size.normal, size.large, size.huge], inline = 'hdrCl', group = section01)
var headerAlign = input.string(defval=text.align_center, title = 'Align',
options = [text.align_left, text.align_center, text.align_right], inline = 'hdrCl', group = section01)
var titleColor = input.color(defval = #b2ebf2, title = 'Title:\tColor', inline = 'ttlCl', group = section01)
var titleSize = input.string(defval=size.small, title = 'Size', options = ['hide', size.auto, size.tiny, size.small,
size.normal, size.large, size.huge], inline = 'ttlCl', group = section01)
var titleAlign = input.string(defval=text.align_right, title = 'Align',
options = [text.align_left, text.align_center, text.align_right], inline = 'ttlCl', group = section01)
var keySize = input.string(defval=size.auto, title = 'Key:\tSize', options = [size.auto, size.tiny, size.small,
size.normal, size.large, size.huge], inline = 'keyCl', group = section01)
var keyAlign = input.string(defval=text.align_center, title = 'Align',
options = [text.align_left, text.align_center, text.align_right], inline = 'keyCl', group = section01)
var keyOffset = input.string(defval='text', title = 'Key:\tOffset Item', options = ['text', 'background'],
inline = 'keyCl2', group = section01) == 'background' ? 'bg' : 'text'
var keyOffsetColor = input.color(defval = #000000, title = 'Offset Color', inline = 'keyCl2', group = section01)
var textSize = input.string(defval=size.auto, title = 'Value:\tSize', options = [size.auto, size.tiny, size.small,
size.normal, size.large, size.huge], inline = 'valueCl', group = section01)
var textAlign = input.string(defval=text.align_right, title = 'Align',
options = [text.align_left, text.align_center, text.align_right], inline = 'valueCl', group = section01)
var textOffset = input.string(defval='background', title = 'Value:\tOffset Item', options = ['text', 'background'],
inline = 'valueCl2', group = section01) == 'background' ? 'bg' : 'text'
var textOffsetColor = input.color(defval = #00000000, title = 'Offset Color', inline = 'valueCl2', group = section01)
var section02 = 'DATA DISPLAY'
//----------------------------:
var prevTip = "Select this box to exhibit data from the previous bar on the chart's current or custom timeframe."
var prevBar = input.bool(defval = false, title = 'Previous Bar Data', tooltip = prevTip, group = section02)
var showVol = input.bool(defval = true, title = 'Show Volume', inline='vol', group = section02)
var displayValues = input.string(defval ='regular', title = 'Display Data Type', options = ['regular', 'change',
'change percent'], inline='/', group = section02)
var sortByOrder = input.string(defval ='descending', title = 'Sort Order', options = ['descending', 'ascending'],
inline = '-', group = section02)
var asc = sortByOrder == 'ascending' ? true : false
var section03 = 'CUSTOM TIMEFRAME'
//--------------------------------:
var tfNote1 = "Use a custom timeframe, instead of chart's timeframe.\n"
var tfNote2 = tfNote1 + '\nNote: Please ensure that the timeframe used is either equal to or higher than that of the '
var tfNote3 = tfNote2 + 'active chart. Using a lower timeframe is not recommended and will run into memory limitation.'
var tfNote4 = tfNote3 + '\n\nValid Multipliers:\n- Seconds, ONLY use 1, 5, 10, 15 or 30.\n- Minutes, 1 to 1440.'
var tfNote5 = tfNote4 + '\n- Days, 1 to 365.\n- Weeks, 1 to 52.\n- Months, 1 to 12.\n\nCheck Apply box to use.'
var tfMultiplier = input.int(defval = 1, title = 'Multiplier', minval = 1, maxval = 1440, inline = 'tf',
group = section03)
var tfUnits = input.timeframe(defval = 'Days', title = 'Unit', options = ['Seconds', 'Minutes', 'Days', 'Weeks',
'Months'], inline = 'tf', group = section03)
var customTf = input.bool(defval = false, title = 'Apply', tooltip = tfNote5, inline = 'tf', group = section03)
var unit = switch tfUnits
'Seconds' => 'S'
'Minutes' => ''
'Days' => 'D'
'Weeks' => 'W'
'Months' => 'M'
var tf = str.tostring(tfMultiplier) + unit
var section04 = 'WATCHLIST SYMBOLS'
//--------------------------------:
var symbol01 = input.symbol(defval = '', title = '01. ', inline = 'r01', group = section04)
var symbol02 = input.symbol(defval = '', title = '02. ', inline = 'r01', group = section04)
var symbol03 = input.symbol(defval = '', title = '03. ', inline = 'r02', group = section04)
var symbol04 = input.symbol(defval = '', title = '04. ', inline = 'r02', group = section04)
var symbol05 = input.symbol(defval = '', title = '05. ', inline = 'r03', group = section04)
var symbol06 = input.symbol(defval = '', title = '06. ', inline = 'r03', group = section04)
var symbol07 = input.symbol(defval = '', title = '07. ', inline = 'r04', group = section04)
var symbol08 = input.symbol(defval = '', title = '08. ', inline = 'r04', group = section04)
var symbol09 = input.symbol(defval = '', title = '09. ', inline = 'r05', group = section04)
var symbol10 = input.symbol(defval = '', title = '10. ', inline = 'r05', group = section04)
var symbol11 = input.symbol(defval = '', title = '11. ', inline = 'r06', group = section04)
var symbol12 = input.symbol(defval = '', title = '12. ', inline = 'r06', group = section04)
var symbol13 = input.symbol(defval = '', title = '13. ', inline = 'r07', group = section04)
var symbol14 = input.symbol(defval = '', title = '14. ', inline = 'r07', group = section04)
var symbol15 = input.symbol(defval = '', title = '15. ', inline = 'r08', group = section04)
var symbol16 = input.symbol(defval = '', title = '16. ', inline = 'r08', group = section04)
var symbol17 = input.symbol(defval = '', title = '17. ', inline = 'r09', group = section04)
var symbol18 = input.symbol(defval = '', title = '18. ', inline = 'r09', group = section04)
var symbol19 = input.symbol(defval = '', title = '19. ', inline = 'r10', group = section04)
var symbol20 = input.symbol(defval = '', title = '20. ', inline = 'r10', group = section04)
var symbol21 = input.symbol(defval = '', title = '21. ', inline = 'r11', group = section04)
var symbol22 = input.symbol(defval = '', title = '22. ', inline = 'r11', group = section04)
var symbol23 = input.symbol(defval = '', title = '23. ', inline = 'r12', group = section04)
var symbol24 = input.symbol(defval = '', title = '24. ', inline = 'r12', group = section04)
var symbol25 = input.symbol(defval = '', title = '25. ', inline = 'r13', group = section04)
var symbol26 = input.symbol(defval = '', title = '26. ', inline = 'r13', group = section04)
var symbol27 = input.symbol(defval = '', title = '27. ', inline = 'r14', group = section04)
var symbol28 = input.symbol(defval = '', title = '28. ', inline = 'r14', group = section04)
var symbol29 = input.symbol(defval = '', title = '29. ', inline = 'r15', group = section04)
var symbol30 = input.symbol(defval = '', title = '30. ', inline = 'r15', group = section04)
var symbol31 = input.symbol(defval = '', title = '31. ', inline = 'r16', group = section04)
var symbol32 = input.symbol(defval = '', title = '32. ', inline = 'r16', group = section04)
var symbol33 = input.symbol(defval = '', title = '33. ', inline = 'r17', group = section04)
var symbol34 = input.symbol(defval = '', title = '34. ', inline = 'r17', group = section04)
var symbol35 = input.symbol(defval = '', title = '35. ', inline = 'r18', group = section04)
var symbol36 = input.symbol(defval = '', title = '36. ', inline = 'r18', group = section04)
var symbol37 = input.symbol(defval = '', title = '37. ', inline = 'r19', group = section04)
var symbol38 = input.symbol(defval = '', title = '38. ', inline = 'r19', group = section04)
var symbol39 = input.symbol(defval = '', title = '39. ', inline = 'r20', group = section04)
var symbol40 = input.symbol(defval = '', title = '40. ', inline = 'r20', group = section04)
var smblNote1 = 'Please note that once selected, symbols cannot be entirely removed from this form; '
var smblNote2 = smblNote1 + 'they can only be replaced with other symbols. To remove one or more symbols, you have two '
var smblNote3 = smblNote2 + 'options: either click \"reset settings\" or utilize this feature to exhibit the total '
var smblNote4 = smblNote3 + 'desired number of symbols, regardless of the existing count on the watchlist form.'
var totSym = input.int(defval = 40, title = 'How many watchlist symbols to display?', minval = 0, maxval = 40,
tooltip = smblNote4, group = section04)
// }
// ::Functions:: {
displayTf() =>
mp = customTf ? tfMultiplier : timeframe.multiplier
ut = customTf ? unit : timeframe.period
_multiplier = str.format('{0}{1} ', (prevBar ? 'Previous ' : ''), mp)
_unit = switch
str.endswith(ut, "S") =>
mp == 1 ? 'Second' : 'Seconds'
str.endswith(ut, "D") =>
mp == 1 ? 'Day' : 'Days'
str.endswith(ut, "W") =>
mp == 1 ? 'Week' : 'Weeks'
str.endswith(ut, "M") =>
mp == 1 ? 'Month' : 'Months'
=>
mp == 1 ? 'Minute' : 'Minutes'
_multiplier + _unit
displayValues() =>
switch displayValues
'regular' => na
'change' => 'change_format'
'change percent' => 'change_percent_format'
getKv(simple string ticker) =>
t = customTf ? tf : ''
p = prevBar ? 1 : 0
key = syminfo.ticker(ticker)
tckr = ticker.new(syminfo.prefix(ticker), key, syminfo.session)
[cl, cl1, vl, vl1] = request.security(tckr, t,[close[p], close[p + 1], volume[p], volume[p + 1]],
ignore_invalid_symbol=true)
cls = mltd.kv(key, cl, cl1, format='{0,number,currency}')
vol = mltd.kv(key, vl, vl1, format=tools.numCompact(vl), changeFormat=tools.numCompact(vl-vl1))
[cls, vol]
// }
if barstate.islast
// ::Data:: {
closeSymbols = array.new<mltd.kv>()
volumeSymbols = array.new<mltd.kv>()
if tools._bool(symbol01) and totSym >= 1
[_close, _vol] = getKv(symbol01)
closeSymbols.push(_close)
volumeSymbols.push(_vol)
if tools._bool(symbol02) and totSym >= 2
[_close, _vol] = getKv(symbol02)
closeSymbols.push(_close)
volumeSymbols.push(_vol)
if tools._bool(symbol03) and totSym >= 3
[_close, _vol] = getKv(symbol03)
closeSymbols.push(_close)
volumeSymbols.push(_vol)
if tools._bool(symbol04) and totSym >= 4
[_close, _vol] = getKv(symbol04)
closeSymbols.push(_close)
volumeSymbols.push(_vol)
if tools._bool(symbol05) and totSym >= 5
[_close, _vol] = getKv(symbol05)
closeSymbols.push(_close)
volumeSymbols.push(_vol)
if tools._bool(symbol06) and totSym >= 6
[_close, _vol] = getKv(symbol06)
closeSymbols.push(_close)
volumeSymbols.push(_vol)
if tools._bool(symbol07) and totSym >= 7
[_close, _vol] = getKv(symbol07)
closeSymbols.push(_close)
volumeSymbols.push(_vol)
if tools._bool(symbol08) and totSym >= 8
[_close, _vol] = getKv(symbol08)
closeSymbols.push(_close)
volumeSymbols.push(_vol)
if tools._bool(symbol09) and totSym >= 9
[_close, _vol] = getKv(symbol09)
closeSymbols.push(_close)
volumeSymbols.push(_vol)
if tools._bool(symbol10) and totSym >= 10
[_close, _vol] = getKv(symbol10)
closeSymbols.push(_close)
volumeSymbols.push(_vol)
if tools._bool(symbol11) and totSym >= 11
[_close, _vol] = getKv(symbol11)
closeSymbols.push(_close)
volumeSymbols.push(_vol)
if tools._bool(symbol12) and totSym >= 12
[_close, _vol] = getKv(symbol12)
closeSymbols.push(_close)
volumeSymbols.push(_vol)
if tools._bool(symbol13) and totSym >= 13
[_close, _vol] = getKv(symbol13)
closeSymbols.push(_close)
volumeSymbols.push(_vol)
if tools._bool(symbol14) and totSym >= 14
[_close, _vol] = getKv(symbol14)
closeSymbols.push(_close)
volumeSymbols.push(_vol)
if tools._bool(symbol15) and totSym >= 15
[_close, _vol] = getKv(symbol15)
closeSymbols.push(_close)
volumeSymbols.push(_vol)
if tools._bool(symbol16) and totSym >= 16
[_close, _vol] = getKv(symbol16)
closeSymbols.push(_close)
volumeSymbols.push(_vol)
if tools._bool(symbol17) and totSym >= 17
[_close, _vol] = getKv(symbol17)
closeSymbols.push(_close)
volumeSymbols.push(_vol)
if tools._bool(symbol18) and totSym >= 18
[_close, _vol] = getKv(symbol18)
closeSymbols.push(_close)
volumeSymbols.push(_vol)
if tools._bool(symbol19) and totSym >= 19
[_close, _vol] = getKv(symbol19)
closeSymbols.push(_close)
volumeSymbols.push(_vol)
if tools._bool(symbol20) and totSym >= 20
[_close, _vol] = getKv(symbol20)
closeSymbols.push(_close)
volumeSymbols.push(_vol)
if tools._bool(symbol21) and totSym >= 21
[_close, _vol] = getKv(symbol21)
closeSymbols.push(_close)
volumeSymbols.push(_vol)
if tools._bool(symbol22) and totSym >= 22
[_close, _vol] = getKv(symbol22)
closeSymbols.push(_close)
volumeSymbols.push(_vol)
if tools._bool(symbol23) and totSym >= 23
[_close, _vol] = getKv(symbol23)
closeSymbols.push(_close)
volumeSymbols.push(_vol)
if tools._bool(symbol24) and totSym >= 24
[_close, _vol] = getKv(symbol24)
closeSymbols.push(_close)
volumeSymbols.push(_vol)
if tools._bool(symbol25) and totSym >= 25
[_close, _vol] = getKv(symbol25)
closeSymbols.push(_close)
volumeSymbols.push(_vol)
if tools._bool(symbol26) and totSym >= 26
[_close, _vol] = getKv(symbol26)
closeSymbols.push(_close)
volumeSymbols.push(_vol)
if tools._bool(symbol27) and totSym >= 27
[_close, _vol] = getKv(symbol27)
closeSymbols.push(_close)
volumeSymbols.push(_vol)
if tools._bool(symbol28) and totSym >= 28
[_close, _vol] = getKv(symbol28)
closeSymbols.push(_close)
volumeSymbols.push(_vol)
if tools._bool(symbol29) and totSym >= 29
[_close, _vol] = getKv(symbol29)
closeSymbols.push(_close)
volumeSymbols.push(_vol)
if tools._bool(symbol30) and totSym >= 30
[_close, _vol] = getKv(symbol30)
closeSymbols.push(_close)
volumeSymbols.push(_vol)
if tools._bool(symbol31) and totSym >= 31
[_close, _vol] = getKv(symbol31)
closeSymbols.push(_close)
volumeSymbols.push(_vol)
if tools._bool(symbol32) and totSym >= 32
[_close, _vol] = getKv(symbol32)
closeSymbols.push(_close)
volumeSymbols.push(_vol)
if tools._bool(symbol33) and totSym >= 33
[_close, _vol] = getKv(symbol33)
closeSymbols.push(_close)
volumeSymbols.push(_vol)
if tools._bool(symbol34) and totSym >= 34
[_close, _vol] = getKv(symbol34)
closeSymbols.push(_close)
volumeSymbols.push(_vol)
if tools._bool(symbol35) and totSym >= 35
[_close, _vol] = getKv(symbol35)
closeSymbols.push(_close)
volumeSymbols.push(_vol)
if tools._bool(symbol36) and totSym >= 36
[_close, _vol] = getKv(symbol36)
closeSymbols.push(_close)
volumeSymbols.push(_vol)
if tools._bool(symbol37) and totSym >= 37
[_close, _vol] = getKv(symbol37)
closeSymbols.push(_close)
volumeSymbols.push(_vol)
if tools._bool(symbol38) and totSym >= 38
[_close, _vol] = getKv(symbol38)
closeSymbols.push(_close)
volumeSymbols.push(_vol)
if tools._bool(symbol39) and totSym >= 39
[_close, _vol] = getKv(symbol39)
closeSymbols.push(_close)
volumeSymbols.push(_vol)
if tools._bool(symbol40) and totSym >= 40
[_close, _vol] = getKv(symbol40)
closeSymbols.push(_close)
volumeSymbols.push(_vol)
// }
if closeSymbols.size() > 0
// Styles.
tbs = prnt.tableStyle.new(bgColor=na, frameColor=na, borderWidth = cellPad)
hs = prnt.headerStyle.new(bgColor=na, textHalign=headerAlign, textColor=headerColor, textSize=headerSize)
ts = prnt.titleStyle.new(top=true, textHalign=titleAlign, textColor=titleColor, textSize=titleSize, bgColor=na)
cs = prnt.cellStyle.new(horizontal=orientation, textHalign=textAlign, textSize=textSize)
kcs = prnt.cellStyle.new(textHalign=keyAlign, textSize=keySize)
// Initialize the printer.
hd = (asc ? ' ↑ ': ' ↓ ') + displayTf()
header = headerSize != 'hide' ? hd : na
printer = prnt.printer(header=header, tableStyle=tbs, headerStyle=hs, titleStyle=ts, keyCellStyle=kcs,
cellStyle=cs, stack=orientation, loc=displayLoc)
// Close.
d2dClose = mltd.data2d(closeSymbols, sort=true, asc=asc, sortByChange=true)
closeDv = d2dClose.changeValues(true)
closeMax = closeDv.max()
closeMin = closeDv.min()
d2dCloseStyles = map.new<string, prnt.cellStyle>()
d2dCloseDv = map.new<string, prnt.dvs>()
closeKeyStyle = prnt.cellStyle.copy(printer.keyCellStyle)
closeKeyStyle.dynamicColor := prnt.dynamicColor.new(numberUp=closeMax, numberDown=closeMin,
offsetItem=keyOffset, offsetColor=keyOffsetColor)
closeKeyStyle.gradient := true
closeValStyle = prnt.cellStyle.copy(cs)
closeValStyle.dynamicColor := prnt.dynamicColor.new(numberUp=closeMax, numberDown=closeMin,
offsetItem=textOffset, offsetColor=textOffsetColor)
closeValStyle.gradient := true
d2dCloseStyles.put('key', closeKeyStyle)
d2dCloseStyles.put('val', closeValStyle)
d2dCloseDv.put('val', closeDv.dvs())
ctd = headerSize == 'hide' ? (asc ? '↑ ': '↓ ') + (prevBar ? ' Previous ' : na): na
ctd := ctd + 'Close' + (displayValues != 'regular' ? (displayValues == 'change' ? ' (-)' : ' (%)') : na)
closeTitle = titleSize != 'hide' ? ctd : na
printer.print(d2dClose, title=closeTitle, displayValues=displayValues(), dynamicValues=d2dCloseDv,
styles=d2dCloseStyles, dynamicKey=true)
// Volume.
if showVol
d2dVolume = mltd.data2d(volumeSymbols, sort=true, asc=asc, sortByChange=true)
volumeDv = d2dVolume.changeValues(true)
volumeMax = volumeDv.max()
volumeMin = volumeDv.min()
d2dVolumeStyles = map.new<string, prnt.cellStyle>()
d2dVolumeDv = map.new<string, prnt.dvs>()
volumeKeyStyle = prnt.cellStyle.copy(printer.keyCellStyle)
volumeKeyStyle.dynamicColor := prnt.dynamicColor.new(numberUp=volumeMax, numberDown=volumeMin,
offsetItem=keyOffset, offsetColor=keyOffsetColor)
volumeKeyStyle.gradient := true
volumeValStyle = prnt.cellStyle.copy(cs)
volumeValStyle.dynamicColor := prnt.dynamicColor.new(numberUp=volumeMax, numberDown=volumeMin,
offsetItem=textOffset, offsetColor=textOffsetColor)
volumeValStyle.gradient := true
d2dVolumeStyles.put('key', volumeKeyStyle)
d2dVolumeStyles.put('val', volumeValStyle)
d2dVolumeDv.put('val', volumeDv.dvs())
vtd = headerSize == 'hide' ? (asc ? '↑ ': '↓ ') + (prevBar ? ' Previous ' : na): na
vtd := vtd + 'Volume' + (displayValues != 'regular' ? (displayValues == 'change' ? ' (-)' : ' (%)') : na)
volumeTitle = titleSize != 'hide' ? vtd : na
printer.print(d2dVolume, title=volumeTitle, displayValues=displayValues(), dynamicValues=d2dVolumeDv,
styles=d2dVolumeStyles, dynamicKey=true)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment