添加未完成笔和线段
This commit is contained in:
+10
-3
@@ -73,8 +73,7 @@ class ChanLun():
|
|||||||
klc.set_fx(Chan_FX_TYPE.TOP)
|
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")
|
#print(klc.start_time, klc.end_time,klc.next.start_time, klc.next.end_time,klc.fx, "TOP")
|
||||||
return Chan_FX_TYPE.TOP
|
return Chan_FX_TYPE.TOP
|
||||||
if klc.pre and klc.next:
|
elif klc.low < klc.pre.low and klc.low < klc.next.low:
|
||||||
if klc.low < klc.pre.low and klc.low < klc.next.low:
|
|
||||||
klc.set_fx(Chan_FX_TYPE.BOTTOM)
|
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")
|
#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.BOTTOM
|
||||||
@@ -778,7 +777,7 @@ class ChanLun():
|
|||||||
|
|
||||||
# Do nothing
|
# Do nothing
|
||||||
if fx == Chan_FX_TYPE.UNKNOWN:
|
if fx == Chan_FX_TYPE.UNKNOWN:
|
||||||
if len(bi_list) > 0:
|
if len(bi_list) > 0 and klc.end_klu:
|
||||||
last_bi = bi_list[-1]
|
last_bi = bi_list[-1]
|
||||||
#print(klc.start_time, last_bi.start_time, last_bi.end_time, last_bi.dir, last_bi.high, last_bi.low, last_bottom.end_time, "last bi")
|
#print(klc.start_time, last_bi.start_time, last_bi.end_time, last_bi.dir, last_bi.high, last_bi.low, last_bottom.end_time, "last bi")
|
||||||
if last_top and last_bi.dir == Chan_BI_DIR.DOWN:
|
if last_top and last_bi.dir == Chan_BI_DIR.DOWN:
|
||||||
@@ -1082,6 +1081,8 @@ class ChanLun():
|
|||||||
if seg.next.next.is_sure:
|
if seg.next.next.is_sure:
|
||||||
zg = min(seg.high, seg.next.high, seg.next.next.high)
|
zg = min(seg.high, seg.next.high, seg.next.next.high)
|
||||||
zd = max(seg.low, seg.next.low, seg.next.next.low)
|
zd = max(seg.low, seg.next.low, seg.next.next.low)
|
||||||
|
gg = max(seg.high, seg.next.high, seg.next.next.high)
|
||||||
|
dd = min(seg.low, seg.next.low, seg.next.next.low)
|
||||||
ddir = Chan_ZS_DIR.UP
|
ddir = Chan_ZS_DIR.UP
|
||||||
ddir = None
|
ddir = None
|
||||||
if last_zs:
|
if last_zs:
|
||||||
@@ -1104,6 +1105,8 @@ class ChanLun():
|
|||||||
zs = ChanZS(seg, len(zs_list), ddir)
|
zs = ChanZS(seg, len(zs_list), ddir)
|
||||||
zs.set_zg(zg)
|
zs.set_zg(zg)
|
||||||
zs.set_zd(zd)
|
zs.set_zd(zd)
|
||||||
|
zs.set_gg(gg)
|
||||||
|
zs.set_dd(dd)
|
||||||
if last_zs:
|
if last_zs:
|
||||||
last_zs.set_next(zs)
|
last_zs.set_next(zs)
|
||||||
zs.set_pre(last_zs)
|
zs.set_pre(last_zs)
|
||||||
@@ -1130,6 +1133,8 @@ class ChanLun():
|
|||||||
if seg.next.next.is_sure:
|
if seg.next.next.is_sure:
|
||||||
zg = min(seg.high, seg.next.high, seg.next.next.high)
|
zg = min(seg.high, seg.next.high, seg.next.next.high)
|
||||||
zd = max(seg.low, seg.next.low, seg.next.next.low)
|
zd = max(seg.low, seg.next.low, seg.next.next.low)
|
||||||
|
gg = max(seg.high, seg.next.high, seg.next.next.high)
|
||||||
|
dd = min(seg.low, seg.next.low, seg.next.next.low)
|
||||||
ddir = None
|
ddir = None
|
||||||
if last_zs:
|
if last_zs:
|
||||||
if zg < last_zs.zd:
|
if zg < last_zs.zd:
|
||||||
@@ -1151,6 +1156,8 @@ class ChanLun():
|
|||||||
zs = ChanZS(seg, len(zs_list), ddir)
|
zs = ChanZS(seg, len(zs_list), ddir)
|
||||||
zs.set_zg(zg)
|
zs.set_zg(zg)
|
||||||
zs.set_zd(zd)
|
zs.set_zd(zd)
|
||||||
|
zs.set_gg(gg)
|
||||||
|
zs.set_dd(dd)
|
||||||
last_zs.set_next(zs)
|
last_zs.set_next(zs)
|
||||||
zs.set_pre(last_zs)
|
zs.set_pre(last_zs)
|
||||||
zs_list.append(zs)
|
zs_list.append(zs)
|
||||||
|
|||||||
@@ -21,6 +21,8 @@ class ChanZS():
|
|||||||
self.is_sure = False
|
self.is_sure = False
|
||||||
self.zg = 0
|
self.zg = 0
|
||||||
self.zd = 0
|
self.zd = 0
|
||||||
|
self.gg = 0
|
||||||
|
self.dd = 0
|
||||||
self.dir = ddir
|
self.dir = ddir
|
||||||
self.sure_time = None
|
self.sure_time = None
|
||||||
self.end_klc = None
|
self.end_klc = None
|
||||||
@@ -64,3 +66,7 @@ class ChanZS():
|
|||||||
self.zg = zg
|
self.zg = zg
|
||||||
def set_zd(self, zd):
|
def set_zd(self, zd):
|
||||||
self.zd = zd
|
self.zd = zd
|
||||||
|
def set_gg(self, gg):
|
||||||
|
self.gg = gg
|
||||||
|
def set_dd(self, dd):
|
||||||
|
self.dd = dd
|
||||||
+103
-4
@@ -538,6 +538,15 @@ def generate_replay_data(df, client_tz, symbol=None, element_timeframe=None, sta
|
|||||||
'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 filtered_bi_list if bi.end_klc],
|
} for bi in filtered_bi_list if bi.end_klc],
|
||||||
|
'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(),
|
||||||
|
'end_time': 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,
|
||||||
|
'end_price': None, # 未完成笔没有结束价格
|
||||||
|
'direction': convert_direction(bi.dir),
|
||||||
|
'macd_div': float(bi.macd_div) if hasattr(bi, 'macd_div') else 0
|
||||||
|
} for bi in filtered_bi_list if not bi.end_klc],
|
||||||
'element_seg_list': [{
|
'element_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,
|
||||||
@@ -545,12 +554,15 @@ def generate_replay_data(df, client_tz, symbol=None, element_timeframe=None, sta
|
|||||||
'start_price': seg.start_bi.start_klc.low if convert_direction(seg.dir) == 1 else seg.start_bi.start_klc.high,
|
'start_price': seg.start_bi.start_klc.low if convert_direction(seg.dir) == 1 else seg.start_bi.start_klc.high,
|
||||||
'end_price': seg.end_bi.end_klc.high if convert_direction(seg.dir) == 1 else seg.end_bi.end_klc.low if seg.end_bi else None,
|
'end_price': seg.end_bi.end_klc.high if convert_direction(seg.dir) == 1 else seg.end_bi.end_klc.low if seg.end_bi else None,
|
||||||
'direction': convert_direction(seg.dir)
|
'direction': convert_direction(seg.dir)
|
||||||
} for seg in filtered_seg_list if seg.end_bi],
|
} for seg in filtered_seg_list if seg.is_sure],
|
||||||
|
'element_uncompleted_seg_list': get_uncompleted_seg_list(filtered_seg_list, client_tz),
|
||||||
'element_zs_list': [{
|
'element_zs_list': [{
|
||||||
'start_time': zs.start_klc.end_time if isinstance(zs.start_klc.end_time, str) else zs.start_klc.end_time.astimezone(client_tz).isoformat(),
|
'start_time': zs.start_klc.end_time if isinstance(zs.start_klc.end_time, str) else zs.start_klc.end_time.astimezone(client_tz).isoformat(),
|
||||||
'end_time': (zs.end_klc.end_time if isinstance(zs.end_klc.end_time, str) else zs.end_klc.end_time.astimezone(client_tz).isoformat()) if zs.end_klc else None,
|
'end_time': (zs.end_klc.end_time if isinstance(zs.end_klc.end_time, str) else zs.end_klc.end_time.astimezone(client_tz).isoformat()) if zs.end_klc else None,
|
||||||
'zg': zs.zg,
|
'zg': zs.zg,
|
||||||
'zd': zs.zd,
|
'zd': zs.zd,
|
||||||
|
'gg': zs.gg,
|
||||||
|
'dd': zs.dd,
|
||||||
'is_sure': zs.is_sure
|
'is_sure': zs.is_sure
|
||||||
} for zs in filtered_zs_list if zs.end_klc],
|
} for zs in filtered_zs_list if zs.end_klc],
|
||||||
'element_uncompleted_zs_list': [{
|
'element_uncompleted_zs_list': [{
|
||||||
@@ -558,6 +570,8 @@ def generate_replay_data(df, client_tz, symbol=None, element_timeframe=None, sta
|
|||||||
'end_time': None,
|
'end_time': None,
|
||||||
'zg': zs.zg,
|
'zg': zs.zg,
|
||||||
'zd': zs.zd,
|
'zd': zs.zd,
|
||||||
|
'gg': zs.gg,
|
||||||
|
'dd': zs.dd,
|
||||||
'is_sure': zs.is_sure
|
'is_sure': zs.is_sure
|
||||||
} for zs in filtered_zs_list if not zs.is_sure],
|
} for zs in filtered_zs_list if not zs.is_sure],
|
||||||
'element_trade_points': [{
|
'element_trade_points': [{
|
||||||
@@ -616,6 +630,15 @@ def generate_replay_data(df, client_tz, symbol=None, element_timeframe=None, sta
|
|||||||
'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.end_klc],
|
||||||
|
'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(),
|
||||||
|
'end_time': 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,
|
||||||
|
'end_price': None, # 未完成笔没有结束价格
|
||||||
|
'direction': convert_direction(bi.dir),
|
||||||
|
'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],
|
||||||
'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,
|
||||||
@@ -623,12 +646,15 @@ def generate_replay_data(df, client_tz, symbol=None, element_timeframe=None, sta
|
|||||||
'start_price': seg.start_bi.start_klc.low if convert_direction(seg.dir) == 1 else seg.start_bi.start_klc.high,
|
'start_price': seg.start_bi.start_klc.low if convert_direction(seg.dir) == 1 else seg.start_bi.start_klc.high,
|
||||||
'end_price': seg.end_bi.end_klc.high if convert_direction(seg.dir) == 1 else seg.end_bi.end_klc.low if seg.end_bi else None,
|
'end_price': seg.end_bi.end_klc.high if convert_direction(seg.dir) == 1 else seg.end_bi.end_klc.low if seg.end_bi else None,
|
||||||
'direction': convert_direction(seg.dir)
|
'direction': convert_direction(seg.dir)
|
||||||
} for seg in analysis_result['seg_list'] if seg.end_bi],
|
} for seg in analysis_result['seg_list'] if seg.is_sure],
|
||||||
|
'uncompleted_seg_list': get_uncompleted_seg_list(analysis_result['seg_list'], client_tz),
|
||||||
'zs_list': [{
|
'zs_list': [{
|
||||||
'start_time': zs.start_klc.end_time if isinstance(zs.start_klc.end_time, str) else zs.start_klc.end_time.astimezone(client_tz).isoformat(),
|
'start_time': zs.start_klc.end_time if isinstance(zs.start_klc.end_time, str) else zs.start_klc.end_time.astimezone(client_tz).isoformat(),
|
||||||
'end_time': (zs.end_klc.end_time if isinstance(zs.end_klc.end_time, str) else zs.end_klc.end_time.astimezone(client_tz).isoformat()) if zs.end_klc else None,
|
'end_time': (zs.end_klc.end_time if isinstance(zs.end_klc.end_time, str) else zs.end_klc.end_time.astimezone(client_tz).isoformat()) if zs.end_klc else None,
|
||||||
'zg': zs.zg,
|
'zg': zs.zg,
|
||||||
'zd': zs.zd,
|
'zd': zs.zd,
|
||||||
|
'gg': zs.gg,
|
||||||
|
'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.end_klc],
|
||||||
'uncompleted_zs_list': [{
|
'uncompleted_zs_list': [{
|
||||||
@@ -636,6 +662,8 @@ def generate_replay_data(df, client_tz, symbol=None, element_timeframe=None, sta
|
|||||||
'end_time': None,
|
'end_time': None,
|
||||||
'zg': zs.zg,
|
'zg': zs.zg,
|
||||||
'zd': zs.zd,
|
'zd': zs.zd,
|
||||||
|
'gg': zs.gg,
|
||||||
|
'dd': zs.dd,
|
||||||
'is_sure': zs.is_sure
|
'is_sure': zs.is_sure
|
||||||
} for zs in analysis_result['zs_list'] if not zs.is_sure],
|
} for zs in analysis_result['zs_list'] if not zs.is_sure],
|
||||||
'trade_points': [{
|
'trade_points': [{
|
||||||
@@ -686,7 +714,9 @@ def generate_replay_data(df, client_tz, symbol=None, element_timeframe=None, sta
|
|||||||
step_data.update({
|
step_data.update({
|
||||||
'element_kline_data': [],
|
'element_kline_data': [],
|
||||||
'element_bi_list': [],
|
'element_bi_list': [],
|
||||||
|
'element_uncompleted_bi_list': [],
|
||||||
'element_seg_list': [],
|
'element_seg_list': [],
|
||||||
|
'element_uncompleted_seg_list': [],
|
||||||
'element_zs_list': [],
|
'element_zs_list': [],
|
||||||
'element_uncompleted_zs_list': [],
|
'element_uncompleted_zs_list': [],
|
||||||
'element_trade_points': [],
|
'element_trade_points': [],
|
||||||
@@ -1089,6 +1119,16 @@ def analyze():
|
|||||||
'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.end_klc],
|
||||||
|
# 添加未完成笔列表
|
||||||
|
'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(),
|
||||||
|
'end_time': 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,
|
||||||
|
'end_price': None, # 未完成笔没有结束价格
|
||||||
|
'direction': convert_direction(bi.dir),
|
||||||
|
'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],
|
||||||
'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,
|
||||||
@@ -1096,12 +1136,16 @@ def analyze():
|
|||||||
'start_price': seg.start_bi.start_klc.low if convert_direction(seg.dir) == 1 else seg.start_bi.start_klc.high,
|
'start_price': seg.start_bi.start_klc.low if convert_direction(seg.dir) == 1 else seg.start_bi.start_klc.high,
|
||||||
'end_price': seg.end_bi.end_klc.high if convert_direction(seg.dir) == 1 else seg.end_bi.end_klc.low if seg.end_bi else None,
|
'end_price': seg.end_bi.end_klc.high if convert_direction(seg.dir) == 1 else seg.end_bi.end_klc.low if seg.end_bi else None,
|
||||||
'direction': convert_direction(seg.dir)
|
'direction': convert_direction(seg.dir)
|
||||||
} for seg in analysis_result['seg_list'] if seg.end_bi],
|
} for seg in analysis_result['seg_list'] if seg.is_sure],
|
||||||
|
# 添加未完成线段列表
|
||||||
|
'uncompleted_seg_list': get_uncompleted_seg_list(analysis_result['seg_list'], client_tz),
|
||||||
'zs_list': [{
|
'zs_list': [{
|
||||||
'start_time': zs.start_klc.end_time if isinstance(zs.start_klc.end_time, str) else zs.start_klc.end_time.astimezone(client_tz).isoformat(),
|
'start_time': zs.start_klc.end_time if isinstance(zs.start_klc.end_time, str) else zs.start_klc.end_time.astimezone(client_tz).isoformat(),
|
||||||
'end_time': (zs.end_klc.end_time if isinstance(zs.end_klc.end_time, str) else zs.end_klc.end_time.astimezone(client_tz).isoformat()) if zs.end_klc else None,
|
'end_time': (zs.end_klc.end_time if isinstance(zs.end_klc.end_time, str) else zs.end_klc.end_time.astimezone(client_tz).isoformat()) if zs.end_klc else None,
|
||||||
'zg': zs.zg,
|
'zg': zs.zg,
|
||||||
'zd': zs.zd,
|
'zd': zs.zd,
|
||||||
|
'gg': zs.gg,
|
||||||
|
'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.end_klc],
|
||||||
# 添加未完成中枢列表
|
# 添加未完成中枢列表
|
||||||
@@ -1110,6 +1154,8 @@ def analyze():
|
|||||||
'end_time': None, # 未完成中枢没有结束时间
|
'end_time': None, # 未完成中枢没有结束时间
|
||||||
'zg': zs.zg,
|
'zg': zs.zg,
|
||||||
'zd': zs.zd,
|
'zd': zs.zd,
|
||||||
|
'gg': zs.gg,
|
||||||
|
'dd': zs.dd,
|
||||||
'is_sure': zs.is_sure # 未完成中枢的is_sure为False
|
'is_sure': zs.is_sure # 未完成中枢的is_sure为False
|
||||||
} for zs in analysis_result['zs_list'] if not zs.is_sure],
|
} for zs in analysis_result['zs_list'] if not zs.is_sure],
|
||||||
'trade_points': [{
|
'trade_points': [{
|
||||||
@@ -1201,6 +1247,16 @@ def analyze():
|
|||||||
'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.end_klc]
|
||||||
|
# 添加次周期未完成笔列表
|
||||||
|
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(),
|
||||||
|
'end_time': 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,
|
||||||
|
'end_price': None, # 未完成笔没有结束价格
|
||||||
|
'direction': convert_direction(bi.dir),
|
||||||
|
'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]
|
||||||
|
|
||||||
# 添加小周期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')
|
||||||
@@ -1212,13 +1268,17 @@ def analyze():
|
|||||||
'start_price': seg.start_bi.start_klc.low if convert_direction(seg.dir) == 1 else seg.start_bi.start_klc.high,
|
'start_price': seg.start_bi.start_klc.low if convert_direction(seg.dir) == 1 else seg.start_bi.start_klc.high,
|
||||||
'end_price': seg.end_bi.end_klc.high if convert_direction(seg.dir) == 1 else seg.end_bi.end_klc.low if seg.end_bi else None,
|
'end_price': seg.end_bi.end_klc.high if convert_direction(seg.dir) == 1 else seg.end_bi.end_klc.low if seg.end_bi else None,
|
||||||
'direction': convert_direction(seg.dir)
|
'direction': convert_direction(seg.dir)
|
||||||
} for seg in element_analysis['seg_list'] if seg.end_bi]
|
} for seg in element_analysis['seg_list'] if seg.is_sure]
|
||||||
|
# 添加次周期未完成线段列表
|
||||||
|
result['element_uncompleted_seg_list'] = get_uncompleted_seg_list(element_analysis['seg_list'], client_tz)
|
||||||
|
|
||||||
result['element_zs_list'] = [{
|
result['element_zs_list'] = [{
|
||||||
'start_time': zs.start_klc.end_time if isinstance(zs.start_klc.end_time, str) else zs.start_klc.end_time.astimezone(client_tz).isoformat(),
|
'start_time': zs.start_klc.end_time if isinstance(zs.start_klc.end_time, str) else zs.start_klc.end_time.astimezone(client_tz).isoformat(),
|
||||||
'end_time': (zs.end_klc.end_time if isinstance(zs.end_klc.end_time, str) else zs.end_klc.end_time.astimezone(client_tz).isoformat()) if zs.end_klc else None,
|
'end_time': (zs.end_klc.end_time if isinstance(zs.end_klc.end_time, str) else zs.end_klc.end_time.astimezone(client_tz).isoformat()) if zs.end_klc else None,
|
||||||
'zg': zs.zg,
|
'zg': zs.zg,
|
||||||
'zd': zs.zd,
|
'zd': zs.zd,
|
||||||
|
'gg': zs.gg,
|
||||||
|
'dd': zs.dd,
|
||||||
'is_sure': zs.is_sure # 添加中枢是否完成的标志
|
'is_sure': zs.is_sure # 添加中枢是否完成的标志
|
||||||
} for zs in element_analysis['zs_list'] if zs.end_klc]
|
} for zs in element_analysis['zs_list'] if zs.end_klc]
|
||||||
|
|
||||||
@@ -1227,6 +1287,8 @@ def analyze():
|
|||||||
'end_time': None, # 未完成中枢没有结束时间
|
'end_time': None, # 未完成中枢没有结束时间
|
||||||
'zg': zs.zg,
|
'zg': zs.zg,
|
||||||
'zd': zs.zd,
|
'zd': zs.zd,
|
||||||
|
'gg': zs.gg,
|
||||||
|
'dd': zs.dd,
|
||||||
'is_sure': zs.is_sure # 未完成中枢的is_sure为False
|
'is_sure': zs.is_sure # 未完成中枢的is_sure为False
|
||||||
} for zs in element_analysis['zs_list'] if not zs.is_sure]
|
} for zs in element_analysis['zs_list'] if not zs.is_sure]
|
||||||
|
|
||||||
@@ -1605,6 +1667,43 @@ def filter_stocks():
|
|||||||
else:
|
else:
|
||||||
return jsonify({'error': str(e)})
|
return jsonify({'error': str(e)})
|
||||||
|
|
||||||
|
def get_uncompleted_seg_list(seg_list, client_tz):
|
||||||
|
"""获取未完成线段列表,正确处理倒数第二个和最后一个未完成线段"""
|
||||||
|
uncompleted_segs = [seg for seg in seg_list if not seg.is_sure]
|
||||||
|
|
||||||
|
if len(uncompleted_segs) == 0:
|
||||||
|
return []
|
||||||
|
|
||||||
|
result = []
|
||||||
|
|
||||||
|
for i, seg in enumerate(uncompleted_segs):
|
||||||
|
is_last = (i == len(uncompleted_segs) - 1) # 是否为最后一个未完成线段
|
||||||
|
|
||||||
|
seg_data = {
|
||||||
|
'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(),
|
||||||
|
'sure_time': format_time_safely(seg.sure_time, client_tz) if seg.sure_time else None,
|
||||||
|
'start_price': seg.start_bi.start_klc.low if convert_direction(seg.dir) == 1 else seg.start_bi.start_klc.high,
|
||||||
|
'direction': convert_direction(seg.dir)
|
||||||
|
}
|
||||||
|
|
||||||
|
if is_last:
|
||||||
|
# 最后一个未完成线段:没有结束时间和价格
|
||||||
|
seg_data['end_time'] = None
|
||||||
|
seg_data['end_price'] = None
|
||||||
|
else:
|
||||||
|
# 倒数第二个及之前的未完成线段:使用实际的结束时间和价格
|
||||||
|
if seg.end_bi and seg.end_bi.end_klc:
|
||||||
|
seg_data['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()
|
||||||
|
seg_data['end_price'] = seg.end_bi.end_klc.high if convert_direction(seg.dir) == 1 else seg.end_bi.end_klc.low
|
||||||
|
else:
|
||||||
|
# 如果没有结束笔,设为None
|
||||||
|
seg_data['end_time'] = None
|
||||||
|
seg_data['end_price'] = None
|
||||||
|
|
||||||
|
result.append(seg_data)
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
def format_fx_type(fx_type):
|
def format_fx_type(fx_type):
|
||||||
"""格式化分型类型显示"""
|
"""格式化分型类型显示"""
|
||||||
fx_type_map = {
|
fx_type_map = {
|
||||||
|
|||||||
+459
-28
@@ -1111,6 +1111,7 @@
|
|||||||
<th>起始价格</th>
|
<th>起始价格</th>
|
||||||
<th>结束价格</th>
|
<th>结束价格</th>
|
||||||
<th>方向</th>
|
<th>方向</th>
|
||||||
|
<th>状态</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody></tbody>
|
<tbody></tbody>
|
||||||
@@ -2578,6 +2579,7 @@
|
|||||||
|
|
||||||
// 清空已有的主周期笔系列
|
// 清空已有的主周期笔系列
|
||||||
tvWidget.series.mainBiSeries = [];
|
tvWidget.series.mainBiSeries = [];
|
||||||
|
tvWidget.series.mainUncompletedBiSeries = [];
|
||||||
|
|
||||||
// 遍历处理每个笔
|
// 遍历处理每个笔
|
||||||
currentData.bi_list.forEach(function(bi) {
|
currentData.bi_list.forEach(function(bi) {
|
||||||
@@ -2658,6 +2660,10 @@
|
|||||||
if ($('#showElementBi').is(':checked') && currentData.element_bi_list && currentData.element_bi_list.length > 0) {
|
if ($('#showElementBi').is(':checked') && currentData.element_bi_list && currentData.element_bi_list.length > 0) {
|
||||||
console.log(`绘制次周期笔数据,共${currentData.element_bi_list.length}条`);
|
console.log(`绘制次周期笔数据,共${currentData.element_bi_list.length}条`);
|
||||||
|
|
||||||
|
// 清空已有的次周期笔系列
|
||||||
|
tvWidget.series.elementBiSeries = [];
|
||||||
|
tvWidget.series.elementUncompletedBiSeries = [];
|
||||||
|
|
||||||
currentData.element_bi_list.forEach(function(bi) {
|
currentData.element_bi_list.forEach(function(bi) {
|
||||||
try {
|
try {
|
||||||
// 直接使用UTC时间戳(秒)
|
// 直接使用UTC时间戳(秒)
|
||||||
@@ -2732,11 +2738,130 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 绘制未完成笔 - 主周期
|
||||||
|
if ($('#showMainBi').is(':checked') && currentData.uncompleted_bi_list && currentData.uncompleted_bi_list.length > 0) {
|
||||||
|
console.log(`绘制主周期未完成笔数据,共${currentData.uncompleted_bi_list.length}条`);
|
||||||
|
|
||||||
|
currentData.uncompleted_bi_list.forEach(function(bi) {
|
||||||
|
try {
|
||||||
|
// 直接使用UTC时间戳(秒)
|
||||||
|
const startTime = Math.floor(new Date(bi.start_time).getTime() / 1000);
|
||||||
|
// 未完成笔的结束时间设为当前K线的最后时间
|
||||||
|
const endTime = Math.floor(new Date(currentData.kline_data[currentData.kline_data.length-1].date).getTime() / 1000);
|
||||||
|
|
||||||
|
if (isNaN(startTime) || isNaN(endTime)) {
|
||||||
|
console.error('主周期未完成笔时间转换错误:', bi.start_time);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const startPrice = parseFloat(bi.start_price);
|
||||||
|
|
||||||
|
if (isNaN(startPrice)) {
|
||||||
|
console.error('主周期未完成笔价格转换错误:', bi.start_price);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 根据笔的方向确定终点价格
|
||||||
|
let endPrice;
|
||||||
|
const latestKline = currentData.kline_data[currentData.kline_data.length-1];
|
||||||
|
if (bi.direction === 1) {
|
||||||
|
// 向上笔,终点为最新K线的最高点
|
||||||
|
endPrice = parseFloat(latestKline.high);
|
||||||
|
} else {
|
||||||
|
// 向下笔,终点为最新K线的最低点
|
||||||
|
endPrice = parseFloat(latestKline.low);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加未完成笔(红色虚线)
|
||||||
|
biLines.push({
|
||||||
|
startTime: startTime,
|
||||||
|
endTime: endTime,
|
||||||
|
startPrice: startPrice,
|
||||||
|
endPrice: endPrice,
|
||||||
|
color: '#FF0000', // 红色
|
||||||
|
lineWidth: 1,
|
||||||
|
lineStyle: 2 // 虚线
|
||||||
|
});
|
||||||
|
|
||||||
|
// 添加到图表对象
|
||||||
|
tvWidget.series.mainUncompletedBiSeries.push({
|
||||||
|
time: startTime,
|
||||||
|
value: startPrice,
|
||||||
|
color: '#FF0000',
|
||||||
|
lineWidth: 1,
|
||||||
|
lineStyle: 2
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
console.error('主周期未完成笔处理出错:', e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 绘制未完成笔 - 次周期
|
||||||
|
if ($('#showElementBi').is(':checked') && currentData.element_uncompleted_bi_list && currentData.element_uncompleted_bi_list.length > 0) {
|
||||||
|
console.log(`绘制次周期未完成笔数据,共${currentData.element_uncompleted_bi_list.length}条`);
|
||||||
|
|
||||||
|
currentData.element_uncompleted_bi_list.forEach(function(bi) {
|
||||||
|
try {
|
||||||
|
// 直接使用UTC时间戳(秒)
|
||||||
|
const startTime = Math.floor(new Date(bi.start_time).getTime() / 1000);
|
||||||
|
// 未完成笔的结束时间设为当前K线的最后时间
|
||||||
|
const endTime = Math.floor(new Date(currentData.kline_data[currentData.kline_data.length-1].date).getTime() / 1000);
|
||||||
|
|
||||||
|
if (isNaN(startTime) || isNaN(endTime)) {
|
||||||
|
console.error('次周期未完成笔时间转换错误:', bi.start_time);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const startPrice = parseFloat(bi.start_price);
|
||||||
|
|
||||||
|
if (isNaN(startPrice)) {
|
||||||
|
console.error('次周期未完成笔价格转换错误:', bi.start_price);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 根据笔的方向确定终点价格
|
||||||
|
let endPrice;
|
||||||
|
const latestKline = currentData.kline_data[currentData.kline_data.length-1];
|
||||||
|
if (bi.direction === 1) {
|
||||||
|
// 向上笔,终点为最新K线的最高点
|
||||||
|
endPrice = parseFloat(latestKline.high);
|
||||||
|
} else {
|
||||||
|
// 向下笔,终点为最新K线的最低点
|
||||||
|
endPrice = parseFloat(latestKline.low);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加未完成笔(红色虚线)
|
||||||
|
biLines.push({
|
||||||
|
startTime: startTime,
|
||||||
|
endTime: endTime,
|
||||||
|
startPrice: startPrice,
|
||||||
|
endPrice: endPrice,
|
||||||
|
color: '#FF0000', // 红色
|
||||||
|
lineWidth: 1,
|
||||||
|
lineStyle: 2 // 虚线
|
||||||
|
});
|
||||||
|
|
||||||
|
// 添加到图表对象
|
||||||
|
tvWidget.series.elementUncompletedBiSeries.push({
|
||||||
|
time: startTime,
|
||||||
|
value: startPrice,
|
||||||
|
color: '#FF0000',
|
||||||
|
lineWidth: 1,
|
||||||
|
lineStyle: 2
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
console.error('次周期未完成笔处理出错:', e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// 添加所有笔到图表
|
// 添加所有笔到图表
|
||||||
biLines.forEach(line => {
|
biLines.forEach(line => {
|
||||||
const lineSeries = mainChart.addLineSeries({
|
const lineSeries = mainChart.addLineSeries({
|
||||||
color: line.color,
|
color: line.color,
|
||||||
lineWidth: line.lineWidth,
|
lineWidth: line.lineWidth,
|
||||||
|
lineStyle: line.lineStyle || 0, // 支持虚线样式
|
||||||
lastValueVisible: false,
|
lastValueVisible: false,
|
||||||
priceLineVisible: false,
|
priceLineVisible: false,
|
||||||
});
|
});
|
||||||
@@ -2759,6 +2884,10 @@
|
|||||||
if ($('#showMainSeg').is(':checked') && currentData.seg_list && currentData.seg_list.length > 0) {
|
if ($('#showMainSeg').is(':checked') && currentData.seg_list && currentData.seg_list.length > 0) {
|
||||||
console.log(`绘制主周期线段数据,共${currentData.seg_list.length}条`);
|
console.log(`绘制主周期线段数据,共${currentData.seg_list.length}条`);
|
||||||
|
|
||||||
|
// 清空已有的主周期线段系列
|
||||||
|
tvWidget.series.mainSegSeries = [];
|
||||||
|
tvWidget.series.mainUncompletedSegSeries = [];
|
||||||
|
|
||||||
currentData.seg_list.forEach(function(seg) {
|
currentData.seg_list.forEach(function(seg) {
|
||||||
try {
|
try {
|
||||||
// 直接使用UTC时间戳(秒)
|
// 直接使用UTC时间戳(秒)
|
||||||
@@ -2805,6 +2934,10 @@
|
|||||||
if ($('#showElementSeg').is(':checked') && currentData.element_seg_list && currentData.element_seg_list.length > 0) {
|
if ($('#showElementSeg').is(':checked') && currentData.element_seg_list && currentData.element_seg_list.length > 0) {
|
||||||
console.log(`绘制次周期线段数据,共${currentData.element_seg_list.length}条`);
|
console.log(`绘制次周期线段数据,共${currentData.element_seg_list.length}条`);
|
||||||
|
|
||||||
|
// 清空已有的次周期线段系列
|
||||||
|
tvWidget.series.elementSegSeries = [];
|
||||||
|
tvWidget.series.elementUncompletedSegSeries = [];
|
||||||
|
|
||||||
currentData.element_seg_list.forEach(function(seg) {
|
currentData.element_seg_list.forEach(function(seg) {
|
||||||
try {
|
try {
|
||||||
// 直接使用UTC时间戳(秒)
|
// 直接使用UTC时间戳(秒)
|
||||||
@@ -2847,11 +2980,166 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 绘制未完成线段 - 主周期
|
||||||
|
if ($('#showMainSeg').is(':checked') && currentData.uncompleted_seg_list && currentData.uncompleted_seg_list.length > 0) {
|
||||||
|
console.log(`绘制主周期未完成线段数据,共${currentData.uncompleted_seg_list.length}条`);
|
||||||
|
|
||||||
|
currentData.uncompleted_seg_list.forEach(function(seg) {
|
||||||
|
try {
|
||||||
|
// 直接使用UTC时间戳(秒)
|
||||||
|
const startTime = Math.floor(new Date(seg.start_time).getTime() / 1000);
|
||||||
|
|
||||||
|
if (isNaN(startTime)) {
|
||||||
|
console.error('主周期未完成线段时间转换错误:', seg.start_time);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const startPrice = parseFloat(seg.start_price);
|
||||||
|
|
||||||
|
if (isNaN(startPrice)) {
|
||||||
|
console.error('主周期未完成线段价格转换错误:', seg.start_price);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let endTime, endPrice;
|
||||||
|
|
||||||
|
if (seg.end_time && seg.end_price) {
|
||||||
|
// 有结束时间和价格的未完成线段(倒数第二个等)
|
||||||
|
endTime = Math.floor(new Date(seg.end_time).getTime() / 1000);
|
||||||
|
endPrice = parseFloat(seg.end_price);
|
||||||
|
|
||||||
|
if (isNaN(endTime) || isNaN(endPrice)) {
|
||||||
|
console.error('主周期未完成线段结束时间或价格转换错误:', seg.end_time, seg.end_price);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 没有结束时间和价格的未完成线段(最后一个)
|
||||||
|
endTime = Math.floor(new Date(currentData.kline_data[currentData.kline_data.length-1].date).getTime() / 1000);
|
||||||
|
|
||||||
|
if (isNaN(endTime)) {
|
||||||
|
console.error('主周期未完成线段结束时间转换错误');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 根据线段的方向确定终点价格
|
||||||
|
const latestKline = currentData.kline_data[currentData.kline_data.length-1];
|
||||||
|
if (seg.direction === 1) {
|
||||||
|
// 向上线段,终点为最新K线的最高点
|
||||||
|
endPrice = parseFloat(latestKline.high);
|
||||||
|
} else {
|
||||||
|
// 向下线段,终点为最新K线的最低点
|
||||||
|
endPrice = parseFloat(latestKline.low);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加未完成线段(红色虚线)
|
||||||
|
segLines.push({
|
||||||
|
startTime: startTime,
|
||||||
|
endTime: endTime,
|
||||||
|
startPrice: startPrice,
|
||||||
|
endPrice: endPrice,
|
||||||
|
color: '#FF0000', // 红色
|
||||||
|
lineWidth: 2,
|
||||||
|
lineStyle: 2 // 虚线
|
||||||
|
});
|
||||||
|
|
||||||
|
// 添加到图表对象
|
||||||
|
tvWidget.series.mainUncompletedSegSeries.push({
|
||||||
|
time: startTime,
|
||||||
|
value: startPrice,
|
||||||
|
color: '#FF0000',
|
||||||
|
lineWidth: 2,
|
||||||
|
lineStyle: 2
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
console.error('主周期未完成线段处理出错:', e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 绘制未完成线段 - 次周期
|
||||||
|
if ($('#showElementSeg').is(':checked') && currentData.element_uncompleted_seg_list && currentData.element_uncompleted_seg_list.length > 0) {
|
||||||
|
console.log(`绘制次周期未完成线段数据,共${currentData.element_uncompleted_seg_list.length}条`);
|
||||||
|
|
||||||
|
currentData.element_uncompleted_seg_list.forEach(function(seg) {
|
||||||
|
try {
|
||||||
|
// 直接使用UTC时间戳(秒)
|
||||||
|
const startTime = Math.floor(new Date(seg.start_time).getTime() / 1000);
|
||||||
|
|
||||||
|
if (isNaN(startTime)) {
|
||||||
|
console.error('次周期未完成线段时间转换错误:', seg.start_time);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const startPrice = parseFloat(seg.start_price);
|
||||||
|
|
||||||
|
if (isNaN(startPrice)) {
|
||||||
|
console.error('次周期未完成线段价格转换错误:', seg.start_price);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let endTime, endPrice;
|
||||||
|
|
||||||
|
if (seg.end_time && seg.end_price) {
|
||||||
|
// 有结束时间和价格的未完成线段(倒数第二个等)
|
||||||
|
endTime = Math.floor(new Date(seg.end_time).getTime() / 1000);
|
||||||
|
endPrice = parseFloat(seg.end_price);
|
||||||
|
|
||||||
|
if (isNaN(endTime) || isNaN(endPrice)) {
|
||||||
|
console.error('次周期未完成线段结束时间或价格转换错误:', seg.end_time, seg.end_price);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 没有结束时间和价格的未完成线段(最后一个)
|
||||||
|
endTime = Math.floor(new Date(currentData.kline_data[currentData.kline_data.length-1].date).getTime() / 1000);
|
||||||
|
|
||||||
|
if (isNaN(endTime)) {
|
||||||
|
console.error('次周期未完成线段结束时间转换错误');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 根据线段的方向确定终点价格
|
||||||
|
const latestKline = currentData.kline_data[currentData.kline_data.length-1];
|
||||||
|
if (seg.direction === 1) {
|
||||||
|
// 向上线段,终点为最新K线的最高点
|
||||||
|
endPrice = parseFloat(latestKline.high);
|
||||||
|
} else {
|
||||||
|
// 向下线段,终点为最新K线的最低点
|
||||||
|
endPrice = parseFloat(latestKline.low);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加未完成线段(红色虚线)
|
||||||
|
segLines.push({
|
||||||
|
startTime: startTime,
|
||||||
|
endTime: endTime,
|
||||||
|
startPrice: startPrice,
|
||||||
|
endPrice: endPrice,
|
||||||
|
color: '#FF0000', // 红色
|
||||||
|
lineWidth: 2,
|
||||||
|
lineStyle: 2 // 虚线
|
||||||
|
});
|
||||||
|
|
||||||
|
// 添加到图表对象
|
||||||
|
tvWidget.series.elementUncompletedSegSeries.push({
|
||||||
|
time: startTime,
|
||||||
|
value: startPrice,
|
||||||
|
color: '#FF0000',
|
||||||
|
lineWidth: 2,
|
||||||
|
lineStyle: 2
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
console.error('次周期未完成线段处理出错:', e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// 添加所有线段到图表
|
// 添加所有线段到图表
|
||||||
segLines.forEach(line => {
|
segLines.forEach(line => {
|
||||||
const lineSeries = mainChart.addLineSeries({
|
const lineSeries = mainChart.addLineSeries({
|
||||||
color: line.color,
|
color: line.color,
|
||||||
lineWidth: line.lineWidth,
|
lineWidth: line.lineWidth,
|
||||||
|
lineStyle: line.lineStyle || 0, // 支持虚线样式
|
||||||
lastValueVisible: false,
|
lastValueVisible: false,
|
||||||
priceLineVisible: false,
|
priceLineVisible: false,
|
||||||
});
|
});
|
||||||
@@ -2886,6 +3174,8 @@
|
|||||||
|
|
||||||
const zg = parseFloat(zs.zg); // 中枢上沿
|
const zg = parseFloat(zs.zg); // 中枢上沿
|
||||||
const zd = parseFloat(zs.zd); // 中枢下沿
|
const zd = parseFloat(zs.zd); // 中枢下沿
|
||||||
|
const gg = parseFloat(zs.gg); // 中枢高高
|
||||||
|
const dd = parseFloat(zs.dd); // 中枢低低
|
||||||
|
|
||||||
if (isNaN(zg) || isNaN(zd)) {
|
if (isNaN(zg) || isNaN(zd)) {
|
||||||
console.error('主周期中枢价格转换错误:', zs.zg, zs.zd);
|
console.error('主周期中枢价格转换错误:', zs.zg, zs.zd);
|
||||||
@@ -2944,6 +3234,36 @@
|
|||||||
{ time: endTime, value: zg }
|
{ time: endTime, value: zg }
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
// 绘制gg线(中枢高高)
|
||||||
|
if (!isNaN(gg) && gg > 0) {
|
||||||
|
const ggSeries = mainChart.addLineSeries({
|
||||||
|
color: '#F1C40F', // 使用中枢自己的颜色
|
||||||
|
lineWidth: 1,
|
||||||
|
lastValueVisible: false,
|
||||||
|
priceLineVisible: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
ggSeries.setData([
|
||||||
|
{ time: startTime, value: gg },
|
||||||
|
{ time: endTime, value: gg }
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 绘制dd线(中枢低低)
|
||||||
|
if (!isNaN(dd) && dd > 0) {
|
||||||
|
const ddSeries = mainChart.addLineSeries({
|
||||||
|
color: '#F1C40F', // 使用中枢自己的颜色
|
||||||
|
lineWidth: 1,
|
||||||
|
lastValueVisible: false,
|
||||||
|
priceLineVisible: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
ddSeries.setData([
|
||||||
|
{ time: startTime, value: dd },
|
||||||
|
{ time: endTime, value: dd }
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
// 添加到图表对象
|
// 添加到图表对象
|
||||||
tvWidget.series.mainZsSeries.push({
|
tvWidget.series.mainZsSeries.push({
|
||||||
time: startTime,
|
time: startTime,
|
||||||
@@ -2992,6 +3312,8 @@
|
|||||||
|
|
||||||
const zg = parseFloat(zs.zg); // 中枢上沿
|
const zg = parseFloat(zs.zg); // 中枢上沿
|
||||||
const zd = parseFloat(zs.zd); // 中枢下沿
|
const zd = parseFloat(zs.zd); // 中枢下沿
|
||||||
|
const gg = parseFloat(zs.gg); // 中枢高高
|
||||||
|
const dd = parseFloat(zs.dd); // 中枢低低
|
||||||
|
|
||||||
if (isNaN(zg) || isNaN(zd)) {
|
if (isNaN(zg) || isNaN(zd)) {
|
||||||
console.error('次周期中枢价格转换错误:', zs.zg, zs.zd);
|
console.error('次周期中枢价格转换错误:', zs.zg, zs.zd);
|
||||||
@@ -3050,6 +3372,36 @@
|
|||||||
{ time: endTime, value: zg }
|
{ time: endTime, value: zg }
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
// 绘制gg线(中枢高高)
|
||||||
|
if (!isNaN(gg) && gg > 0) {
|
||||||
|
const ggSeries = mainChart.addLineSeries({
|
||||||
|
color: '#3f51b5', // 使用次周期中枢自己的颜色
|
||||||
|
lineWidth: 1,
|
||||||
|
lastValueVisible: false,
|
||||||
|
priceLineVisible: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
ggSeries.setData([
|
||||||
|
{ time: startTime, value: gg },
|
||||||
|
{ time: endTime, value: gg }
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 绘制dd线(中枢低低)
|
||||||
|
if (!isNaN(dd) && dd > 0) {
|
||||||
|
const ddSeries = mainChart.addLineSeries({
|
||||||
|
color: '#3f51b5', // 使用次周期中枢自己的颜色
|
||||||
|
lineWidth: 1,
|
||||||
|
lastValueVisible: false,
|
||||||
|
priceLineVisible: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
ddSeries.setData([
|
||||||
|
{ time: startTime, value: dd },
|
||||||
|
{ time: endTime, value: dd }
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
// 添加到图表对象
|
// 添加到图表对象
|
||||||
tvWidget.series.elementZsSeries.push({
|
tvWidget.series.elementZsSeries.push({
|
||||||
time: startTime,
|
time: startTime,
|
||||||
@@ -3106,6 +3458,8 @@
|
|||||||
|
|
||||||
const zg = parseFloat(zs.zg); // 中枢上沿
|
const zg = parseFloat(zs.zg); // 中枢上沿
|
||||||
const zd = parseFloat(zs.zd); // 中枢下沿
|
const zd = parseFloat(zs.zd); // 中枢下沿
|
||||||
|
const gg = parseFloat(zs.gg); // 中枢高高
|
||||||
|
const dd = parseFloat(zs.dd); // 中枢低低
|
||||||
|
|
||||||
if (isNaN(zg) || isNaN(zd)) {
|
if (isNaN(zg) || isNaN(zd)) {
|
||||||
console.error('主周期未完成中枢价格转换错误:', zs.zg, zs.zd);
|
console.error('主周期未完成中枢价格转换错误:', zs.zg, zs.zd);
|
||||||
@@ -3116,7 +3470,6 @@
|
|||||||
const topSeries = mainChart.addLineSeries({
|
const topSeries = mainChart.addLineSeries({
|
||||||
color: '#F1C40F', // 主周期中枢颜色
|
color: '#F1C40F', // 主周期中枢颜色
|
||||||
lineWidth: 1,
|
lineWidth: 1,
|
||||||
lineStyle: 2, // 虚线
|
|
||||||
lastValueVisible: false,
|
lastValueVisible: false,
|
||||||
priceLineVisible: false,
|
priceLineVisible: false,
|
||||||
});
|
});
|
||||||
@@ -3130,7 +3483,6 @@
|
|||||||
const bottomSeries = mainChart.addLineSeries({
|
const bottomSeries = mainChart.addLineSeries({
|
||||||
color: '#F1C40F', // 主周期中枢颜色
|
color: '#F1C40F', // 主周期中枢颜色
|
||||||
lineWidth: 1,
|
lineWidth: 1,
|
||||||
lineStyle: 2, // 虚线
|
|
||||||
lastValueVisible: false,
|
lastValueVisible: false,
|
||||||
priceLineVisible: false,
|
priceLineVisible: false,
|
||||||
});
|
});
|
||||||
@@ -3144,7 +3496,6 @@
|
|||||||
const leftSeries = mainChart.addLineSeries({
|
const leftSeries = mainChart.addLineSeries({
|
||||||
color: '#F1C40F', // 主周期中枢颜色
|
color: '#F1C40F', // 主周期中枢颜色
|
||||||
lineWidth: 1,
|
lineWidth: 1,
|
||||||
lineStyle: 2, // 虚线
|
|
||||||
lastValueVisible: false,
|
lastValueVisible: false,
|
||||||
priceLineVisible: false,
|
priceLineVisible: false,
|
||||||
});
|
});
|
||||||
@@ -3171,34 +3522,60 @@
|
|||||||
}
|
}
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
// 绘制gg线(中枢高高)
|
||||||
|
if (!isNaN(gg) && gg > 0) {
|
||||||
|
const ggSeries = mainChart.addLineSeries({
|
||||||
|
color: '#F1C40F', // 使用中枢自己的颜色
|
||||||
|
lineWidth: 1,
|
||||||
|
lastValueVisible: false,
|
||||||
|
priceLineVisible: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
ggSeries.setData([
|
||||||
|
{ time: startTime, value: gg },
|
||||||
|
{ time: endTime, value: gg }
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 绘制dd线(中枢低低)
|
||||||
|
if (!isNaN(dd) && dd > 0) {
|
||||||
|
const ddSeries = mainChart.addLineSeries({
|
||||||
|
color: '#F1C40F', // 使用中枢自己的颜色
|
||||||
|
lineWidth: 1,
|
||||||
|
lastValueVisible: false,
|
||||||
|
priceLineVisible: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
ddSeries.setData([
|
||||||
|
{ time: startTime, value: dd },
|
||||||
|
{ time: endTime, value: dd }
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
// 添加到图表对象
|
// 添加到图表对象
|
||||||
tvWidget.series.mainUncompletedZsSeries.push({
|
tvWidget.series.mainUncompletedZsSeries.push({
|
||||||
time: startTime,
|
time: startTime,
|
||||||
value: zg,
|
value: zg,
|
||||||
color: '#F1C40F',
|
color: '#F1C40F',
|
||||||
lineWidth: 1,
|
lineWidth: 1
|
||||||
lineStyle: 2
|
|
||||||
});
|
});
|
||||||
tvWidget.series.mainUncompletedZsSeries.push({
|
tvWidget.series.mainUncompletedZsSeries.push({
|
||||||
time: endTime,
|
time: endTime,
|
||||||
value: zg,
|
value: zg,
|
||||||
color: '#F1C40F',
|
color: '#F1C40F',
|
||||||
lineWidth: 1,
|
lineWidth: 1
|
||||||
lineStyle: 2
|
|
||||||
});
|
});
|
||||||
tvWidget.series.mainUncompletedZsSeries.push({
|
tvWidget.series.mainUncompletedZsSeries.push({
|
||||||
time: startTime,
|
time: startTime,
|
||||||
value: zd,
|
value: zd,
|
||||||
color: '#F1C40F',
|
color: '#F1C40F',
|
||||||
lineWidth: 1,
|
lineWidth: 1
|
||||||
lineStyle: 2
|
|
||||||
});
|
});
|
||||||
tvWidget.series.mainUncompletedZsSeries.push({
|
tvWidget.series.mainUncompletedZsSeries.push({
|
||||||
time: endTime,
|
time: endTime,
|
||||||
value: zd,
|
value: zd,
|
||||||
color: '#F1C40F',
|
color: '#F1C40F',
|
||||||
lineWidth: 1,
|
lineWidth: 1
|
||||||
lineStyle: 2
|
|
||||||
});
|
});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('主周期未完成中枢处理出错:', e);
|
console.error('主周期未完成中枢处理出错:', e);
|
||||||
@@ -3224,6 +3601,8 @@
|
|||||||
|
|
||||||
const zg = parseFloat(zs.zg); // 中枢上沿
|
const zg = parseFloat(zs.zg); // 中枢上沿
|
||||||
const zd = parseFloat(zs.zd); // 中枢下沿
|
const zd = parseFloat(zs.zd); // 中枢下沿
|
||||||
|
const gg = parseFloat(zs.gg); // 中枢高高
|
||||||
|
const dd = parseFloat(zs.dd); // 中枢低低
|
||||||
|
|
||||||
if (isNaN(zg) || isNaN(zd)) {
|
if (isNaN(zg) || isNaN(zd)) {
|
||||||
console.error('次周期未完成中枢价格转换错误:', zs.zg, zs.zd);
|
console.error('次周期未完成中枢价格转换错误:', zs.zg, zs.zd);
|
||||||
@@ -3234,7 +3613,6 @@
|
|||||||
const topSeries = mainChart.addLineSeries({
|
const topSeries = mainChart.addLineSeries({
|
||||||
color: '#3f51b5', // 次周期中枢颜色
|
color: '#3f51b5', // 次周期中枢颜色
|
||||||
lineWidth: 1,
|
lineWidth: 1,
|
||||||
lineStyle: 2, // 虚线
|
|
||||||
lastValueVisible: false,
|
lastValueVisible: false,
|
||||||
priceLineVisible: false,
|
priceLineVisible: false,
|
||||||
});
|
});
|
||||||
@@ -3248,7 +3626,6 @@
|
|||||||
const bottomSeries = mainChart.addLineSeries({
|
const bottomSeries = mainChart.addLineSeries({
|
||||||
color: '#3f51b5', // 次周期中枢颜色
|
color: '#3f51b5', // 次周期中枢颜色
|
||||||
lineWidth: 1,
|
lineWidth: 1,
|
||||||
lineStyle: 2, // 虚线
|
|
||||||
lastValueVisible: false,
|
lastValueVisible: false,
|
||||||
priceLineVisible: false,
|
priceLineVisible: false,
|
||||||
});
|
});
|
||||||
@@ -3262,7 +3639,6 @@
|
|||||||
const leftSeries = mainChart.addLineSeries({
|
const leftSeries = mainChart.addLineSeries({
|
||||||
color: '#3f51b5', // 次周期中枢颜色
|
color: '#3f51b5', // 次周期中枢颜色
|
||||||
lineWidth: 1,
|
lineWidth: 1,
|
||||||
lineStyle: 2, // 虚线
|
|
||||||
lastValueVisible: false,
|
lastValueVisible: false,
|
||||||
priceLineVisible: false,
|
priceLineVisible: false,
|
||||||
});
|
});
|
||||||
@@ -3289,34 +3665,60 @@
|
|||||||
}
|
}
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
// 绘制gg线(中枢高高)
|
||||||
|
if (!isNaN(gg) && gg > 0) {
|
||||||
|
const ggSeries = mainChart.addLineSeries({
|
||||||
|
color: '#3f51b5', // 使用次周期中枢自己的颜色
|
||||||
|
lineWidth: 1,
|
||||||
|
lastValueVisible: false,
|
||||||
|
priceLineVisible: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
ggSeries.setData([
|
||||||
|
{ time: startTime, value: gg },
|
||||||
|
{ time: endTime, value: gg }
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 绘制dd线(中枢低低)
|
||||||
|
if (!isNaN(dd) && dd > 0) {
|
||||||
|
const ddSeries = mainChart.addLineSeries({
|
||||||
|
color: '#3f51b5', // 使用次周期中枢自己的颜色
|
||||||
|
lineWidth: 1,
|
||||||
|
lastValueVisible: false,
|
||||||
|
priceLineVisible: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
ddSeries.setData([
|
||||||
|
{ time: startTime, value: dd },
|
||||||
|
{ time: endTime, value: dd }
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
// 添加到图表对象
|
// 添加到图表对象
|
||||||
tvWidget.series.elementUncompletedZsSeries.push({
|
tvWidget.series.elementUncompletedZsSeries.push({
|
||||||
time: startTime,
|
time: startTime,
|
||||||
value: zg,
|
value: zg,
|
||||||
color: '#3f51b5',
|
color: '#3f51b5',
|
||||||
lineWidth: 1,
|
lineWidth: 1
|
||||||
lineStyle: 2
|
|
||||||
});
|
});
|
||||||
tvWidget.series.elementUncompletedZsSeries.push({
|
tvWidget.series.elementUncompletedZsSeries.push({
|
||||||
time: endTime,
|
time: endTime,
|
||||||
value: zg,
|
value: zg,
|
||||||
color: '#3f51b5',
|
color: '#3f51b5',
|
||||||
lineWidth: 1,
|
lineWidth: 1
|
||||||
lineStyle: 2
|
|
||||||
});
|
});
|
||||||
tvWidget.series.elementUncompletedZsSeries.push({
|
tvWidget.series.elementUncompletedZsSeries.push({
|
||||||
time: startTime,
|
time: startTime,
|
||||||
value: zd,
|
value: zd,
|
||||||
color: '#3f51b5',
|
color: '#3f51b5',
|
||||||
lineWidth: 1,
|
lineWidth: 1
|
||||||
lineStyle: 2
|
|
||||||
});
|
});
|
||||||
tvWidget.series.elementUncompletedZsSeries.push({
|
tvWidget.series.elementUncompletedZsSeries.push({
|
||||||
time: endTime,
|
time: endTime,
|
||||||
value: zd,
|
value: zd,
|
||||||
color: '#3f51b5',
|
color: '#3f51b5',
|
||||||
lineWidth: 1,
|
lineWidth: 1
|
||||||
lineStyle: 2
|
|
||||||
});
|
});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('次周期未完成中枢处理出错:', e);
|
console.error('次周期未完成中枢处理出错:', e);
|
||||||
@@ -5233,27 +5635,56 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 根据用户选择决定使用哪个周期的数据
|
// 根据用户选择决定使用哪个周期的数据
|
||||||
let segData, segSource;
|
let segData, segSource, uncompletedSegData;
|
||||||
if (useElementPeriod && data.element_seg_list && data.element_seg_list.length > 0) {
|
if (useElementPeriod && data.element_seg_list && data.element_seg_list.length > 0) {
|
||||||
segData = data.element_seg_list;
|
segData = data.element_seg_list;
|
||||||
|
uncompletedSegData = data.element_uncompleted_seg_list || [];
|
||||||
segSource = '小周期';
|
segSource = '小周期';
|
||||||
} else {
|
} else {
|
||||||
segData = data.seg_list;
|
segData = data.seg_list;
|
||||||
|
uncompletedSegData = data.uncompleted_seg_list || [];
|
||||||
segSource = '主周期';
|
segSource = '主周期';
|
||||||
}
|
}
|
||||||
console.log(`表格显示${segSource}线段数据,共${segData ? segData.length : 0}条`);
|
|
||||||
|
// 合并已完成和未完成的线段数据
|
||||||
|
let allSegData = [];
|
||||||
|
if (segData && segData.length > 0) {
|
||||||
|
allSegData = allSegData.concat(segData.map(seg => ({...seg, status: '已完成'})));
|
||||||
|
}
|
||||||
|
if (uncompletedSegData && uncompletedSegData.length > 0) {
|
||||||
|
allSegData = allSegData.concat(uncompletedSegData.map(seg => ({...seg, status: '未完成'})));
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(`表格显示${segSource}线段数据,已完成${segData ? segData.length : 0}条,未完成${uncompletedSegData ? uncompletedSegData.length : 0}条,总计${allSegData.length}条`);
|
||||||
|
|
||||||
tables.seg = $('#segTable').DataTable({
|
tables.seg = $('#segTable').DataTable({
|
||||||
data: segData || [],
|
data: allSegData,
|
||||||
order: [[0, 'desc']],
|
order: [[0, 'desc']],
|
||||||
pageLength: 25,
|
pageLength: 25,
|
||||||
columns: [
|
columns: [
|
||||||
{ data: 'start_time', render: formatTime },
|
{ data: 'start_time', render: formatTime },
|
||||||
{ data: 'end_time', render: formatTime },
|
{ data: 'end_time', render: function(data, type, row) {
|
||||||
|
if (data === null || data === undefined) {
|
||||||
|
return type === 'display' ? '<span style="color: red;">未完成</span>' : '';
|
||||||
|
}
|
||||||
|
return formatTime(data, type, row);
|
||||||
|
}},
|
||||||
{ data: 'sure_time', render: formatConfirmTime },
|
{ data: 'sure_time', render: formatConfirmTime },
|
||||||
{ data: 'start_price', render: formatPrice },
|
{ data: 'start_price', render: formatPrice },
|
||||||
{ data: 'end_price', render: formatPrice },
|
{ data: 'end_price', render: function(data, type, row) {
|
||||||
{ data: 'direction', render: formatDirection }
|
if (data === null || data === undefined) {
|
||||||
|
return type === 'display' ? '<span style="color: red;">未完成</span>' : '';
|
||||||
|
}
|
||||||
|
return formatPrice(data, type, row);
|
||||||
|
}},
|
||||||
|
{ data: 'direction', render: formatDirection },
|
||||||
|
{ data: 'status', render: function(data, type, row) {
|
||||||
|
if (type === 'display') {
|
||||||
|
const color = data === '已完成' ? 'green' : 'red';
|
||||||
|
return `<span style="color: ${color}; font-weight: bold;">${data}</span>`;
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}}
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user