Quasimodo Pattern指标滞后修复求助:5-15K线延迟问题排查
Quasimodo Pattern指标滞后修复方案
问题说明
找到一款可检测扫盘(sweep)后MSB突破的Quasimodo Pattern指标,该指标存在5至15根K线的显示滞后问题,无法及时识别形态。原指标代码如下:
indicator("Quasimodo Pattern", "QML", overlay=true, max_bars_back=5000, max_labels_count=500, max_lines_count=500) zigzag_len = input.int(5, "ZigZag Length") //pivotLookup = input.int(defval=1, minval=1, maxval=5,title='Pivot Lookup', tooltip='Minimum = 1, Maximum = 5') var float[] high_points_arr = array.new_float(5) var int[] high_index_arr = array.new_int(5) var float[] low_points_arr = array.new_float(5) var int[] low_index_arr = array.new_int(5) to_up = high >= ta.highest(zigzag_len) to_down = low <= ta.lowest(zigzag_len) trend = 1 trend := nz(trend[1], 1) trend := trend == 1 and to_down ? -1 : trend == -1 and to_up ? 1 : trend last_trend_up_since = ta.barssince(to_up[1]) low_val = ta.lowest(nz(last_trend_up_since > 0 ? last_trend_up_since : 1, 1)) low_index = bar_index - ta.barssince(low_val == low) last_trend_down_since = ta.barssince(to_down[1]) high_val = ta.highest(nz(last_trend_down_since > 0 ? last_trend_down_since : 1, 1)) high_index = bar_index - ta.barssince(high_val == high) if ta.change(trend) != 0 if trend == 1 //Down array.push(low_points_arr, low_val) array.push(low_index_arr, low_index) if trend == -1 //Up array.push(high_points_arr, high_val) array.push(high_index_arr, high_index) f_get_high(ind) => [array.get(high_points_arr, array.size(high_points_arr) - 1 - ind), array.get(high_index_arr, array.size(high_index_arr) - 1 - ind)] f_get_low(ind) => [array.get(low_points_arr, array.size(low_points_arr) - 1 - ind), array.get(low_index_arr, array.size(low_index_arr) - 1 - ind)] [h0, h0i] = f_get_high(0) [l0, l0i] = f_get_low(0) [h1, h1i] = f_get_high(1) [l1, l1i] = f_get_low(1) [h2, h2i] = f_get_high(2) [l2, l2i] = f_get_low(2) bu_cond = trend == -1 and h2 > h1 and l1 > l0 and h0 > h1 //and close > h1 be_cond = trend == 1 and l2 < l1 and h1 < h0 and l0 < l1 //and close < l1 if bu_cond and not bu_cond[1] //line.new(h2i, h2, l1i, l1, color=color.green, width=2) line.new(l1i, l1, h1i, h1, color=color.green, width=2) line.new(h1i, h1, l0i, l0, color=color.green, width=2) line.new(l0i, l0, h0i, h0, color=color.green, width=2) line.new(l1i, l1, bar_index, l1, color=color.green, width=2) label.new(bar_index, l1, "Bull BB", style=label.style_label_up, textcolor=color.white, color=color.green, size=size.tiny) alert("Bullish QM!", alert.freq_once_per_bar) if be_cond and not be_cond[1] //line.new(l2i, l2, h1i, h1, color=color.red, width=2) line.new(h1i, h1, l1i, l1, color=color.red, width=2) line.new(l1i, l1, h0i, h0, color=color.red, width=2) line.new(h0i, h0, l0i, l0, color=color.red, width=2) line.new(h1i, h1, bar_index, h1, color=color.red, width=2) label.new(bar_index, h1, "Bear BB", style=label.style_label_down, textcolor=color.white, color=color.red, size=size.tiny) alert("Bearish BB!", alert.freq_once_per_bar)
问题根源
- 高低点识别滞后:原代码通过
ta.barssince(to_up[1])回溯寻找高低点,需等待趋势信号确认后反向查找,导致信号延迟5-15根K线。 - 形态触发依赖趋势反转:仅在趋势反转时记录高低点,但Quasimodo形态确认无需等待趋势完全反转,MSB突破后即可触发。
- 高低点计算逻辑冗余:
ta.lowest(nz(last_trend_up_since > 0 ? last_trend_up_since : 1, 1))的计算范围基于滞后信号,无法实时捕捉最新形态结构。
修复后的代码
indicator("Quasimodo Pattern (Fixed)", "QML-FIX", overlay=true, max_bars_back=5000, max_labels_count=500, max_lines_count=500) zigzag_len = input.int(5, "ZigZag Length") pivot_lookback = input.int(1, "Pivot Lookback", minval=1, maxval=5) // 实时识别高低点 pivot is_high_pivot = ta.pivothigh(zigzag_len, zigzag_len) is_low_pivot = ta.pivotlow(zigzag_len, zigzag_len) // 存储最近的3个高低点(用于形态判断) var float[] high_points = array.new_float(3) var int[] high_indices = array.new_int(3) var float[] low_points = array.new_float(3) var int[] low_indices = array.new_int(3) // 更新高低点数组 if is_high_pivot array.unshift(high_points, high) array.unshift(high_indices, bar_index) if array.size(high_points) > 3 array.pop(high_points) array.pop(high_indices) if is_low_pivot array.unshift(low_points, low) array.unshift(low_indices, bar_index) if array.size(low_points) > 3 array.pop(low_points) array.pop(low_indices) // 获取最近的3个高低点(确保数组元素足够) has_enough_highs = array.size(high_points) >= 3 has_enough_lows = array.size(low_points) >= 3 h0 = has_enough_highs ? array.get(high_points, 0) : na h0i = has_enough_highs ? array.get(high_indices, 0) : na h1 = has_enough_highs ? array.get(high_points, 1) : na h1i = has_enough_highs ? array.get(high_indices, 1) : na h2 = has_enough_highs ? array.get(high_points, 2) : na h2i = has_enough_highs ? array.get(high_indices, 2) : na l0 = has_enough_lows ? array.get(low_points, 0) : na l0i = has_enough_lows ? array.get(low_indices, 0) : na l1 = has_enough_lows ? array.get(low_points, 1) : na l1i = has_enough_lows ? array.get(low_indices, 1) : na l2 = has_enough_lows ? array.get(low_points, 2) : na l2i = has_enough_lows ? array.get(low_indices, 2) : na // 修正形态条件:直接通过pivot顺序和价格关系+MSB突破判断 bull_qm_cond = has_enough_highs and has_enough_lows and h2 > h1 and l1 > l0 and h0 > h1 and close > h1 bear_qm_cond = has_enough_highs and has_enough_lows and l2 < l1 and h1 < h0 and l0 < l1 and close < l1 // 避免重复触发信号 var bool last_bull = false var bool last_bear = false if bull_qm_cond and not last_bull line.new(l1i, l1, h1i, h1, color=color.green, width=2) line.new(h1i, h1, l0i, l0, color=color.green, width=2) line.new(l0i, l0, h0i, h0, color=color.green, width=2) line.new(l1i, l1, bar_index, l1, color=color.green, width=2) label.new(bar_index, l1, "Bull QM", style=label.style_label_up, textcolor=color.white, color=color.green, size=size.tiny) alert("Bullish Quasimodo!", alert.freq_once_per_bar) last_bull := true else last_bull := bull_qm_cond if bear_qm_cond and not last_bear line.new(h1i, h1, l1i, l1, color=color.red, width=2) line.new(l1i, l1, h0i, h0, color=color.red, width=2) line.new(h0i, h0, l0i, l0, color=color.red, width=2) line.new(h1i, h1, bar_index, h1, color=color.red, width=2) label.new(bar_index, h1, "Bear QM", style=label.style_label_down, textcolor=color.white, color=color.red, size=size.tiny) alert("Bearish Quasimodo!", alert.freq_once_per_bar) last_bear := true else last_bear := bear_qm_cond
修复说明
- 实时Pivot识别:改用
ta.pivothigh()和ta.pivotlow()直接实时捕捉高低点,消除回溯滞后。 - 动态高低点存储:用
array.unshift()实时更新最近3个高低点,确保形态判断使用最新数据。 - 同步触发条件:将形态确认与MSB突破(收盘价突破关键位)绑定,无需依赖趋势反转,信号触发与形态完成同步。
- 防重复触发:通过变量记录上一次信号状态,避免同一形态多次触发。
内容的提问来源于stack exchange,提问作者F H
相关产品推荐
相关产品推荐

