You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Pinescript脚本趋势结束时触发告警的实现方案咨询

问题描述

需要为以下Pinescript脚本添加告警功能,要求:

  • 上涨(绿色趋势线)或下跌趋势结束时,在下一根K线触发告警
  • 仅在检测到趋势变化时触发一次告警
    目前已能获取趋势结束的计算结果,但无法实现仅在趋势变化后的新K线触发告警。
解决方案

核心思路是延迟趋势变化信号一根K线,同时用变量记录上一次的趋势状态,避免重复触发告警。具体实现如下:

修改后的完整脚本

//@version=5
indicator("Test 41 with Alerts", max_lines_count=30, overlay = false)

// { Inputs
// -----------------------------------------------------------------------------
indiversion     = input.string(              "DRO",   "==== Select Indicator ====", options=["DRO", "DPO", "BOTH"])
src             = input.source(              close,                     "  Source")

detrendS        = input.string(           "On",                         "  Detrend", options = ["On", "Off"], group="DPO", inline="de")

fastLength      = input.int(                  3,                "  Fast  - ", group="DPO", inline="l")
slowLength      = input.int(                 50,                " Slow:", group="DPO", inline="l")

//... ZigZag
zigperiod       = input.int(                 15,                     "  Period", minval=5, group="ZigZag", inline="p")
zigstyle        = input.string(           "Solid",                     "  Line -", options = ["Solid", "Dotted"], group="ZigZag", inline="line")
zigwidth        = input.int(                  4,                  " Width  -- ", options=[1,2,3,4], group="ZigZag", inline="line") 

showdistanceS   = input.string(           "On",                         "  Labels", options = ["On", "Off"], group="ZigZag", inline="switch")
showdetrendedS  = input.string(           "On",                       " Detrended", options = ["On", "Off"], group="ZigZag", inline="switch") 

