WATER 发表于 2026-9-22 11:42:19

【tradingview 多时间周期突破缺口检测】K线缺口检测指标

//@version=5
indicator("多时间周期突破型缺口 (MTF Breakaway Gaps)", overlay=true, max_lines_count=500, max_labels_count=500)

// ==================== 1. 基础算法参数 ====================
grp_algo = "缺口识别算法设置"
lookback_max   = input.int(10, "锚点向左最大回溯根数", minval=1, maxval=50, group=grp_algo, tooltip="在各周期中寻找被套锚点K线的最大回溯范围")
min_body_ratio = input.float(0.3, "实体占K线最小比例 (0~1)", minval=0.0, maxval=1.0, step=0.1, group=grp_algo, tooltip="过滤掉十字星,确保锚点是具有明确力量的K线")

// ==================== 2. 多时间周期开关与显示 ====================
grp_tf = "周期开关 (勾选开启对应周期的缺口显示)"
show_5m= input.bool(false, "5 分钟 (5m)", inline="5m", group=grp_tf)
show_15m = input.bool(true,"15 分钟 (15m)", inline="15m", group=grp_tf)
show_30m = input.bool(false, "30 分钟 (30m)", inline="30m", group=grp_tf)
show_1h= input.bool(true,"1 小时 (1H)", inline="1h", group=grp_tf)
show_2h= input.bool(false, "2 小时 (2H)", inline="2h", group=grp_tf)
show_4h= input.bool(true,"4 小时 (4H)", inline="4h", group=grp_tf)
show_1d= input.bool(true,"日线 (1D)", inline="1d", group=grp_tf)
show_1w= input.bool(true,"周线 (1W)", inline="1w", group=grp_tf)

