From 2bf9fe58253e005d902310784359559d3d7ae69d Mon Sep 17 00:00:00 2001 From: jackyu66git Date: Sun, 5 Apr 2026 17:55:09 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=B8=AD=E6=9E=A2=E5=BB=B6?= =?UTF-8?q?=E7=BB=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ChanBI.py | 16 ++++++++++ ChanKLC.py | 4 +-- ChanZS.py | 15 ++++++++- TF_DF.py | 91 ++++++++++++++++++++++++++++++++++++++---------------- web/app.py | 11 ++++--- 缠论.txt | 1 + 6 files changed, 103 insertions(+), 35 deletions(-) diff --git a/ChanBI.py b/ChanBI.py index 73c6743..f5ef16d 100644 --- a/ChanBI.py +++ b/ChanBI.py @@ -20,6 +20,11 @@ class ChanBI(): self.macd_hist = 0 self.macd_div = 0 self.seg = None + self.height = 0 + self.width = 0 + self.slop = 0 + self.fib_list = [] + self.seg_index = 0 self.bi_zs = None self.seg_zs = None def set_bi_zs(self, bi_zs): @@ -27,6 +32,7 @@ class ChanBI(): klc.set_bi_zs(bi_zs) def set_seg(self, seg): self.seg = seg + self.seg_index = len(seg.bi_list)-1 def set_macdhist(self, macd_hist): self.macd_hist = macd_hist def set_macd_div(self, macd_div): @@ -71,7 +77,17 @@ class ChanBI(): self.end_klc = klc self.set_is_sure(True, sure_klc.end_time) self.end_time = klc.end_time + self.cal_properties() #print(self.start_time, klc.fx, "This bi is ended", len(self.klc_list), klc.index - self.start_klc.index) + def cal_properties(self): + if self.is_sure: + self.height = float(format(self.high - self.low, ".2f")) + self.width = self.end_klc.index - self.start_klc.index + self.slop = float(format(self.height / self.width, ".2f")) + fib_list = [0.0, 0.236, 0.382, 0.5, 0.618, 0.786, 1.0] + for fib in fib_list: + self.fib_list.append(float(format(self.height * fib + self.low, ".2f"))) + #print(self.end_time, self.height, self.width, self.slop, self.fib_list) def set_is_sure(self, is_sure, time): self.is_sure = is_sure self.sure_time = time diff --git a/ChanKLC.py b/ChanKLC.py index 8b76b3c..a140f1d 100644 --- a/ChanKLC.py +++ b/ChanKLC.py @@ -355,8 +355,8 @@ class ChanKLC(): self.fx_type = Chan_FX.CONTINUATION else: self.fx_type = Chan_FX.REVERSAL - if self.fx_type != Chan_FX.UNKNOWN and self.fx_type != Chan_FX.CONTINUATION: - print(self.end_time, self.fx_type) + #if self.fx_type != Chan_FX.UNKNOWN and self.fx_type != Chan_FX.CONTINUATION: + #print(self.end_time, self.fx_type) def cal_fx_box(self): # 每次重算前先清空,避免旧box残留 self.fx_box = None diff --git a/ChanZS.py b/ChanZS.py index dbc7ae8..0643c41 100644 --- a/ChanZS.py +++ b/ChanZS.py @@ -30,6 +30,7 @@ class ChanZS(): self.bi_out_list = [] self.bi_out_seg_list = [] self.bi_out_seg = None + self.is_extended = False def set_last_bi_in(self, last_bi_in): self.last_bi_in = last_bi_in def set_bi_out(self, bi_out, bi_out_seg): @@ -70,7 +71,19 @@ class ChanZS(): self.gg = gg def set_dd(self, dd): self.dd = dd - + def extend_zs(self, seg_list): + self.is_sure = False + self.end_seg = None + self.end_klc = None + self.sure_time = None + for seg in seg_list: + if seg.end_bi.high > self.gg: + self.set_gg(seg.end_bi.high) + if seg.end_bi.low < self.dd: + self.set_dd(seg.end_bi.low) + self.seg_list.append(seg) + self.is_extended = True + #print(self.start_time, "extend zs", seg_list[-1].end_time) # 大级别中枢:由多个区间重叠(扩张)的笔/线段中枢合并而成,用于显示更大级别的震荡区间 class ChanZS_Big(): diff --git a/TF_DF.py b/TF_DF.py index 9890d8a..1bb8c78 100644 --- a/TF_DF.py +++ b/TF_DF.py @@ -923,12 +923,18 @@ class TF_DF(): """ #self.cal_bi_zs(seg_list) return seg_list - + def get_zs_state(self, df): + bi_list = self.cal_bi_list(self.get_klc_list(self.get_kl_data(df))) + seg_list = self.get_seg_list(bi_list) + zs_list = self.calculate_zs(seg_list) + for zs in zs_list: + last_zs = zs + return zs_list def cal_bi_list(self, klc_list): bi_list = [] last_top = None last_bottom = None - bi_klc_min = 7 + bi_klc_min = 4 last_fx_klc = None for klc in klc_list: if last_fx_klc: @@ -1784,26 +1790,44 @@ class TF_DF(): # 不重叠下移 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) - + create_new_zs = False # 验证是否有效 if not valid: - start_idx += 1 - continue + # 如果新中枢和前一个中枢的中枢区间有重叠,不行成新中枢需要合并两个中枢 + is_in_last_zs = (zd > last_zs.zd and zd < last_zs.zg) or (zg < last_zs.zg and zg > last_zs.zd) or (zg > last_zs.zg and zd < last_zs.zd) or (zg < last_zs.zg and zd > last_zs.zd) + if is_in_last_zs: + #print(seg1.start_time, "New zs is in last zs, not valid") + last_zs.extend_zs(seg_list[last_zs.seg_list[-1].index:(seg3.index + 1)]) + create_new_zs = False + else: + start_idx += 1 + continue + else: + create_new_zs = True + if last_zs and create_new_zs: + last_seg = last_zs.seg_list[-1] + last_bi = last_seg.end_bi + if last_bi: + last_zs.is_sure = True + last_zs.set_end_klc(last_bi.end_klc, last_bi.sure_time, 0, last_seg) + last_zs.set_end_seg(last_seg) + zs = last_zs + if create_new_zs: + # 创建新中枢 + gg = max(seg1.high, seg2.high, seg3.high) + dd = min(seg1.low, seg2.low, seg3.low) - # 创建新中枢 - gg = max(seg1.high, seg2.high, seg3.high) - dd = min(seg1.low, seg2.low, seg3.low) - - zs = ChanZS(seg1, len(zs_list), zs_dir) - zs.set_zg(zg) - zs.set_zd(zd) - zs.set_gg(gg) - zs.set_dd(dd) - zs.is_sure = False - zs.seg_list = [seg1, seg2, seg3] + zs = ChanZS(seg1, len(zs_list), zs_dir) + zs.set_zg(zg) + zs.set_zd(zd) + zs.set_gg(gg) + zs.set_dd(dd) + zs.is_sure = False + zs.seg_list = [seg1, seg2, seg3] # 若第二线段与 [zd,zg] 重叠(如离开后回抽回到前中枢)则并入扩展 added_after_leave = [] leave_index = start_idx + 4 + is_break = False while leave_index < len(seg_list): s = seg_list[leave_index] if not s.is_sure: @@ -1813,9 +1837,24 @@ class TF_DF(): if sh >= zs.zd and sl <= zs.zg: added_after_leave.append(s.pre) added_after_leave.append(s) + leave_index += 2 else: + next_seg = s.next + if next_seg and next_seg.is_sure: + if next_seg.dir == Chan_SEG_DIR.UP: + if next_seg.high <= zs.zg and next_seg.low >= zs.zd: + leave_index += 2 + continue + else: + is_break = True + else: + if next_seg.low >= zs.zd and next_seg.low <= zs.zg: + leave_index += 2 + continue + else: + is_break = True + if is_break: break - leave_index += 2 if added_after_leave: #print(len(added_after_leave)) segs_for_zs = list(zs.seg_list) + list(added_after_leave) @@ -1825,16 +1864,12 @@ class TF_DF(): 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 + #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: + if last_zs and last_zs.index != zs.index: last_zs.set_next(zs) zs.set_pre(last_zs) @@ -1845,6 +1880,7 @@ class TF_DF(): start_idx += 4 if last_zs: last_zs.is_sure = seg_list[-1].is_sure + """ # 处理最后一个未确认的中枢 - 不自动扩展,保持未完成状态 if last_zs and not last_zs.is_sure: # 获取中枢最后一个线段的索引 @@ -1876,10 +1912,11 @@ class TF_DF(): else: # 有离开,确认中枢 if last_seg_of_zs.end_bi: + #print(last_seg_of_zs.start_time, "last_seg_of_zs.end_time", last_seg_of_zs.end_time) last_zs.set_end_klc(last_seg_of_zs.end_bi.end_klc, last_seg_of_zs.sure_time, 0, last_seg_of_zs) last_zs.set_end_seg(last_seg_of_zs) last_zs.is_sure = True - + """ return zs_list def get_big_zs_list(self, zs_list): diff --git a/web/app.py b/web/app.py index d29d29a..4d8918a 100644 --- a/web/app.py +++ b/web/app.py @@ -33,7 +33,8 @@ class TRADE_POINT_TYPE: SELL3 = -3 # 三类卖点 app = Flask(__name__) -macd_factor = 2 +macd_factor = 2 *6 +smooth_factor = 1 # 初始化交易所 exchange = ccxt.binance({ 'enableRateLimit': True, @@ -421,9 +422,9 @@ def get_a_stock_kl_data(symbol, timeframe, limit=100000, start_time=None, end_ti return None def add_indicators(df): - fast = 12*macd_factor - slow = 26*macd_factor - period = 9*1 + fast = 12 * macd_factor + slow = 26 * macd_factor + period = 9 * smooth_factor macd = ta.MACD(df, fastperiod=fast, slowperiod=slow, signalperiod=period) df['macd'] = macd['macd'] @@ -512,7 +513,7 @@ def calculate_macd(df): exp1 = df['close'].ewm(span=12*macd_factor, adjust=False).mean() exp2 = df['close'].ewm(span=26*macd_factor, adjust=False).mean() macd = exp1 - exp2 - signal = macd.ewm(span=9, adjust=False).mean() + signal = macd.ewm(span=9 * smooth_factor, adjust=False).mean() histogram = macd - signal return { diff --git a/缠论.txt b/缠论.txt index a446705..bd92f5e 100644 --- a/缠论.txt +++ b/缠论.txt @@ -81,3 +81,4 @@ 注意,这里必须提醒一句,就是这在以前也曾说过,就是,如果线段中,最高或最低点不是线段的端点,那么,在任何以线段为基础的分析中,例如把线段为基础构成最小级别的中枢等,都可以把该线段标准化为最高低点都在端点。因为, 在以线段为基础的分析中,都把线段当成一个没有内部 结构的基本部件,所以,只需要关心这线段的实际区间就可以,这样就可以只看其高低点。 经过标准化处理后,所有向上线段都是以最低点开始最高点结束,向下线段都是以最高点开始最低点结束,这样,所以线段的连接,就形成一条延续不断、首尾相连的折线,这样,复杂的图形,就会十分地标准化,也为后面的中枢、走势类型等分析提供了最标准且基础的部件。 +本级别没有背驰的,次级别背驰下跌后形成第三类卖点进而形成本级别的V型反转,小转大