Untitled
s7s
java
a month ago
8.6 kB
12
Indexable
Never
// github @ 2LV, telegram @ nqmicro, discord @ nqmicro //@version=5 indicator("Institutional Supply & Demand Zones", overlay=true, max_boxes_count = 500) //inputs candleDifferenceScale = input.float(defval = 1.8, minval = 1, title = 'Zone Difference Scale', tooltip = 'The scale of how much a candle needs to be larger than a previous to be considered a zone (minimum value 1.0, default 1.8)', group = 'Zone Settings') zoneOffset = input.int(defval = 15, minval = 0, title="Zone Extension", group = 'Display Settings', tooltip = 'How much to extend zones to the right of latest bar in bars') displayLowerTFZones = input.bool(false, title="Display Lower Timeframe Zones", group = 'Display Settings', tooltip = 'Whether to or not to display zones from a lower timeframe (ie. 2h zones on 4h timeframe, Recommended OFF)') supplyEnable = input(true, title = "Enable Supply Zones", group = "Zone Personalization") supplyColor = input.color(defval = color.rgb(242, 54, 69, 94), title = 'Supply Background Color', group = 'Zone Personalization') supplyBorderColor = input.color(defval = color.rgb(209, 212, 220, 90), title = 'Supply Border Color', group = 'Zone Personalization') demandEnable = input(true, title = "Enable Demand Zones", group = "Zone Personalization") demandColor = input.color(defval = color.rgb(76, 175, 80, 94), title = 'Demand Background Color', group = 'Zone Personalization') demandBorderColor = input.color(defval = color.rgb(209, 212, 220, 80), title = 'Demand Border Color', group = 'Zone Personalization') textEnable = input(true, title = "Display Text", group = 'Text Settings') // 60 m displayHL = input.bool(false, title="Display High/Low", group = 'Text Settings', tooltip = 'Whether to or not to display the tops and bottoms of a zone as text (ie. Top: 4000.00 Bottom: 3900.00)') // ====== text ===== textColor = input.color(defval = color.rgb(255, 255, 255), title = 'Text Color', group = 'Text Settings') // textSize = input.string("Small", title="Text Size", options=["Auto", "Tiny", "Small", "Normal", "Large", "Huge"], group = 'Text Settings') // halign = input.string("Right", title="Horizontal Alignment", options=["Left", "Center", "Right"], group = 'Text Settings') // supplyValign = input.string("Bottom", title="Vertical Alignment (Supply)", options=["Top", "Center", "Bottom"], group = 'Text Settings') // demandValign = input.string("Top", title="Vertical Alignment (Demand)", options=["Top", "Center", "Bottom"], group = 'Text Settings') // === DISPLAY TIME === // display15m = input.bool(true, title="Show 15m Zones", group = 'Timeframe Options') // display1h = input.bool(true, title="Show 1h Zones", group = 'Timeframe Options') // display4h = input.bool(true, title="Show 4h Zones", group = 'Timeframe Options') // displayD = input.bool(false, title="Show 1D Zones", group = 'Timeframe Options') // // variables currentTimeframe = timeframe.period if currentTimeframe == 'D' currentTimeframe := '1440' if currentTimeframe == 'W' currentTimeframe := '10080' if displayLowerTFZones currentTimeframe := '0' momentCTD = math.round(time(timeframe.period) + (zoneOffset * 60000 * str.tonumber(currentTimeframe))) textSize := switch textSize "Auto" => size.auto "Tiny" => size.tiny "Small" => size.small "Normal" => size.normal "Large" => size.large "Huge" => size.huge halign := switch halign 'Left' => text.align_left 'Center' => text.align_center 'Right' => text.align_right supplyValign := switch supplyValign 'Bottom'=> text.align_bottom 'Center'=> text.align_center 'Top' => text.align_top demandValign := switch demandValign 'Bottom'=> text.align_bottom 'Center'=> text.align_center 'Top' => text.align_top var box[] supply_HT = array.new_box() var box[] demand_HT = array.new_box() // === plotting zones === createSupplyDemandZones(timeframe) => [open_HT, high_HT, low_HT, close_HT]= request.security(syminfo.tickerid, timeframe, [open[1], high[1], low[1], close[1]], lookahead = barmerge.lookahead_on) var timeframeFormatted = switch timeframe '1' => '1m' '3' => '3m' '5' => '5m' '16' => '15m' '30' => '30m' '45' => '45m' '60' => '1h' '120' => '2h' '180' => '3h' '240' => '4h' 'D' => '1D' 'W' => '1W' redCandle_HT = close_HT < open_HT greenCandle_HT = close_HT > open_HT neutralCandle_HT = close_HT == open_HT candleChange_HT = math.abs(close_HT - open_HT) var float bottomBox_HT = na var float topBox_HT = na momentCTD_HT = time(timeframe)[2] if (((redCandle_HT and greenCandle_HT[1]) or (redCandle_HT and neutralCandle_HT[1])) and (candleChange_HT / candleChange_HT[1]) >= candleDifferenceScale and barstate.isconfirmed[1] and supplyEnable and close_HT[1] >= close_HT and open_HT[1] <= open_HT) if displayHL timeframeFormatted := timeframeFormatted + '\nTop: ' + str.tostring(topBox_HT) + '\nBottom: ' + str.tostring(open_HT[1]) if high_HT >= high_HT[1] topBox_HT := high_HT else topBox_HT := high_HT[1] box supply = box.new(left=momentCTD_HT, top=topBox_HT, right=momentCTD, bgcolor=supplyColor, bottom=open_HT[1], xloc=xloc.bar_time) box.set_border_color(supply, supplyBorderColor) if textEnable box.set_text(supply, timeframeFormatted) box.set_text_size(supply, textSize) box.set_text_color(supply, textColor) box.set_text_halign(supply, halign) box.set_text_valign(supply, supplyValign) array.push(supply_HT, supply) if (((greenCandle_HT and redCandle_HT[1]) or (greenCandle_HT and neutralCandle_HT[1])) and (candleChange_HT / candleChange_HT[1]) >= candleDifferenceScale and barstate.isconfirmed[1] and demandEnable and close_HT[1] <= close_HT and open_HT[1] >= open_HT) if displayHL timeframeFormatted := timeframeFormatted + '\nTop: ' + str.tostring(open_HT[1]) + '\nBottom: ' + str.tostring(bottomBox_HT) if low_HT <= low_HT[1] bottomBox_HT := low_HT else bottomBox_HT := low_HT[1] box demand = box.new(left=momentCTD_HT, top=open_HT[1], right=momentCTD, bottom=bottomBox_HT, bgcolor=demandColor, xloc=xloc.bar_time) box.set_border_color(demand, demandBorderColor) if textEnable box.set_text(demand, timeframeFormatted) box.set_text_size(demand, textSize) box.set_text_color(demand, textColor) box.set_text_halign(demand, halign) box.set_text_valign(demand, demandValign) array.push(demand_HT, demand) // initiation // remove comments to add these zones to the chart (warning: this will break replay mode) // if str.tonumber(currentTimeframe) <= 5 // createSupplyDemandZones('5') //if str.tonumber(currentTimeframe) <= 15 // createSupplyDemandZones('15') //if str.tonumber(currentTimeframe) <= 10 // createSupplyDemandZones('10') //if str.tonumber(currentTimeframe) <= 15 // createSupplyDemandZones('15') if display30m and str.tonumber(currentTimeframe) <= 30 createSupplyDemandZones('30') if display45m and str.tonumber(currentTimeframe) <= 45 createSupplyDemandZones('45') if display1h and str.tonumber(currentTimeframe) <= 60 createSupplyDemandZones('60') if display2h and str.tonumber(currentTimeframe) <= 120 createSupplyDemandZones('120') if display3h and str.tonumber(currentTimeframe) <= 180 createSupplyDemandZones('180') if display4h and str.tonumber(currentTimeframe) <= 240 createSupplyDemandZones('240') if displayD and str.tonumber(currentTimeframe) <= 1440 createSupplyDemandZones('D') if displayW and str.tonumber(currentTimeframe) <= 10080 createSupplyDemandZones('W') // remove broken zones i = 0 while i < array.size(supply_HT) and array.size(supply_HT) > 0 box currentBox = array.get(supply_HT, i) float breakLevel = box.get_top(currentBox) if high > breakLevel array.remove(supply_HT, i) box.delete(currentBox) int(na) else box.set_right(currentBox, momentCTD) i += 1 int(na) i2 = 0 while i2 < array.size(demand_HT) and array.size(demand_HT) > 0 box currentBox = array.get(demand_HT, i2) float breakLevel = box.get_bottom(currentBox) if low < breakLevel array.remove(demand_HT, i2) box.delete(currentBox) int(na) else box.set_right(currentBox, momentCTD) i2 += 1 int(na)