add new line of code

This commit is contained in:
jackyu66git
2025-09-24 01:42:44 +08:00
parent 81cccb2b7a
commit daa8c25c91
5 changed files with 103 additions and 46 deletions
+26 -25
View File
@@ -57,6 +57,7 @@ class ChanKLC():
def set_klc_fx_type(self, klc_fx_type):
#print(self.start_time, klc_fx_type, self.get_feature_data()['klu_macd'], self.get_feature_data()['klu_macdhist'], self.get_feature_data()['klu_rsi'])
self.klc_fx_type = klc_fx_type
self.cal_invisible()
self.cal_bb_out()
def add_klu(self, klu):
self.klus.append(klu)
@@ -72,8 +73,32 @@ class ChanKLC():
if klu.macd_state != Chan_MACD_STATE.UNKNOWN:
self.state = klu.macd_state
self.cal_indicators()
def cal_invisible(self):
if self.klc_fx_type == Chan_KLC_FX.TOP1 or self.klc_fx_type == Chan_KLC_FX.TOP2:
#print(self.end_time, self.fx, self.macd, self.macdhist, len(self.klus))
if self.macdhist < 0 and self.macd > 0:
self.klc_fx_type = Chan_KLC_FX.TOP5
return
if self.state == Chan_MACD_STATE.HIGH_EMPTY and self.macd > 0:
#print(self.end_time, self.state, self.macd, self.klc_fx_type)
self.klc_fx_type = Chan_KLC_FX.TOP6
if self.separate_div or self.continue_div:
self.klc_fx_type = Chan_KLC_FX.TOP7
if self.signal > 0 and self.macd > self.signal:
self.klc_fx_type = Chan_KLC_FX.TOP8
else:
if self.klc_fx_type == Chan_KLC_FX.BOTTOM1 or self.klc_fx_type == Chan_KLC_FX.BOTTOM2:
if self.macdhist > 0 and self.macd < 0:
self.klc_fx_type = Chan_KLC_FX.BOTTOM5
return
if self.state == Chan_MACD_STATE.HIGH_EMPTY and self.macd < 0:
self.klc_fx_type = Chan_KLC_FX.BOTTOM6
#print(self.end_time, self.state, self.macd, self.klc_fx_type)
if self.separate_div or self.continue_div:
self.klc_fx_type = Chan_KLC_FX.BOTTOM7
if self.signal < 0 and self.macd < self.signal:
self.klc_fx_type = Chan_KLC_FX.BOTTOM8
def cal_bb_out(self):
return
for klu in self.klus:
if self.high >= klu.bbup302 and klu.bbup302 > 0 and (self.klc_fx_type == Chan_KLC_FX.TOP1 or self.klc_fx_type == Chan_KLC_FX.TOP2):
#print(self.end_time, self.high, klu.bbup302, self.klc_fx_type)
@@ -84,30 +109,6 @@ class ChanKLC():
if self.low <= klu.bblow30 and klu.bblow30 > 0 and self.next and (self.macd - self.next.macd) < 0:
self.klc_fx_type = Chan_KLC_FX.BOTTOM4
#self.bb_out = True
if self.klc_fx_type == Chan_KLC_FX.TOP1 or self.klc_fx_type == Chan_KLC_FX.TOP2:
#print(self.end_time, self.fx, self.macd, self.macdhist, len(self.klus))
if self.macdhist < 0 and self.macd > 0:
self.klc_fx_type = Chan_KLC_FX.TOP5
self.bb_out = True
if self.state == Chan_MACD_STATE.HIGH_EMPTY and self.macd > 0:
#print(self.end_time, self.state, self.macd, self.klc_fx_type)
self.klc_fx_type = Chan_KLC_FX.TOP6
self.bb_out = True
if self.continue_div:
self.klc_fx_type = Chan_KLC_FX.TOP7
self.bb_out = True
else:
if self.klc_fx_type == Chan_KLC_FX.BOTTOM1 or self.klc_fx_type == Chan_KLC_FX.BOTTOM2:
if self.macdhist > 0 and self.macd < 0:
self.klc_fx_type = Chan_KLC_FX.BOTTOM5
self.bb_out = True
if self.state == Chan_MACD_STATE.HIGH_EMPTY and self.macd < 0:
self.klc_fx_type = Chan_KLC_FX.BOTTOM6
self.bb_out = True
#print(self.end_time, self.state, self.macd, self.klc_fx_type)
if self.continue_div:
self.klc_fx_type = Chan_KLC_FX.BOTTOM7
self.bb_out = True
def cal_macd_state(self, dir):
macd_state = 0
return macd_state
+3 -1
View File
@@ -14,6 +14,7 @@ class ChanKLU:
self.macd = 0
self.signal = 0
self.macdhist = 0
self.klc = None
self.ma5 = 0
self.ma10 = 0
self.ma30 = 0
@@ -125,7 +126,8 @@ class ChanKLU:
#print(self.index, self.time, self.fx_type, self.fx_confirmed, self.fx_strength)
def set_pre(self, pre):
self.pre = pre
def set_klc(self, klc):
self.klc = klc
def set_histset(self, histset):
"""设置HistSet关联"""
self.histset = histset
+10 -11
View File
@@ -23,6 +23,7 @@ class ChanLun():
time1 = 1
time3 = 3
time5 = 5
time10 = 10
time15 = 15
time30 = 30
time60 = 60
@@ -32,7 +33,7 @@ class ChanLun():
time8h = 480
time12h = 720
time1d = 1440
timeframes = [time1, time3, time5, time15, time30, time60]
timeframes = [time1, time3, time5, time10, time15, time30, time60]
tf_df_dict = {}
def init_data(self, dataframe, ticker_indicator):
for timeframe in self.timeframes:
@@ -52,16 +53,14 @@ class ChanLun():
return klu_list, klc_list, bi_list
def check_fx(self, klc):
if klc.pre and klc.next:
if klc.high > klc.pre.high and klc.high > klc.next.high:
if klc.signal > 0 and klc.macd > klc.signal:
klc.set_fx(Chan_FX_TYPE.TOP)
#print(klc.start_time, klc.end_time,klc.next.start_time, klc.next.end_time,klc.fx, "TOP")
return Chan_FX_TYPE.TOP
elif klc.low < klc.pre.low and klc.low < klc.next.low:
if klc.signal < 0 and klc.macd < klc.signal:
klc.set_fx(Chan_FX_TYPE.BOTTOM)
#print(klc.start_time, klc.end_time,klc.next.start_time, klc.next.end_time,klc.fx, "BOTTOM")
return Chan_FX_TYPE.BOTTOM
if klc.high > klc.pre.high and klc.high > klc.next.high and klc.ema24 > klc.ema52:
klc.set_fx(Chan_FX_TYPE.TOP)
#print(klc.start_time, klc.end_time,klc.next.start_time, klc.next.end_time,klc.fx, "TOP")
return Chan_FX_TYPE.TOP
elif klc.low < klc.pre.low and klc.low < klc.next.low and klc.ema24 < klc.ema52:
klc.set_fx(Chan_FX_TYPE.BOTTOM)
#print(klc.start_time, klc.end_time,klc.next.start_time, klc.next.end_time,klc.fx, "BOTTOM")
return Chan_FX_TYPE.BOTTOM
return Chan_FX_TYPE.UNKNOWN
def add_indicators(self, df):
fast = 12
+2 -1
View File
@@ -26,7 +26,7 @@ class ChanMACDHistSet():
def set_middle_klu(self, middle_klu):
self.middle_klu = middle_klu
#self.middle_area = abs(middle_klu.macdhist)
self.middle_klu = None
#self.middle_klu = None
def set_unittf_div(self, unittf_div):
self.unittf_div = unittf_div
def add_klu(self, klu):
@@ -58,6 +58,7 @@ class ChanMACDHistSet():
if klu.pre.macd * klu.pre.macdhist > 0:
self.peak_div_list.append(klu.pre)
self.div_count += 1
klu.pre.continue_div = True
else:
self.peak_klu = klu.pre
else:
+62 -8
View File
@@ -3066,6 +3066,25 @@
const mainMarkers = [];
const elementMarkers = [];
// 基于时间构建 MACD 值映射,便于按时间快速获取对应的 MACD 值
const buildMacdTimeMap = (macdObj, klineArr) => {
const map = new Map();
if (!macdObj || !klineArr || !Array.isArray(klineArr)) return map;
for (let i = 0; i < klineArr.length; i++) {
const k = klineArr[i];
if (!k || !k.date) continue;
const t = Math.floor(new Date(k.date).getTime() / 1000);
const val = (macdObj.macd && macdObj.macd[i] !== undefined && macdObj.macd[i] !== null) ? macdObj.macd[i] : null;
map.set(t, val);
}
return map;
};
const mainMacdMap = buildMacdTimeMap(currentData.macd, currentData.kline_data);
const elementMacdMap = buildMacdTimeMap(
(currentData.element_macd || currentData.macd),
(currentData.element_kline_data || currentData.kline_data)
);
// 主周期 U 标记(蓝/橙,与原样式一致)
if ((typeof window.showUOnMain === 'undefined' ? true : window.showUOnMain) && Array.isArray(mainCm.klu_list)) {
mainCm.klu_list.forEach((item) => {
@@ -3073,10 +3092,14 @@
const ts = Math.floor(new Date(item.time).getTime() / 1000);
if (isNaN(ts)) return;
if (Number(item.separate_div) > 0) {
mainMarkers.push({ time: ts, position: 'aboveBar', color: '#03a9f4', shape: 'arrowUp', text: `SD${Number(item.separate_div)}`, size: 0.6 });
const macdVal = mainMacdMap.get(ts);
const posSd = (macdVal > 0) ? 'aboveBar' : (macdVal < 0) ? 'belowBar' : 'aboveBar';
mainMarkers.push({ time: ts, position: posSd, color: '#03a9f4', shape: 'arrowUp', text: `SD${Number(item.separate_div)}`, size: 0.6 });
}
if (item.continue_div === true) {
mainMarkers.push({ time: ts, position: 'belowBar', color: '#ff9800', shape: 'arrowDown', text: 'CD', size: 0.6 });
const macdVal = mainMacdMap.get(ts);
const posCd = (macdVal > 0) ? 'aboveBar' : (macdVal < 0) ? 'belowBar' : 'belowBar';
mainMarkers.push({ time: ts, position: posCd, color: '#ff9800', shape: 'arrowDown', text: 'CD', size: 0.6 });
}
if (item.near0_return && Number(item.near0_return) > 0) {
mainMarkers.push({ time: ts, position: 'belowBar', color: '#8bc34a', shape: 'circle', text: `N${Number(item.near0_return)}`, size: 0.6 });
@@ -3091,10 +3114,14 @@
const ts = Math.floor(new Date(item.time).getTime() / 1000);
if (isNaN(ts)) return;
if (Number(item.separate_div) > 0) {
elementMarkers.push({ time: ts, position: 'aboveBar', color: '#9c27b0', shape: 'arrowUp', text: `SD${Number(item.separate_div)}`, size: 0.6 });
const macdVal = elementMacdMap.get(ts);
const posSd = (macdVal > 0) ? 'aboveBar' : (macdVal < 0) ? 'belowBar' : 'aboveBar';
elementMarkers.push({ time: ts, position: posSd, color: '#9c27b0', shape: 'arrowUp', text: `SD${Number(item.separate_div)}`, size: 0.6 });
}
if (item.continue_div === true) {
elementMarkers.push({ time: ts, position: 'belowBar', color: '#4caf50', shape: 'arrowDown', text: 'CD', size: 0.6 });
const macdVal = elementMacdMap.get(ts);
const posCd = (macdVal > 0) ? 'aboveBar' : (macdVal < 0) ? 'belowBar' : 'belowBar';
elementMarkers.push({ time: ts, position: posCd, color: '#4caf50', shape: 'arrowDown', text: 'CD', size: 0.6 });
}
if (item.near0_return && Number(item.near0_return) > 0) {
elementMarkers.push({ time: ts, position: 'belowBar', color: '#009688', shape: 'circle', text: `N${Number(item.near0_return)}`, size: 0.6 });
@@ -3126,16 +3153,39 @@
const elementCmAll = currentData.element_chan_macd || {};
const mainMarkersAll = [];
const elementMarkersAll = [];
// 构建 MACD 时间映射,用于依据 MACD 正负决定 SD/CD 的显示上下位置
const buildMacdTimeMapAll = (macdObj, klineArr) => {
const map = new Map();
if (!macdObj || !klineArr || !Array.isArray(klineArr)) return map;
for (let i = 0; i < klineArr.length; i++) {
const k = klineArr[i];
if (!k || !k.date) continue;
const t = Math.floor(new Date(k.date).getTime() / 1000);
const val = (macdObj.macd && macdObj.macd[i] !== undefined && macdObj.macd[i] !== null) ? macdObj.macd[i] : null;
map.set(t, val);
}
return map;
};
const mainMacdMapAll = buildMacdTimeMapAll(currentData.macd, currentData.kline_data);
const elementMacdMapAll = buildMacdTimeMapAll(
(currentData.element_macd || currentData.macd),
(currentData.element_kline_data || currentData.kline_data)
);
if ((typeof window.showUOnMain === 'undefined' ? true : window.showUOnMain) && Array.isArray(mainCmAll.klu_list)) {
mainCmAll.klu_list.forEach((item) => {
if (!item || !item.time) return;
const ts = Math.floor(new Date(item.time).getTime() / 1000);
if (isNaN(ts)) return;
if (Number(item.separate_div) > 0) {
mainMarkersAll.push({ time: ts, position: 'aboveBar', color: '#03a9f4', shape: 'arrowUp', text: `SD${Number(item.separate_div)}`, size: 0.6 });
const macdVal = mainMacdMapAll.get(ts);
const posSd = (macdVal > 0) ? 'aboveBar' : (macdVal < 0) ? 'belowBar' : 'aboveBar';
mainMarkersAll.push({ time: ts, position: posSd, color: '#03a9f4', shape: 'arrowUp', text: `SD${Number(item.separate_div)}`, size: 0.6 });
}
if (item.continue_div === true) {
mainMarkersAll.push({ time: ts, position: 'belowBar', color: '#ff9800', shape: 'arrowDown', text: 'CD', size: 0.6 });
const macdVal = mainMacdMapAll.get(ts);
const posCd = (macdVal > 0) ? 'aboveBar' : (macdVal < 0) ? 'belowBar' : 'belowBar';
mainMarkersAll.push({ time: ts, position: posCd, color: '#ff9800', shape: 'arrowDown', text: 'CD', size: 0.6 });
}
if (item.near0_return && Number(item.near0_return) > 0) {
mainMarkersAll.push({ time: ts, position: 'belowBar', color: '#8bc34a', shape: 'circle', text: `N${Number(item.near0_return)}`, size: 0.6 });
@@ -3148,10 +3198,14 @@
const ts = Math.floor(new Date(item.time).getTime() / 1000);
if (isNaN(ts)) return;
if (Number(item.separate_div) > 0) {
elementMarkersAll.push({ time: ts, position: 'aboveBar', color: '#9c27b0', shape: 'arrowUp', text: `SD${Number(item.separate_div)}`, size: 0.6 });
const macdVal = elementMacdMapAll.get(ts);
const posSd = (macdVal > 0) ? 'aboveBar' : (macdVal < 0) ? 'belowBar' : 'aboveBar';
elementMarkersAll.push({ time: ts, position: posSd, color: '#9c27b0', shape: 'arrowUp', text: `SD${Number(item.separate_div)}`, size: 0.6 });
}
if (item.continue_div === true) {
elementMarkersAll.push({ time: ts, position: 'belowBar', color: '#4caf50', shape: 'arrowDown', text: 'CD', size: 0.6 });
const macdVal = elementMacdMapAll.get(ts);
const posCd = (macdVal > 0) ? 'aboveBar' : (macdVal < 0) ? 'belowBar' : 'belowBar';
elementMarkersAll.push({ time: ts, position: posCd, color: '#4caf50', shape: 'arrowDown', text: 'CD', size: 0.6 });
}
if (item.near0_return && Number(item.near0_return) > 0) {
elementMarkersAll.push({ time: ts, position: 'belowBar', color: '#009688', shape: 'circle', text: `N${Number(item.near0_return)}`, size: 0.6 });