去掉trim data,修改check_fx回去
This commit is contained in:
@@ -4,7 +4,7 @@ from ChanEnum import Chan_BI_DIR
|
|||||||
class ChanBI():
|
class ChanBI():
|
||||||
def __init__(self, klc: ChanKLC, index, ddir=Chan_BI_DIR.UP):
|
def __init__(self, klc: ChanKLC, index, ddir=Chan_BI_DIR.UP):
|
||||||
self.start_klc = klc
|
self.start_klc = klc
|
||||||
self.end_klc = None
|
self.end_klc = klc
|
||||||
self.next = None
|
self.next = None
|
||||||
self.pre = None
|
self.pre = None
|
||||||
self.dir = ddir
|
self.dir = ddir
|
||||||
@@ -15,7 +15,7 @@ class ChanBI():
|
|||||||
self.sure_time = None
|
self.sure_time = None
|
||||||
self.klc_list = []
|
self.klc_list = []
|
||||||
self.klc_list.append(klc)
|
self.klc_list.append(klc)
|
||||||
self.end_time = None
|
self.end_time = klc.end_time
|
||||||
self.start_time = klc.start_time
|
self.start_time = klc.start_time
|
||||||
self.macd_hist = 0
|
self.macd_hist = 0
|
||||||
self.macd_div = 0
|
self.macd_div = 0
|
||||||
@@ -112,6 +112,9 @@ class ChanBI():
|
|||||||
if not added:
|
if not added:
|
||||||
self.klc_list.append(klc)
|
self.klc_list.append(klc)
|
||||||
#print(self.start_time, klc.start_time)
|
#print(self.start_time, klc.start_time)
|
||||||
|
#print(klc.end_time, klc.index)
|
||||||
|
self.end_klc = klc
|
||||||
|
self.end_time = klc.klu_list[-1].time
|
||||||
self.cal_macdhist()
|
self.cal_macdhist()
|
||||||
self.cal_macd_div()
|
self.cal_macd_div()
|
||||||
def append_klc_list(self, klc_list):
|
def append_klc_list(self, klc_list):
|
||||||
|
|||||||
+4
-2
@@ -45,7 +45,7 @@ class ChanSEG():
|
|||||||
self.macd_div = macd_div
|
self.macd_div = macd_div
|
||||||
def set_end_bi(self, bi: ChanBI, sure_bi: ChanBI):
|
def set_end_bi(self, bi: ChanBI, sure_bi: ChanBI):
|
||||||
self.end_bi = bi
|
self.end_bi = bi
|
||||||
if bi:
|
if bi and bi.is_sure:
|
||||||
if self.dir == Chan_SEG_DIR.UP:
|
if self.dir == Chan_SEG_DIR.UP:
|
||||||
self.high = bi.high
|
self.high = bi.high
|
||||||
else:
|
else:
|
||||||
@@ -57,7 +57,7 @@ class ChanSEG():
|
|||||||
self.format_bi_list()
|
self.format_bi_list()
|
||||||
def pre_set_end_bi(self, bi: ChanBI):
|
def pre_set_end_bi(self, bi: ChanBI):
|
||||||
self.end_bi = bi
|
self.end_bi = bi
|
||||||
if bi:
|
if bi and bi.is_sure:
|
||||||
if self.dir == Chan_SEG_DIR.UP:
|
if self.dir == Chan_SEG_DIR.UP:
|
||||||
self.high = bi.high
|
self.high = bi.high
|
||||||
else:
|
else:
|
||||||
@@ -87,6 +87,8 @@ class ChanSEG():
|
|||||||
if len(self.bi_list) > 0:
|
if len(self.bi_list) > 0:
|
||||||
self.bi_list.append(bi)
|
self.bi_list.append(bi)
|
||||||
bi.set_seg(self)
|
bi.set_seg(self)
|
||||||
|
self.end_time = bi.end_time
|
||||||
|
self.end_bi = bi
|
||||||
def cal_bi_zs(self):
|
def cal_bi_zs(self):
|
||||||
zs_list = []
|
zs_list = []
|
||||||
if len(self.bi_list) > 3:
|
if len(self.bi_list) > 3:
|
||||||
|
|||||||
@@ -63,6 +63,10 @@ class ChanZS():
|
|||||||
self.end_time = end_time
|
self.end_time = end_time
|
||||||
def add_klc(self, klc):
|
def add_klc(self, klc):
|
||||||
self.klc_list.append(klc)
|
self.klc_list.append(klc)
|
||||||
|
def add_seg(self, seg):
|
||||||
|
self.seg_list.append(seg)
|
||||||
|
self.end_time = seg.end_time
|
||||||
|
self.end_seg = seg
|
||||||
def set_zg(self, zg):
|
def set_zg(self, zg):
|
||||||
self.zg = zg
|
self.zg = zg
|
||||||
def set_zd(self, zd):
|
def set_zd(self, zd):
|
||||||
|
|||||||
@@ -175,7 +175,7 @@ class TF_DF():
|
|||||||
else:
|
else:
|
||||||
klu_state_list.append("0")
|
klu_state_list.append("0")
|
||||||
return klu_state_list
|
return klu_state_list
|
||||||
def check_fx(self, klc):
|
def check_fx1(self, klc):
|
||||||
if klc.pre and klc.next:
|
if klc.pre and klc.next:
|
||||||
if klc.high > klc.pre.high and klc.high > klc.next.high and klc.low > klc.pre.low and klc.low > klc.next.low:
|
if klc.high > klc.pre.high and klc.high > klc.next.high and klc.low > klc.pre.low and klc.low > klc.next.low:
|
||||||
if klc.pre.pre and klc.next.next:
|
if klc.pre.pre and klc.next.next:
|
||||||
@@ -192,7 +192,7 @@ class TF_DF():
|
|||||||
#print(klc.start_time, klc.end_time,klc.next.start_time, klc.next.end_time, klc.macd, klc.state, klc.fx, "BOTTOM")
|
#print(klc.start_time, klc.end_time,klc.next.start_time, klc.next.end_time, klc.macd, klc.state, klc.fx, "BOTTOM")
|
||||||
return Chan_FX_TYPE.BOTTOM
|
return Chan_FX_TYPE.BOTTOM
|
||||||
return Chan_FX_TYPE.UNKNOWN
|
return Chan_FX_TYPE.UNKNOWN
|
||||||
def check_fx1(self, klc):
|
def check_fx(self, klc):
|
||||||
if klc.pre and klc.next:
|
if klc.pre and klc.next:
|
||||||
if klc.high > klc.pre.high and klc.high > klc.next.high and klc.low > klc.pre.low and klc.low > klc.next.low:
|
if klc.high > klc.pre.high and klc.high > klc.next.high and klc.low > klc.pre.low and klc.low > klc.next.low:
|
||||||
#if (klc.close > klc.ema52 or klc.next.close > klc.next.ema52) and klc.macd > 0:
|
#if (klc.close > klc.ema52 or klc.next.close > klc.next.ema52) and klc.macd > 0:
|
||||||
@@ -954,6 +954,7 @@ class TF_DF():
|
|||||||
if fx == Chan_FX_TYPE.UNKNOWN:
|
if fx == Chan_FX_TYPE.UNKNOWN:
|
||||||
if len(bi_list) > 0:
|
if len(bi_list) > 0:
|
||||||
bi_list[-1].add_klc(klc)
|
bi_list[-1].add_klc(klc)
|
||||||
|
klc.set_bi(bi_list[-1])
|
||||||
#continue
|
#continue
|
||||||
if len(bi_list) > 0 and klc.end_klu:
|
if len(bi_list) > 0 and klc.end_klu:
|
||||||
last_bi = bi_list[-1]
|
last_bi = bi_list[-1]
|
||||||
@@ -1074,7 +1075,7 @@ class TF_DF():
|
|||||||
#print(klc.end_time, klc.fx, bi_list[-1].dir, "Last Top Change 2")
|
#print(klc.end_time, klc.fx, bi_list[-1].dir, "Last Top Change 2")
|
||||||
klc.set_klc_fx_type(Chan_KLC_FX.TOP2)
|
klc.set_klc_fx_type(Chan_KLC_FX.TOP2)
|
||||||
self.check_fx_pattern(klc)
|
self.check_fx_pattern(klc)
|
||||||
bi_list[-1].add_klc(klc)
|
#bi_list[-1].add_klc(klc)
|
||||||
klc.set_bi(bi_list[-1])
|
klc.set_bi(bi_list[-1])
|
||||||
#print(klc.start_time, last_bottom.start_time, "Normal TOP Found, Confirm down bi 4")
|
#print(klc.start_time, last_bottom.start_time, "Normal TOP Found, Confirm down bi 4")
|
||||||
# last bottom = None 初始化的时候用,其他时间不用
|
# last bottom = None 初始化的时候用,其他时间不用
|
||||||
@@ -1189,7 +1190,7 @@ class TF_DF():
|
|||||||
#print(klc.start_time, klc.fx, bi_list[-1].dir, "Last Bottom Change 2")
|
#print(klc.start_time, klc.fx, bi_list[-1].dir, "Last Bottom Change 2")
|
||||||
klc.set_klc_fx_type(Chan_KLC_FX.BOTTOM2)
|
klc.set_klc_fx_type(Chan_KLC_FX.BOTTOM2)
|
||||||
self.check_fx_pattern(klc)
|
self.check_fx_pattern(klc)
|
||||||
bi_list[-1].add_klc(klc)
|
#bi_list[-1].add_klc(klc)
|
||||||
klc.set_bi(bi_list[-1])
|
klc.set_bi(bi_list[-1])
|
||||||
#print(klc.start_time, last_top.start_time, "Normal Bottom Found, Confirm up bi 6")
|
#print(klc.start_time, last_top.start_time, "Normal Bottom Found, Confirm up bi 6")
|
||||||
# last_top = None 初始化的时候用,其他时间不用
|
# last_top = None 初始化的时候用,其他时间不用
|
||||||
@@ -1237,6 +1238,7 @@ class TF_DF():
|
|||||||
#print(klc.start_time, klc.fx, bi_list[-1].dir, "Last Bottom Change 5")
|
#print(klc.start_time, klc.fx, bi_list[-1].dir, "Last Bottom Change 5")
|
||||||
#print(klc.start_time, klc.fx, "笔买点Buy 4")
|
#print(klc.start_time, klc.fx, "笔买点Buy 4")
|
||||||
self.get_above_zero_bsp(klc_list)
|
self.get_above_zero_bsp(klc_list)
|
||||||
|
#print(bi_list[-1].start_time, bi_list[-1].end_time, len(bi_list[-1].klc_list))
|
||||||
return bi_list
|
return bi_list
|
||||||
def get_above_zero_bsp(self, klc_list):
|
def get_above_zero_bsp(self, klc_list):
|
||||||
buy_bsp_list = []
|
buy_bsp_list = []
|
||||||
@@ -1260,12 +1262,12 @@ class TF_DF():
|
|||||||
#print(klc.end_time, "Sell BSP Found")
|
#print(klc.end_time, "Sell BSP Found")
|
||||||
return buy_bsp_list
|
return buy_bsp_list
|
||||||
def check_top_fx(self, last_bottom, klc):
|
def check_top_fx(self, last_bottom, klc):
|
||||||
if (last_bottom.high > klc.pre.low or last_bottom.high > klc.next.low) and (klc.index - last_bottom.index < 10):
|
if (last_bottom.high > klc.pre.low or last_bottom.high > klc.next.low) and (klc.index - last_bottom.index < 100):
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def check_bottom_fx(self, last_top, klc):
|
def check_bottom_fx(self, last_top, klc):
|
||||||
if (last_top.low < klc.pre.high or last_top.low < klc.next.high) and (klc.index - last_top.index < 10):
|
if (last_top.low < klc.pre.high or last_top.low < klc.next.high) and (klc.index - last_top.index < 100):
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
# 建议用这种方式生成笔中枢
|
# 建议用这种方式生成笔中枢
|
||||||
@@ -1364,7 +1366,7 @@ class TF_DF():
|
|||||||
zs.set_dd(min(bi_lows))
|
zs.set_dd(min(bi_lows))
|
||||||
zs.bi_list = bis_for_zs
|
zs.bi_list = bis_for_zs
|
||||||
bi = bis_for_zs[-1]
|
bi = bis_for_zs[-1]
|
||||||
if bi.end_klc:
|
if bi.is_sure:
|
||||||
zs.set_end_bi(bi, bi.sure_time)
|
zs.set_end_bi(bi, bi.sure_time)
|
||||||
|
|
||||||
start_idx = start_idx + len(added_after_leave)
|
start_idx = start_idx + len(added_after_leave)
|
||||||
@@ -1404,7 +1406,7 @@ class TF_DF():
|
|||||||
break
|
break
|
||||||
|
|
||||||
if has_leave:
|
if has_leave:
|
||||||
if last_bi_of_zs.end_klc:
|
if last_bi_of_zs.is_sure:
|
||||||
last_zs.set_end_bi(last_bi_of_zs, last_bi_of_zs.sure_time)
|
last_zs.set_end_bi(last_bi_of_zs, last_bi_of_zs.sure_time)
|
||||||
return bi_zs_list
|
return bi_zs_list
|
||||||
def find_all_bsp(self, bi_list, bi_zs_list):
|
def find_all_bsp(self, bi_list, bi_zs_list):
|
||||||
@@ -1434,12 +1436,12 @@ class TF_DF():
|
|||||||
# 中枢结束后的第一笔(离开笔)
|
# 中枢结束后的第一笔(离开笔)
|
||||||
last_zs_bi = zs.bi_list[-1]
|
last_zs_bi = zs.bi_list[-1]
|
||||||
if last_zs_bi.dir == Chan_BI_DIR.UP:
|
if last_zs_bi.dir == Chan_BI_DIR.UP:
|
||||||
if last_zs_bi.end_klc.high <= zs.zg or (last_zs_bi.next and last_zs_bi.next.is_sure and last_zs_bi.next.end_klc.low < zs.zd):
|
if last_zs_bi.is_sure and last_zs_bi.end_klc.high <= zs.zg or (last_zs_bi.next and last_zs_bi.next.is_sure and last_zs_bi.next.end_klc.low < zs.zd):
|
||||||
leave_bi = last_zs_bi.next
|
leave_bi = last_zs_bi.next
|
||||||
else:
|
else:
|
||||||
leave_bi = last_zs_bi
|
leave_bi = last_zs_bi
|
||||||
else:
|
else:
|
||||||
if last_zs_bi.end_klc.low >= zs.zd or (last_zs_bi.next and last_zs_bi.next.is_sure and last_zs_bi.next.end_klc.high > zs.zg):
|
if last_zs_bi.is_sure and last_zs_bi.end_klc.low >= zs.zd or (last_zs_bi.next and last_zs_bi.next.is_sure and last_zs_bi.next.end_klc.high > zs.zg):
|
||||||
leave_bi = last_zs_bi.next
|
leave_bi = last_zs_bi.next
|
||||||
else:
|
else:
|
||||||
leave_bi = last_zs_bi
|
leave_bi = last_zs_bi
|
||||||
@@ -1578,13 +1580,13 @@ class TF_DF():
|
|||||||
# 确定离开笔:中枢最后一笔之后的第一笔
|
# 确定离开笔:中枢最后一笔之后的第一笔
|
||||||
if last_zs_bi.dir == Chan_BI_DIR.UP:
|
if last_zs_bi.dir == Chan_BI_DIR.UP:
|
||||||
# 中枢最后一笔向上,如果没有真正离开中枢,取下一笔
|
# 中枢最后一笔向上,如果没有真正离开中枢,取下一笔
|
||||||
if last_zs_bi.end_klc.high <= zs.zg:
|
if last_zs_bi.is_sure and last_zs_bi.end_klc.high <= zs.zg:
|
||||||
leave_bi = last_zs_bi.next
|
leave_bi = last_zs_bi.next
|
||||||
else:
|
else:
|
||||||
leave_bi = last_zs_bi
|
leave_bi = last_zs_bi
|
||||||
else:
|
else:
|
||||||
# 中枢最后一笔向下,如果没有真正离开中枢,取下一笔
|
# 中枢最后一笔向下,如果没有真正离开中枢,取下一笔
|
||||||
if last_zs_bi.end_klc.low >= zs.zd:
|
if last_zs_bi.is_sure and last_zs_bi.end_klc.low >= zs.zd:
|
||||||
leave_bi = last_zs_bi.next
|
leave_bi = last_zs_bi.next
|
||||||
else:
|
else:
|
||||||
leave_bi = last_zs_bi
|
leave_bi = last_zs_bi
|
||||||
|
|||||||
+13
-13
@@ -1339,17 +1339,17 @@ def analyze():
|
|||||||
'end_price': bi.end_klc.high if convert_direction(bi.dir) == 1 else bi.end_klc.low if bi.end_klc else None,
|
'end_price': bi.end_klc.high if convert_direction(bi.dir) == 1 else bi.end_klc.low if bi.end_klc else None,
|
||||||
'direction': convert_direction(bi.dir),
|
'direction': convert_direction(bi.dir),
|
||||||
'macd_div': float(bi.macd_div) if hasattr(bi, 'macd_div') else 0
|
'macd_div': float(bi.macd_div) if hasattr(bi, 'macd_div') else 0
|
||||||
} for bi in analysis_result['bi_list'] if bi.end_klc],
|
} for bi in analysis_result['bi_list'] if bi.is_sure],
|
||||||
# 添加未完成笔列表
|
# 添加未完成笔列表
|
||||||
'uncompleted_bi_list': [{
|
'uncompleted_bi_list': [{
|
||||||
'start_time': bi.start_klc.end_time if isinstance(bi.start_klc.end_time, str) else bi.start_klc.end_time.astimezone(client_tz).isoformat(),
|
'start_time': bi.start_klc.end_time if isinstance(bi.start_klc.end_time, str) else bi.start_klc.end_time.astimezone(client_tz).isoformat(),
|
||||||
'end_time': None, # 未完成笔没有结束时间
|
'end_time': bi.end_time, # 未完成笔没有结束时间
|
||||||
'sure_time': format_time_safely(bi.sure_time, client_tz) if bi.sure_time else None,
|
'sure_time': format_time_safely(bi.sure_time, client_tz) if bi.sure_time else None,
|
||||||
'start_price': bi.start_klc.low if convert_direction(bi.dir) == 1 else bi.start_klc.high,
|
'start_price': bi.start_klc.low if convert_direction(bi.dir) == 1 else bi.start_klc.high,
|
||||||
'end_price': None, # 未完成笔没有结束价格
|
'end_price': bi.end_klc.low if convert_direction(bi.dir) == 1 else bi.end_klc.high, # 未完成笔没有结束价格
|
||||||
'direction': convert_direction(bi.dir),
|
'direction': convert_direction(bi.dir),
|
||||||
'macd_div': float(bi.macd_div) if hasattr(bi, 'macd_div') else 0
|
'macd_div': float(bi.macd_div) if hasattr(bi, 'macd_div') else 0
|
||||||
} for bi in analysis_result['bi_list'] if not bi.end_klc],
|
} for bi in analysis_result['bi_list'] if not bi.is_sure],
|
||||||
'seg_list': [{
|
'seg_list': [{
|
||||||
'start_time': seg.start_bi.start_klc.end_time if isinstance(seg.start_bi.start_klc.end_time, str) else seg.start_bi.start_klc.end_time.astimezone(client_tz).isoformat(),
|
'start_time': seg.start_bi.start_klc.end_time if isinstance(seg.start_bi.start_klc.end_time, str) else seg.start_bi.start_klc.end_time.astimezone(client_tz).isoformat(),
|
||||||
'end_time': (seg.end_bi.end_klc.end_time if isinstance(seg.end_bi.end_klc.end_time, str) else seg.end_bi.end_klc.end_time.astimezone(client_tz).isoformat()) if seg.end_bi else None,
|
'end_time': (seg.end_bi.end_klc.end_time if isinstance(seg.end_bi.end_klc.end_time, str) else seg.end_bi.end_klc.end_time.astimezone(client_tz).isoformat()) if seg.end_bi else None,
|
||||||
@@ -1368,7 +1368,7 @@ def analyze():
|
|||||||
'gg': zs.gg,
|
'gg': zs.gg,
|
||||||
'dd': zs.dd,
|
'dd': zs.dd,
|
||||||
'is_sure': zs.is_sure # 添加中枢是否完成的标志
|
'is_sure': zs.is_sure # 添加中枢是否完成的标志
|
||||||
} for zs in analysis_result['zs_list'] if zs.end_klc],
|
} for zs in analysis_result['zs_list'] if zs.is_sure],
|
||||||
# 添加主周期BI中枢列表(已完成)
|
# 添加主周期BI中枢列表(已完成)
|
||||||
'bi_zs_list': [{
|
'bi_zs_list': [{
|
||||||
'start_time': (
|
'start_time': (
|
||||||
@@ -1534,17 +1534,17 @@ def analyze():
|
|||||||
'end_price': bi.end_klc.high if convert_direction(bi.dir) == 1 else bi.end_klc.low if bi.end_klc else None,
|
'end_price': bi.end_klc.high if convert_direction(bi.dir) == 1 else bi.end_klc.low if bi.end_klc else None,
|
||||||
'direction': convert_direction(bi.dir),
|
'direction': convert_direction(bi.dir),
|
||||||
'macd_div': float(bi.macd_div) if hasattr(bi, 'macd_div') else 0
|
'macd_div': float(bi.macd_div) if hasattr(bi, 'macd_div') else 0
|
||||||
} for bi in element_analysis['bi_list'] if bi.end_klc]
|
} for bi in element_analysis['bi_list'] if bi.is_sure]
|
||||||
# 添加次周期未完成笔列表
|
# 添加次周期未完成笔列表
|
||||||
result['element_uncompleted_bi_list'] = [{
|
result['element_uncompleted_bi_list'] = [{
|
||||||
'start_time': bi.start_klc.end_time if isinstance(bi.start_klc.end_time, str) else bi.start_klc.end_time.astimezone(client_tz).isoformat(),
|
'start_time': bi.start_klc.end_time if isinstance(bi.start_klc.end_time, str) else bi.start_klc.end_time.astimezone(client_tz).isoformat(),
|
||||||
'end_time': None, # 未完成笔没有结束时间
|
'end_time': bi.end_time, # 未完成笔没有结束时间
|
||||||
'sure_time': format_time_safely(bi.sure_time, client_tz) if bi.sure_time else None,
|
'sure_time': format_time_safely(bi.sure_time, client_tz) if bi.sure_time else None,
|
||||||
'start_price': bi.start_klc.low if convert_direction(bi.dir) == 1 else bi.start_klc.high,
|
'start_price': bi.start_klc.low if convert_direction(bi.dir) == 1 else bi.start_klc.high,
|
||||||
'end_price': None, # 未完成笔没有结束价格
|
'end_price': bi.end_klc.low if convert_direction(bi.dir) == 1 else bi.end_klc.high, # 未完成笔没有结束价格
|
||||||
'direction': convert_direction(bi.dir),
|
'direction': convert_direction(bi.dir),
|
||||||
'macd_div': float(bi.macd_div) if hasattr(bi, 'macd_div') else 0
|
'macd_div': float(bi.macd_div) if hasattr(bi, 'macd_div') else 0
|
||||||
} for bi in element_analysis['bi_list'] if not bi.end_klc]
|
} for bi in element_analysis['bi_list'] if not bi.is_sure]
|
||||||
|
|
||||||
# 添加小周期K线数据
|
# 添加小周期K线数据
|
||||||
result['element_kline_data'] = clean_dataframe_for_json(element_df).to_dict('records')
|
result['element_kline_data'] = clean_dataframe_for_json(element_df).to_dict('records')
|
||||||
@@ -1674,16 +1674,16 @@ def analyze():
|
|||||||
'end_price': bi.end_klc.high if convert_direction(bi.dir) == 1 else bi.end_klc.low if bi.end_klc else None,
|
'end_price': bi.end_klc.high if convert_direction(bi.dir) == 1 else bi.end_klc.low if bi.end_klc else None,
|
||||||
'direction': convert_direction(bi.dir),
|
'direction': convert_direction(bi.dir),
|
||||||
'macd_div': float(bi.macd_div) if hasattr(bi, 'macd_div') else 0
|
'macd_div': float(bi.macd_div) if hasattr(bi, 'macd_div') else 0
|
||||||
} for bi in sub_sub_analysis['bi_list'] if bi.end_klc]
|
} for bi in sub_sub_analysis['bi_list'] if bi.is_sure]
|
||||||
result['sub_sub_uncompleted_bi_list'] = [{
|
result['sub_sub_uncompleted_bi_list'] = [{
|
||||||
'start_time': bi.start_klc.end_time if isinstance(bi.start_klc.end_time, str) else bi.start_klc.end_time.astimezone(client_tz).isoformat(),
|
'start_time': bi.start_klc.end_time if isinstance(bi.start_klc.end_time, str) else bi.start_klc.end_time.astimezone(client_tz).isoformat(),
|
||||||
'end_time': None,
|
'end_time': bi.end_time,
|
||||||
'sure_time': format_time_safely(bi.sure_time, client_tz) if bi.sure_time else None,
|
'sure_time': format_time_safely(bi.sure_time, client_tz) if bi.sure_time else None,
|
||||||
'start_price': bi.start_klc.low if convert_direction(bi.dir) == 1 else bi.start_klc.high,
|
'start_price': bi.start_klc.low if convert_direction(bi.dir) == 1 else bi.start_klc.high,
|
||||||
'end_price': None,
|
'end_price': bi.end_klc.low if convert_direction(bi.dir) == 1 else bi.end_klc.high,
|
||||||
'direction': convert_direction(bi.dir),
|
'direction': convert_direction(bi.dir),
|
||||||
'macd_div': float(bi.macd_div) if hasattr(bi, 'macd_div') else 0
|
'macd_div': float(bi.macd_div) if hasattr(bi, 'macd_div') else 0
|
||||||
} for bi in sub_sub_analysis['bi_list'] if not bi.end_klc]
|
} for bi in sub_sub_analysis['bi_list'] if not bi.is_sure]
|
||||||
# 次次周期 KLC 列表
|
# 次次周期 KLC 列表
|
||||||
result['sub_sub_klc_list'] = [{
|
result['sub_sub_klc_list'] = [{
|
||||||
'date': klc.end_time if isinstance(klc.end_time, str) else klc.end_time.astimezone(client_tz).isoformat(),
|
'date': klc.end_time if isinstance(klc.end_time, str) else klc.end_time.astimezone(client_tz).isoformat(),
|
||||||
|
|||||||
@@ -1256,47 +1256,6 @@
|
|||||||
// ======= 趋势筛选(币对) =======
|
// ======= 趋势筛选(币对) =======
|
||||||
let trendTable = null;
|
let trendTable = null;
|
||||||
|
|
||||||
// 不在前端截断数据,保留完整历史,避免K线数量限制
|
|
||||||
function trimDataInPlace(payload, maxLen = 2000) {
|
|
||||||
if (!payload || typeof payload !== 'object') return;
|
|
||||||
delete payload.original_kline_data;
|
|
||||||
delete payload.original_macd;
|
|
||||||
|
|
||||||
// 截断大型数组,只保留最新 maxLen 条数据
|
|
||||||
const arrayKeys = [
|
|
||||||
'kline_data', 'element_kline_data', 'sub_sub_kline_data',
|
|
||||||
'bi_list', 'element_bi_list', 'sub_sub_bi_list',
|
|
||||||
'seg_list', 'element_seg_list', 'sub_sub_seg_list',
|
|
||||||
'zs_list', 'element_zs_list', 'sub_sub_zs_list',
|
|
||||||
'uncompleted_bi_list', 'uncompleted_seg_list', 'uncompleted_zs_list',
|
|
||||||
'element_uncompleted_bi_list', 'element_uncompleted_seg_list', 'element_uncompleted_zs_list',
|
|
||||||
'bsp_list', 'element_bsp_list', 'sub_sub_bsp_list',
|
|
||||||
'trade_points', 'element_trade_points'
|
|
||||||
];
|
|
||||||
for (const key of arrayKeys) {
|
|
||||||
if (Array.isArray(payload[key]) && payload[key].length > maxLen) {
|
|
||||||
payload[key] = payload[key].slice(-maxLen);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 截断 MACD 子数组
|
|
||||||
const macdKeys = ['macd', 'element_macd', 'sub_sub_macd'];
|
|
||||||
for (const mk of macdKeys) {
|
|
||||||
const m = payload[mk];
|
|
||||||
if (m && typeof m === 'object') {
|
|
||||||
for (const sub of ['macd', 'signal', 'histogram']) {
|
|
||||||
if (Array.isArray(m[sub]) && m[sub].length > maxLen) {
|
|
||||||
m[sub] = m[sub].slice(-maxLen);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 截断 ATR 数组
|
|
||||||
for (const ak of ['atr', 'element_atr', 'sub_sub_atr']) {
|
|
||||||
if (Array.isArray(payload[ak]) && payload[ak].length > maxLen) {
|
|
||||||
payload[ak] = payload[ak].slice(-maxLen);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let trendDetailTable = null;
|
let trendDetailTable = null;
|
||||||
let trendChart = null;
|
let trendChart = null;
|
||||||
|
|
||||||
@@ -2081,16 +2040,21 @@
|
|||||||
}
|
}
|
||||||
ensureSubSubLteElement();
|
ensureSubSubLteElement();
|
||||||
});
|
});
|
||||||
|
let _lastKlinePeriod = 'main';
|
||||||
function updateChartDisplay() {
|
function updateChartDisplay() {
|
||||||
if (currentData) {
|
if (currentData) {
|
||||||
// 保存当前的可见逻辑范围
|
// 检测K线周期是否切换
|
||||||
|
const curPeriod = $('#subSubPeriodKline').is(':checked') ? 'subsub' :
|
||||||
|
($('#elementPeriodKline').is(':checked') ? 'element' : 'main');
|
||||||
|
const periodChanged = (curPeriod !== _lastKlinePeriod);
|
||||||
|
_lastKlinePeriod = curPeriod;
|
||||||
|
|
||||||
|
// 保存当前的可见逻辑范围(周期切换时不保留,避免范围越界)
|
||||||
let logicalRange = null;
|
let logicalRange = null;
|
||||||
let visibleRange = null;
|
let visibleRange = null;
|
||||||
|
|
||||||
if (tvWidget && tvWidget.mainChart) {
|
if (!periodChanged && tvWidget && tvWidget.mainChart) {
|
||||||
// 优先使用逻辑范围,这样在缩放级别上更准确
|
|
||||||
logicalRange = tvWidget.mainChart.timeScale().getVisibleLogicalRange();
|
logicalRange = tvWidget.mainChart.timeScale().getVisibleLogicalRange();
|
||||||
// 备用方案,获取实际时间戳范围
|
|
||||||
visibleRange = tvWidget.mainChart.timeScale().getVisibleRange();
|
visibleRange = tvWidget.mainChart.timeScale().getVisibleRange();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2279,9 +2243,6 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 截断数据以限制内存占用
|
|
||||||
trimDataInPlace(data, 2000);
|
|
||||||
|
|
||||||
// 保存当前数据
|
// 保存当前数据
|
||||||
if (currentData) {
|
if (currentData) {
|
||||||
// 覆盖前断开旧引用,帮助GC尽快回收
|
// 覆盖前断开旧引用,帮助GC尽快回收
|
||||||
|
|||||||
Reference in New Issue
Block a user