//@version=5
//@author Honestcowboy
//
indicator(title="Developing Market Profile", shorttitle="Dev MP/TPO", max_boxes_count=32, overlay=true)
// $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ >>
// ---------> Script Explanation <----------- >>
// $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ >>
lookbackTip = "The amount of bars the Market Profile will look in the past to calculate where price has been the most in that range"
resolutionTip = "This is the amount of columns the Market Profile will have\nThese columns are calculated using the highest and lowest point price has been for the lookback period"
distanceFromChartTip = "The amount of bars the market profile will be offset from the current bar\nThis setting will not impact the developing market profile lines."
minSizeTip = "This setting is there to avoid visual bugs in the script\nScaling the chart there can be issues where the Market Profile extends all the way to 0\nTo avoid this use a minimum size bigger than the bugged box"
// $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ >>
// ---------> User Inputs <----------- >>
// $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ >>
marketProfileLength = input.int(defval=200, minval=10, title="lookback", group="Market Profiling", tooltip=lookbackTip )
amountOfColumns = input.int(defval=32, minval=2, maxval=32, title="resolution", group="Market Profiling", tooltip=resolutionTip )
distLastCandle = input.int(defval=1, minval=0, title="profile distance from chart", group="Visual Settings", tooltip=distanceFromChartTip)
borderWidth = input.int(defval=1, minval=1, title="border width (MP)", group="Visual Settings" )
charToUse = input.string(defval="▉", title="character", group="Visual Settings" )
col1 = input.color(defval=#F24968, title="color theme", group="Visual Settings", inline="color" )
col2 = input.color(defval=#9B72F2, title="", group="Visual Settings", inline="color" )
col3 = input.color(defval=#6929F2, title="", group="Visual Settings", inline="color" )
col4 = input.color(defval=#14D990, title="", group="Visual Settings", inline="color" )
col5 = input.color(defval=#F2B807, title="", group="Visual Settings", inline="color" )
perc1 = input.int(defval=20, minval=1, title="", group="Visual Settings", inline="perc" )
perc2 = input.int(defval=40, minval=1, title="", group="Visual Settings", inline="perc" )
perc3 = input.int(defval=60, minval=1, title="", group="Visual Settings", inline="perc" )
perc4 = input.int(defval=80, minval=1, title="", group="Visual Settings", inline="perc" )
showProfile = input.bool(defval=true, title="show Market Profile", group="Visual Settings" )
showHistory = input.bool(defval=true, title="show Profile history", group="Visual Settings" )
timeFilter = input.time(defval=timestamp('2023-05-10 14:30 GMT+2'), title="calculate from here", group="Optimisation and Debugging" )
minSize = input.int(defval=2, minval=0, title='minimum size of histogram', group="Optimisation and Debugging", tooltip=minSizeTip )
// $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ >>
// ---------> Functions <----------- >>
// $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ >>
getTransp(index, array, maxCount) =>
transp = array.size(array) > index ? 100-math.round((array.get(array, index)/maxCount)*100) : 100
getColor(index, array, maxCount) =>
number = getTransp(index, array, maxCount)
color = number<perc1 ? color.new(col1, number) : number < perc2 ? color.new(col2, number) : number < perc3 ? color.new(col3, number) : number < perc4 ? color.new(col4, number) : color.new(col5, number)
// $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ >>
// ---------> Calculate Market Profile <----------- >>
// $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ >>
MPTop = ta.highest(high,marketProfileLength)
MPBottom = ta.lowest(low,marketProfileLength)
ColumnSize = (MPTop-MPBottom)/amountOfColumns
//Delete all boxes
boxes = box.all
if array.size(boxes) > 0
for i = 0 to array.size(boxes) - 1
box.delete( array.get(boxes, i))
//Build Levels
float[] MPArray = array.new<float>(amountOfColumns+2,0.0)
if time>timeFilter // used for faster loading times
array.set(MPArray,0,MPTop)
float previousArrayValue = 0
for counter = 1 to amountOfColumns
previousArrayValue := array.get(MPArray,counter-1)
array.set(MPArray,counter,previousArrayValue-ColumnSize)
// Count Occurence of Source Between Levels
int[] occurenceArray = array.new<int>(amountOfColumns+1,0)
if time>timeFilter // used for faster loading times
for counter = 0 to amountOfColumns
arrayCounter = 0
upLimit = array.get(MPArray,counter)
bottomLimit = array.get(MPArray,counter+1)
for offset = 0 to marketProfileLength
if (low[offset]>bottomLimit and low[offset]<upLimit) or (high[offset]>bottomLimit and high[offset]<upLimit) or (low[offset]<bottomLimit and high[offset]>upLimit)
arrayCounter := arrayCounter+1
array.set(occurenceArray, counter,arrayCounter)
// Draw Market Profile
if showProfile
for i = 0 to amountOfColumns by 1
MPLows = array.get(MPArray, i+1)
MPHigh = array.get(MPArray, i)
MPOccurence = array.get(occurenceArray, i)
maxCount = array.size(occurenceArray) > 0 ? array.max(occurenceArray) : 1
if MPOccurence >= minSize
box.new(left=bar_index + distLastCandle, top=MPHigh, right=bar_index + distLastCandle + MPOccurence, bottom=MPLows, bgcolor=color.new(getColor(i,occurenceArray, maxCount),93), border_color=color.new(getColor(i,occurenceArray, maxCount),0), border_width=borderWidth)
// $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ >>
// ---------> Extract Market Profile Levels <----------- >>
// $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ >>
level0 = showHistory ? array.size(MPArray)>=3 ? (array.get(MPArray, 0) + array.get(MPArray, 1))/2 : na : na
level1 = showHistory ? array.size(MPArray)>=4 ? (array.get(MPArray, 1) + array.get(MPArray, 2))/2 : na : na
level2 = showHistory ? array.size(MPArray)>=5 ? (array.get(MPArray, 2) + array.get(MPArray, 3))/2 : na : na
level3 = showHistory ? array.size(MPArray)>=6 ? (array.get(MPArray, 3) + array.get(MPArray, 4))/2 : na : na
level4 = showHistory ? array.size(MPArray)>=7 ? (array.get(MPArray, 4) + array.get(MPArray, 5))/2 : na : na
level5 = showHistory ? array.size(MPArray)>=8 ? (array.get(MPArray, 5) + array.get(MPArray, 6))/2 : na : na
level6 = showHistory ? array.size(MPArray)>=9 ? (array.get(MPArray, 6) + array.get(MPArray, 7))/2 : na : na
level7 = showHistory ? array.size(MPArray)>=10 ? (array.get(MPArray, 7) + array.get(MPArray, 8))/2 : na : na
level8 = showHistory ? array.size(MPArray)>=11 ? (array.get(MPArray, 8) + array.get(MPArray, 9))/2 : na : na
level9 = showHistory ? array.size(MPArray)>=12 ? (array.get(MPArray, 9) + array.get(MPArray, 10))/2 : na : na
level10 = showHistory ? array.size(MPArray)>=13 ? (array.get(MPArray, 10) + array.get(MPArray, 11))/2 : na : na
level11 = showHistory ? array.size(MPArray)>=14 ? (array.get(MPArray, 11) + array.get(MPArray, 12))/2 : na : na
level12 = showHistory ? array.size(MPArray)>=15 ? (array.get(MPArray, 12) + array.get(MPArray, 13))/2 : na : na
level13 = showHistory ? array.size(MPArray)>=16 ? (array.get(MPArray, 13) + array.get(MPArray, 14))/2 : na : na
level14 = showHistory ? array.size(MPArray)>=17 ? (array.get(MPArray, 14) + array.get(MPArray, 15))/2 : na : na
level15 = showHistory ? array.size(MPArray)>=18 ? (array.get(MPArray, 15) + array.get(MPArray, 16))/2 : na : na
level16 = showHistory ? array.size(MPArray)>=19 ? (array.get(MPArray, 16) + array.get(MPArray, 17))/2 : na : na
level17 = showHistory ? array.size(MPArray)>=20 ? (array.get(MPArray, 17) + array.get(MPArray, 18))/2 : na : na
level18 = showHistory ? array.size(MPArray)>=21 ? (array.get(MPArray, 18) + array.get(MPArray, 19))/2 : na : na
level19 = showHistory ? array.size(MPArray)>=22 ? (array.get(MPArray, 19) + array.get(MPArray, 20))/2 : na : na
level20 = showHistory ? array.size(MPArray)>=23 ? (array.get(MPArray, 20) + array.get(MPArray, 21))/2 : na : na
level21 = showHistory ? array.size(MPArray)>=24 ? (array.get(MPArray, 21) + array.get(MPArray, 22))/2 : na : na
level22 = showHistory ? array.size(MPArray)>=25 ? (array.get(MPArray, 22) + array.get(MPArray, 23))/2 : na : na
level23 = showHistory ? array.size(MPArray)>=26 ? (array.get(MPArray, 23) + array.get(MPArray, 24))/2 : na : na
level24 = showHistory ? array.size(MPArray)>=27 ? (array.get(MPArray, 24) + array.get(MPArray, 25))/2 : na : na
level25 = showHistory ? array.size(MPArray)>=28 ? (array.get(MPArray, 25) + array.get(MPArray, 26))/2 : na : na
level26 = showHistory ? array.size(MPArray)>=29 ? (array.get(MPArray, 26) + array.get(MPArray, 27))/2 : na : na
level27 = showHistory ? array.size(MPArray)>=30 ? (array.get(MPArray, 27) + array.get(MPArray, 28))/2 : na : na
level28 = showHistory ? array.size(MPArray)>=31 ? (array.get(MPArray, 28) + array.get(MPArray, 29))/2 : na : na
level29 = showHistory ? array.size(MPArray)>=32 ? (array.get(MPArray, 29) + array.get(MPArray, 30))/2 : na : na
level30 = showHistory ? array.size(MPArray)>=33 ? (array.get(MPArray, 30) + array.get(MPArray, 31))/2 : na : na
level31 = showHistory ? array.size(MPArray)>=34 ? (array.get(MPArray, 31) + array.get(MPArray, 32))/2 : na : na
maxCount = showHistory ? array.size(occurenceArray) > 0 ? array.max(occurenceArray) : 1 : na
// $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ >>
// ---------> Graphical Display <----------- >>
// $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ >>
sizing = size.auto // change code here if you want to change size of the developing profile characters
noColor = color.rgb(0,0,0,100)
plotchar(level0>0 and showHistory ? level0 : close, char=charToUse, location = location.absolute, color=showHistory ? getColor(0, occurenceArray, maxCount) : noColor, size=sizing, editable=false)
plotchar(level1>0 and showHistory ? level1 : close, char=charToUse, location = location.absolute, color=showHistory ? getColor(1, occurenceArray, maxCount) : noColor, size=sizing, editable=false)
plotchar(level2>0 and showHistory ? level2 : close, char=charToUse, location = location.absolute, color=showHistory ? getColor(2, occurenceArray, maxCount) : noColor, size=sizing, editable=false)
plotchar(level3>0 and showHistory ? level3 : close, char=charToUse, location = location.absolute, color=showHistory ? getColor(3, occurenceArray, maxCount) : noColor, size=sizing, editable=false)
plotchar(level4>0 and showHistory ? level4 : close, char=charToUse, location = location.absolute, color=showHistory ? getColor(4, occurenceArray, maxCount) : noColor, size=sizing, editable=false)
plotchar(level5>0 and showHistory ? level5 : close, char=charToUse, location = location.absolute, color=showHistory ? getColor(5, occurenceArray, maxCount) : noColor, size=sizing, editable=false)
plotchar(level6>0 and showHistory ? level6 : close, char=charToUse, location = location.absolute, color=showHistory ? getColor(6, occurenceArray, maxCount) : noColor, size=sizing, editable=false)
plotchar(level7>0 and showHistory ? level7 : close, char=charToUse, location = location.absolute, color=showHistory ? getColor(7, occurenceArray, maxCount) : noColor, size=sizing, editable=false)
plotchar(level8>0 and showHistory ? level8 : close, char=charToUse, location = location.absolute, color=showHistory ? getColor(8, occurenceArray, maxCount) : noColor, size=sizing, editable=false)
plotchar(level9>0 and showHistory ? level9 : close, char=charToUse, location = location.absolute, color=showHistory ? getColor(9, occurenceArray, maxCount) : noColor, size=sizing, editable=false)
plotchar(level10>0 and showHistory ? level10 : close, char=charToUse, location = location.absolute, color=showHistory ? getColor(10,occurenceArray, maxCount) : noColor, size=sizing, editable=false)
plotchar(level11>0 and showHistory ? level11 : close, char=charToUse, location = location.absolute, color=showHistory ? getColor(11,occurenceArray, maxCount) : noColor, size=sizing, editable=false)
plotchar(level12>0 and showHistory ? level12 : close, char=charToUse, location = location.absolute, color=showHistory ? getColor(12,occurenceArray, maxCount) : noColor, size=sizing, editable=false)
plotchar(level13>0 and showHistory ? level13 : close, char=charToUse, location = location.absolute, color=showHistory ? getColor(13,occurenceArray, maxCount) : noColor, size=sizing, editable=false)
plotchar(level14>0 and showHistory ? level14 : close, char=charToUse, location = location.absolute, color=showHistory ? getColor(14,occurenceArray, maxCount) : noColor, size=sizing, editable=false)
plotchar(level15>0 and showHistory ? level15 : close, char=charToUse, location = location.absolute, color=showHistory ? getColor(15,occurenceArray, maxCount) : noColor, size=sizing, editable=false)
plotchar(level16>0 and showHistory ? level16 : close, char=charToUse, location = location.absolute, color=showHistory ? getColor(16,occurenceArray, maxCount) : noColor, size=sizing, editable=false)
plotchar(level17>0 and showHistory ? level17 : close, char=charToUse, location = location.absolute, color=showHistory ? getColor(17,occurenceArray, maxCount) : noColor, size=sizing, editable=false)
plotchar(level18>0 and showHistory ? level18 : close, char=charToUse, location = location.absolute, color=showHistory ? getColor(18,occurenceArray, maxCount) : noColor, size=sizing, editable=false)
plotchar(level19>0 and showHistory ? level19 : close, char=charToUse, location = location.absolute, color=showHistory ? getColor(19,occurenceArray, maxCount) : noColor, size=sizing, editable=false)
plotchar(level20>0 and showHistory ? level20 : close, char=charToUse, location = location.absolute, color=showHistory ? getColor(20,occurenceArray, maxCount) : noColor, size=sizing, editable=false)
plotchar(level21>0 and showHistory ? level21 : close, char=charToUse, location = location.absolute, color=showHistory ? getColor(21,occurenceArray, maxCount) : noColor, size=sizing, editable=false)
plotchar(level22>0 and showHistory ? level22 : close, char=charToUse, location = location.absolute, color=showHistory ? getColor(22,occurenceArray, maxCount) : noColor, size=sizing, editable=false)
plotchar(level23>0 and showHistory ? level23 : close, char=charToUse, location = location.absolute, color=showHistory ? getColor(23,occurenceArray, maxCount) : noColor, size=sizing, editable=false)
plotchar(level24>0 and showHistory ? level24 : close, char=charToUse, location = location.absolute, color=showHistory ? getColor(24,occurenceArray, maxCount) : noColor, size=sizing, editable=false)
plotchar(level25>0 and showHistory ? level25 : close, char=charToUse, location = location.absolute, color=showHistory ? getColor(25,occurenceArray, maxCount) : noColor, size=sizing, editable=false)
plotchar(level26>0 and showHistory ? level26 : close, char=charToUse, location = location.absolute, color=showHistory ? getColor(26,occurenceArray, maxCount) : noColor, size=sizing, editable=false)
plotchar(level27>0 and showHistory ? level27 : close, char=charToUse, location = location.absolute, color=showHistory ? getColor(27,occurenceArray, maxCount) : noColor, size=sizing, editable=false)
plotchar(level28>0 and showHistory ? level28 : close, char=charToUse, location = location.absolute, color=showHistory ? getColor(28,occurenceArray, maxCount) : noColor, size=sizing, editable=false)
plotchar(level29>0 and showHistory ? level29 : close, char=charToUse, location = location.absolute, color=showHistory ? getColor(29,occurenceArray, maxCount) : noColor, size=sizing, editable=false)
plotchar(level30>0 and showHistory ? level30 : close, char=charToUse, location = location.absolute, color=showHistory ? getColor(30,occurenceArray, maxCount) : noColor, size=sizing, editable=false)
plotchar(level31>0 and showHistory ? level31 : close, char=charToUse, location = location.absolute, color=showHistory ? getColor(31,occurenceArray, maxCount) : noColor, size=sizing, editable=false)