Files
tradingview/chan_theory_perfect.pine
T
2025-09-28 11:48:03 +08:00

168 lines
7.1 KiB
Plaintext

//@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<Fractal>()
var final_fractals = array.new<Fractal>()
var strokes = array.new<line>()
// 安全的分型识别 - 添加历史数据检查
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)