//@version=6 indicator("缠论完美版", shorttitle="完美版", overlay=true, max_lines_count=100, max_labels_count=100) // 参数设置 min_gap = input.int(10, "分型间隔", minval=5, maxval=30) show_debug = input.bool(false, "显示调试信息") show_strokes = input.bool(true, "显示笔") // 数据类型 type Fractal int bar_index float price string type // 全局变量 var raw_fractals = array.new() var final_fractals = array.new() var strokes = array.new() // 安全的分型识别 - 添加历史数据检查 is_top = bar_index >= 2 and high[1] > high[0] and high[1] > high[2] and low[1] > low[0] and low[1] > low[2] is_bottom = bar_index >= 2 and low[1] < low[0] and low[1] < low[2] and high[1] < high[0] and high[1] < high[2] // 距离检查 valid_distance(new_bar) => result = true if array.size(raw_fractals) > 0 last = array.get(raw_fractals, array.size(raw_fractals) - 1) if new_bar - last.bar_index < min_gap result := false result // 添加原始分型 - 简化条件检查 if is_top and valid_distance(bar_index[1]) array.push(raw_fractals, Fractal.new(bar_index[1], high[1], "top")) if array.size(raw_fractals) > 50 // 减少数组大小限制 array.shift(raw_fractals) if is_bottom and valid_distance(bar_index[1]) array.push(raw_fractals, Fractal.new(bar_index[1], low[1], "bottom")) if array.size(raw_fractals) > 50 // 减少数组大小限制 array.shift(raw_fractals) // 显示原始分型(调试) if show_debug if is_top and valid_distance(bar_index[1]) label.new(bar_index[1], high[1], "顶", color=color.red, style=label.style_label_down, size=size.tiny) if is_bottom and valid_distance(bar_index[1]) label.new(bar_index[1], low[1], "底", color=color.green, style=label.style_label_up, size=size.tiny) // 核心:结合律过滤 - 添加更多安全检查 if barstate.isconfirmed and array.size(raw_fractals) > 0 // 重新构建有效分型 array.clear(final_fractals) // 第一个分型 array.push(final_fractals, array.get(raw_fractals, 0)) // 从第二个开始处理 if array.size(raw_fractals) > 1 i = 1 while i < array.size(raw_fractals) current = array.get(raw_fractals, i) if array.size(final_fractals) > 0 last_final = array.get(final_fractals, array.size(final_fractals) - 1) if current.type != last_final.type // 不同类型:直接加入 array.push(final_fractals, current) i += 1 else // 相同类型:找最极端的 extreme = current j = i + 1 // 扫描后续同类型分型 while j < array.size(raw_fractals) next = array.get(raw_fractals, j) if next.type == current.type if current.type == "top" if next.price > extreme.price extreme := next else if next.price < extreme.price extreme := next j += 1 else break // 加入极值分型 array.push(final_fractals, extreme) i := j else // 如果final_fractals为空,直接添加 array.push(final_fractals, current) i += 1 // 重绘笔 - 修复统计问题 if array.size(strokes) > 0 for k = 0 to array.size(strokes) - 1 line.delete(array.get(strokes, k)) array.clear(strokes) if show_strokes and array.size(final_fractals) >= 2 for m = 0 to array.size(final_fractals) - 2 f1 = array.get(final_fractals, m) f2 = array.get(final_fractals, m + 1) // 放宽距离限制,确保所有笔都能绘制 distance_from_current = bar_index - f1.bar_index if distance_from_current <= 500 and distance_from_current >= 0 // 恢复到500根K线 color_line = f1.type == "bottom" ? color.blue : color.red line_obj = line.new(f1.bar_index, f1.price, f2.bar_index, f2.price, color=color_line, width=3) array.push(strokes, line_obj) // 显示最终分型 - 添加距离检查 if barstate.islast and array.size(final_fractals) > 0 for n = 0 to array.size(final_fractals) - 1 frac = array.get(final_fractals, n) distance_from_current = bar_index - frac.bar_index if distance_from_current <= 500 // 恢复到500根K线 if frac.type == "top" label.new(frac.bar_index, frac.price, "T", color=color.yellow, style=label.style_label_down, size=size.normal) else label.new(frac.bar_index, frac.price, "B", color=color.orange, style=label.style_label_up, size=size.normal) // 改进的信息统计 if barstate.islast var table info = table.new(position.top_right, 2, 7, bgcolor=color.white, border_width=1) raw_count = array.size(raw_fractals) final_count = array.size(final_fractals) stroke_count = array.size(strokes) theoretical_strokes = final_count > 0 ? final_count - 1 : 0 filter_percent = raw_count > 0 ? math.round((raw_count - final_count) * 100 / raw_count) : 0 // 计算实际可绘制的笔数 drawable_strokes = 0 if array.size(final_fractals) >= 2 for m = 0 to array.size(final_fractals) - 2 f1 = array.get(final_fractals, m) distance_from_current = bar_index - f1.bar_index if distance_from_current <= 500 and distance_from_current >= 0 drawable_strokes += 1 table.cell(info, 0, 0, "缠论完美版", text_color=color.blue, text_size=size.normal) table.cell(info, 1, 0, "V1.2", text_color=color.gray) table.cell(info, 0, 1, "原始分型", text_color=color.black) table.cell(info, 1, 1, str.tostring(raw_count), text_color=color.green) table.cell(info, 0, 2, "有效分型", text_color=color.black) table.cell(info, 1, 2, str.tostring(final_count), text_color=color.red) table.cell(info, 0, 3, "过滤率", text_color=color.black) table.cell(info, 1, 3, str.tostring(filter_percent) + "%", text_color=color.purple) table.cell(info, 0, 4, "笔数", text_color=color.black) table.cell(info, 1, 4, str.tostring(stroke_count), text_color=color.blue) table.cell(info, 0, 5, "可绘制笔", text_color=color.black) table.cell(info, 1, 5, str.tostring(drawable_strokes), text_color=color.gray) table.cell(info, 0, 6, "状态", text_color=color.black) status = stroke_count == drawable_strokes ? "✓正常" : "✗异常" status_color = stroke_count == drawable_strokes ? color.green : color.red table.cell(info, 1, 6, status, text_color=status_color)