grp_style = "全局样式设置"
col_bull       = input.color(color.new(#089981, 0), "上涨缺口 (支撑线)", group=grp_style)
col_bear       = input.color(color.new(#f23645, 0), "下跌缺口 (阻力线)", group=grp_style)
col_mitigated= input.color(color.new(color.gray, 60), "已回补缺口颜色", group=grp_style)
show_mitigated = input.bool(true, "保留已回补缺口 (虚线灰线)", group=grp_style)
show_labels    = input.bool(true, "显示周期/方向标签", group=grp_style)
line_width   = input.int(2, "缺口线粗细", minval=1, maxval=4, group=grp_style)

// ==================== 3. 自定义结构体与全局变量 ====================
type MTFGap
    line l
    label lbl
    float level
    bool is_bull
    bool mitigated
    int start_time
    string tf_tag

var MTFGap[] all_gaps = array.new<MTFGap>()

// 用于去重的各周期时间戳记录
var int last_b_5m= 0, var int last_s_5m= 0
var int last_b_15m = 0, var int last_s_15m = 0
var int last_b_30m = 0, var int last_s_30m = 0
var int last_b_1h= 0, var int last_s_1h= 0
var int last_b_2h= 0, var int last_s_2h= 0
var int last_b_4h= 0, var int last_s_4h= 0
var int last_b_1d= 0, var int last_s_1d= 0
var int last_b_1w= 0, var int last_s_1w= 0

// ==================== 4. 周期计算核心函数 ====================
f_calc_gaps(lookback, min_ratio) =>
    float bull_lvl = na
    int bull_t = na
    float bear_lvl = na
    int bear_t = na
   
    // 当前周期阳线实体突破左侧锚点阴线最高点(套住空头)
    if close > open
      for i = 1 to lookback
            float b_open = open
            float b_close = close
            float b_high = high
            float b_low = low
            float b_ratio = (b_high - b_low > 0) ? (b_open - b_close) / (b_high - b_low) : 0.0
            if b_close < b_open and b_ratio >= min_ratio
                if close > b_high
                  bull_lvl := b_high
                  bull_t := time
                  break
                  
    // 当前周期阴线实体跌破左侧锚点阳线最低点(套住多头)
    if close < open
      for i = 1 to lookback
            float b_open = open
            float b_close = close
            float b_high = high
            float b_low = low
            float b_ratio = (b_high - b_low > 0) ? (b_close - b_open) / (b_high - b_low) : 0.0
            if b_close > b_open and b_ratio >= min_ratio
                if close < b_low
                  bear_lvl := b_low
                  bear_t := time
                  break
                  
   

// ==================== 5. 全局最外层获取各周期数据 (避免报错) ====================
= request.security(syminfo.tickerid, "5",   f_calc_gaps(lookback_max, min_body_ratio), lookahead=barmerge.lookahead_off)
= request.security(syminfo.tickerid, "15",f_calc_gaps(lookback_max, min_body_ratio), lookahead=barmerge.lookahead_off)
= request.security(syminfo.tickerid, "30",f_calc_gaps(lookback_max, min_body_ratio), lookahead=barmerge.lookahead_off)
= request.security(syminfo.tickerid, "60",f_calc_gaps(lookback_max, min_body_ratio), lookahead=barmerge.lookahead_off)
= request.security(syminfo.tickerid, "120", f_calc_gaps(lookback_max, min_body_ratio), lookahead=barmerge.lookahead_off)
= request.security(syminfo.tickerid, "240", f_calc_gaps(lookback_max, min_body_ratio), lookahead=barmerge.lookahead_off)
= request.security(syminfo.tickerid, "D",   f_calc_gaps(lookback_max, min_body_ratio), lookahead=barmerge.lookahead_off)
= request.security(syminfo.tickerid, "W",   f_calc_gaps(lookback_max, min_body_ratio), lookahead=barmerge.lookahead_off)

// 缺口画线注册辅助处理
add_gap(float bull_lvl, int bull_t, float bear_lvl, int bear_t, string tf_name, bool enabled, int last_b, int last_s) =>
    int new_b = last_b
    int new_s = last_s
    if enabled
      // 注册多头缺口
      if not na(bull_lvl) and not na(bull_t) and bull_t != last_b
            newLine = line.new(x1=bull_t, y1=bull_lvl, x2=time, y2=bull_lvl, xloc=xloc.bar_time, color=col_bull, width=line_width, style=line.style_solid)
            newLbl= show_labels ? label.new(x=bull_t, y=bull_lvl, text="[" + tf_name + "] 多头缺口", xloc=xloc.bar_time, style=label.style_label_down, color=col_bull, textcolor=color.white, size=size.tiny) : na
            array.push(all_gaps, MTFGap.new(newLine, newLbl, bull_lvl, true, false, bull_t, tf_name))
            new_b := bull_t

      // 注册空头缺口
      if not na(bear_lvl) and not na(bear_t) and bear_t != last_s
            newLine = line.new(x1=bear_t, y1=bear_lvl, x2=time, y2=bear_lvl, xloc=xloc.bar_time, color=col_bear, width=line_width, style=line.style_solid)
            newLbl= show_labels ? label.new(x=bear_t, y=bear_lvl, text="[" + tf_name + "] 空头缺口", xloc=xloc.bar_time, style=label.style_label_up, color=col_bear, textcolor=color.white, size=size.tiny) : na
            array.push(all_gaps, MTFGap.new(newLine, newLbl, bear_lvl, false, false, bear_t, tf_name))
            new_s := bear_t
   

// 处理各周期缺口画线
= add_gap(b_lvl_5m,b_t_5m,s_lvl_5m,s_t_5m,"5m",show_5m,last_b_5m,last_s_5m)
= add_gap(b_lvl_15m, b_t_15m, s_lvl_15m, s_t_15m, "15m", show_15m, last_b_15m, last_s_15m)
= add_gap(b_lvl_30m, b_t_30m, s_lvl_30m, s_t_30m, "30m", show_30m, last_b_30m, last_s_30m)
= add_gap(b_lvl_1h,b_t_1h,s_lvl_1h,s_t_1h,"1H",show_1h,last_b_1h,last_s_1h)
= add_gap(b_lvl_2h,b_t_2h,s_lvl_2h,s_t_2h,"2H",show_2h,last_b_2h,last_s_2h)
= add_gap(b_lvl_4h,b_t_4h,s_lvl_4h,s_t_4h,"4H",show_4h,last_b_4h,last_s_4h)
= add_gap(b_lvl_1d,b_t_1d,s_lvl_1d,s_t_1d,"日线", show_1d,last_b_1d,last_s_1d)
= add_gap(b_lvl_1w,b_t_1w,s_lvl_1w,s_t_1w,"周线", show_1w,last_b_1w,last_s_1w)

last_b_5m := nb_5m,   last_s_5m := ns_5m
last_b_15m := nb_15m, last_s_15m := ns_15m
last_b_30m := nb_30m, last_s_30m := ns_30m
last_b_1h := nb_1h,   last_s_1h := ns_1h
last_b_2h := nb_2h,   last_s_2h := ns_2h
last_b_4h := nb_4h,   last_s_4h := ns_4h
last_b_1d := nb_1d,   last_s_1d := ns_1d
last_b_1w := nb_1w,   last_s_1w := ns_1w

// ==================== 6. 实时回补与线段向右延伸 ====================
if array.size(all_gaps) > 0
    for i = array.size(all_gaps) - 1 to 0
      MTFGap g = array.get(all_gaps, i)
      
      if not g.mitigated
            bool is_hit = false
            // 支撑线触碰回补 (low <= level)
            if g.is_bull and low <= g.level and time > g.start_time
                is_hit := true
            // 阻力线触碰回补 (high >= level)
            if not g.is_bull and high >= g.level and time > g.start_time
                is_hit := true
               
            if is_hit
                g.mitigated := true
                line.set_x2(g.l, time)
                if show_mitigated
                  line.set_color(g.l, col_mitigated)
                  line.set_style(g.l, line.style_dashed)
                  line.set_width(g.l, 1)
                  if not na(g.lbl)
                        label.set_text(g.lbl, "[" + g.tf_tag + "] 已回补")
                        label.set_color(g.lbl, color.gray)
                else
                  line.delete(g.l)
                  if not na(g.lbl)
                        label.delete(g.lbl)
            else
                // 尚未回补,持续往当前最新时间延伸
                line.set_x2(g.l, time)

// 内存清理,超出上限时删除最旧的绘图对象
if array.size(all_gaps) > 400
    MTFGap old_g = array.shift(all_gaps)
    line.delete(old_g.l)
    if not na(old_g.lbl)
      label.delete(old_g.lbl)

dyh1334318 发表于 2026-9-23 11:05:29

看看还要花币啊
页: [1]
查看完整版本: 【tradingview 多时间周期突破缺口检测】K线缺口检测指标