【tradingview 多时间周期突破缺口检测】K线缺口检测指标
//@version=5indicator("多时间周期突破型缺口 (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)
看看还要花币啊
页:
[1]