diff --git a/ChanMACDHistSet.py b/ChanMACDHistSet.py index beb650a..b85dc75 100644 --- a/ChanMACDHistSet.py +++ b/ChanMACDHistSet.py @@ -52,7 +52,10 @@ class ChanMACDHistSet(): else: self.peak_div_list.append(klu.pre) self.div_count += 1 - klu.pre.continue_div = True + if klu.macd > 0 and self.histset_dir == Chan_MACDHISTSET_DIR.ABOVE: + klu.pre.continue_div = True + elif klu.macd < 0 and self.histset_dir == Chan_MACDHISTSET_DIR.UNDER: + klu.pre.continue_div = True else: self.peak_klu = klu.pre else: @@ -67,7 +70,10 @@ class ChanMACDHistSet(): else: self.peak_div_list.append(klu.pre) self.div_count += 1 - klu.pre.continue_div = True + if klu.macd > 0 and self.histset_dir == Chan_MACDHISTSET_DIR.ABOVE: + klu.pre.continue_div = True + elif klu.macd < 0 and self.histset_dir == Chan_MACDHISTSET_DIR.UNDER: + klu.pre.continue_div = True else: self.peak_klu = klu.pre def set_end_klu(self, end_klu): @@ -80,6 +86,12 @@ class ChanMACDHistSet(): self.peak_klu = self.start_klu else: self.peak_klu = end_klu + if self.start_klu.index + 2 == end_klu.index: + peak = self.klu_list[0] + for klu in self.klu_list: + if abs(klu.macdhist) > abs(peak.macdhist): + peak = klu + self.peak_klu = peak peak_str = "" for peak_div in self.peak_div_list: peak_str += f"{peak_div.time}, " diff --git a/ChanMACDUnitTF.py b/ChanMACDUnitTF.py index 37b0a75..5602519 100644 --- a/ChanMACDUnitTF.py +++ b/ChanMACDUnitTF.py @@ -46,6 +46,8 @@ class ChanMACDUnitTF(): for index in range(0, len(self.histset_list)): histset = self.histset_list[index] if self.same_dir(histset): + if histset.peak_klu: + print("Unittf: ", self.start_klu.time, len(self.histset_list), histset.peak_klu.time) if self.peak_klu: if histset.peak_klu and histset.end_time: if abs(histset.peak_klu.macdhist) >= abs(self.peak_klu.macdhist): @@ -56,6 +58,11 @@ class ChanMACDUnitTF(): self.div_type = Chan_MACDUNITTF_DIV.DISCRETE self.div_count += 1 self.div_peak_list.append(histset.peak_klu) + print("Unittf: ", self.start_klu.time) + if histset.peak_klu.macd > 0 and histset.histset_dir == Chan_MACDHISTSET_DIR.ABOVE: + histset.peak_klu.separate_div = True + elif histset.peak_klu.macd < 0 and histset.histset_dir == Chan_MACDHISTSET_DIR.UNDER: + histset.peak_klu.separate_div = True else: if histset.peak_klu: self.peak_klu = histset.peak_klu @@ -107,6 +114,7 @@ class ChanMACDUnitTF(): return_zero = False if last_klu.close < last_klu.ema52 and klu.close > klu.ema52: return_zero = True + return_zero = False return return_zero def same_dir(self, histset): if self.unittf_dir == Chan_MACDUNITTF_DIR.ABOVE: diff --git a/web/app.py b/web/app.py index 4d43f89..a93e707 100644 --- a/web/app.py +++ b/web/app.py @@ -378,6 +378,7 @@ def analyze_chan(df): 'seg_list': chan_macd.seg_list, 'unittf_list': chan_macd.unittf_list, 'histset_list': chan_macd.histset_list, + 'klu_list': chan_macd.klu_list, 'high_position_list': chan_macd.high_position_list, 'high_empty_list': chan_macd.high_empty_list, 'low_position_list': getattr(chan_macd, 'low_position_list', []), @@ -1048,7 +1049,9 @@ def serialize_chan_macd_data(chan_macd_data, client_tz): 'low_empty_list': [], 'return_zero_list': [], 'cross0_up_list': [], - 'cross0_down_list': [] + 'cross0_down_list': [], + # 新增:输出KLU的继续背驰/分离背驰标志 + 'klu_list': [] } # 序列化seg_list @@ -1237,6 +1240,18 @@ def serialize_chan_macd_data(chan_macd_data, client_tz): except Exception as e: print(f"序列化cross0_down出错: {e}") continue + + # 序列化 KLU 列表(仅导出需要的时间与背驰标志) + for klu in chan_macd_data.get('klu_list', []): + try: + serialized_data['klu_list'].append({ + 'time': format_time_safely(getattr(klu, 'time', None), client_tz), + 'continue_div': bool(getattr(klu, 'continue_div', False)), + 'separate_div': bool(getattr(klu, 'separate_div', False)) + }) + except Exception as e: + print(f"序列化klu出错: {e}") + continue return serialized_data diff --git a/web/templates/index.html b/web/templates/index.html index 0bb3dab..1bdc9fe 100644 --- a/web/templates/index.html +++ b/web/templates/index.html @@ -3053,8 +3053,47 @@ cross0_down_list: cm.cross0_down_list || [] } ); + + // 从 ChanMACD 的 klu_list 提取 continue_div / separate_div 标记,供主K线图显示 + try { + const kluList = Array.isArray(cm.klu_list) ? cm.klu_list : []; + const kluDivMarkers = []; + kluList.forEach((item) => { + if (!item || !item.time) return; + const ts = Math.floor(new Date(item.time).getTime() / 1000); + if (isNaN(ts)) return; + // separate_div 为 true:上方蓝色箭头 + if (item.separate_div === true) { + kluDivMarkers.push({ + time: ts, + position: 'aboveBar', + color: '#03a9f4', + shape: 'arrowUp', + text: 'SD', + size: 0.6 + }); + } + // continue_div 为 true:下方橙色箭头 + if (item.continue_div === true) { + kluDivMarkers.push({ + time: ts, + position: 'belowBar', + color: '#ff9800', + shape: 'arrowDown', + text: 'CD', + size: 0.6 + }); + } + }); + window.kluDivMarkers = kluDivMarkers; + } catch (e) { + console.warn('处理 KLU 背驰标记出错:', e); + window.kluDivMarkers = []; + } } else { console.log('⚠️ 没有ChanMACD分析数据'); + // 无数据时清空本次的 KLU 背驰标记 + window.kluDivMarkers = []; } } else { console.log('⚠️ ChanMACD图表创建条件不满足'); @@ -5330,7 +5369,8 @@ const combinedMarkers = [ ...(window.mainFxMarkers || []), ...allElementFxMarkers, - ...((typeof window.showUOnMain === 'undefined' || window.showUOnMain) ? (window.unittfMarkers || []) : []) + ...((typeof window.showUOnMain === 'undefined' || window.showUOnMain) ? (window.unittfMarkers || []) : []), + ...(window.kluDivMarkers || []) ]; if (combinedMarkers.length > 0) { console.log('合并设置', combinedMarkers.length, '个标记(主周期分型:', (window.mainFxMarkers || []).length, '个,小周期分型:', allElementFxMarkers.length, '个,UnitTF:', (window.unittfMarkers || []).length, '个)'); @@ -5353,7 +5393,8 @@ // 只设置主周期分型 + UnitTF 标记 const onlyMainAndU = [ ...(window.mainFxMarkers || []), - ...((typeof window.showUOnMain === 'undefined' || window.showUOnMain) ? (window.unittfMarkers || []) : []) + ...((typeof window.showUOnMain === 'undefined' || window.showUOnMain) ? (window.unittfMarkers || []) : []), + ...(window.kluDivMarkers || []) ]; if (onlyMainAndU.length > 0) { console.log('仅设置', onlyMainAndU.length, '个主周期/UnitTF标记(主周期分型:', (window.mainFxMarkers || []).length, ',UnitTF:', (window.unittfMarkers || []).length, ')');