Pine Script实现任意时间框架标注周/月/年高低点(解决重复标记问题)
问题原因
- 标记全K线重复:原代码用
ta.valuewhen()会持续返回最近一次匹配条件的固定值,没有做「仅在极值生成的那根K线返回有效值、其余K线返回空值na」的限制,导致后续所有K线都会触发绘制。 - 上周高点逻辑错误:原代码对应判断条件写为
high == high[1],完全没有关联拉取到的周线高点数据,逻辑不生效。 - 跨周期调用未加防漂移参数:直接调用
request.security默认会启用未来数据引用,会导致信号来回漂移。
修正后完整代码(支持周/月/年、当前/上一周期高低点,仅在对应极值K线显示标记)
//@version=5 indicator("多周期高低点标记", overlay=true, shorttitle="HL Mark", precision=2) // 封装无未来函数的跨周期数据拉取方法 get_htf_data(tf, src) => request.security(syminfo.tickerid, tf, src, barmerge.gaps_on, barmerge.lookahead_off) // 拉取各周期高低点 w_high = get_htf_data("W", high) w_low = get_htf_data("W", low) m_high = get_htf_data("M", high) m_low = get_htf_data("M", low) y_high = get_htf_data("Y", high) y_low = get_htf_data("Y", low) // 封装:仅在极值K线返回对应值,其余位置返回na,避免重复绘制 get_hl_mark(is_high, tf, htf_high, htf_low, is_prev) => target_h = is_prev ? htf_high[1] : htf_high target_l = is_prev ? htf_low[1] : htf_low if is_prev // 上一周期极值:仅标记上一周期内创出极值的K线 prev_cycle_end = ta.barssince(ta.change(time(tf))) in_prev_cycle = prev_cycle_end > 0 h_mark = is_high ? (in_prev_cycle and high == target_h ? high : na) : na l_mark = not is_high ? (in_prev_cycle and low == target_l ? low : na) : na else // 当前周期极值:仅标记周期启动以来最新创出极值的K线 cycle_bars = ta.barssince(ta.change(time(tf))) + 1 h_mark = is_high ? (high == ta.highest(high, cycle_bars) ? high : na) : na l_mark = not is_high ? (low == ta.lowest(low, cycle_bars) ? low : na) : na is_high ? h_mark : l_mark // 计算各标记位置 // 周级别 cur_w_h = get_hl_mark(true, "W", w_high, w_low, false) cur_w_l = get_hl_mark(false, "W", w_high, w_low, false) prev_w_h = get_hl_mark(true, "W", w_high, w_low, true) prev_w_l = get_hl_mark(false, "W", w_high, w_low, true) // 月级别 cur_m_h = get_hl_mark(true, "M", m_high, m_low, false) cur_m_l = get_hl_mark(false, "M", m_high, m_low, false) prev_m_h = get_hl_mark(true, "M", m_high, m_low, true) prev_m_l = get_hl_mark(false, "M", m_high, m_low, true) // 年级别 cur_y_h = get_hl_mark(true, "Y", y_high, y_low, false) cur_y_l = get_hl_mark(false, "Y", y_high, y_low, false) prev_y_h = get_hl_mark(true, "Y", y_high, y_low, true) prev_y_l = get_hl_mark(false, "Y", y_high, y_low, true) // 绘制字符标记 plotchar(cur_w_h, "本周高点", "▼", location.abovebar, color.lime, size=size.tiny) plotchar(cur_w_l, "本周低点", "▲", location.belowbar, color.blue, size=size.tiny) plotchar(prev_w_h, "上周高点", "▼", location.abovebar, color.teal, size=size.tiny) plotchar(prev_w_l, "上周低点", "▲", location.belowbar, color.maroon, size=size.tiny) plotchar(cur_m_h, "本月高点", "▼", location.abovebar, color.green, size=size.small) plotchar(cur_m_l, "本月低点", "▲", location.belowbar, color.navy, size=size.small) plotchar(prev_m_h, "上月高点", "▼", location.abovebar, color.olive, size=size.small) plotchar(prev_m_l, "上月低点", "▲", location.belowbar, color.purple, size=size.small) plotchar(cur_y_h, "本年高点", "▼", location.abovebar, color.red, size=size.normal) plotchar(cur_y_l, "本年低点", "▲", location.belowbar, color.orange, size=size.normal) plotchar(prev_y_h, "上年高点", "▼", location.abovebar, color.gray, size=size.normal) plotchar(prev_y_l, "上年低点", "▲", location.belowbar, color.black, size=size.normal)
style_label_up/style_label_down 标签配置方法
这两个样式是label.new()函数的专属样式,不能直接在plotchar中调用,配置规则如下:
- 坐标参数:x轴直接传当前K线的
bar_index即可;y轴高点传high + ta.tr * 0.1(在高点上方留10%当前波幅的空隙,避免遮挡K线),低点传low - ta.tr * 0.1。 - 样式匹配:
- 标注高点用
label.style_label_up:标签主体在坐标点上方,尖角向下指向高点,不会遮挡K线 - 标注低点用
label.style_label_down:标签主体在坐标点下方,尖角向上指向低点
- 标注高点用
- 注意:标注实时更新的当前周期高低点时,需要用
var声明标签变量,每次刷新极值前先删除旧标签,避免残留无效标记。 - 参考代码片段:
// 本周高点带数值标签 if not na(cur_w_h) label.new(bar_index, high + ta.tr*0.1, str.tostring(cur_w_h, "#.##"), style=label.style_label_up, color=color.lime, textcolor=color.black, size=size.tiny) // 本周低点带数值标签 if not na(cur_w_l) label.new(bar_index, low - ta.tr*0.1, str.tostring(cur_w_l, "#.##"), style=label.style_label_down, color=color.blue, textcolor=color.white, size=size.tiny)
内容的提问来源于stack exchange,提问作者silverstreak
相关产品推荐
相关产品推荐

