添加老的策略
This commit is contained in:
@@ -0,0 +1,371 @@
|
||||
//@version=6
|
||||
indicator("缠论标准版V3", shorttitle="缠论标准V3", overlay=true, max_lines_count=200, max_labels_count=200)
|
||||
|
||||
// ================== 参数设置 ==================
|
||||
show_merged_k = input.bool(true, "显示合并K线", group="显示设置")
|
||||
show_fenxing = input.bool(true, "显示分型", group="显示设置")
|
||||
show_bi = input.bool(true, "显示笔", group="显示设置")
|
||||
show_xianduan = input.bool(true, "显示线段", group="显示设置")
|
||||
show_zhongshu = input.bool(true, "显示中枢", group="显示设置")
|
||||
show_signals = input.bool(true, "显示买卖点", group="显示设置")
|
||||
debug_mode = input.bool(false, "调试模式(禁用分型间隔过滤)", group="显示设置")
|
||||
|
||||
// 缠论参数
|
||||
fractal_length = input.int(1, "分型识别周期", minval=1, maxval=3, group="缠论参数")
|
||||
min_bars_between = input.int(2, "分型最小间隔", minval=1, maxval=20, group="缠论参数")
|
||||
strict_fractal = input.bool(false, "严格分型模式", group="缠论参数")
|
||||
bi_color = input.color(color.blue, "笔的颜色", group="颜色设置")
|
||||
xianduan_color = input.color(color.red, "线段颜色", group="颜色设置")
|
||||
zhongshu_color = input.color(color.gray, "中枢颜色", group="颜色设置")
|
||||
merged_k_color = input.color(color.orange, "合并K线颜色", group="颜色设置")
|
||||
|
||||
// ================== 数据类型定义 ==================
|
||||
type MergedK
|
||||
int bar_index
|
||||
float high
|
||||
float low
|
||||
float open
|
||||
float close
|
||||
int direction // 1: 向上, -1: 向下, 0: 未确定
|
||||
|
||||
type FractalPoint
|
||||
int bar_index
|
||||
float price
|
||||
string fractal_type
|
||||
bool confirmed
|
||||
|
||||
type BiSegment
|
||||
FractalPoint start_point
|
||||
FractalPoint end_point
|
||||
int direction
|
||||
|
||||
type XianDuan
|
||||
array<BiSegment> bi_segments
|
||||
FractalPoint start_point
|
||||
FractalPoint end_point
|
||||
bool broken
|
||||
|
||||
// ================== 全局变量 ==================
|
||||
var merged_ks = array.new<MergedK>()
|
||||
var fractal_points = array.new<FractalPoint>()
|
||||
var bi_segments = array.new<BiSegment>()
|
||||
var xianduan_segments = array.new<XianDuan>()
|
||||
var bi_lines = array.new<line>()
|
||||
var xianduan_lines = array.new<line>()
|
||||
var zhongshu_boxes = array.new<box>()
|
||||
var merged_k_lines = array.new<line>()
|
||||
var last_signal_bar = 0
|
||||
var current_trend = 0 // 当前趋势方向
|
||||
|
||||
// ================== K线合并处理 ==================
|
||||
// 判断是否存在包含关系
|
||||
is_contained(k1_high, k1_low, k2_high, k2_low) =>
|
||||
(k1_high >= k2_high and k1_low <= k2_low) or (k2_high >= k1_high and k2_low <= k1_low)
|
||||
|
||||
// 执行K线合并
|
||||
if barstate.isconfirmed
|
||||
current_k = MergedK.new(bar_index, high, low, open, close, 0)
|
||||
|
||||
if array.size(merged_ks) == 0
|
||||
array.push(merged_ks, current_k)
|
||||
else
|
||||
last_k = array.get(merged_ks, array.size(merged_ks) - 1)
|
||||
|
||||
// 检查包含关系
|
||||
if is_contained(last_k.high, last_k.low, current_k.high, current_k.low)
|
||||
// 存在包含关系,需要合并
|
||||
merged_high = 0.0
|
||||
merged_low = 0.0
|
||||
|
||||
// 根据趋势方向确定合并规则
|
||||
if current_trend > 0 // 向上趋势
|
||||
merged_high := math.max(last_k.high, current_k.high)
|
||||
merged_low := math.max(last_k.low, current_k.low)
|
||||
else if current_trend < 0 // 向下趋势
|
||||
merged_high := math.min(last_k.high, current_k.high)
|
||||
merged_low := math.min(last_k.low, current_k.low)
|
||||
else // 趋势未确定,按第一根K线方向
|
||||
if last_k.close > last_k.open // 阳线趋势
|
||||
merged_high := math.max(last_k.high, current_k.high)
|
||||
merged_low := math.max(last_k.low, current_k.low)
|
||||
else // 阴线趋势
|
||||
merged_high := math.min(last_k.high, current_k.high)
|
||||
merged_low := math.min(last_k.low, current_k.low)
|
||||
|
||||
// 更新最后一个合并K线
|
||||
last_k.high := merged_high
|
||||
last_k.low := merged_low
|
||||
last_k.close := current_k.close
|
||||
last_k.bar_index := current_k.bar_index
|
||||
else
|
||||
// 无包含关系,直接添加
|
||||
array.push(merged_ks, current_k)
|
||||
|
||||
// 更新趋势方向
|
||||
if array.size(merged_ks) >= 2
|
||||
prev_k = array.get(merged_ks, array.size(merged_ks) - 2)
|
||||
if current_k.high > prev_k.high
|
||||
current_trend := 1
|
||||
else if current_k.low < prev_k.low
|
||||
current_trend := -1
|
||||
|
||||
// 限制数组大小
|
||||
if array.size(merged_ks) > 1000
|
||||
array.shift(merged_ks)
|
||||
|
||||
// ================== 分型识别(基于合并K线)==================
|
||||
// 标准分型识别
|
||||
check_fractal_from_merged() =>
|
||||
var top_fractal = false
|
||||
var bottom_fractal = false
|
||||
var fractal_bar = 0
|
||||
var fractal_high = 0.0
|
||||
var fractal_low = 0.0
|
||||
|
||||
if array.size(merged_ks) >= 3
|
||||
// 检查最近三根合并K线
|
||||
k1 = array.get(merged_ks, array.size(merged_ks) - 3)
|
||||
k2 = array.get(merged_ks, array.size(merged_ks) - 2)
|
||||
k3 = array.get(merged_ks, array.size(merged_ks) - 1)
|
||||
|
||||
if strict_fractal
|
||||
// 严格分型:中间K线的高低点都比左右K线高/低
|
||||
if k2.high > k1.high and k2.high > k3.high and k2.low > k1.low and k2.low > k3.low
|
||||
top_fractal := true
|
||||
fractal_bar := k2.bar_index
|
||||
fractal_high := k2.high
|
||||
|
||||
if k2.high < k1.high and k2.high < k3.high and k2.low < k1.low and k2.low < k3.low
|
||||
bottom_fractal := true
|
||||
fractal_bar := k2.bar_index
|
||||
fractal_low := k2.low
|
||||
else
|
||||
// 宽松分型:只要高点或低点满足条件即可
|
||||
if k2.high > k1.high and k2.high > k3.high
|
||||
top_fractal := true
|
||||
fractal_bar := k2.bar_index
|
||||
fractal_high := k2.high
|
||||
|
||||
if k2.low < k1.low and k2.low < k3.low
|
||||
bottom_fractal := true
|
||||
fractal_bar := k2.bar_index
|
||||
fractal_low := k2.low
|
||||
|
||||
[top_fractal, bottom_fractal, fractal_bar, fractal_high, fractal_low]
|
||||
|
||||
[is_top_fractal, is_bottom_fractal, fractal_bar_index, fractal_high_price, fractal_low_price] = check_fractal_from_merged()
|
||||
|
||||
// 检查距离过滤
|
||||
distance_ok(new_bar, new_type) =>
|
||||
if debug_mode
|
||||
true
|
||||
else
|
||||
result = true
|
||||
if array.size(fractal_points) > 0
|
||||
last_fractal = array.get(fractal_points, array.size(fractal_points) - 1)
|
||||
bar_distance = new_bar - last_fractal.bar_index
|
||||
if bar_distance < min_bars_between
|
||||
result := false
|
||||
result
|
||||
|
||||
// ================== 添加分型 ==================
|
||||
var bool fractal_added = false
|
||||
fractal_added := false
|
||||
|
||||
if is_top_fractal and distance_ok(fractal_bar_index, "top")
|
||||
new_fractal = FractalPoint.new(fractal_bar_index, fractal_high_price, "top", true)
|
||||
array.push(fractal_points, new_fractal)
|
||||
fractal_added := true
|
||||
|
||||
if array.size(fractal_points) > 100
|
||||
array.shift(fractal_points)
|
||||
|
||||
if is_bottom_fractal and distance_ok(fractal_bar_index, "bottom")
|
||||
new_fractal = FractalPoint.new(fractal_bar_index, fractal_low_price, "bottom", true)
|
||||
array.push(fractal_points, new_fractal)
|
||||
fractal_added := true
|
||||
|
||||
if array.size(fractal_points) > 100
|
||||
array.shift(fractal_points)
|
||||
|
||||
// ================== 显示合并K线 ==================
|
||||
if show_merged_k and array.size(merged_ks) >= 2
|
||||
// 清理旧线条
|
||||
if array.size(merged_k_lines) > 0
|
||||
for i = 0 to array.size(merged_k_lines) - 1
|
||||
line.delete(array.get(merged_k_lines, i))
|
||||
array.clear(merged_k_lines)
|
||||
|
||||
// 绘制合并K线连线
|
||||
for i = 0 to array.size(merged_ks) - 2
|
||||
k1 = array.get(merged_ks, i)
|
||||
k2 = array.get(merged_ks, i + 1)
|
||||
|
||||
// 检查距离限制
|
||||
k_distance = bar_index - k1.bar_index
|
||||
if k_distance <= 500
|
||||
high_line = line.new(k1.bar_index, k1.high, k2.bar_index, k2.high, color=merged_k_color, width=1, style=line.style_dashed)
|
||||
low_line = line.new(k1.bar_index, k1.low, k2.bar_index, k2.low, color=merged_k_color, width=1, style=line.style_dashed)
|
||||
array.push(merged_k_lines, high_line)
|
||||
array.push(merged_k_lines, low_line)
|
||||
|
||||
// ================== 显示分型 ==================
|
||||
if show_fenxing
|
||||
if is_top_fractal and distance_ok(fractal_bar_index, "top")
|
||||
label.new(fractal_bar_index, fractal_high_price, "顶", color=color.red, style=label.style_label_down, size=size.small)
|
||||
|
||||
if is_bottom_fractal and distance_ok(fractal_bar_index, "bottom")
|
||||
label.new(fractal_bar_index, fractal_low_price, "底", color=color.green, style=label.style_label_up, size=size.small)
|
||||
|
||||
// ================== 构建笔 ==================
|
||||
// 在每根K线重新构建所有笔
|
||||
if barstate.isconfirmed
|
||||
// 清理旧笔
|
||||
if array.size(bi_lines) > 0
|
||||
for i = 0 to array.size(bi_lines) - 1
|
||||
line.delete(array.get(bi_lines, i))
|
||||
array.clear(bi_lines)
|
||||
array.clear(bi_segments)
|
||||
|
||||
// 重新构建所有笔
|
||||
if array.size(fractal_points) >= 2 and show_bi
|
||||
for i = 0 to array.size(fractal_points) - 2
|
||||
current_fractal = array.get(fractal_points, i)
|
||||
next_fractal = array.get(fractal_points, i + 1)
|
||||
|
||||
// 只连接不同类型的分型
|
||||
if current_fractal.fractal_type != next_fractal.fractal_type
|
||||
// 确定方向
|
||||
direction = current_fractal.fractal_type == "bottom" ? 1 : -1
|
||||
|
||||
// 创建笔段
|
||||
bi_seg = BiSegment.new(current_fractal, next_fractal, direction)
|
||||
array.push(bi_segments, bi_seg)
|
||||
|
||||
// 检查距离限制
|
||||
distance = bar_index - current_fractal.bar_index
|
||||
if distance <= 500
|
||||
new_line = line.new(current_fractal.bar_index, current_fractal.price, next_fractal.bar_index, next_fractal.price, color=bi_color, width=2, style=line.style_solid)
|
||||
array.push(bi_lines, new_line)
|
||||
|
||||
// ================== 线段识别 ==================
|
||||
// 在每根K线重新构建线段
|
||||
if barstate.isconfirmed and array.size(bi_segments) >= 3
|
||||
// 清理旧线段
|
||||
if array.size(xianduan_lines) > 0
|
||||
for i = 0 to array.size(xianduan_lines) - 1
|
||||
line.delete(array.get(xianduan_lines, i))
|
||||
array.clear(xianduan_lines)
|
||||
array.clear(xianduan_segments)
|
||||
|
||||
// 每三笔构建一个线段
|
||||
segment_count = array.size(bi_segments) // 3
|
||||
for j = 0 to segment_count - 1
|
||||
start_idx = j * 3
|
||||
if start_idx + 2 < array.size(bi_segments)
|
||||
bi1 = array.get(bi_segments, start_idx)
|
||||
bi2 = array.get(bi_segments, start_idx + 1)
|
||||
bi3 = array.get(bi_segments, start_idx + 2)
|
||||
|
||||
// 创建线段
|
||||
bi_array = array.new<BiSegment>()
|
||||
array.push(bi_array, bi1)
|
||||
array.push(bi_array, bi2)
|
||||
array.push(bi_array, bi3)
|
||||
xianduan = XianDuan.new(bi_array, bi1.start_point, bi3.end_point, false)
|
||||
array.push(xianduan_segments, xianduan)
|
||||
|
||||
// 绘制线段
|
||||
if show_xianduan
|
||||
xianduan_distance = bar_index - bi1.start_point.bar_index
|
||||
if xianduan_distance <= 500
|
||||
xianduan_line = line.new(bi1.start_point.bar_index, bi1.start_point.price, bi3.end_point.bar_index, bi3.end_point.price, color=xianduan_color, width=3, style=line.style_solid)
|
||||
array.push(xianduan_lines, xianduan_line)
|
||||
|
||||
// ================== 中枢识别(基于笔的重叠)==================
|
||||
if barstate.isconfirmed and array.size(bi_segments) >= 3 and show_zhongshu
|
||||
// 清理旧中枢
|
||||
if array.size(zhongshu_boxes) > 0
|
||||
for i = 0 to array.size(zhongshu_boxes) - 1
|
||||
box.delete(array.get(zhongshu_boxes, i))
|
||||
array.clear(zhongshu_boxes)
|
||||
|
||||
// 为每三笔检查中枢
|
||||
for k = 0 to array.size(bi_segments) - 3
|
||||
bi1 = array.get(bi_segments, k)
|
||||
bi2 = array.get(bi_segments, k + 1)
|
||||
bi3 = array.get(bi_segments, k + 2)
|
||||
|
||||
// 计算笔的价格区间
|
||||
bi1_high = math.max(bi1.start_point.price, bi1.end_point.price)
|
||||
bi1_low = math.min(bi1.start_point.price, bi1.end_point.price)
|
||||
bi2_high = math.max(bi2.start_point.price, bi2.end_point.price)
|
||||
bi2_low = math.min(bi2.start_point.price, bi2.end_point.price)
|
||||
bi3_high = math.max(bi3.start_point.price, bi3.end_point.price)
|
||||
bi3_low = math.min(bi3.start_point.price, bi3.end_point.price)
|
||||
|
||||
// 计算重叠区域
|
||||
overlap_high = math.min(math.min(bi1_high, bi2_high), bi3_high)
|
||||
overlap_low = math.max(math.max(bi1_low, bi2_low), bi3_low)
|
||||
|
||||
// 形成中枢
|
||||
if overlap_high > overlap_low
|
||||
start_bar = math.min(bi1.start_point.bar_index, bi1.end_point.bar_index)
|
||||
end_bar = math.max(bi3.start_point.bar_index, bi3.end_point.bar_index)
|
||||
|
||||
// 创建中枢(检查距离限制)
|
||||
zs_distance = bar_index - start_bar
|
||||
if zs_distance <= 500
|
||||
zs_box = box.new(start_bar, overlap_high, end_bar, overlap_low, border_color=zhongshu_color, bgcolor=color.new(zhongshu_color, 85))
|
||||
array.push(zhongshu_boxes, zs_box)
|
||||
|
||||
// ================== 改进的买卖点识别 ==================
|
||||
if show_signals and array.size(zhongshu_boxes) > 0 and array.size(fractal_points) >= 2
|
||||
last_zhongshu = array.get(zhongshu_boxes, array.size(zhongshu_boxes) - 1)
|
||||
last_fractal = array.get(fractal_points, array.size(fractal_points) - 1)
|
||||
|
||||
zhongshu_high = box.get_top(last_zhongshu)
|
||||
zhongshu_low = box.get_bottom(last_zhongshu)
|
||||
|
||||
// 一买点:跌破中枢下沿后的底分型
|
||||
if last_fractal.fractal_type == "bottom" and last_fractal.price < zhongshu_low and last_fractal.bar_index > last_signal_bar + 5
|
||||
label.new(last_fractal.bar_index, last_fractal.price, "一买", color=color.green, style=label.style_label_up, size=size.normal)
|
||||
last_signal_bar := last_fractal.bar_index
|
||||
|
||||
// 一卖点:突破中枢上沿后的顶分型
|
||||
if last_fractal.fractal_type == "top" and last_fractal.price > zhongshu_high and last_fractal.bar_index > last_signal_bar + 5
|
||||
label.new(last_fractal.bar_index, last_fractal.price, "一卖", color=color.red, style=label.style_label_down, size=size.normal)
|
||||
last_signal_bar := last_fractal.bar_index
|
||||
|
||||
|
||||
|
||||
// ================== 信息面板 ==================
|
||||
if barstate.islast
|
||||
var info_table = table.new(position.top_right, 2, 10, bgcolor=color.white, border_width=1)
|
||||
table.cell(info_table, 0, 0, "缠论标准V3", text_color=color.black, text_size=size.small)
|
||||
table.cell(info_table, 1, 0, "", text_color=color.black)
|
||||
table.cell(info_table, 0, 1, "合并K线数", text_color=color.black)
|
||||
table.cell(info_table, 1, 1, str.tostring(array.size(merged_ks)), text_color=color.black)
|
||||
table.cell(info_table, 0, 2, "分型数", text_color=color.black)
|
||||
table.cell(info_table, 1, 2, str.tostring(array.size(fractal_points)), text_color=color.black)
|
||||
table.cell(info_table, 0, 3, "笔数", text_color=color.black)
|
||||
table.cell(info_table, 1, 3, str.tostring(array.size(bi_segments)), text_color=color.black)
|
||||
table.cell(info_table, 0, 4, "线段数", text_color=color.black)
|
||||
table.cell(info_table, 1, 4, str.tostring(array.size(xianduan_segments)), text_color=color.black)
|
||||
table.cell(info_table, 0, 5, "中枢数", text_color=color.black)
|
||||
table.cell(info_table, 1, 5, str.tostring(array.size(zhongshu_boxes)), text_color=color.black)
|
||||
table.cell(info_table, 0, 6, "当前趋势", text_color=color.black)
|
||||
trend_text = current_trend > 0 ? "向上" : current_trend < 0 ? "向下" : "震荡"
|
||||
table.cell(info_table, 1, 6, trend_text, text_color=color.black)
|
||||
table.cell(info_table, 0, 7, "合并K线", text_color=color.black)
|
||||
table.cell(info_table, 1, 7, show_merged_k ? "开" : "关", text_color=color.black)
|
||||
table.cell(info_table, 0, 8, "线段显示", text_color=color.black)
|
||||
table.cell(info_table, 1, 8, show_xianduan ? "开" : "关", text_color=color.black)
|
||||
table.cell(info_table, 0, 9, "调试模式", text_color=color.black)
|
||||
table.cell(info_table, 1, 9, debug_mode ? "开" : "关", text_color=color.black)
|
||||
|
||||
// ================== 警报 ==================
|
||||
alertcondition(is_bottom_fractal and distance_ok(fractal_bar_index, "bottom"),
|
||||
title="缠论买点", message="发现底分型")
|
||||
alertcondition(is_top_fractal and distance_ok(fractal_bar_index, "top"),
|
||||
title="缠论卖点", message="发现顶分型")
|
||||
Reference in New Issue
Block a user