添加新的判断依据

This commit is contained in:
jackyu66git
2025-11-16 20:58:03 +08:00
parent 03c5148c29
commit d61cbbec21
8 changed files with 24 additions and 76 deletions
+2 -1
View File
@@ -77,6 +77,7 @@ class ChanKLC():
self.continue_div = klu.continue_div self.continue_div = klu.continue_div
if klu.macd_state != Chan_MACD_STATE.UNKNOWN: if klu.macd_state != Chan_MACD_STATE.UNKNOWN:
self.state = klu.macd_state self.state = klu.macd_state
klu.set_klc(self)
self.klc_dir = Chan_KLINE_DIR.UP if self.close > self.open else Chan_KLINE_DIR.DOWN self.klc_dir = Chan_KLINE_DIR.UP if self.close > self.open else Chan_KLINE_DIR.DOWN
self.cal_indicators() self.cal_indicators()
def cal_fx(self): def cal_fx(self):
@@ -175,7 +176,7 @@ class ChanKLC():
return False return False
else: else:
# high小于,low大于,右包含 # high小于,low大于,右包含
if self.low >= klu.low: if self.low >= klu.low-10:
self.add_klu(klu=klu) self.add_klu(klu=klu)
# gn>gn-1 # gn>gn-1
if self.dir == Chan_KLINE_DIR.UP: if self.dir == Chan_KLINE_DIR.UP:
+8 -1
View File
@@ -1,4 +1,4 @@
from ChanEnum import Chan_FX_TYPE, Chan_KLU_TYPE, Chan_K_DIR, Chan_MACD_STATE, Chan_MACDHIST_STATE, Chan_PRICE_TREND, Chan_KLU_PATTERN from ChanEnum import Chan_FX_TYPE, Chan_KLU_TYPE, Chan_K_DIR, Chan_MACD_STATE, Chan_MACDHIST_STATE, Chan_PRICE_TREND, Chan_KLU_PATTERN, Chan_KLC_FX
class ChanKLU: class ChanKLU:
def __init__(self, time, open, high, low, close, volume): def __init__(self, time, open, high, low, close, volume):
# _time, _close, _open, _high, _low, _extra_info={} # _time, _close, _open, _high, _low, _extra_info={}
@@ -79,6 +79,13 @@ class ChanKLU:
self.exception = False self.exception = False
def set_trend(self, trend): def set_trend(self, trend):
self.trend = trend self.trend = trend
def set_separate_div(self, separate_div):
self.separate_div = separate_div
if self.klc:
if self.klc.klc_fx_type != Chan_KLC_FX.UNKNOWN:
self.separate_div = 99
else:
self.separate_div = 0
def set_next(self, next): def set_next(self, next):
self.next = next self.next = next
#if self.fx_type != Chan_FX_TYPE.UNKNOWN and self.fx_strength > 1: #if self.fx_type != Chan_FX_TYPE.UNKNOWN and self.fx_strength > 1:
+2 -2
View File
@@ -115,7 +115,7 @@ class ChanLun():
return self.tf_df.cal_bi_zs(seg_list) return self.tf_df.cal_bi_zs(seg_list)
def get_decimal(self, value): def get_decimal(self, value):
return Decimal("{:.2f}".format(value)) return Decimal("{:.2f}".format(value))
def get_klc_list(self, dataframe): def get_klc_list(self, klu_list):
return self.tf_df.get_klc_list(dataframe) return self.tf_df.get_klc_list(klu_list)
def get_klu_list(self, dataframe): def get_klu_list(self, dataframe):
return self.tf_df.cal_klu_pattern(self.get_kl_data(dataframe)) return self.tf_df.cal_klu_pattern(self.get_kl_data(dataframe))
+1 -1
View File
@@ -38,7 +38,7 @@ class ChanMACD():
else: else:
signal = klu.pre.signal < klu.signal and klu.next.signal > klu.signal signal = klu.pre.signal < klu.signal and klu.next.signal > klu.signal
sd = klu.separate_div sd = klu.separate_div
if sd > 1 and ((hist > 0 and hist < 20) or (hist < 0 and hist > -20)): if sd > 1 and ((hist > 0 and hist < 200) or (hist < 0 and hist > -200)):
sd_list.append(klu.time) sd_list.append(klu.time)
print(klu.time, sd) print(klu.time, sd)
return sd_list return sd_list
+2 -2
View File
@@ -61,9 +61,9 @@ class ChanMACDUnitTF():
self.div_peak_list.append(histset.peak_klu) self.div_peak_list.append(histset.peak_klu)
#print("Unittf: ", self.start_klu.time) #print("Unittf: ", self.start_klu.time)
if histset.peak_klu.macd > 0 and histset.histset_dir == Chan_MACDHISTSET_DIR.ABOVE: if histset.peak_klu.macd > 0 and histset.histset_dir == Chan_MACDHISTSET_DIR.ABOVE:
histset.peak_klu.separate_div = self.div_count histset.peak_klu.set_separate_div(self.div_count)
elif histset.peak_klu.macd < 0 and histset.histset_dir == Chan_MACDHISTSET_DIR.UNDER: elif histset.peak_klu.macd < 0 and histset.histset_dir == Chan_MACDHISTSET_DIR.UNDER:
histset.peak_klu.separate_div = self.div_count histset.peak_klu.set_separate_div(self.div_count)
else: else:
if histset.peak_klu: if histset.peak_klu:
self.peak_klu = histset.peak_klu self.peak_klu = histset.peak_klu
+3 -37
View File
@@ -492,42 +492,8 @@ class TF_DF():
bi_list = self.cal_bi_list(self.get_klc_list(dataframe)) bi_list = self.cal_bi_list(self.get_klc_list(dataframe))
return bi_list return bi_list
def get_kl_data(self, dataframe:DataFrame): def get_kl_data(self, dataframe:DataFrame):
fields = "time,open,high,low,close,volume" return self.cal_kl_data(dataframe)
klu_list = [] def get_klc_list(self, klu_list):
last_klu = None
for i in range(0, len(dataframe)):
item = dataframe.iloc[i]
date = item['date']
o = item['open']
h = item['high']
l = item['low']
c = item['close']
v = item['volume']
#time_obj = date.fromtimestamp(date)
#date = date + timedelta(hours=8)
time_str = date.strftime('%Y-%m-%d %H:%M:%S')
item_data = [
time_str,
o,
h,
l,
c,
v
]
#klu = KLU(self.create_item_dict(item_data, GetColumnNameFromFieldList(fields)))
klu = ChanKLU(time_str, o, h, l, c, v)
#print(klu.time, klu.open, klu.high, klu.low, klu.close, klu.volume)
klu.set_idx(i)
klu_list.append(klu)
if last_klu:
last_klu.set_next(klu)
klu.set_pre(last_klu)
last_klu = klu
if 'macd' in item:
klu.set_indicators(item)
return klu_list
def get_klc_list(self, dataframe):
klu_list = self.get_klu_list(dataframe)
klc_list = [] klc_list = []
last_klu = None last_klu = None
macd = ChanMACD(klu_list) macd = ChanMACD(klu_list)
@@ -1664,6 +1630,6 @@ class TF_DF():
if is_near_support or volume_confirmation: if is_near_support or volume_confirmation:
third_klu.set_pattern(Chan_KLU_PATTERN.TWEEZER_BOTTOM) third_klu.set_pattern(Chan_KLU_PATTERN.TWEEZER_BOTTOM)
return return
def get_decimal(self, value): def get_decimal(self, value):
return Decimal("{:.2f}".format(value)) return Decimal("{:.2f}".format(value))
+5 -5
View File
@@ -29,10 +29,10 @@ TIMEFRAME_TO_MS: Dict[str, int] = {
"1w": 604_800_000, "1w": 604_800_000,
} }
DERIVED_TIMEFRAME_PLAN: Dict[str, List[str]] = { DERIVED_TIMEFRAME_PLAN: Dict[str, List[str]] = {
"1m": ["2m", "3m", "4m", "5m", "10m", "15m", "20m", "25m", "30m"], "1m": ["2m", "3m", "4m", "5m", "10m", "15m", "20m", "25m", "30m", "45m"],
"1h": ["2h", "3h", "4h", "6h", "8h", "12h", "16h"], "1h": ["2h", "3h", "4h", "6h", "8h", "12h", "16h", "20h"],
"1d": ["2d", "3d", "4d", "5d", "6d"], "1d": ["2d", "3d", "4d", "5d", "6d"],
"1w": ["2w"], "1w": ["2w", "3w"],
} }
CSV_FIELDNAMES = ["timestamp", "datetime", "open", "high", "low", "close", "volume"] CSV_FIELDNAMES = ["timestamp", "datetime", "open", "high", "low", "close", "volume"]
DEFAULT_LIMIT = 500 DEFAULT_LIMIT = 500
@@ -583,14 +583,14 @@ class DataProvider:
resampled_df = resampled.copy() resampled_df = resampled.copy()
if "date" in resampled_df.columns: if "date" in resampled_df.columns:
dates = pd.to_datetime(resampled_df["date"], utc=True, errors="coerce") dates = pd.to_datetime(resampled_df["date"], utc=True, errors="coerce")
resampled_df["timestamp"] = (dates.view("int64") // 1_000_000).astype("int64") resampled_df["timestamp"] = (dates.astype("int64", copy=False) // 1_000_000).astype("int64")
elif isinstance(resampled_df.index, pd.DatetimeIndex): elif isinstance(resampled_df.index, pd.DatetimeIndex):
idx = resampled_df.index idx = resampled_df.index
if idx.tz is None: if idx.tz is None:
idx = idx.tz_localize("UTC") idx = idx.tz_localize("UTC")
else: else:
idx = idx.tz_convert("UTC") idx = idx.tz_convert("UTC")
resampled_df["timestamp"] = (idx.view("int64") // 1_000_000).astype("int64") resampled_df["timestamp"] = (idx.astype("int64", copy=False) // 1_000_000).astype("int64")
else: else:
raise HTTPException(status_code=500, detail=f"聚合结果缺少 timestamp 列 ({timeframe})") raise HTTPException(status_code=500, detail=f"聚合结果缺少 timestamp 列 ({timeframe})")
resampled_df = resampled_df.dropna(subset=["timestamp"]).sort_values("timestamp") resampled_df = resampled_df.dropna(subset=["timestamp"]).sort_values("timestamp")
+1 -27
View File
@@ -521,7 +521,7 @@ def analyze_chan(df, symbol=None, timeframe=None):
ema52_dict = None ema52_dict = None
# 获取分析结果 # 获取分析结果
klu_list = chan.get_kl_data(df) klu_list = chan.get_kl_data(df)
klc_list = chan.get_klc_list(df) klc_list = chan.get_klc_list(klu_list)
bi_list = chan.cal_bi_list(klc_list) bi_list = chan.cal_bi_list(klc_list)
#for index in range(0, 10): #for index in range(0, 10):
#print(bi_list[index].start_time, bi_list[index].start_klc.end_time, bi_list[index].dir) #print(bi_list[index].start_time, bi_list[index].start_klc.end_time, bi_list[index].dir)
@@ -1209,9 +1209,6 @@ def analyze():
elements_only_param = request.args.get('elements_only') elements_only_param = request.args.get('elements_only')
elements_only = elements_only_param == 'true' elements_only = elements_only_param == 'true'
# 获取是否需要回放数据的参数
need_replay_data = request.args.get('need_replay_data', 'false').lower() == 'true'
# 验证小周期是否小于主周期 # 验证小周期是否小于主周期
if element_timeframe and not is_smaller_or_equal_timeframe(element_timeframe, timeframe): if element_timeframe and not is_smaller_or_equal_timeframe(element_timeframe, timeframe):
return jsonify({'error': '分形元素时间周期必须小于或等于主图表时间周期'}) return jsonify({'error': '分形元素时间周期必须小于或等于主图表时间周期'})
@@ -1243,12 +1240,6 @@ def analyze():
# 计算MACD # 计算MACD
macd_data = calculate_macd(df) macd_data = calculate_macd(df)
# 如果需要回放数据,生成逐步计算的回放数据
if need_replay_data:
replay_data = generate_replay_data(df, client_tz, symbol, element_timeframe, start_time, end_time)
else:
replay_data = None
# 基于已有 KLC 列表生成趋势标记(不做额外计算) # 基于已有 KLC 列表生成趋势标记(不做额外计算)
klc_trend = [] klc_trend = []
try: try:
@@ -1391,9 +1382,6 @@ def analyze():
'klc_trend': klc_trend 'klc_trend': klc_trend
}) })
# 如果生成了回放数据,添加到返回结果中
if replay_data is not None:
result['replay_data'] = replay_data
# 如果有指定分形元素时间周期,获取小周期数据 # 如果有指定分形元素时间周期,获取小周期数据
if element_timeframe: if element_timeframe:
@@ -1670,19 +1658,5 @@ def get_uncompleted_seg_list(seg_list, client_tz):
return result return result
def format_fx_type(fx_type):
"""格式化分型类型显示"""
fx_type_map = {
'TOP1': '顶分型1',
'TOP2': '顶分型2',
'TOP3': '顶分型3',
'BOTTOM1': '底分型1',
'BOTTOM2': '底分型2',
'BOTTOM3': '底分型3',
'TOP': '顶分型',
'BOTTOM': '底分型'
}
return fx_type_map.get(fx_type, fx_type)
if __name__ == '__main__': if __name__ == '__main__':
app.run(debug=True, host='0.0.0.0', port=8128) app.run(debug=True, host='0.0.0.0', port=8128)