//@version=6 indicator("缠论正确版", shorttitle="缠论正确", overlay=true, max_lines_count=100, max_labels_count=100) // 简单参数 min_gap = input.int(5, "分型间隔") show_fractals = input.bool(true, "显示分型") show_strokes = input.bool(true, "显示笔") // 数据类型 type Fractal int bar_index float price string type // "top" or "bottom" // 全局变量 var fractals = array.new() var stroke_lines = array.new() // 简单分型检测 is_high = high[1] > high[0] and high[1] > high[2] is_low = low[1] < low[0] and low[1] < low[2] // 距离检查 distance_ok(new_bar) => result = true if array.size(fractals) > 0 last_fractal = array.get(fractals, array.size(fractals) - 1) if new_bar - last_fractal.bar_index < min_gap result := false result // 添加分型 if is_high and distance_ok(bar_index[1]) new_fractal = Fractal.new(bar_index[1], high[1], "top") array.push(fractals, new_fractal) if array.size(fractals) > 50 array.shift(fractals) if is_low and distance_ok(bar_index[1]) new_fractal = Fractal.new(bar_index[1], low[1], "bottom") array.push(fractals, new_fractal) if array.size(fractals) > 50 array.shift(fractals) // 显示分型 if show_fractals if is_high and distance_ok(bar_index[1]) label.new(bar_index[1], high[1], "顶", color=color.red, style=label.style_label_down, size=size.small) if is_low and distance_ok(bar_index[1]) label.new(bar_index[1], low[1], "底", color=color.green, style=label.style_label_up, size=size.small) // 重新构建所有笔(满足结合律) if barstate.isconfirmed and show_strokes // 清理旧笔 if array.size(stroke_lines) > 0 for i = 0 to array.size(stroke_lines) - 1 line.delete(array.get(stroke_lines, i)) array.clear(stroke_lines) // 构建连续的笔序列(处理中继分型) if array.size(fractals) >= 2 var current_start_idx = 0 var current_direction = "" // 确定起始方向 if array.size(fractals) >= 2 first_fractal = array.get(fractals, 0) second_fractal = array.get(fractals, 1) if first_fractal.type != second_fractal.type current_direction := first_fractal.type // 从第二个分型开始遍历 for i = 1 to array.size(fractals) - 1 current_fractal = array.get(fractals, i) // 如果找到不同类型的分型,结束当前笔 if current_fractal.type != current_direction start_fractal = array.get(fractals, current_start_idx) // 绘制笔 distance = bar_index - start_fractal.bar_index if distance <= 500 stroke_line = line.new(start_fractal.bar_index, start_fractal.price, current_fractal.bar_index, current_fractal.price, color=color.blue, width=2, style=line.style_solid) array.push(stroke_lines, stroke_line) // 开始新笔 current_start_idx := i current_direction := current_fractal.type else // 同类型分型,处理中继 start_fractal = array.get(fractals, current_start_idx) // 如果当前分型更极端,更新起始点 if current_direction == "top" if current_fractal.price > start_fractal.price current_start_idx := i else // bottom if current_fractal.price < start_fractal.price current_start_idx := i // 信息显示 if barstate.islast var table info = table.new(position.top_right, 2, 4, bgcolor=color.white, border_width=1) table.cell(info, 0, 0, "缠论正确版", text_color=color.black, text_size=size.small) table.cell(info, 1, 0, "", text_color=color.black) table.cell(info, 0, 1, "分型数", text_color=color.black) table.cell(info, 1, 1, str.tostring(array.size(fractals)), text_color=color.black) table.cell(info, 0, 2, "笔数", text_color=color.black) table.cell(info, 1, 2, str.tostring(array.size(stroke_lines)), text_color=color.black) table.cell(info, 0, 3, "分型间隔", text_color=color.black) table.cell(info, 1, 3, str.tostring(min_gap), text_color=color.black)