add changes
This commit is contained in:
@@ -53,6 +53,7 @@ class ChanBI():
|
||||
self.end_klc = klc
|
||||
self.set_is_sure(True, sure_klc.end_time)
|
||||
self.end_time = klc.end_time
|
||||
#print(self.start_time, klc.start_time, klc.fx, "This bi is ended")
|
||||
def set_is_sure(self, is_sure, time):
|
||||
self.is_sure = is_sure
|
||||
self.sure_time = time
|
||||
@@ -88,4 +89,4 @@ class ChanBI():
|
||||
self.low = klc.low
|
||||
self.is_sure = False
|
||||
self.sure_time = None
|
||||
#print(self.start_klc.start_time, klc.start_time, klc.fx, "This bi is extended")
|
||||
#print(self.start_time, klc.start_time, klc.fx, "This bi is extended")
|
||||
+11
@@ -40,6 +40,17 @@ class Chan_FX_TYPE(Enum):
|
||||
DOWN = auto()
|
||||
TT = auto()
|
||||
BB = auto()
|
||||
PTOP = auto()
|
||||
PBOTTOM = auto()
|
||||
|
||||
class Chan_KLC_FX(Enum):
|
||||
TOP1 = auto()
|
||||
TOP2 = auto()
|
||||
TOP3 = auto()
|
||||
BOTTOM1 = auto()
|
||||
BOTTOM2 = auto()
|
||||
BOTTOM3 = auto()
|
||||
UNKNOWN = auto()
|
||||
|
||||
|
||||
class Chan_BI_DIR(Enum):
|
||||
|
||||
+12
-1
@@ -1,7 +1,7 @@
|
||||
import copy
|
||||
from typing import Dict, Optional
|
||||
|
||||
from ChanEnum import Chan_FX_TYPE, Chan_KLINE_DIR, Chan_BI_DIR
|
||||
from ChanEnum import Chan_FX_TYPE, Chan_KLINE_DIR, Chan_BI_DIR, Chan_KLC_FX
|
||||
import ChanKLU
|
||||
import ChanCTime
|
||||
|
||||
@@ -29,6 +29,10 @@ class ChanKLC():
|
||||
self.bi_macdhist = 0
|
||||
self.bi_macd_div = 0.0
|
||||
self.bi = None
|
||||
self.distance = 0
|
||||
self.klc_fx_type = Chan_KLC_FX.UNKNOWN
|
||||
def set_klc_fx_type(self, klc_fx_type):
|
||||
self.klc_fx_type = klc_fx_type
|
||||
def add_klu(self, klu):
|
||||
self.klus.append(klu)
|
||||
def set_end_klu(self, klu):
|
||||
@@ -123,6 +127,12 @@ class ChanKLC():
|
||||
self.bi_macdhist += klc.get_macdhist()
|
||||
elif bi.dir == Chan_BI_DIR.DOWN and klc.get_macdhist() < 0:
|
||||
self.bi_macdhist -= klc.get_macdhist()
|
||||
self.distance = self.index - bi.start_klc.index
|
||||
if False:
|
||||
if bi.is_sure:
|
||||
print(self.start_time, self.distance, bi.index, bi.start_time, bi.dir, bi.end_time)
|
||||
else:
|
||||
print(self.start_time, self.distance, bi.index, bi.start_time, bi.dir)
|
||||
def get_macdhist(self):
|
||||
self.macdhist = 0
|
||||
for klu in self.klus:
|
||||
@@ -164,6 +174,7 @@ class ChanKLC():
|
||||
features['klc_pre_fx'] = (0 if self.pre.fx == Chan_FX_TYPE.UNKNOWN else 1 if self.pre.fx == Chan_FX_TYPE.TOP else 2) if self.pre else 0 #10
|
||||
features['klc_pre_pre_fx'] = (0 if self.pre.pre.fx == Chan_FX_TYPE.UNKNOWN else 1 if self.pre.pre.fx == Chan_FX_TYPE.TOP else 2) if self.pre and self.pre.pre else 0 #11
|
||||
features['klc_pre_pre_pre_fx'] = (0 if self.pre.pre.pre.fx == Chan_FX_TYPE.UNKNOWN else 1 if self.pre.pre.pre.fx == Chan_FX_TYPE.TOP else 2) if self.pre and self.pre.pre and self.pre.pre.pre else 0 #12
|
||||
features['klc_distance'] = self.distance #13
|
||||
# New Add 20250422
|
||||
#features['klc_macdhist'] = self.get_macdhist() #11
|
||||
#features['klc_bi_macdhist'] = self.bi_macdhist #12
|
||||
|
||||
@@ -21,6 +21,15 @@ class ChanKLU:
|
||||
def set_idx(self, idx):
|
||||
self.idx = idx
|
||||
self.index = idx
|
||||
def set_indicators(self, dict):
|
||||
self.macd = dict['macd']
|
||||
self.signal = dict['macdsignal']
|
||||
self.macdhist = dict['macdhist']
|
||||
self.ma5 = dict['ma5']
|
||||
self.ma10 = dict['ma10']
|
||||
self.ma30 = dict['ma30']
|
||||
self.ma250 = dict['ma250']
|
||||
self.rsi = dict['rsi']
|
||||
def get_feature_data(self):
|
||||
features = dict()
|
||||
features['klu_close'] = self.close
|
||||
|
||||
+80
-33
@@ -1,6 +1,6 @@
|
||||
from datetime import timedelta
|
||||
from pandas import DataFrame
|
||||
from ChanEnum import Chan_FX_TYPE, Chan_KLINE_DIR, Chan_BI_DIR, Chan_SEG_DIR, Chan_ZS_DIR, Chan_BSP_DIR, Chan_BSP_TYPE
|
||||
from ChanEnum import Chan_FX_TYPE, Chan_KLINE_DIR, Chan_BI_DIR, Chan_SEG_DIR, Chan_ZS_DIR, Chan_BSP_DIR, Chan_BSP_TYPE, Chan_KLC_FX
|
||||
from ChanKLU import ChanKLU
|
||||
from ChanKLC import ChanKLC
|
||||
from ChanBI import ChanBI
|
||||
@@ -88,6 +88,7 @@ class ChanLun():
|
||||
df['macdhist'] = macd['macdhist']
|
||||
return df
|
||||
def plot_dataframe(self, dataframe):
|
||||
return self.get_klu_list(dataframe)
|
||||
klc_list = self.get_klc_list(dataframe)
|
||||
bi_list= self.cal_bi_list(klc_list)
|
||||
seg_list = self.get_seg_list(bi_list)
|
||||
@@ -529,7 +530,7 @@ class ChanLun():
|
||||
fx = self.check_fx(klc)
|
||||
# Do nothing
|
||||
if fx == Chan_FX_TYPE.UNKNOWN:
|
||||
klc.set_fx(Chan_FX_TYPE.UNKNOWN)
|
||||
klc.set_fx(fx)
|
||||
if len(bi_list) > 0:
|
||||
bi_list[-1].add_klc(klc)
|
||||
klc.set_bi(bi_list[-1])
|
||||
@@ -541,16 +542,19 @@ class ChanLun():
|
||||
if last_bottom.index < last_top.index:
|
||||
# Second top lower to be second sell point
|
||||
if last_top.high > klc.high:
|
||||
klc.set_fx(Chan_FX_TYPE.TT)
|
||||
#klc.set_fx(Chan_FX_TYPE.TT)
|
||||
klc.set_state("20")
|
||||
bi_list[-1].add_klc(klc)
|
||||
klc.set_bi(bi_list[-1])
|
||||
#print(klc.start_time, klc.fx, "二类买卖点Sell 1")
|
||||
#print(klc.start_time, klc.fx, "二类卖点Sell 1")
|
||||
else:
|
||||
# A new top found
|
||||
#last_top.set_fx(Chan_FX_TYPE.UNKNOWN)
|
||||
last_top = klc
|
||||
#print(klc.start_time, klc.fx, "一类买卖点Sell 1")
|
||||
print(klc.start_time, klc.fx, bi_list[-1].dir, "Last Top Change 1")
|
||||
klc.set_klc_fx_type(Chan_KLC_FX.TOP1)
|
||||
#print(klc.start_time, klc.fx, "一类卖点Sell 1")
|
||||
#klc.set_fx(fx)
|
||||
klc.set_state("10")
|
||||
bi_list[-1].add_klc(klc)
|
||||
klc.set_bi(bi_list[-1])
|
||||
@@ -558,8 +562,8 @@ class ChanLun():
|
||||
# 不满足结合律的分型
|
||||
if last_bottom.index + 4 > klc.index:
|
||||
if last_top.high > klc.high:
|
||||
#print(klc.start_time, last_bottom.start_time, klc.fx, "中枢买卖点Sell 1")
|
||||
klc.set_fx(Chan_FX_TYPE.UNKNOWN)
|
||||
#print(klc.start_time, klc.fx, "二类卖点Sell 1")
|
||||
#klc.set_fx(Chan_FX_TYPE.PTOP)
|
||||
bi_list[-1].add_klc(klc)
|
||||
klc.set_bi(bi_list[-1])
|
||||
# New TOP Found replace last top
|
||||
@@ -571,18 +575,21 @@ class ChanLun():
|
||||
pre_last_bi.update_bi(klc)
|
||||
bi_list.remove(last_bi)
|
||||
pre_last_bi.set_next(None)
|
||||
last_top.set_fx(Chan_FX_TYPE.UNKNOWN)
|
||||
#last_top.set_fx(Chan_FX_TYPE.PTOP)
|
||||
last_top = klc
|
||||
last_bottom = pre_last_bi.start_klc
|
||||
print(klc.start_time, klc.fx, bi_list[-1].dir, "Last Top Bottom Change 1")
|
||||
klc.set_klc_fx_type(Chan_KLC_FX.TOP2)
|
||||
#print(klc.start_time, last_bi.start_klc.start_time, "New TOP Found reset last bi")
|
||||
klc.set_state("10")
|
||||
#print(klc.start_time, klc.fx, "笔卖点Sell 1")
|
||||
bi_list[-1].add_klc(klc)
|
||||
klc.set_bi(bi_list[-1])
|
||||
else:
|
||||
klc.set_fx(Chan_FX_TYPE.UNKNOWN)
|
||||
klc.set_fx(Chan_FX_TYPE.PTOP)
|
||||
bi_list[-1].add_klc(klc)
|
||||
klc.set_bi(bi_list[-1])
|
||||
#print(klc.start_time, last_bottom.start_time, klc.fx, "中枢买卖点Sell 2")
|
||||
#print(klc.start_time, klc.fx, "无效分型")
|
||||
# 满足结合律
|
||||
else:
|
||||
# New Temp TOP and last bottom confirmed ***** confirm last down bi(last bottom and last top)
|
||||
@@ -595,10 +602,13 @@ class ChanLun():
|
||||
bi.add_klc(klc)
|
||||
bi_list.append(bi)
|
||||
last_top = klc
|
||||
print(klc.start_time, klc.fx, bi_list[-1].dir, "Last Top Change 2")
|
||||
klc.set_klc_fx_type(Chan_KLC_FX.TOP2)
|
||||
klc.set_state('30')
|
||||
bi_list[-1].add_klc(klc)
|
||||
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, klc.fx, "笔卖点Sell 2")
|
||||
# last bottom = None
|
||||
else:
|
||||
if last_top.high < klc.high:
|
||||
@@ -606,29 +616,42 @@ class ChanLun():
|
||||
last_bi.set_start_klc(klc, Chan_BI_DIR.DOWN)
|
||||
#last_top.set_fx(Chan_FX_TYPE.UNKNOWN)
|
||||
last_top = klc
|
||||
print(klc.start_time, klc.fx, bi_list[-1].dir, "Last Top Change 3")
|
||||
bi_list[-1].add_klc(klc)
|
||||
klc.set_bi(bi_list[-1])
|
||||
#print(klc.start_time, klc.fx, "笔卖点Sell 3")
|
||||
else:
|
||||
klc.set_fx(Chan_FX_TYPE.TT)
|
||||
klc.set_state('20')
|
||||
#print(klc.start_time, klc.fx, "二类买卖点Sell 2")
|
||||
#print(klc.start_time, klc.fx, "二类卖点Sell 2")
|
||||
bi_list[-1].add_klc(klc)
|
||||
klc.set_bi(bi_list[-1])
|
||||
else:
|
||||
if last_bottom:
|
||||
# 不满足结合律的分型
|
||||
if last_bottom.index + 4 > klc.index:
|
||||
klc.set_fx(Chan_FX_TYPE.UNKNOWN)
|
||||
#klc.set_fx(Chan_FX_TYPE.PTOP)
|
||||
bi_list[-1].add_klc(klc)
|
||||
klc.set_bi(bi_list[-1])
|
||||
#print(klc.start_time, klc.fx, "中枢卖点Sell 1")
|
||||
else:
|
||||
# First temp top and last bottom confirmed
|
||||
last_top = klc
|
||||
print(klc.start_time, klc.fx, bi_list[-1].dir, "Last Top Change 4")
|
||||
bi_list[-1].add_klc(klc)
|
||||
klc.set_bi(bi_list[-1])
|
||||
#print(klc.start_time, klc.fx, "一类卖点Sell 1")
|
||||
# Last top = None, last bottom = None, create first down bi
|
||||
else:
|
||||
# First temp top
|
||||
last_top = klc
|
||||
bi = ChanBI(klc, len(bi_list), Chan_BI_DIR.DOWN)
|
||||
bi_list.append(bi)
|
||||
bi_list[-1].add_klc(klc)
|
||||
klc.set_bi(bi_list[-1])
|
||||
print(klc.start_time, klc.fx, bi_list[-1].dir, "Last Top Change 5")
|
||||
#print(klc.start_time, 'Create first top')
|
||||
#print(klc.start_time, klc.fx, "笔卖点Sell 1")
|
||||
#klc.fx = Bottom ========================
|
||||
else:
|
||||
if last_bottom:
|
||||
@@ -637,16 +660,18 @@ class ChanLun():
|
||||
if last_top.index < last_bottom.index:
|
||||
# Second bottom uppper to be second buy point and confirm last bi
|
||||
if last_bottom.low < klc.low:
|
||||
klc.set_fx(Chan_FX_TYPE.BB)
|
||||
#klc.set_fx(Chan_FX_TYPE.BB)
|
||||
klc.set_state("-20")
|
||||
bi_list[-1].add_klc(klc)
|
||||
klc.set_bi(bi_list[-1])
|
||||
#print(klc.start_time, klc.fx, "二类买卖点Buy 1")
|
||||
#print(klc.start_time, klc.fx, "二类买点Buy 1")
|
||||
else:
|
||||
# A new bottom found
|
||||
#last_bottom.set_fx(Chan_FX_TYPE.UNKNOWN)
|
||||
last_bottom = klc
|
||||
#print(klc.start_time, klc.fx, "一类买卖点Buy 1")
|
||||
print(klc.start_time, klc.fx, bi_list[-1].dir, "Last Bottom Change 1")
|
||||
klc.set_klc_fx_type(Chan_KLC_FX.BOTTOM1)
|
||||
#print(klc.start_time, klc.fx, "一类买点Buy 1")
|
||||
klc.set_state("-10")
|
||||
bi_list[-1].add_klc(klc)
|
||||
klc.set_bi(bi_list[-1])
|
||||
@@ -654,10 +679,10 @@ class ChanLun():
|
||||
# 不满足结合律的分型
|
||||
if last_top.index + 4 > klc.index:
|
||||
if last_bottom.low < klc.low:
|
||||
klc.set_fx(Chan_FX_TYPE.UNKNOWN)
|
||||
#klc.set_fx(Chan_FX_TYPE.PBOTTOM)
|
||||
#klc.set_fx(Chan_FX_TYPE.BB)
|
||||
#klc.set_state("-100")
|
||||
#print(klc.start_time, klc.fx, "中枢买卖点Buy 1")
|
||||
#print(klc.start_time, klc.fx, "中枢买点Buy 1")
|
||||
bi_list[-1].add_klc(klc)
|
||||
klc.set_bi(bi_list[-1])
|
||||
# Found new bottom
|
||||
@@ -669,18 +694,21 @@ class ChanLun():
|
||||
pre_last_bi.update_bi(klc)
|
||||
bi_list.remove(last_bi)
|
||||
pre_last_bi.set_next(None)
|
||||
last_bottom.set_fx(Chan_FX_TYPE.UNKNOWN)
|
||||
#last_bottom.set_fx(Chan_FX_TYPE.PBOTTOM)
|
||||
last_bottom = klc
|
||||
last_top = pre_last_bi.start_klc
|
||||
print(klc.start_time, klc.fx, bi_list[-1].dir, "Last Top Bottom Change 2")
|
||||
klc.set_klc_fx_type(Chan_KLC_FX.BOTTOM2)
|
||||
#print(klc.start_time, last_bi.start_klc.start_time, "New BOTTOM Found reset last bi")
|
||||
klc.set_state("-10")
|
||||
#print(klc.start_time, klc.fx, "笔买点Buy 1")
|
||||
bi_list[-1].add_klc(klc)
|
||||
klc.set_bi(bi_list[-1])
|
||||
else:
|
||||
klc.set_fx(Chan_FX_TYPE.UNKNOWN)
|
||||
#klc.set_fx(Chan_FX_TYPE.UNKNOWN)
|
||||
bi_list[-1].add_klc(klc)
|
||||
klc.set_bi(bi_list[-1])
|
||||
#print(klc.start_time, klc.fx, "中枢买卖点Buy 2")
|
||||
#print(klc.start_time, klc.fx, "无效分型")
|
||||
# 满足结合律的分型
|
||||
else:
|
||||
# New Temp Bottom and last top confirmed ***** confirm last up bi(last bottom and last top)
|
||||
@@ -693,9 +721,12 @@ class ChanLun():
|
||||
bi.add_klc(klc)
|
||||
bi_list.append(bi)
|
||||
last_bottom = klc
|
||||
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_state('-30')
|
||||
bi_list[-1].add_klc(klc)
|
||||
klc.set_bi(bi_list[-1])
|
||||
#print(klc.start_time, klc.fx, "笔买点Buy 2")
|
||||
#print(klc.start_time, last_top.start_time, "Normal Bottom Found, Confirm up bi 6")
|
||||
# last_top = None
|
||||
else:
|
||||
@@ -704,12 +735,14 @@ class ChanLun():
|
||||
last_bi.set_start_klc(klc, Chan_BI_DIR.UP)
|
||||
#last_bottom.set_fx(Chan_FX_TYPE.UNKNOWN)
|
||||
last_bottom = klc
|
||||
print(klc.start_time, klc.fx, bi_list[-1].dir, "Last Bottom Change 3")
|
||||
bi_list[-1].add_klc(klc)
|
||||
klc.set_bi(bi_list[-1])
|
||||
#print(klc.start_time, klc.fx, "笔买点Buy 3")
|
||||
else:
|
||||
klc.set_fx(Chan_FX_TYPE.BB)
|
||||
klc.set_state('-20')
|
||||
#print(klc.start_time, klc.fx, "二类买卖点Buy 2")
|
||||
#print(klc.start_time, klc.fx, "二类买点Buy 2")
|
||||
bi_list[-1].add_klc(klc)
|
||||
klc.set_bi(bi_list[-1])
|
||||
# last_bottom = None
|
||||
@@ -717,14 +750,17 @@ class ChanLun():
|
||||
if last_top:
|
||||
# 不满足结合律的分型
|
||||
if last_top.index + 4 > klc.index:
|
||||
klc.set_fx(Chan_FX_TYPE.UNKNOWN)
|
||||
#klc.set_fx(Chan_FX_TYPE.PBOTTOM)
|
||||
bi_list[-1].add_klc(klc)
|
||||
klc.set_bi(bi_list[-1])
|
||||
#print(klc.start_time, klc.fx, "中枢买点Buy 1")
|
||||
else:
|
||||
# First temp bottom and last top confirmed
|
||||
last_bottom = klc
|
||||
print(klc.start_time, klc.fx, bi_list[-1].dir, "Last Bottom Change 4")
|
||||
bi_list[-1].add_klc(klc)
|
||||
klc.set_bi(bi_list[-1])
|
||||
#print(klc.start_time, klc.fx, "一类买点Buy 1")
|
||||
# Last top = None, last bottom = None, create first up bi
|
||||
else:
|
||||
# First temp bottom and no top yet
|
||||
@@ -733,8 +769,11 @@ class ChanLun():
|
||||
bi_list.append(bi)
|
||||
bi_list[-1].add_klc(klc)
|
||||
klc.set_bi(bi_list[-1])
|
||||
#print(klc.start_time, 'Create first bottom')
|
||||
#print(klc.time, klc.fx, klc.state)
|
||||
print(klc.start_time, klc.fx, bi_list[-1].dir, "Last Bottom Change 5")
|
||||
#print(klc.start_time, klc.fx, "笔买点Buy 4")
|
||||
#if klc.fx != Chan_FX_TYPE.UNKNOWN:
|
||||
#print(klc.start_time, klc.fx, klc.index)
|
||||
"""
|
||||
for klc in klc_list:
|
||||
if klc.fx == Chan_FX_TYPE.TOP:
|
||||
klc.state = "10"
|
||||
@@ -742,6 +781,7 @@ class ChanLun():
|
||||
if klc.fx == Chan_FX_TYPE.BOTTOM:
|
||||
klc.state = "-10"
|
||||
#print(klc.time, klc.state)
|
||||
"""
|
||||
return bi_list
|
||||
|
||||
def get_zs_list(self, bi_list, seg_list):
|
||||
@@ -997,7 +1037,20 @@ class ChanLun():
|
||||
|
||||
def get_decimal(self, value):
|
||||
return Decimal("{:.2f}".format(value))
|
||||
|
||||
def add_indicators(self, df):
|
||||
fast = 8
|
||||
slow = 16
|
||||
period = 6
|
||||
macd = ta.MACD(df, fastperiod=fast, slowperiod=slow, signalperiod=period)
|
||||
df['macd'] = macd['macd']
|
||||
df['macdsignal'] = macd['macdsignal']
|
||||
df['macdhist'] = macd['macdhist']
|
||||
df['ma5'] = ta.MA(df, timeperiod=5)
|
||||
df['ma10'] = ta.MA(df, timeperiod=10)
|
||||
df['ma30'] = ta.EMA(df, timeperiod=30)
|
||||
df['ma250'] = ta.MA(df, timeperiod=250)
|
||||
df['rsi'] = ta.RSI(df, timeperiod=14)
|
||||
return df
|
||||
def get_klc_list(self, dataframe):
|
||||
klu_list = self.get_klu_list(dataframe)
|
||||
klc_list = []
|
||||
@@ -1075,14 +1128,8 @@ class ChanLun():
|
||||
klu = ChanKLU(time_str, o, h, l, c, v)
|
||||
klu.set_idx(i)
|
||||
klu_list.append(klu)
|
||||
klu.macd = item['macd']
|
||||
klu.signal = item['macdsignal']
|
||||
klu.macdhist = item['macdhist']
|
||||
klu.ma5 = item['ma5']
|
||||
klu.ma10 = item['ma10']
|
||||
klu.ma30 = item['ma30']
|
||||
klu.ma250 = item['ma250']
|
||||
klu.rsi = item['rsi']
|
||||
if True:
|
||||
klu.set_indicators(item)
|
||||
return klu_list
|
||||
|
||||
def get_bsp_list1(self, big_df):
|
||||
|
||||
+18
-4
@@ -289,6 +289,13 @@ class ChanLunClassifier:
|
||||
bi_index = 0
|
||||
sample_list = []
|
||||
for klc in klc_list:
|
||||
if klc.pre and klc.next:
|
||||
if klc.high > klc.pre.high and klc.high > klc.next.high:
|
||||
klc.set_fx(Chan_FX_TYPE.TOP)
|
||||
elif klc.low < klc.pre.low and klc.low < klc.next.low:
|
||||
klc.set_fx(Chan_FX_TYPE.BOTTOM)
|
||||
else:
|
||||
klc.set_fx(Chan_FX_TYPE.UNKNOWN)
|
||||
if klc.fx != Chan_FX_TYPE.UNKNOWN:
|
||||
sample_list.append(klc)
|
||||
for klc in sample_list:
|
||||
@@ -311,8 +318,8 @@ class ChanLunClassifier:
|
||||
|
||||
# 判断这个bi是否赚钱(这里简单定义为:如果bi的结束价格高于起始价格,则标记为1,否则为0)
|
||||
# 这个标签定义可以根据实际需求修改
|
||||
seg = seg_list[bi_index]
|
||||
if bi.start_klc.index == klc.index and bi.dir == Chan_BI_DIR.UP:
|
||||
bi = bi_list[bi_index]
|
||||
if bi.start_klc.index == klc.index:
|
||||
#if klc.index == seg.start_bi.start_klc.index and seg.dir == Chan_SEG_DIR.UP:
|
||||
label = 1
|
||||
bi_index += 2
|
||||
@@ -339,6 +346,13 @@ class ChanLunClassifier:
|
||||
bi_index = 0
|
||||
sample_list = []
|
||||
for klc in klc_list:
|
||||
if klc.pre and klc.next:
|
||||
if klc.high > klc.pre.high and klc.high > klc.next.high:
|
||||
klc.set_fx(Chan_FX_TYPE.TOP)
|
||||
elif klc.low < klc.pre.low and klc.low < klc.next.low:
|
||||
klc.set_fx(Chan_FX_TYPE.BOTTOM)
|
||||
else:
|
||||
klc.set_fx(Chan_FX_TYPE.UNKNOWN)
|
||||
if klc.fx != Chan_FX_TYPE.UNKNOWN:
|
||||
sample_list.append(klc)
|
||||
for klc in sample_list:
|
||||
@@ -357,7 +371,7 @@ class ChanLunClassifier:
|
||||
else:
|
||||
feature_vec.append(0)
|
||||
seg = seg_list[bi_index]
|
||||
if bi.start_klc.index == klc.index and bi.dir == Chan_BI_DIR.UP:
|
||||
if bi.start_klc.index == klc.index:
|
||||
#if klc.index == seg.start_bi.start_klc.index and seg.dir == Chan_SEG_DIR.UP:
|
||||
label = 1
|
||||
bi_index += 2
|
||||
@@ -449,5 +463,5 @@ class ChanLunClassifier:
|
||||
return self.get_decimal(self.model.predict(dtest)[0])
|
||||
|
||||
def get_decimal(self, value):
|
||||
return Decimal("{:.2f}".format(value))
|
||||
return Decimal("{:.4f}".format(value))
|
||||
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+19
-54
@@ -128,14 +128,25 @@ def get_kl_data(symbol, timeframe, limit=1000, start_time=None, end_time=None):
|
||||
|
||||
# 按时间排序
|
||||
df = df.sort_values('timestamp')
|
||||
|
||||
chan = ChanLun()
|
||||
klc_list = chan.get_klc_list(df)
|
||||
klc_index = 0
|
||||
df_copy = df.copy()
|
||||
ret_df = pd.DataFrame(columns=['timestamp', 'open', 'high', 'low', 'close', 'volume', 'date'])
|
||||
for index in range(0, len(df)):
|
||||
if klc_index >= len(klc_list):
|
||||
klc_index = len(klc_list) - 1
|
||||
klc = klc_list[klc_index]
|
||||
if index == klc.start_klu.index:
|
||||
ret_df.loc[klc_index] = df_copy.loc[index]
|
||||
klc_index += 1
|
||||
# 如果过滤后没有数据,返回None
|
||||
if len(df) == 0:
|
||||
if len(ret_df) == 0:
|
||||
print("过滤后无数据")
|
||||
return None
|
||||
|
||||
print(f"获取到总共 {len(df)} 条数据")
|
||||
return df
|
||||
print(f"获取到总共 {len(ret_df)} 条数据")
|
||||
return ret_df
|
||||
|
||||
except Exception as e:
|
||||
print(f"获取数据错误: {e}")
|
||||
@@ -166,9 +177,6 @@ def analyze_chan(df):
|
||||
seg_list = chan.get_seg_list(bi_list)
|
||||
zs_list = chan.calculate_zs(bi_list, seg_list)
|
||||
|
||||
# 获取笔中枢列表
|
||||
bi_zs_list = chan.get_bi_zs_list(bi_list)
|
||||
|
||||
# 添加买卖点识别
|
||||
buy_sell_points = identify_trade_points(bi_list, seg_list, zs_list)
|
||||
|
||||
@@ -177,7 +185,6 @@ def analyze_chan(df):
|
||||
'bi_list': bi_list,
|
||||
'seg_list': seg_list,
|
||||
'zs_list': zs_list,
|
||||
'bi_zs_list': bi_zs_list, # 添加笔中枢数据
|
||||
'trade_points': buy_sell_points
|
||||
}
|
||||
|
||||
@@ -403,36 +410,16 @@ def analyze():
|
||||
'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,
|
||||
'zd': zs.zd,
|
||||
'is_sure': zs.is_sure, # 添加中枢是否完成的标志
|
||||
'type': getattr(zs, 'type', 'SEG_ZS') # 中枢类型,默认为线段中枢
|
||||
'is_sure': zs.is_sure # 添加中枢是否完成的标志
|
||||
} for zs in analysis_result['zs_list'] if zs.end_klc],
|
||||
# 添加笔中枢列表
|
||||
'bi_zs_list': [{
|
||||
'start_time': zs.start_klc.start_time if isinstance(zs.start_klc.start_time, str) else zs.start_klc.start_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,
|
||||
'zg': zs.zg,
|
||||
'zd': zs.zd,
|
||||
'is_sure': zs.is_sure, # 添加中枢是否完成的标志
|
||||
'type': 'BI_ZS' # 标记为笔中枢
|
||||
} for zs in analysis_result['bi_zs_list'] if zs.end_klc],
|
||||
# 添加未完成中枢列表
|
||||
'uncompleted_zs_list': [{
|
||||
'start_time': zs.start_klc.start_time if isinstance(zs.start_klc.start_time, str) else zs.start_klc.start_time.astimezone(client_tz).isoformat(),
|
||||
'end_time': None, # 未完成中枢没有结束时间
|
||||
'zg': zs.zg,
|
||||
'zd': zs.zd,
|
||||
'is_sure': zs.is_sure, # 未完成中枢的is_sure为False
|
||||
'type': getattr(zs, 'type', 'SEG_ZS') # 中枢类型,默认为线段中枢
|
||||
'is_sure': zs.is_sure # 未完成中枢的is_sure为False
|
||||
} for zs in analysis_result['zs_list'] if not zs.is_sure],
|
||||
# 添加未完成笔中枢列表
|
||||
'uncompleted_bi_zs_list': [{
|
||||
'start_time': zs.start_klc.start_time if isinstance(zs.start_klc.start_time, str) else zs.start_klc.start_time.astimezone(client_tz).isoformat(),
|
||||
'end_time': None, # 未完成中枢没有结束时间
|
||||
'zg': zs.zg,
|
||||
'zd': zs.zd,
|
||||
'is_sure': zs.is_sure, # 未完成中枢的is_sure为False
|
||||
'type': 'BI_ZS' # 标记为笔中枢
|
||||
} for zs in analysis_result['bi_zs_list'] if not zs.is_sure],
|
||||
'trade_points': [{
|
||||
'type': point['type'],
|
||||
'time': format_time_safely(point['time'], client_tz),
|
||||
@@ -477,40 +464,18 @@ def analyze():
|
||||
'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,
|
||||
'zd': zs.zd,
|
||||
'is_sure': zs.is_sure, # 添加中枢是否完成的标志
|
||||
'type': getattr(zs, 'type', 'SEG_ZS') # 中枢类型,默认为线段中枢
|
||||
'is_sure': zs.is_sure # 添加中枢是否完成的标志
|
||||
} for zs in element_analysis['zs_list'] if zs.end_klc]
|
||||
|
||||
# 添加小周期笔中枢
|
||||
result['element_bi_zs_list'] = [{
|
||||
'start_time': zs.start_klc.start_time if isinstance(zs.start_klc.start_time, str) else zs.start_klc.start_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,
|
||||
'zg': zs.zg,
|
||||
'zd': zs.zd,
|
||||
'is_sure': zs.is_sure, # 添加中枢是否完成的标志
|
||||
'type': 'BI_ZS' # 标记为笔中枢
|
||||
} for zs in element_analysis['bi_zs_list'] if zs.end_klc]
|
||||
|
||||
# 添加小周期未完成中枢列表
|
||||
result['element_uncompleted_zs_list'] = [{
|
||||
'start_time': zs.start_klc.start_time if isinstance(zs.start_klc.start_time, str) else zs.start_klc.start_time.astimezone(client_tz).isoformat(),
|
||||
'end_time': None, # 未完成中枢没有结束时间
|
||||
'zg': zs.zg,
|
||||
'zd': zs.zd,
|
||||
'is_sure': zs.is_sure, # 未完成中枢的is_sure为False
|
||||
'type': getattr(zs, 'type', 'SEG_ZS') # 中枢类型,默认为线段中枢
|
||||
'is_sure': zs.is_sure # 未完成中枢的is_sure为False
|
||||
} for zs in element_analysis['zs_list'] if not zs.is_sure]
|
||||
|
||||
# 添加小周期未完成笔中枢列表
|
||||
result['element_uncompleted_bi_zs_list'] = [{
|
||||
'start_time': zs.start_klc.start_time if isinstance(zs.start_klc.start_time, str) else zs.start_klc.start_time.astimezone(client_tz).isoformat(),
|
||||
'end_time': None, # 未完成中枢没有结束时间
|
||||
'zg': zs.zg,
|
||||
'zd': zs.zd,
|
||||
'is_sure': zs.is_sure, # 未完成中枢的is_sure为False
|
||||
'type': 'BI_ZS' # 标记为笔中枢
|
||||
} for zs in element_analysis['bi_zs_list'] if not zs.is_sure]
|
||||
|
||||
result['element_trade_points'] = [{
|
||||
'type': point['type'],
|
||||
'time': format_time_safely(point['time'], client_tz),
|
||||
|
||||
+91
-315
@@ -196,16 +196,6 @@
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.main-bi-zs {
|
||||
color: #FF9800;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.element-bi-zs {
|
||||
color: #9C27B0;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
/* 加载指示器旋转动画 */
|
||||
@keyframes spin {
|
||||
0% { transform: rotate(0deg); }
|
||||
@@ -308,14 +298,6 @@
|
||||
<input class="form-check-input" type="checkbox" id="showMainUncompletedZs" checked>
|
||||
<label class="form-check-label" for="showMainUncompletedZs">未完成中枢</label>
|
||||
</div>
|
||||
<div class="form-check form-check-inline">
|
||||
<input class="form-check-input" type="checkbox" id="showMainBiZs" checked>
|
||||
<label class="form-check-label" for="showMainBiZs">笔中枢</label>
|
||||
</div>
|
||||
<div class="form-check form-check-inline">
|
||||
<input class="form-check-input" type="checkbox" id="showMainUncompletedBiZs" checked>
|
||||
<label class="form-check-label" for="showMainUncompletedBiZs">未完成笔中枢</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-flex align-items-center mt-2">
|
||||
<label class="form-label me-3 mb-0">次周期:</label>
|
||||
@@ -335,14 +317,6 @@
|
||||
<input class="form-check-input" type="checkbox" id="showElementUncompletedZs" checked>
|
||||
<label class="form-check-label" for="showElementUncompletedZs">未完成中枢</label>
|
||||
</div>
|
||||
<div class="form-check form-check-inline">
|
||||
<input class="form-check-input" type="checkbox" id="showElementBiZs" checked>
|
||||
<label class="form-check-label" for="showElementBiZs">笔中枢</label>
|
||||
</div>
|
||||
<div class="form-check form-check-inline">
|
||||
<input class="form-check-input" type="checkbox" id="showElementUncompletedBiZs" checked>
|
||||
<label class="form-check-label" for="showElementUncompletedBiZs">未完成笔中枢</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
@@ -542,14 +516,10 @@
|
||||
mainSegSeries: [],
|
||||
mainZsSeries: [],
|
||||
mainUncompletedZsSeries: [],
|
||||
mainBiZsSeries: [], // 添加主周期笔中枢系列
|
||||
mainUncompletedBiZsSeries: [], // 添加未完成主周期笔中枢系列
|
||||
elementBiSeries: [],
|
||||
elementSegSeries: [],
|
||||
elementZsSeries: [],
|
||||
elementUncompletedZsSeries: [],
|
||||
elementBiZsSeries: [], // 添加元素周期笔中枢系列
|
||||
elementUncompletedBiZsSeries: [], // 添加未完成元素周期笔中枢系列
|
||||
tradePointSeries: []
|
||||
},
|
||||
state: {
|
||||
@@ -735,16 +705,6 @@
|
||||
updateChartDisplay();
|
||||
});
|
||||
|
||||
// 添加笔中枢复选框变更事件
|
||||
$('#showMainBiZs').change(function() {
|
||||
updateChartDisplay();
|
||||
});
|
||||
|
||||
// 添加未完成笔中枢复选框变更事件
|
||||
$('#showMainUncompletedBiZs').change(function() {
|
||||
updateChartDisplay();
|
||||
});
|
||||
|
||||
// 添加买卖点复选框变更事件
|
||||
$('#showElementBi').change(function() {
|
||||
updateChartDisplay();
|
||||
@@ -765,16 +725,6 @@
|
||||
updateChartDisplay();
|
||||
});
|
||||
|
||||
// 添加笔中枢复选框变更事件
|
||||
$('#showElementBiZs').change(function() {
|
||||
updateChartDisplay();
|
||||
});
|
||||
|
||||
// 添加未完成笔中枢复选框变更事件
|
||||
$('#showElementUncompletedBiZs').change(function() {
|
||||
updateChartDisplay();
|
||||
});
|
||||
|
||||
// 添加买卖点复选框变更事件
|
||||
$('#showTradePoints').change(function() {
|
||||
updateChartDisplay();
|
||||
@@ -946,39 +896,51 @@
|
||||
});
|
||||
|
||||
function updateChartDisplay() {
|
||||
// 获取复选框状态
|
||||
var showMainBi = $('#showMainBi').prop('checked');
|
||||
var showMainSeg = $('#showMainSeg').prop('checked');
|
||||
var showMainZs = $('#showMainZs').prop('checked');
|
||||
var showMainUncompletedZs = $('#showMainUncompletedZs').prop('checked');
|
||||
var showMainBiZs = $('#showMainBiZs').prop('checked');
|
||||
var showMainUncompletedBiZs = $('#showMainUncompletedBiZs').prop('checked');
|
||||
var showElementBi = $('#showElementBi').prop('checked');
|
||||
var showElementSeg = $('#showElementSeg').prop('checked');
|
||||
var showElementZs = $('#showElementZs').prop('checked');
|
||||
var showElementUncompletedZs = $('#showElementUncompletedZs').prop('checked');
|
||||
var showElementBiZs = $('#showElementBiZs').prop('checked');
|
||||
var showElementUncompletedBiZs = $('#showElementUncompletedBiZs').prop('checked');
|
||||
var showTradePoints = $('#showTradePoints').prop('checked');
|
||||
|
||||
// 调用显示/隐藏函数
|
||||
if (showMainBi) { drawBi(main_bi_list); } else { removeBi(); }
|
||||
if (showMainSeg) { drawSeg(main_seg_list); } else { removeSeg(); }
|
||||
if (showMainZs) { drawZones(main_zs_list); } else { removeZones(); }
|
||||
if (showMainUncompletedZs) { drawUncompletedZones(main_uncompleted_zs_list); } else { removeUncompletedZones(); }
|
||||
if (showMainBiZs) { drawBiZones(main_bi_zs_list); } else { removeBiZones(); }
|
||||
if (showMainUncompletedBiZs) { drawUncompletedBiZones(main_uncompleted_bi_zs_list); } else { removeUncompletedBiZones(); }
|
||||
|
||||
// 元素显示
|
||||
if (showElementBi) { drawBiOnElement(element_bi_list); } else { removeBiOnElement(); }
|
||||
if (showElementSeg) { drawSegOnElement(element_seg_list); } else { removeSegOnElement(); }
|
||||
if (showElementZs) { drawZonesOnElement(element_zs_list); } else { removeZonesOnElement(); }
|
||||
if (showElementUncompletedZs) { drawUncompletedZonesOnElement(element_uncompleted_zs_list); } else { removeUncompletedZonesOnElement(); }
|
||||
if (showElementBiZs) { drawBiZonesOnElement(element_bi_zs_list); } else { removeBiZonesOnElement(); }
|
||||
if (showElementUncompletedBiZs) { drawUncompletedBiZonesOnElement(element_uncompleted_bi_zs_list); } else { removeUncompletedBiZonesOnElement(); }
|
||||
|
||||
// 买卖点
|
||||
if (showTradePoints) { drawTradePoints(trade_points_list); } else { removeTradePoints(); }
|
||||
if (currentData) {
|
||||
// 保存当前的可见逻辑范围
|
||||
let logicalRange = null;
|
||||
let visibleRange = null;
|
||||
|
||||
if (tvWidget && tvWidget.mainChart) {
|
||||
// 优先使用逻辑范围,这样在缩放级别上更准确
|
||||
logicalRange = tvWidget.mainChart.timeScale().getVisibleLogicalRange();
|
||||
// 备用方案,获取实际时间戳范围
|
||||
visibleRange = tvWidget.mainChart.timeScale().getVisibleRange();
|
||||
}
|
||||
|
||||
console.log('更新图表显示');
|
||||
console.log('- 显示K线:', $('#showOriginalKline').is(':checked'));
|
||||
console.log('- 显示笔:', $('#showMainBi').is(':checked'));
|
||||
console.log('- 显示线段:', $('#showMainSeg').is(':checked'));
|
||||
console.log('- 显示中枢:', $('#showMainZs').is(':checked'));
|
||||
console.log('- 显示未完成中枢:', $('#showMainUncompletedZs').is(':checked'));
|
||||
console.log('- 显示MACD:', $('#showMacd').is(':checked'));
|
||||
console.log('- 显示买卖点:', $('#showTradePoints').is(':checked'));
|
||||
|
||||
// 重新初始化图表,这将清除旧图形并重新绘制
|
||||
initTradingView($('#symbol').val(), $('#timeframe').val());
|
||||
|
||||
// 如果有保存的范围,恢复它
|
||||
setTimeout(() => {
|
||||
if (tvWidget) {
|
||||
if (logicalRange) {
|
||||
// 应用保存的逻辑范围到所有图表
|
||||
tvWidget.mainChart.timeScale().setVisibleLogicalRange(logicalRange);
|
||||
tvWidget.volumeChart.timeScale().setVisibleLogicalRange(logicalRange);
|
||||
if (tvWidget.macdChart) {
|
||||
tvWidget.macdChart.timeScale().setVisibleLogicalRange(logicalRange);
|
||||
}
|
||||
} else if (visibleRange) {
|
||||
// 如果没有逻辑范围,使用时间戳范围
|
||||
tvWidget.mainChart.timeScale().setVisibleRange(visibleRange);
|
||||
tvWidget.volumeChart.timeScale().setVisibleRange(visibleRange);
|
||||
if (tvWidget.macdChart) {
|
||||
tvWidget.macdChart.timeScale().setVisibleRange(visibleRange);
|
||||
}
|
||||
}
|
||||
}
|
||||
}, 100);
|
||||
}
|
||||
}
|
||||
|
||||
// 确保所有时间处理都使用UTC时间,包括表格数据显示
|
||||
@@ -1076,8 +1038,8 @@
|
||||
$('#refreshLoadingSpinner').hide();
|
||||
|
||||
// 保存当前数据
|
||||
currentData = data;
|
||||
|
||||
currentData = data;
|
||||
|
||||
// 刷新图表
|
||||
refreshChart(data);
|
||||
},
|
||||
@@ -1116,14 +1078,10 @@
|
||||
mainSegSeries: [],
|
||||
mainZsSeries: [],
|
||||
mainUncompletedZsSeries: [],
|
||||
mainBiZsSeries: [], // 添加主周期笔中枢系列
|
||||
mainUncompletedBiZsSeries: [], // 添加未完成主周期笔中枢系列
|
||||
elementBiSeries: [],
|
||||
elementSegSeries: [],
|
||||
elementZsSeries: [],
|
||||
elementUncompletedZsSeries: [],
|
||||
elementBiZsSeries: [], // 添加元素周期笔中枢系列
|
||||
elementUncompletedBiZsSeries: [], // 添加未完成元素周期笔中枢系列
|
||||
tradePointSeries: []
|
||||
},
|
||||
state: {
|
||||
@@ -1348,22 +1306,22 @@
|
||||
|
||||
if (currentData.macd && currentData.macd.macd && currentData.macd.macd[i] !== undefined) {
|
||||
macdData.push({
|
||||
time: timestamp,
|
||||
time: timestamp,
|
||||
value: currentData.macd.macd[i]
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
signalData.push({
|
||||
time: timestamp,
|
||||
time: timestamp,
|
||||
value: currentData.macd.signal[i]
|
||||
});
|
||||
|
||||
// 设置直方图颜色
|
||||
const histValue = currentData.macd.histogram[i];
|
||||
histogramData.push({
|
||||
time: timestamp,
|
||||
time: timestamp,
|
||||
value: histValue,
|
||||
color: histValue >= 0 ? 'rgba(220, 53, 69, 0.5)' : 'rgba(40, 167, 69, 0.5)'
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2624,7 +2582,7 @@
|
||||
// 添加事件监听
|
||||
addChartSyncEvents(mainChartContainer, mainChart);
|
||||
addChartSyncEvents(volumeChartContainer, volumeChart);
|
||||
if (showMacd && macdChart) {
|
||||
if (showMacd && macdChart) {
|
||||
addChartSyncEvents(macdChartContainer, macdChart);
|
||||
}
|
||||
|
||||
@@ -2714,7 +2672,7 @@
|
||||
if (isNaN(timeValue.getTime())) {
|
||||
console.error(`买卖点 #${i} 时间格式无效:`, tradePointsData[i].time);
|
||||
}
|
||||
} catch (e) {
|
||||
} catch (e) {
|
||||
console.error(`买卖点 #${i} 时间格式异常:`, e);
|
||||
}
|
||||
} else {
|
||||
@@ -3366,14 +3324,48 @@
|
||||
}
|
||||
|
||||
console.log('重绘分形元素 - 开始');
|
||||
console.log('- 显示笔:', $('#showMainBi').is(':checked'));
|
||||
console.log('- 显示线段:', $('#showMainSeg').is(':checked'));
|
||||
console.log('- 显示中枢:', $('#showMainZs').is(':checked'));
|
||||
|
||||
// 保存当前的图表可见范围
|
||||
const mainChart = tvWidget.mainChart;
|
||||
const visibleRange = mainChart.timeScale().getVisibleRange();
|
||||
const logicalRange = mainChart.timeScale().getVisibleLogicalRange();
|
||||
|
||||
// 调用显示所有元素函数
|
||||
displayAllElements();
|
||||
// 获取当前图表设置
|
||||
const showMacd = $('#showMacd').is(':checked');
|
||||
const showOriginalKline = $('#showOriginalKline').is(':checked');
|
||||
const showBi = $('#showMainBi').is(':checked');
|
||||
const showSeg = $('#showMainSeg').is(':checked');
|
||||
const showZs = $('#showMainZs').is(':checked');
|
||||
|
||||
// 保存原始K线和MACD数据,确保即使使用小级别,我们依然使用主周期的K线和MACD数据
|
||||
const originalKlineData = currentData.kline_data;
|
||||
const originalMacdData = currentData.macd;
|
||||
|
||||
// 重新初始化图表 - 这将清除所有系列并重新创建
|
||||
console.log('重新初始化图表...');
|
||||
|
||||
// 临时存储currentData中可能被修改的字段
|
||||
const tempCurrentData = {
|
||||
kline_data: originalKlineData,
|
||||
macd: originalMacdData
|
||||
};
|
||||
|
||||
// 在重绘前确保K线和MACD数据不变
|
||||
if (currentData.original_kline_data && currentData.original_macd) {
|
||||
// 如果已经保存了原始数据,恢复它们
|
||||
currentData.kline_data = currentData.original_kline_data;
|
||||
currentData.macd = currentData.original_macd;
|
||||
} else {
|
||||
// 首次运行 - 保存原始数据
|
||||
currentData.original_kline_data = originalKlineData;
|
||||
currentData.original_macd = originalMacdData;
|
||||
}
|
||||
|
||||
// 调用初始化函数
|
||||
initTradingView($('#symbol').val(), $('#timeframe').val());
|
||||
|
||||
// 恢复原始可见范围
|
||||
setTimeout(() => {
|
||||
@@ -3486,14 +3478,12 @@
|
||||
|
||||
console.log('API返回数据:', data);
|
||||
console.log('K线数据点数:', data.kline_data ? data.kline_data.length : 0);
|
||||
console.log('笔中枢数据点数:', data.bi_zs_list ? data.bi_zs_list.length : 0);
|
||||
|
||||
// 检查是否包含小周期数据
|
||||
if (data.element_timeframe) {
|
||||
console.log('小周期笔数据点数:', data.element_bi_list ? data.element_bi_list.length : 0);
|
||||
console.log('小周期线段数据点数:', data.element_seg_list ? data.element_seg_list.length : 0);
|
||||
console.log('小周期中枢数据点数:', data.element_zs_list ? data.element_zs_list.length : 0);
|
||||
console.log('小周期笔中枢数据点数:', data.element_bi_zs_list ? data.element_bi_zs_list.length : 0);
|
||||
|
||||
// 更新小周期选择器
|
||||
$('#elementTimeframe').val(data.element_timeframe);
|
||||
@@ -3517,220 +3507,6 @@
|
||||
// 更新表格数据
|
||||
updateTables(data);
|
||||
}
|
||||
|
||||
// 显示中枢
|
||||
function displayZones() {
|
||||
// 主周期或元素周期中枢
|
||||
if ($('#showMainZs').is(':checked') || $('#showElementZs').is(':checked') ||
|
||||
$('#showMainUncompletedZs').is(':checked') || $('#showElementUncompletedZs').is(':checked') ||
|
||||
$('#showMainBiZs').is(':checked') || $('#showElementBiZs').is(':checked') ||
|
||||
$('#showMainUncompletedBiZs').is(':checked') || $('#showElementUncompletedBiZs').is(':checked')) {
|
||||
|
||||
console.log('绘制中枢 - 已启用');
|
||||
|
||||
// 绘制主周期线段中枢
|
||||
if ($('#showMainZs').is(':checked') && currentData.zs_list && currentData.zs_list.length > 0) {
|
||||
console.log(`绘制主周期线段中枢数据,共${currentData.zs_list.length}条`);
|
||||
drawZoneList(currentData.zs_list, '#F1C40F', 'SEG_ZS');
|
||||
}
|
||||
|
||||
// 绘制主周期笔中枢
|
||||
if ($('#showMainBiZs').is(':checked') && currentData.bi_zs_list && currentData.bi_zs_list.length > 0) {
|
||||
console.log(`绘制主周期笔中枢数据,共${currentData.bi_zs_list.length}条`);
|
||||
// 添加检查笔中枢数据的详细日志
|
||||
if (currentData.bi_zs_list.length > 0) {
|
||||
console.log('笔中枢数据示例:', currentData.bi_zs_list[0]);
|
||||
}
|
||||
drawZoneList(currentData.bi_zs_list, '#FF9800', 'BI_ZS');
|
||||
} else {
|
||||
console.log('笔中枢数据不存在或勾选框未选中:',
|
||||
'勾选状态=', $('#showMainBiZs').is(':checked'),
|
||||
'数据存在=', !!(currentData.bi_zs_list),
|
||||
'数据长度=', currentData.bi_zs_list ? currentData.bi_zs_list.length : 0);
|
||||
}
|
||||
|
||||
// 元素周期线段中枢
|
||||
if ($('#showElementZs').is(':checked') && currentData.element_zs_list && currentData.element_zs_list.length > 0) {
|
||||
console.log(`绘制元素周期线段中枢数据,共${currentData.element_zs_list.length}条`);
|
||||
drawZoneList(currentData.element_zs_list, '#3f51b5', 'SEG_ZS');
|
||||
}
|
||||
|
||||
// 元素周期笔中枢
|
||||
if ($('#showElementBiZs').is(':checked') && currentData.element_bi_zs_list && currentData.element_bi_zs_list.length > 0) {
|
||||
console.log(`绘制元素周期笔中枢数据,共${currentData.element_bi_zs_list.length}条`);
|
||||
if (currentData.element_bi_zs_list.length > 0) {
|
||||
console.log('元素笔中枢数据示例:', currentData.element_bi_zs_list[0]);
|
||||
}
|
||||
drawZoneList(currentData.element_bi_zs_list, '#9C27B0', 'BI_ZS');
|
||||
} else {
|
||||
console.log('元素笔中枢数据不存在或勾选框未选中:',
|
||||
'勾选状态=', $('#showElementBiZs').is(':checked'),
|
||||
'数据存在=', !!(currentData.element_bi_zs_list),
|
||||
'数据长度=', currentData.element_bi_zs_list ? currentData.element_bi_zs_list.length : 0);
|
||||
}
|
||||
|
||||
// 主周期未完成线段中枢
|
||||
if ($('#showMainUncompletedZs').is(':checked') && currentData.uncompleted_zs_list && currentData.uncompleted_zs_list.length > 0) {
|
||||
console.log(`绘制主周期未完成线段中枢数据,共${currentData.uncompleted_zs_list.length}条`);
|
||||
drawZoneList(currentData.uncompleted_zs_list, '#F1C40F', 'SEG_ZS', true);
|
||||
}
|
||||
|
||||
// 主周期未完成笔中枢
|
||||
if ($('#showMainUncompletedBiZs').is(':checked') && currentData.uncompleted_bi_zs_list && currentData.uncompleted_bi_zs_list.length > 0) {
|
||||
console.log(`绘制主周期未完成笔中枢数据,共${currentData.uncompleted_bi_zs_list.length}条`);
|
||||
drawZoneList(currentData.uncompleted_bi_zs_list, '#FF9800', 'BI_ZS', true);
|
||||
}
|
||||
|
||||
// 元素周期未完成线段中枢
|
||||
if ($('#showElementUncompletedZs').is(':checked') && currentData.element_uncompleted_zs_list && currentData.element_uncompleted_zs_list.length > 0) {
|
||||
console.log(`绘制元素周期未完成线段中枢数据,共${currentData.element_uncompleted_zs_list.length}条`);
|
||||
drawZoneList(currentData.element_uncompleted_zs_list, '#3f51b5', 'SEG_ZS', true);
|
||||
}
|
||||
|
||||
// 元素周期未完成笔中枢
|
||||
if ($('#showElementUncompletedBiZs').is(':checked') && currentData.element_uncompleted_bi_zs_list && currentData.element_uncompleted_bi_zs_list.length > 0) {
|
||||
console.log(`绘制元素周期未完成笔中枢数据,共${currentData.element_uncompleted_bi_zs_list.length}条`);
|
||||
drawZoneList(currentData.element_uncompleted_bi_zs_list, '#9C27B0', 'BI_ZS', true);
|
||||
}
|
||||
} else {
|
||||
console.log('绘制中枢 - 已禁用');
|
||||
}
|
||||
}
|
||||
|
||||
// 绘制中枢列表函数
|
||||
function drawZoneList(zoneList, color, type, isUncompleted = false) {
|
||||
zoneList.forEach(function(zs) {
|
||||
try {
|
||||
// 直接使用UTC时间戳(秒)
|
||||
const startTime = Math.floor(new Date(zs.start_time).getTime() / 1000);
|
||||
// 未完成中枢的结束时间设为当前K线的最后时间
|
||||
let endTime;
|
||||
|
||||
if (isUncompleted) {
|
||||
endTime = Math.floor(new Date(currentData.kline_data[currentData.kline_data.length-1].date).getTime() / 1000);
|
||||
} else {
|
||||
endTime = Math.floor(new Date(zs.end_time).getTime() / 1000);
|
||||
}
|
||||
|
||||
if (isNaN(startTime) || isNaN(endTime)) {
|
||||
console.error(`${type}中枢时间转换错误:`, zs.start_time, zs.end_time);
|
||||
return;
|
||||
}
|
||||
|
||||
const zg = parseFloat(zs.zg); // 中枢上沿
|
||||
const zd = parseFloat(zs.zd); // 中枢下沿
|
||||
|
||||
if (isNaN(zg) || isNaN(zd)) {
|
||||
console.error(`${type}中枢价格转换错误:`, zs.zg, zs.zd);
|
||||
return;
|
||||
}
|
||||
|
||||
// 创建中枢上边界
|
||||
const topSeries = mainChart.addLineSeries({
|
||||
color: color,
|
||||
lineWidth: 1,
|
||||
lineStyle: isUncompleted ? 2 : 0, // 未完成中枢用虚线
|
||||
lastValueVisible: false,
|
||||
priceLineVisible: false,
|
||||
});
|
||||
|
||||
topSeries.setData([
|
||||
{ time: startTime, value: zg },
|
||||
{ time: endTime, value: zg }
|
||||
]);
|
||||
|
||||
// 为下边界创建另一条线
|
||||
const bottomSeries = mainChart.addLineSeries({
|
||||
color: color,
|
||||
lineWidth: 1,
|
||||
lineStyle: isUncompleted ? 2 : 0, // 未完成中枢用虚线
|
||||
lastValueVisible: false,
|
||||
priceLineVisible: false,
|
||||
});
|
||||
|
||||
bottomSeries.setData([
|
||||
{ time: startTime, value: zd },
|
||||
{ time: endTime, value: zd }
|
||||
]);
|
||||
|
||||
// 添加左边界
|
||||
const leftSeries = mainChart.addLineSeries({
|
||||
color: color,
|
||||
lineWidth: 1,
|
||||
lineStyle: isUncompleted ? 2 : 0, // 未完成中枢用虚线
|
||||
lastValueVisible: false,
|
||||
priceLineVisible: false,
|
||||
});
|
||||
|
||||
leftSeries.setData([
|
||||
{ time: startTime, value: zd },
|
||||
{ time: startTime, value: zg }
|
||||
]);
|
||||
|
||||
// 添加右边界
|
||||
const rightSeries = mainChart.addLineSeries({
|
||||
color: color,
|
||||
lineWidth: 1,
|
||||
lineStyle: isUncompleted ? 2 : 0, // 未完成中枢用虚线
|
||||
lastValueVisible: false,
|
||||
priceLineVisible: false,
|
||||
});
|
||||
|
||||
rightSeries.setData([
|
||||
{ time: endTime, value: zd },
|
||||
{ time: endTime, value: zg }
|
||||
]);
|
||||
|
||||
// 储存到相应的系列集合中
|
||||
if (type === 'BI_ZS') {
|
||||
if (color === '#FF9800') { // 主周期笔中枢
|
||||
tvWidget.series.mainBiZsSeries.push({
|
||||
time: startTime,
|
||||
value: zg,
|
||||
color: color,
|
||||
lineWidth: 1,
|
||||
lineStyle: isUncompleted ? 2 : 0
|
||||
});
|
||||
} else { // 元素周期笔中枢
|
||||
tvWidget.series.elementBiZsSeries.push({
|
||||
time: startTime,
|
||||
value: zg,
|
||||
color: color,
|
||||
lineWidth: 1,
|
||||
lineStyle: isUncompleted ? 2 : 0
|
||||
});
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(`${type}中枢处理出错:`, e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 辅助函数,在updateTradingViewData或redrawFractalElements中调用
|
||||
function displayAllElements() {
|
||||
console.log('调用displayAllElements,开始绘制所有图形元素...');
|
||||
|
||||
// 显示笔
|
||||
if ($('#showMainBi').is(':checked') || $('#showElementBi').is(':checked')) {
|
||||
displayBi();
|
||||
}
|
||||
|
||||
// 显示线段
|
||||
if ($('#showMainSeg').is(':checked') || $('#showElementSeg').is(':checked')) {
|
||||
displaySeg();
|
||||
}
|
||||
|
||||
// 显示中枢(包含线段中枢和笔中枢)
|
||||
displayZones();
|
||||
|
||||
// 显示买卖点
|
||||
if ($('#showTradePoints').is(':checked')) {
|
||||
displayTradePoints();
|
||||
}
|
||||
|
||||
console.log('displayAllElements执行完成');
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user