终于搞定中枢了

This commit is contained in:
jackyu66git
2026-03-24 01:24:34 +08:00
parent 2b10c889bc
commit cc9dc1f79f
3 changed files with 72 additions and 147 deletions
+57 -116
View File
@@ -1576,9 +1576,10 @@ class TF_DF():
"""
根据缠论线段中枢定义计算中枢
从第4根线段开始(索引3),每3根线段为一组检查
后一个中枢比前一个高 -> 上涨中枢,以下跌开始、以下跌结束
后一个中枢比前一个低 -> 下跌中枢,以上涨开始、以上涨结束
中枢可以扩展到5根、7根...
上涨中枢:后中枢 zd > 前中枢 zg(不重叠上移)
下跌中枢:后中枢 zg < 前中枢 zd(不重叠下移)
盘整/扩张:后中枢与前中枢整体区间(GG/DD)有交集
中枢可按两段一组继续扩展到5根、7根...
"""
zs_list = []
if len(seg_list) < 3:
@@ -1609,32 +1610,34 @@ class TF_DF():
if zg <= zd:
start_idx += 1
#print(seg1.start_bi.start_klc.end_time, "not valid", zg, zd)
continue
# 判断中枢类型
# 上涨中枢:以下跌开始、以下跌结束(下跌+上涨+下跌
# 下跌中枢:以上涨开始、以上涨结束(上涨+下跌+上涨
# 判断中枢类型(按注释定义)
# 上涨中枢:后中枢 zd > 前中枢 zg(不重叠上移
# 下跌中枢:后中枢 zg < 前中枢 zd(不重叠下移
# 盘整/扩张:后中枢与前中枢区间有交集
if last_zs is None:
# 第一个中枢
# 第一个中枢仅按线段形态判定方向
if seg1.dir == Chan_SEG_DIR.DOWN:
# 下跌开始 -> 上涨中枢
zs_dir = Chan_ZS_DIR.DOWN
# 验证模式:下跌+上涨+下跌
# 下跌+上涨+下跌,对应上涨中枢
zs_dir = Chan_ZS_DIR.UP
valid = (seg2.dir == Chan_SEG_DIR.UP and seg3.dir == Chan_SEG_DIR.DOWN)
else:
# 上涨开始 -> 下跌中枢
zs_dir = Chan_ZS_DIR.UP
# 验证模式:上涨+下跌+上涨
# 上涨+下跌+上涨,对应下跌中枢
zs_dir = Chan_ZS_DIR.DOWN
valid = (seg2.dir == Chan_SEG_DIR.DOWN and seg3.dir == Chan_SEG_DIR.UP)
else:
# 根据与前一个中枢的高低比较判断
if zg > last_zs.zg:
# 上涨中枢:以下跌开始、以下跌结束
zs_dir = Chan_ZS_DIR.DOWN
valid = (seg1.dir == Chan_SEG_DIR.DOWN and seg2.dir == Chan_SEG_DIR.UP and seg3.dir == Chan_SEG_DIR.DOWN)
else:
# 下跌中枢:以上涨开始、以上涨结束
is_up_zs = zd > last_zs.zg
is_down_zs = zg < last_zs.zd
if is_up_zs:
# 不重叠上移
zs_dir = Chan_ZS_DIR.UP
valid = (seg1.dir == Chan_SEG_DIR.DOWN and seg2.dir == Chan_SEG_DIR.UP and seg3.dir == Chan_SEG_DIR.DOWN)
elif is_down_zs:
# 不重叠下移
zs_dir = Chan_ZS_DIR.DOWN
valid = (seg1.dir == Chan_SEG_DIR.UP and seg2.dir == Chan_SEG_DIR.DOWN and seg3.dir == Chan_SEG_DIR.UP)
# 验证是否有效
@@ -1642,98 +1645,6 @@ class TF_DF():
start_idx += 1
continue
# 检查是否与前一个中枢重叠
if last_zs:
# 判断是否有重叠
overlap = (zg >= last_zs.zd and zd <= last_zs.zg)
if overlap:
# 有重叠,扩展中枢到5根、7根...(缠论:合并为同一中枢)
# 本组先纳入当前 3 根,再向后逐根尝试;遇到与 [zd,zg] 不重叠(离开中枢)则停止扩展
added_segs = [seg_list[start_idx], seg_list[start_idx + 1], seg_list[start_idx + 2]]
cur_idx = start_idx + 3
while cur_idx < len(seg_list):
next_seg = seg_list[cur_idx]
if not next_seg.is_sure:
break
# 扩展条件:新线段与中枢区间 [zd, zg] 有重叠即并入;不重叠则停止,离开中枢的线段不包含
# 用起止笔的极值算线段区间,避免 seg.high/seg.low 在个别线段上未同步导致的误判
seg_high = max(next_seg.start_bi.high, next_seg.end_bi.high) if next_seg.end_bi else next_seg.start_bi.high
seg_low = min(next_seg.start_bi.low, next_seg.end_bi.low) if next_seg.end_bi else next_seg.start_bi.low
overlap_with_zs = (seg_high >= last_zs.zd and seg_low <= last_zs.zg)
if not overlap_with_zs:
break
added_segs.append(next_seg)
cur_idx += 1
# 扩展中枢 = 原中枢线段 + 本组并入的线段(缠论合并)
segs_for_zs = list(last_zs.seg_list) + list(added_segs)
# 中枢开始与结束线段方向一致:上涨中枢结束于 DOWN,下跌中枢结束于 UP
required_end_seg_dir = Chan_SEG_DIR.DOWN if last_zs.dir == Chan_ZS_DIR.DOWN else Chan_SEG_DIR.UP
while len(segs_for_zs) >= 3 and segs_for_zs[-1].dir != required_end_seg_dir:
segs_for_zs.pop()
# 扩展时只更新 gg、dd 和 seg_list;zg、zd 由前 3 根线段确定,不随扩展改变
seg_highs = [s.high for s in segs_for_zs]
seg_lows = [s.low for s in segs_for_zs]
last_zs.set_gg(max(seg_highs))
last_zs.set_dd(min(seg_lows))
last_zs.seg_list = segs_for_zs
# 更新结束时间(以裁剪后的最后一段为准)
last_seg = segs_for_zs[-1]
if last_seg.end_bi:
last_zs.set_end_klc(last_seg.end_bi.end_klc, last_seg.sure_time, 0, last_seg)
last_zs.set_end_seg(last_seg)
# 下一组从「裁剪后保留的最后一段」的下一条线段开始,被裁掉的线段会参与下一组 3 根,避免漏到下一中枢
last_kept_idx = cur_idx - 1
for i in range(len(seg_list)):
if seg_list[i] == last_seg:
last_kept_idx = i
break
start_idx = last_kept_idx + 1
continue
else:
# 本组3段整体与前中枢不重叠,仍逐根检查:若某线段与 [zd,zg] 重叠(如离开后回抽回到前中枢)则并入扩展,不直接新中枢
added_after_leave = []
for k in range(start_idx, min(start_idx + 3, len(seg_list))):
s = seg_list[k]
if not s.is_sure:
break
sh = max(s.start_bi.high, s.end_bi.high) if s.end_bi else s.start_bi.high
sl = min(s.start_bi.low, s.end_bi.low) if s.end_bi else s.start_bi.low
if sh >= last_zs.zd and sl <= last_zs.zg:
added_after_leave.append(s)
else:
break
if added_after_leave:
segs_for_zs = list(last_zs.seg_list) + list(added_after_leave)
required_end_seg_dir = Chan_SEG_DIR.DOWN if last_zs.dir == Chan_ZS_DIR.DOWN else Chan_SEG_DIR.UP
while len(segs_for_zs) >= 3 and segs_for_zs[-1].dir != required_end_seg_dir:
segs_for_zs.pop()
seg_highs = [s.high for s in segs_for_zs]
seg_lows = [s.low for s in segs_for_zs]
last_zs.set_gg(max(seg_highs))
last_zs.set_dd(min(seg_lows))
last_zs.seg_list = segs_for_zs
last_seg = segs_for_zs[-1]
if last_seg.end_bi:
last_zs.set_end_klc(last_seg.end_bi.end_klc, last_seg.sure_time, 0, last_seg)
last_zs.set_end_seg(last_seg)
start_idx = start_idx + len(added_after_leave)
continue
# 没有任何线段与前中枢重叠,确认前中枢结束并创建新中枢
if last_zs.seg_list and len(last_zs.seg_list) > 0:
prev_zs_last_seg = last_zs.seg_list[-1]
if prev_zs_last_seg.end_bi:
last_zs.set_end_klc(prev_zs_last_seg.end_bi.end_klc, prev_zs_last_seg.sure_time, 0, prev_zs_last_seg)
last_zs.set_end_seg(prev_zs_last_seg)
last_zs.is_sure = True
# 创建新中枢
gg = max(seg1.high, seg2.high, seg3.high)
dd = min(seg1.low, seg2.low, seg3.low)
@@ -1743,11 +1654,41 @@ class TF_DF():
zs.set_zd(zd)
zs.set_gg(gg)
zs.set_dd(dd)
zs.set_end_klc(seg3.end_bi.end_klc, seg3.sure_time, 0, seg3)
zs.set_end_seg(seg3)
zs.is_sure = False
zs.seg_list = [seg1, seg2, seg3]
# 若第二线段与 [zd,zg] 重叠(如离开后回抽回到前中枢)则并入扩展
added_after_leave = []
leave_index = start_idx + 4
while leave_index < len(seg_list):
s = seg_list[leave_index]
if not s.is_sure:
break
sh = max(s.start_bi.high, s.end_bi.high) if s.end_bi else s.start_bi.high
sl = min(s.start_bi.low, s.end_bi.low) if s.end_bi else s.start_bi.low
if sh >= zs.zd and sl <= zs.zg:
added_after_leave.append(s.pre)
added_after_leave.append(s)
else:
break
leave_index += 2
if added_after_leave:
#print(len(added_after_leave))
segs_for_zs = list(zs.seg_list) + list(added_after_leave)
seg_highs = [s.high for s in segs_for_zs]
seg_lows = [s.low for s in segs_for_zs]
zs.set_gg(max(seg_highs))
zs.set_dd(min(seg_lows))
zs.seg_list = segs_for_zs
seg = segs_for_zs[-1]
if seg.end_bi:
zs.set_end_klc(seg.end_bi.end_klc, seg.sure_time, 0, seg)
zs.set_end_seg(seg)
zs.is_sure = True
start_idx = start_idx + len(added_after_leave)
else:
zs.set_end_klc(seg3.end_bi.end_klc, seg3.sure_time, 0, seg3)
zs.set_end_seg(seg3)
zs.is_sure = True
if last_zs:
last_zs.set_next(zs)
zs.set_pre(last_zs)
@@ -1756,7 +1697,7 @@ class TF_DF():
last_zs = zs
# 移动到下一组
start_idx += 3
start_idx += 4
# 处理最后一个未确认的中枢 - 不自动扩展,保持未完成状态
if last_zs and not last_zs.is_sure: