add new line of code
This commit is contained in:
+26
-25
@@ -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_bb_out(self):
|
||||
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):
|
||||
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
@@ -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
|
||||
|
||||
+4
-5
@@ -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,13 +53,11 @@ 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:
|
||||
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:
|
||||
if klc.signal < 0 and klc.macd < klc.signal:
|
||||
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
|
||||
|
||||
+2
-1
@@ -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:
|
||||
|
||||
@@ -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 });
|
||||
|
||||
Reference in New Issue
Block a user