1
//@version=6 indicator("Danilov Levels v3", overlay = true, max_lines_count = 500, max_labels_count = 500)
pivLen = input.int(8, "Чувствительность (бары слева/справа)", minval = 2, maxval = 30) mergeMult = input.float(0.5, "Объединять ближе чем (× ATR)", minval = 0.1, maxval = 2.0, step = 0.1) touchMult = input.float(0.25,"Зона касания (× ATR)", minval = 0.05, maxval = 1.0, step = 0.05) minStrength = input.int(40, "Мин. сила для показа (0-100)", minval = 0, maxval = 100) maxLevels = input.int(15, "Максимум уровней", minval = 3, maxval = 40) nearATR = input.float(3.0, "Близкая зона (× ATR от цены)", minval = 1.0, maxval = 10.0, step = 0.5) showLabels = input.bool(true, "Показывать подписи")
cNear = input.color(#1e2530, "Актуальные (близкие, пунктир)") cFar = input.color(#c9885a, "Неактуальные (дальние)")
atrG = ta.sma(high - low, 20)
var array pPrice = array.new_float() var array pBar = array.new_int() var array pType = array.new_string() var array pTouch = array.new_int() var array pIsHigh = array.new_bool() var array pFalseBrk = array.new_bool() var array pStrength = array.new_float()
ph = ta.pivothigh(high, pivLen, pivLen) pl = ta.pivotlow(low, pivLen, pivLen)
f_round(p) => r = p - math.floor(p) math.abs(r) < 0.02 or math.abs(r - 0.25) < 0.02 or math.abs(r - 0.5) < 0.02 or math.abs(r - 0.75) < 0.02
f_typeBase(t) => out = 25.0 if t == "trend" out := 45.0 else if t == "mirror" out := 40.0 else if t == "limit" out := 32.0 else if t == "paranormal" out := 30.0 out
f_typeName(t) => out = t if t == "trend" out := "Излом тренда" else if t == "mirror" out := "Зеркальный" else if t == "limit" out := "Лимитный" else if t == "paranormal" out := "Паранормальный" out
f_addLevel(price, isHigh, typ) => merged = false sz = array.size(pPrice) if sz > 0 for i = 0 to sz - 1 ep = array.get(pPrice, i) if atrG > 0 and math.abs(ep - price) <= atrG * mergeMult array.set(pTouch, i, array.get(pTouch, i) + 1) if array.get(pIsHigh, i) != isHigh array.set(pType, i, "mirror") merged := true break if not merged array.push(pPrice, price) array.push(pBar, bar_index) array.push(pType, typ) array.push(pTouch, 1) array.push(pIsHigh, isHigh) array.push(pFalseBrk, false) array.push(pStrength, 0.0)
if not na(ph) p0 = high[pivLen] p1 = low[pivLen * 2] impulse = atrG > 0 ? math.abs(p0 - p1) / atrG : 0.0 typ = "limit" if impulse >= 2.5 typ := "trend" else if atrG > 0 and (high[pivLen] - low[pivLen]) >= atrG * 2.0 typ := "paranormal" f_addLevel(high[pivLen], true, typ)
if not na(pl) q0 = low[pivLen] q1 = high[pivLen * 2] impulse2 = atrG > 0 ? math.abs(q0 - q1) / atrG : 0.0 typ2 = "limit" if impulse2 >= 2.5 typ2 := "trend" else if atrG > 0 and (high[pivLen] - low[pivLen]) >= atrG * 2.0 typ2 := "paranormal" f_addLevel(low[pivLen], false, typ2)
szAll = array.size(pPrice) if szAll > 0 for i = 0 to szAll - 1 ep = array.get(pPrice, i) isH = array.get(pIsHigh, i) zone = atrG * touchMult if low <= ep + zone and high >= ep - zone array.set(pTouch, i, array.get(pTouch, i) + 1) if isH and high > ep and close < ep array.set(pFalseBrk, i, true) if not isH and low < ep and close > ep array.set(pFalseBrk, i, true)
var array drawn = array.new_line() var array drawnL = array.new_label()
if barstate.islast if array.size(drawn) > 0 for i = 0 to array.size(drawn) - 1 line.delete(array.get(drawn, i)) array.clear(drawn) if array.size(drawnL) > 0 for i = 0 to array.size(drawnL) - 1 label.delete(array.get(drawnL, i)) array.clear(drawnL)
n = array.size(pPrice)
if n > 0
for i = 0 to n - 1
base = f_typeBase(array.get(pType, i))
touches = array.get(pTouch, i)
touchPts = math.min(touches * 6.0, 35.0)
fbPts = array.get(pFalseBrk, i) ? 15.0 : 0.0
roundPts = f_round(array.get(pPrice, i)) ? 8.0 : 0.0
distA = atrG > 0 ? math.abs(close - array.get(pPrice, i)) / atrG : 999.0
nearPts = distA <= nearATR ? (25.0 * (1.0 - distA / nearATR)) : 0.0
s = math.min(base + touchPts + fbPts + roundPts + nearPts, 100.0)
array.set(pStrength, i, s)
idx = array.new_int()
for i = 0 to n - 1
if array.get(pStrength, i) >= minStrength
array.push(idx, i)
cnt = array.size(idx)
if cnt > 1
for a = 0 to cnt - 2
for b = 0 to cnt - 2 - a
i1 = array.get(idx, b)
i2 = array.get(idx, b + 1)
if array.get(pStrength, i1) < array.get(pStrength, i2)
array.set(idx, b, i2)
array.set(idx, b + 1, i1)
drawCount = math.min(cnt, maxLevels)
if drawCount > 0
for k = 0 to drawCount - 1
i = array.get(idx, k)
pr = array.get(pPrice, i)
s = array.get(pStrength, i)
distA = atrG > 0 ? math.abs(close - pr) / atrG : 999.0
isNear = distA <= nearATR
col = cFar
lstyle = line.style_solid
if isNear
col := cNear
lstyle := line.style_dashed
else
col := cFar
lstyle := line.style_solid
ln = line.new(array.get(pBar, i), pr, bar_index + 10, pr, color = col, width = 1, style = lstyle, extend = extend.right)
array.push(drawn, ln)
if showLabels and isNear
nm = f_typeName(array.get(pType, i))
fb = array.get(pFalseBrk, i) ? " ЛП" : ""
txt = nm + " [" + str.tostring(math.round(s)) + "]" + fb + " к" + str.tostring(array.get(pTouch, i))
lb = label.new(bar_index + 10, pr, txt, style = label.style_label_left, color = color.new(col, 75), textcolor = col, size = size.small)
array.push(drawnL, lb)
исправь ошибки
Source: deepseek-ai/DeepSeek-Coder