如何在PineScript中为OBV-MACD指标添加方向变化警报
OBV-MACD指标添加方向变化警报的解决方案
问题原因
你添加的警报无效果,核心原因有两点:
- 视觉信号使用了
offset=-1,将交叉标记绘制在前一根K线,但警报条件直接使用当前K线的up/down状态,导致逻辑不同步 - 未限制信号单次触发,
change(oc)>0会在信号持续的K线中持续返回true,无法精准捕捉信号触发的瞬间
解决方案
1. 同步警报与视觉信号逻辑
因为你的绘图用了offset=-1,警报条件需要对应前一根K线的信号状态,确保和视觉标记同步:
down = change(oc) < 0 up = change(oc) > 0 showsignal=input(false, title="显示信号") // 保留原绘图逻辑(带offset) plot(showsignal and up ? tt1 : na, style=plot.style_cross, color=color.blue, linewidth=4, transp=0, offset=-1) plot(showsignal and down ? tt1 : na, style=plot.style_cross, color=color.red, linewidth=4, transp=0, offset=-1) // 添加与视觉信号同步的警报条件 alertcondition(showsignal and up[1], title="上涨信号", message="OBV-MACD发出上涨信号!") alertcondition(showsignal and down[1], title="下跌信号", message="OBV-MACD发出下跌信号!")
2. 可选:让警报在信号触发瞬间触发
如果希望警报在信号产生的当前K线触发,去掉绘图的offset=-1,并添加单次触发逻辑避免重复警报:
down = change(oc) < 0 up = change(oc) > 0 showsignal=input(false, title="显示信号") // 定义单次触发信号(仅在信号从无到有时触发) up_single_trigger = showsignal and up and not up[1] down_single_trigger = showsignal and down and not down[1] // 绘制信号(去掉offset) plot(showsignal and up ? tt1 : na, style=plot.style_cross, color=color.blue, linewidth=4, transp=0) plot(showsignal and down ? tt1 : na, style=plot.style_cross, color=color.red, linewidth=4, transp=0) // 添加单次触发警报 alertcondition(up_single_trigger, title="上涨信号", message="OBV-MACD发出上涨信号!") alertcondition(down_single_trigger, title="下跌信号", message="OBV-MACD发出下跌信号!")
修改后的完整代码
//@version=4 study("OBV MACD Indicator",overlay=false) // MACD src1 = close window_len = 28 v_len = 14 price_spread = stdev(high-low, window_len) v = cum(sign(change(src1)) * volume) smooth = sma(v, v_len) v_spread = stdev(v - smooth, window_len) shadow = (v - smooth) / v_spread * price_spread out = shadow > 0 ? high + shadow : low + shadow //plot(out, style=line,linewidth=3, color=color) len10=input(1,title="OBV Length ") obvema=ema(out,len10) // src = obvema type = input(defval="DEMA", title="MA Type", options=["TDEMA", "TTEMA", "TEMA", "DEMA", "EMA", "AVG", "THMA", "ZLEMA", "ZLDEMA", "ZLTEMA", "DZLEMA", "TZLEMA", "LLEMA", "NMA"]) showma = true len = input(9, title="MA Length ") showma1 = false len1 = 26 showma2 =false len2 = 52 nma(src, length1, length2) => lambda = length1 / length2 alpha = lambda * (length1 - 1) / (length1 - lambda) ma1 = ema(src, length1) ma2 = ema(ma1, length2) nma = (1 + alpha) * ma1 - alpha * ma2 dema(src, len) => ma1 = ema(src, len) ma2 = ema(ma1, len) 2 * ma1 - ma2 tema(src, len) => ma1 = ema(src, len) ma2 = ema(ma1, len) ma3 = ema(ma2, len) 3 * (ma1 - ma2) + ma3 tdema(src, len) => ma1 = dema(src, len) ma2 = dema(ma1, len) ma3 = dema(ma2, len) 3 * (ma1 - ma2) + ma3 ttema(src, len) => ma1 = tema(src, len) ma2 = tema(ma1, len) ma3 = tema(ma2, len) 3 * (ma1 - ma2) + ma3 tnma(src, len) => ma1 = nma(src, len, 3) ma2 = nma(ma1, len, 3) ma3 = nma(ma2, len, 3) 3 * (ma1 - ma2) + ma3 hma(src, len) => wma(2*wma(src, len/2)-wma(src, len), round(sqrt(len))) thma(src, len) => ma1 = hma(src, len) ma2 = hma(ma1, len) ma3 = hma(ma2, len) 3 * (ma1 - ma2) + ma3 zlema(src, len) => lag = round((len - 1) / 2) zlsrc = src + (src - src[lag]) ema(zlsrc, len) zldema(src, len) => lag = round((len - 1) / 2) zlsrc = src + (src - src[lag]) dema(zlsrc, len) zltema(src, len) => lag = round((len - 1) / 2) zlsrc = src + (src - src[lag]) tema(zlsrc, len) dzlema(src, len) => ma1 = zlema(src, len) ma2 = zlema(ma1, len) 2 * ma1 - ma2 tzlema(src, len) => ma1 = zlema(src, len) ma2 = zlema(ma1, len) ma3 = zlema(ma2, len) 3 * (ma1 - ma2) + ma3 llema(src, len) => srcnew = 0.25*src + 0.5*src[1] + 0.25*src[2] ema(srcnew, len) lltema(src, len) => srcnew = 0.25*src + 0.5*src[1] + 0.25*src[2] tema(srcnew, len) myma(src, len) => if type == "EMA" ema(src, len) else if type == "DEMA" dema(src, len) else if type == "TEMA" tema(src, len) else if type == "TDEMA" tdema(src, len) else if type == "TTEMA" ttema(src, len) else if type == "THMA" thma(src, len) else if type == "ZLEMA" zlema(src, len) else if type == "ZLDEMA" zldema(src, len) else if type == "ZLTEMA" zltema(src, len) else if type == "DZLEMA" dzlema(src, len) else if type == "TZLEMA" tzlema(src, len) else if type == "LLEMA" llema(src, len) else if type == "NMA" nma(src, len, len1) else avg(ttema(src, len), tdema(src, len)) ma = showma ? myma(src, len) : na slow_length = input(title="MACD Slow Length", type=input.integer, defval=26) //signal_length = input(title="MACD Signal Smoothing", type=input.integer, minval = 1, maxval = 50, defval = 9) src12=close plot(0,linewidth=3,color=color.black) // Calculating MACD slow_ma = ema(src12, slow_length) macd =ma-slow_ma //signal_length=input(9) //signal = ema(macd, signal_length) //plot(signal,linewidth=2) src5 = macd len5 = input(2) offset = 0 calcSlope(src5, len5) => sumX = 0.0 sumY = 0.0 sumXSqr = 0.0 sumXY = 0.0 for i = 1 to len5 val = src5[len5-i] per = i + 1.0 sumX := sumX + per sumY := sumY + val sumXSqr := sumXSqr + per * per sumXY := sumXY + val * per slope = (len5 * sumXY - sumX * sumY) / (len5 * sumXSqr - sumX * sumX) average = sumY / len5 intercept = average - slope * sumX / len5 + slope [slope, average, intercept] var float tmp = na [s, a5, i] = calcSlope(src5, len5) tt1=(i + s * (len5 - offset)) ////script based on alex grover p = 1,src15=tt1 b5 = 0.,dev5 = 0.,oc = 0 n5 = cum(1) - 1 a15 = cum(abs(src15 - nz(b5[1],src15)))/n5*p b5 := src15 > nz(b5[1],src15) + a15 ? src15 : src15 < nz(b5[1],src15) - a15 ? src15 : nz(b5[1],src15) //---- dev5 := change(b5) ? a15 : nz(dev5[1],a15) //---- oc := change(b5) > 0 ? 1 : change(b5) < 0 ? -1 : nz(oc[1]) //---- cs = oc == 1 ? color.blue : color.red //change(oc)>0 plot(b5,color=cs,linewidth=4,transp=50) // down = change(oc) < 0 up = change(oc) > 0 showsignal=input(false, title="显示信号") // 保留原绘图逻辑(带offset) plot(showsignal and up ? tt1 : na, style=plot.style_cross, color=color.blue, linewidth=4, transp=0, offset=-1) plot(showsignal and down ? tt1 : na, style=plot.style_cross, color=color.red, linewidth=4, transp=0, offset=-1) // 添加同步视觉信号的警报条件 alertcondition(showsignal and up[1], title="上涨信号", message="OBV-MACD发出上涨信号!") alertcondition(showsignal and down[1], title="下跌信号", message="OBV-MACD发出下跌信号!") // DIVS code piv = input(true, "Hide pivots?") shrt = false xbars = input(50, "period", input.integer, minval=1) hb = abs(highestbars(upper, xbars)) lb = abs(lowestbars(lower, xbars)) max = float(na) max_upper = float(na) min = float(na) min_lower = float(na) pivoth = bool(na) pivotl = bool(na) max := hb == 0 ? close : na(max[1]) ? close : max[1] max_upper := hb == 0 ? upper : na(max_upper[1]) ? upper : max_upper[1] min := lb == 0 ? close : na(min[1]) ? close : min[1] min_lower := lb == 0 ? lower : na(min_lower[1]) ? lower : min_lower[1] if close > max max := close max if upper > max_upper max_upper := upper max_upper if close < min_lower min_lower := lower min_lower if lower < min_lower min_lower := lower min_lower pivoth := max_upper == max_upper[2] and max_upper[2] != max_upper[3] ? true : na pivotl := min_lower == min_lower[2] and min_lower[2] != min_lower[3] ? true : na plotshape(piv ? na : shrt ? na : pivoth ? max_upper + 2 : na, location=location.absolute, style=shape.labeldown, color=color.red, size=size.tiny, text="Pivot", textcolor=color.white, transp=0, offset=0) plotshape(piv ? na : shrt ? na : pivotl ? min_lower - 2 : na, location=location.absolute, style=shape.labelup, color=color.blue, size=size.tiny, text="Pivot", textcolor=color.white, transp=0, offset=0)
内容的提问来源于stack exchange,提问作者zessor
相关产品推荐
相关产品推荐