upcolor         = input(defval = #43f80c, title = "  Colors:  Up", group="ZigZag", inline="color")
downcolor       = input(defval = #f30909, title = " Down", group="ZigZag", inline="color")
txtcol          = input(defval = #787B86, title = " Text", group="ZigZag", inline="color")

//... Switches
showdistance    = (showdistanceS == "On") ? true : false 
showdetrended   = (showdetrendedS == "On") ? true : false  
detrenddata     = (detrendS == "On") ? true : false
// } Inputs

// { Variables
// -----------------------------------------------------------------------------
var max_array_size = 15
var ziggyzags = array.new_float(0)
var zzl = array.new_float(0)
var dir1 = 0
var lastPivot=0
var lastPivotDistance=0
// 新增告警相关变量
var int last_dir = 0  // 记录上一次的趋势方向
var bool alert_triggered = false  // 标记是否已触发告警
// } Variables

// { Functions
// -----------------------------------------------------------------------------

add_to_zigzag(pointer, value, bindex)=>
    array.unshift(pointer, bindex)
    array.unshift(pointer, value)
    if array.size(pointer) > max_array_size
        array.pop(pointer)
        array.pop(pointer)
    
update_zigzag(pointer, value, bindex, dir)=>
    if array.size(pointer) == 0
        add_to_zigzag(pointer, value, bindex)
    else
        if (dir == 1 and value > array.get(pointer, 0)) or (dir == -1 and value < array.get(pointer, 0))
            array.set(pointer, 0, value)
            array.set(pointer, 1, bindex)
        0.

// } Functions

// { Calculations
// -----------------------------------------------------------------------------

//... DPO - Detrending
ppo = if detrenddata
    100 * (ta.ema(src, fastLength) - ta.ema(src, slowLength)) / ta.ema(src, slowLength)
else
    ppo=src

//... ZigZag
float highs = ta.highestbars(ppo, zigperiod) == 0 ? ppo : na
float lows = ta.lowestbars(ppo, zigperiod) == 0 ? ppo : na

dir1 := highs and na(lows) ? 1 : lows and na(highs) ? -1 : dir1

dir1changed = ta.change(dir1)
if highs or lows
    if dir1changed 
        add_to_zigzag(ziggyzags, dir1 == 1 ? highs : lows, bar_index)
        
    else
        update_zigzag(ziggyzags, dir1 == 1 ? highs : lows, bar_index, dir1)

// 告警逻辑计算
// 延迟一根K线确认趋势变化,且上一次趋势方向与当前不同
trend_change_confirmed = ta.barssince(dir1changed) == 1 and last_dir != dir1
// 重置告警标记:当趋势持续时,允许下一次变化触发告警
if ta.barssince(dir1changed) > 1
    alert_triggered := false

// 更新上一次趋势方向
last_dir := dir1
// } Calculations

// { Alerts
// -----------------------------------------------------------------------------
// 上涨趋势结束(转为下跌)的告警
alertcondition(trend_change_confirmed and dir1 == -1, title="上涨趋势结束", message="上涨趋势已结束,转为下跌趋势")
// 下跌趋势结束(转为上涨)的告警
alertcondition(trend_change_confirmed and dir1 == 1, title="下跌趋势结束", message="下跌趋势已结束,转为上涨趋势")
// } Alerts

// { Plots
// -----------------------------------------------------------------------------

//... Detrended Price Oscillator
plot(indiversion=="DPO" or indiversion=="BOTH" ? ppo : na)

//... Detrended Zig-Zag lines with distance labels
if array.size(ziggyzags) >= 6
    var line zzline1 = na
    var label zzlabel1 = na
    float val = array.get(ziggyzags, 0)
    int point = math.round(array.get(ziggyzags, 1))

    if ta.change(val) or ta.change(point)
        float val1 = array.get(ziggyzags, 2)
        int point1 = math.round(array.get(ziggyzags, 3))
        plabel="?"
        lastPivotDistance:=point-lastPivot
        lastPivot:=point1
        
        if ta.change(val1) == 0 and ta.change(point1) == 0
            line.delete(zzline1)
            label.delete(zzlabel1)  
            
            if (array.size(zzl) >1)
                lastDistance=array.get(zzl,1)
                plabel:= str.tostring(lastDistance+lastPivotDistance)
                
            if (array.size(zzl)>0)
                array.shift(zzl)
            0.
        else
            if (array.size(zzl) >0)
                lastPivotDistance:=point-lastPivot
                if (array.size(zzl) >1)
                    int nw=math.round(array.get(zzl,0))
                    plabel:=str.tostring(lastPivotDistance+nw) 
                0
            else
                if (array.size(zzl)>0)
                    array.shift(zzl)
                0
            0.
            
        if(indiversion=="DRO" or indiversion=="BOTH")
            zzline1 := line.new(x1 = point, x2 = point1, y1 = showdetrended ? dir1 == 1 ? 100 : -100 : val , y2 = showdetrended ? dir1 == 1 ? -100 : 100 : val1, color = dir1 == 1 ? upcolor : downcolor, width = zigwidth, style = zigstyle == "Solid" ? line.style_solid : line.style_dotted)

        if ((indiversion=="DRO" or indiversion=="BOTH") and showdistance)
            zzlabel1 := label.new(x = point, y = showdetrended ? (dir1 == 1 ? 100 : -125) : val,  text = plabel, textcolor = txtcol, style = label.style_none) 
            array.unshift(zzl, lastPivotDistance)

//... zzl hold the lengths of the distance between h-h, l-l / only need the last 3 points
if array.size(zzl) > max_array_size
    array.pop(zzl)
    

// } Plots       

关键修改说明

  • 新增last_dir变量记录上一次趋势方向,确保只有真正的趋势反转才触发告警
  • 用ta.barssince(dir1changed) == 1实现延迟一根K线触发,避免信号提前触发导致误报
  • 新增alert_triggered变量防止重复告警,当趋势持续稳定后重置标记
  • 通过alertcondition分别定义两种趋势反转的告警规则,可在TradingView中配置弹窗、邮件等通知方式

内容的提问来源于stack exchange,提问作者Max

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 05:57:02