Hi

Wait 5 sec.

HiSOL / TetherUSBINANCE:SOLUSDTrezagolsefid//@version=5 indicator("SR Zones | Pivot + Volume + SMC + RSI + MFI", shorttitle="SR Score Zones", overlay=true, max_boxes_count=200, max_labels_count=200) // ============================== Inputs ============================== grpPiv = "Pivot (کف و سقف)" len = input.int(10, "Pivot Length", minval=2, group=grpPiv, tooltip="عدد بزرگ‌تر = فقط کف و سقف‌های مهم‌تر") zoneATR = input.float(1.0, "Max Zone Thickness (x ATR)", minval=0.2, step=0.1, group=grpPiv) grpVol = "Volume (حجم)" volLen = input.int(20, "Volume MA Length", minval=2, group=grpVol) volMult = input.float(1.5, "High Volume Multiplier", minval=1.0, step=0.1, group=grpVol, tooltip="حجم حداقل چند برابر میانگین باشد تا «معامله‌ی حجم بالا» حساب شود") grpOsc = "RSI / MFI" rsiLen = input.int(14, "RSI Length", group=grpOsc) mfiLen = input.int(14, "MFI Length", group=grpOsc) rsiHigh = input.float(65, "RSI Overbought", group=grpOsc) rsiLow = input.float(35, "RSI Oversold", group=grpOsc) mfiHigh = input.float(70, "MFI Overbought", group=grpOsc) mfiLow = input.float(30, "MFI Oversold", group=grpOsc) grpZone = "Zones (نمایش)" minScore = input.int(3, "Minimum Score (از 5)", minval=1, maxval=5, group=grpZone, tooltip="فقط ناحیه‌هایی که امتیازشان حداقل این عدد باشد رسم می‌شوند") maxZones = input.int(6, "Max Zones per side", minval=1, maxval=30, group=grpZone) showLabels = input.bool(true, "Show Labels", group=grpZone) showBroken = input.bool(false, "Keep Broken Zones (gray)", group=grpZone) showTable = input.bool(true, "Show Info Table", group=grpZone) resColor = input.color(color.red, "Resistance Color", group=grpZone) supColor = input.color(color.green, "Support Color", group=grpZone) // ============================== Calculations ============================== volMA = ta.sma(volume, volLen) rsi = ta.rsi(close, rsiLen) mfi = ta.mfi(hlc3, mfiLen) atr = ta.atr(14) ph = ta.pivothigh(high, len, len) pl = ta.pivotlow(low, len, len) var float lastPH = na var float lastPL = na var resBoxes = array.new_box() var supBoxes = array.new_box() // transparency by score: higher score = more solid f_transp(s) => s >= 5 ? 65 : s == 4 ? 78 : 88 // ============================== Resistance (pivot high) ============================== if not na(ph) pivVol = volume pivMA = volMA spike = ta.highest(volume, 3) sVolume = pivVol > pivMA ? 1 : 0 sSpike = spike >= pivMA * volMult ? 1 : 0 sRsi = rsi >= rsiHigh ? 1 : 0 sMfi = mfi >= mfiHigh ? 1 : 0 sSmc = (not na(lastPH) and high > lastPH and close < lastPH) ? 1 : 0 score = sVolume + sSpike + sRsi + sMfi + sSmc if score >= minScore topP = high botP = math.max(math.min(open, close), topP - atr * zoneATR) b = box.new(bar_index - len, topP, bar_index, botP, border_color=color.new(resColor, 30), bgcolor=color.new(resColor, f_transp(score)), extend=extend.right) array.push(resBoxes, b) if showLabels label.new(bar_index - len, topP, "R " + str(score) + "/5" + (sSmc == 1 ? " SMC" : ""), style=label.style_label_down, color=color.new(resColor, 20), textcolor=color.white, size=size.tiny) if array.size(resBoxes) > maxZones box.delete(array.shift(resBoxes)) lastPH := high // ============================== Support (pivot low) ============================== if not na(pl) pivVol = volume pivMA = volMA spike = ta.highest(volume, 3) sVolume = pivVol > pivMA ? 1 : 0 sSpike = spike >= pivMA * volMult ? 1 : 0 sRsi = rsi = minScore botP = low topP = math.min(math.max(open, close), botP + atr * zoneATR) b = box.new(bar_index - len, topP, bar_index, botP, border_color=color.new(supColor, 30), bgcolor=color.new(supColor, f_transp(score)), extend=extend.right) array.push(supBoxes, b) if showLabels label.new(bar_index - len, botP, "S " + str(score) + "/5" + (sSmc == 1 ? " SMC" : ""), style=label.style_label_up, color=color.new(supColor, 20), textcolor=color.white, size=size.tiny) if array.size(supBoxes) > maxZones box.delete(array.shift(supBoxes)) lastPL := low // ============================== Break handling ============================== if array.size(resBoxes) > 0 for i = array.size(resBoxes) - 1 to 0 rb = array.get(resBoxes, i) if close > box.get_top(rb) if showBroken box.set_extend(rb, extend.none) box.set_right(rb, bar_index) box.set_bgcolor(rb, color.new(color.gray, 92)) box.set_border_color(rb, color.new(color.gray, 70)) else box.delete(rb) array.remove(resBoxes, i) if array.size(supBoxes) > 0 for i = array.size(supBoxes) - 1 to 0 sb = array.get(supBoxes, i) if close < box.get_bottom(sb) if showBroken box.set_extend(sb, extend.none) box.set_right(sb, bar_index) box.set_bgcolor(sb, color.new(color.gray, 92)) box.set_border_color(sb, color.new(color.gray, 70)) else box.delete(sb) array.remove(supBoxes, i) // ============================== Info Table ============================== var table info = table.new(position.top_right, 2, 4, border_width=1) if showTable and barstate.islast volRatio = volMA > 0 ? volume / volMA : 0.0 table.cell(info, 0, 0, "RSI", text_color=color.white, bgcolor=color.new(color.gray, 30), text_size=size.small) table.cell(info, 1, 0, str.tostring(rsi, "#.0"), text_color=color.white, bgcolor=rsi >= rsiHigh ? color.new(color.red, 30) : rsi = mfiHigh ? color.new(color.red, 30) : mfi = volMult ? color.new(color.orange, 30) : color.new(color.gray, 60), text_size=size.small) table.cell(info, 0, 3, "Zones R/S", text_color=color.white, bgcolor=color.new(color.gray, 30), text_size=size.small) table.cell(info, 1, 3, str.tostring(array.size(resBoxes)) + " / " + str.tostring(array.size(supBoxes)), text_color=color.white, bgcolor=color.new(color.gray, 60), text_size=size.small) // ============================== Alerts ============================== alertcondition(not na(ph), "Pivot High confirmed", "A pivot high was confirmed") alertcondition(not na(pl), "Pivot Low confirmed", "A pivot low was confirmed")