154 lines
6.2 KiB
Plaintext
154 lines
6.2 KiB
Plaintext
//@version=6
|
|
indicator("缠论结合律版", shorttitle="结合律", overlay=true, max_lines_count=100, max_labels_count=100)
|
|
|
|
// 参数
|
|
min_gap = input.int(3, "分型间隔", minval=1, maxval=20)
|
|
show_fractals = input.bool(true, "显示分型")
|
|
show_strokes = input.bool(true, "显示笔")
|
|
show_filtered = input.bool(true, "显示过滤后分型")
|
|
|
|
// 数据类型
|
|
type Fractal
|
|
int bar_index
|
|
float price
|
|
string type
|
|
bool is_valid // 是否为有效分型(非中继)
|
|
|
|
// 全局变量
|
|
var all_fractals = array.new<Fractal>() // 所有分型
|
|
var valid_fractals = array.new<Fractal>() // 过滤后的分型
|
|
var stroke_lines = array.new<line>()
|
|
|
|
// 分型识别
|
|
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(all_fractals) > 0
|
|
last_fractal = array.get(all_fractals, array.size(all_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", true)
|
|
array.push(all_fractals, new_fractal)
|
|
|
|
if array.size(all_fractals) > 100
|
|
array.shift(all_fractals)
|
|
|
|
if is_low and distance_ok(bar_index[1])
|
|
new_fractal = Fractal.new(bar_index[1], low[1], "bottom", true)
|
|
array.push(all_fractals, new_fractal)
|
|
|
|
if array.size(all_fractals) > 100
|
|
array.shift(all_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.tiny)
|
|
|
|
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.tiny)
|
|
|
|
// 应用结合律,过滤中继分型
|
|
filter_fractals() =>
|
|
// 清空有效分型数组
|
|
array.clear(valid_fractals)
|
|
|
|
if array.size(all_fractals) <= 1
|
|
// 如果分型数量不足,直接返回
|
|
if array.size(all_fractals) == 1
|
|
array.push(valid_fractals, array.get(all_fractals, 0))
|
|
else
|
|
// 第一个分型总是有效的
|
|
first_fractal = array.get(all_fractals, 0)
|
|
array.push(valid_fractals, first_fractal)
|
|
|
|
// 从第二个分型开始处理
|
|
i = 1
|
|
while i < array.size(all_fractals)
|
|
current_fractal = array.get(all_fractals, i)
|
|
last_valid = array.get(valid_fractals, array.size(valid_fractals) - 1)
|
|
|
|
if current_fractal.type != last_valid.type
|
|
// 不同类型,直接添加
|
|
array.push(valid_fractals, current_fractal)
|
|
i += 1
|
|
else
|
|
// 相同类型,找到最极端的分型
|
|
extreme_fractal = current_fractal
|
|
extreme_idx = i
|
|
|
|
// 继续查找同类型的更极端分型
|
|
j = i + 1
|
|
while j < array.size(all_fractals)
|
|
next_fractal = array.get(all_fractals, j)
|
|
if next_fractal.type == current_fractal.type
|
|
// 同类型,比较极端程度
|
|
if current_fractal.type == "top"
|
|
if next_fractal.price > extreme_fractal.price
|
|
extreme_fractal := next_fractal
|
|
extreme_idx := j
|
|
else // bottom
|
|
if next_fractal.price < extreme_fractal.price
|
|
extreme_fractal := next_fractal
|
|
extreme_idx := j
|
|
j += 1
|
|
else
|
|
// 不同类型,结束查找
|
|
break
|
|
|
|
// 添加最极端的分型
|
|
array.push(valid_fractals, extreme_fractal)
|
|
i := j // 跳到不同类型的分型
|
|
|
|
// 每根K线更新
|
|
if barstate.isconfirmed
|
|
// 过滤分型
|
|
filter_fractals()
|
|
|
|
// 清理旧笔
|
|
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 show_strokes and array.size(valid_fractals) >= 2
|
|
for i = 0 to array.size(valid_fractals) - 2
|
|
current_fractal = array.get(valid_fractals, i)
|
|
next_fractal = array.get(valid_fractals, i + 1)
|
|
|
|
// 检查距离
|
|
distance = bar_index - current_fractal.bar_index
|
|
if distance <= 500
|
|
stroke_line = line.new(current_fractal.bar_index, current_fractal.price, next_fractal.bar_index, next_fractal.price, color=color.blue, width=2, style=line.style_solid)
|
|
array.push(stroke_lines, stroke_line)
|
|
|
|
// 显示过滤后的分型
|
|
if show_filtered and barstate.islast
|
|
for i = 0 to array.size(valid_fractals) - 1
|
|
fractal = array.get(valid_fractals, i)
|
|
if fractal.type == "top"
|
|
label.new(fractal.bar_index, fractal.price, "T", color=color.yellow, style=label.style_label_down, size=size.small)
|
|
else
|
|
label.new(fractal.bar_index, fractal.price, "B", color=color.orange, style=label.style_label_up, size=size.small)
|
|
|
|
// 信息显示
|
|
if barstate.islast
|
|
var table info = table.new(position.top_right, 2, 5, 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(all_fractals)), text_color=color.black)
|
|
table.cell(info, 0, 2, "有效分型", text_color=color.black)
|
|
table.cell(info, 1, 2, str.tostring(array.size(valid_fractals)), text_color=color.black)
|
|
table.cell(info, 0, 3, "笔数", text_color=color.black)
|
|
table.cell(info, 1, 3, str.tostring(array.size(stroke_lines)), text_color=color.black)
|
|
table.cell(info, 0, 4, "分型间隔", text_color=color.black)
|
|
table.cell(info, 1, 4, str.tostring(min_gap), text_color=color.black) |