Change some klc and bi recognition

This commit is contained in:
jackyu66git
2025-06-21 03:07:11 +08:00
parent 6e1c335d28
commit 08ca03fc3d
7 changed files with 132 additions and 35 deletions
+13 -1
View File
@@ -10,8 +10,12 @@ class Chan_DATA_SRC(Enum):
class Chan_ZS_DIR(Enum): class Chan_ZS_DIR(Enum):
UP = auto() UP = auto()
DOWN = auto() DOWN = auto()
class Chan_K_DIR(Enum):
BULL = auto()
BEAR = auto()
CROSS = auto()
class Chan_KL_TYPE(Enum): class Chan_KL_TYPE(Enum):
K_1S = auto()
K_1M = auto() K_1M = auto()
K_DAY = auto() K_DAY = auto()
K_WEEK = auto() K_WEEK = auto()
@@ -21,6 +25,14 @@ class Chan_KL_TYPE(Enum):
K_15M = auto() K_15M = auto()
K_30M = auto() K_30M = auto()
K_60M = auto() K_60M = auto()
K_1H = auto()
K_2H = auto()
K_4H = auto()
K_6H = auto()
K_8H = auto()
K_12H = auto()
K_1D = auto()
K_3D = auto()
K_3M = auto() K_3M = auto()
K_QUARTER = auto() K_QUARTER = auto()
+54 -24
View File
@@ -1,7 +1,7 @@
import copy import copy
from typing import Dict, Optional from typing import Dict, Optional
from ChanEnum import Chan_FX_TYPE, Chan_KLINE_DIR, Chan_BI_DIR, Chan_KLC_FX from ChanEnum import Chan_FX_TYPE, Chan_KLINE_DIR, Chan_BI_DIR, Chan_KLC_FX, Chan_K_DIR
import ChanKLU import ChanKLU
import ChanCTime import ChanCTime
@@ -31,7 +31,15 @@ class ChanKLC():
self.rsi = klu.rsi self.rsi = klu.rsi
self.volume_ratio = klu.volume_ratio self.volume_ratio = klu.volume_ratio
self.macdhist = 0 self.macdhist = 0
self.strength_list = [] self.body = klu.body
self.upper_shadow = klu.upper_shadow
self.lower_shadow = klu.lower_shadow
self.body_ratio = klu.body_ratio
self.upper_shadow_ratio = klu.upper_shadow_ratio
self.lower_shadow_ratio = klu.lower_shadow_ratio
self.candle_dir = klu.candle_dir
self.range = klu.range
self.strength = klu.strength
def set_klc_fx_type(self, klc_fx_type): def set_klc_fx_type(self, klc_fx_type):
#print(self.start_time, klc_fx_type, self.get_feature_data()['klu_macd'], self.get_feature_data()['klu_macdhist'], self.get_feature_data()['klu_rsi']) #print(self.start_time, klc_fx_type, self.get_feature_data()['klu_macd'], self.get_feature_data()['klu_macdhist'], self.get_feature_data()['klu_rsi'])
self.klc_fx_type = klc_fx_type self.klc_fx_type = klc_fx_type
@@ -41,6 +49,10 @@ class ChanKLC():
self.end_klu = klu self.end_klu = klu
self.end_time = klu.time self.end_time = klu.time
self.close = klu.close self.close = klu.close
self.cal_indicators()
self.cal_shape_1()
self.strength = self.cal_klc_strength()
def cal_indicators(self):
for index in range(1, len(self.klus)): for index in range(1, len(self.klus)):
self.volume += self.klus[index].volume self.volume += self.klus[index].volume
self.rsi += self.klus[index].rsi self.rsi += self.klus[index].rsi
@@ -50,16 +62,31 @@ class ChanKLC():
self.volume_ratio = self.volume_ratio / len(self.klus) self.volume_ratio = self.volume_ratio / len(self.klus)
self.volume = self.volume / len(self.klus) self.volume = self.volume / len(self.klus)
self.macdhist = self.macdhist / len(self.klus) self.macdhist = self.macdhist / len(self.klus)
self.cal_self_strength() def cal_shape_1(self):
def cal_self_strength(self): for index in range(1, len(self.klus)):
strength = 0 self.body += self.klus[index].body
if self.klus: self.upper_shadow += self.klus[index].upper_shadow
if len(self.klus) == 1: self.lower_shadow += self.klus[index].lower_shadow
strength = 1 self.body_ratio += self.klus[index].body_ratio
else: self.upper_shadow_ratio += self.klus[index].upper_shadow_ratio
if len(self.klus) > 1: self.lower_shadow_ratio += self.klus[index].lower_shadow_ratio
strength = 0 self.range += self.klus[index].range
self.strength_list.append(strength) self.body = self.body / len(self.klus)
self.upper_shadow = self.upper_shadow / len(self.klus)
self.lower_shadow = self.lower_shadow / len(self.klus)
self.body_ratio = self.body_ratio / len(self.klus)
self.upper_shadow_ratio = self.upper_shadow_ratio / len(self.klus)
self.lower_shadow_ratio = self.lower_shadow_ratio / len(self.klus)
self.range = self.range / len(self.klus)
def cal_shape_2(self):
self.body = abs(self.close - self.open)
self.upper_shadow = self.high - max(self.close, self.open)
self.lower_shadow = min(self.close, self.open) - self.low
self.body_ratio = self.body / self.open
self.upper_shadow_ratio = self.upper_shadow / self.open
self.lower_shadow_ratio = self.lower_shadow / self.open
self.candle_dir = Chan_K_DIR.CROSS if self.close == self.open else Chan_K_DIR.BULL if self.close > self.open else Chan_K_DIR.BEAR
self.range = self.high - self.low
def set_next(self, klc): def set_next(self, klc):
self.next = klc self.next = klc
def set_pre(self, klc): def set_pre(self, klc):
@@ -1171,10 +1198,20 @@ class ChanKLC():
return features return features
def cal_klc_strength(self):
strength = 0
if not self.end_klu:
return strength
if len(self.klus) > 0:
for klu in self.klus:
strength += klu.strength
return strength
def cal_fx_strength(self, klc_offset=2): def cal_fx_strength(self, klc_offset=2):
strength = 0 strength = 0
if self.fx == Chan_FX_TYPE.UNKNOWN or not self.pre or not self.next: if not self.end_klu:
return 0 return 0
if self.fx == Chan_FX_TYPE.UNKNOWN or not self.pre or not self.next:
return strength
else: else:
if self.pre and self.next: if self.pre and self.next:
klc1 = self.pre klc1 = self.pre
@@ -1182,34 +1219,27 @@ class ChanKLC():
klc3 = self.next klc3 = self.next
if self.bi: if self.bi:
if self.bi.dir == Chan_BI_DIR.UP and self.fx == Chan_FX_TYPE.BOTTOM: if self.bi.dir == Chan_BI_DIR.UP and self.fx == Chan_FX_TYPE.BOTTOM:
return 0 return strength
if self.bi.dir == Chan_BI_DIR.DOWN and self.fx == Chan_FX_TYPE.TOP: if self.bi.dir == Chan_BI_DIR.DOWN and self.fx == Chan_FX_TYPE.TOP:
return 0 return strength
if self.bi.dir == Chan_BI_DIR.UP: if self.bi.dir == Chan_BI_DIR.UP:
if self.klc_fx_type == Chan_KLC_FX.TOP1: if self.klc_fx_type == Chan_KLC_FX.TOP1:
strength += self.check_bi_end(self.bi) strength += self.check_bi_end(self.bi)
elif self.klc_fx_type == Chan_KLC_FX.TOP2: elif self.klc_fx_type == Chan_KLC_FX.TOP2:
strength += self.check_bi_end(self.bi) strength += self.check_bi_end(self.bi)
else: else:
if self.klc_fx_type == Chan_KLC_FX.BOTTOM1 or self.klc_fx_type == Chan_KLC_FX.BOTTOM2: if self.klc_fx_type == Chan_KLC_FX.BOTTOM1:
strength += self.check_bi_end(self.bi) strength += self.check_bi_end(self.bi)
elif self.klc_fx_type == Chan_KLC_FX.BOTTOM2: elif self.klc_fx_type == Chan_KLC_FX.BOTTOM2:
strength += self.check_bi_end(self.bi) strength += self.check_bi_end(self.bi)
else: else:
return 0 return strength
return strength return strength
def check_bi_end(self, bi): def check_bi_end(self, bi):
if bi.dir == Chan_BI_DIR.UP: if bi.dir == Chan_BI_DIR.UP:
return 1 return 1
else: else:
return 1 return 1
def cal_klu_strength(self, klc1, klc2, klc3):
klu_list = []
klu_list.extend(klc1.klus)
klu_list.extend(klc2.klus)
klu_list.extend(klc3.klus)
return
def calculate_fx_strength(self): def calculate_fx_strength(self):
""" """
基于专业缠论理论的分型强度评估体系 基于专业缠论理论的分型强度评估体系
+23 -1
View File
@@ -1,4 +1,4 @@
from ChanEnum import Chan_FX_TYPE, Chan_KLU_TYPE from ChanEnum import Chan_FX_TYPE, Chan_KLU_TYPE, Chan_K_DIR
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={}
@@ -34,6 +34,28 @@ class ChanKLU:
self.fx_confirmed = False # 分型是否确认 self.fx_confirmed = False # 分型是否确认
self.klu_type = None self.klu_type = None
self.cal_klu_min_max() self.cal_klu_min_max()
self.body = abs(self.close - self.open)
self.upper_shadow = self.high - max(self.close, self.open)
self.lower_shadow = min(self.close, self.open) - self.low
self.body_ratio = self.body / self.open
self.upper_shadow_ratio = self.upper_shadow / self.open
self.lower_shadow_ratio = self.lower_shadow / self.open
self.candle_dir = Chan_K_DIR.CROSS if self.close == self.open else Chan_K_DIR.BULL if self.close > self.open else Chan_K_DIR.BEAR
self.range = self.high - self.low
self.strength = 0 if self.candle_dir == Chan_K_DIR.CROSS else self.cal_klu_strength()
#print(self.open, self.close, self.high, self.low, self.candle_dir, self.strength)
def cal_klu_strength(self):
strength = 0
if range != 0:
if self.candle_dir == Chan_K_DIR.BULL and (self.upper_shadow + self.lower_shadow) != 0:
strength += self.body / self.range
strength += self.body / (self.upper_shadow + self.lower_shadow)
elif self.candle_dir == Chan_K_DIR.BEAR and (self.upper_shadow + self.lower_shadow) != 0:
strength -=self.body / self.range
strength -= self.body / (self.upper_shadow + self.lower_shadow)
#print(self.time, self.body, self.range, self.upper_shadow, self.lower_shadow, self.candle_dir, strength)
return strength
return strength
def cal_klu_min_max(self): def cal_klu_min_max(self):
""" """
计算K线类型:大阳线、大阴线、小阳线、小阴线 计算K线类型:大阳线、大阴线、小阳线、小阴线
+38 -5
View File
@@ -312,6 +312,7 @@ class ChanLun():
self.last_peak['low'] = l self.last_peak['low'] = l
#klu = KLU(self.create_item_dict(item_data, GetColumnNameFromFieldList(fields))) #klu = KLU(self.create_item_dict(item_data, GetColumnNameFromFieldList(fields)))
klu = ChanKLU(time_str, o, h, l, c, v) 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.set_idx(i)
klu_list.append(klu) klu_list.append(klu)
if last_klu: if last_klu:
@@ -571,6 +572,13 @@ class ChanLun():
else: else:
last_down_bi = bi last_down_bi = bi
down_bi_list.append(bi) down_bi_list.append(bi)
if len(seg_list) > 0:
seg = seg_list[-1]
if seg.end_bi and len(bi_list) > seg.end_bi.index + 1:
bi_index = seg.end_bi.index
for index in range(bi_index+1, len(bi_list)):
bi = bi_list[index]
return seg_list return seg_list
def get_bi_zs_list(self, bi_list): def get_bi_zs_list(self, bi_list):
@@ -729,12 +737,37 @@ class ChanLun():
last_bottom = None last_bottom = None
for klc in klc_list: for klc in klc_list:
fx = self.check_fx(klc) fx = self.check_fx(klc)
# Do nothing # Do nothing
if fx == Chan_FX_TYPE.UNKNOWN: if fx == Chan_FX_TYPE.UNKNOWN:
klc.set_fx(fx)
if len(bi_list) > 0: if len(bi_list) > 0:
bi_list[-1].add_klc(klc) last_bi = bi_list[-1]
klc.set_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")
if last_top and last_bi.dir == Chan_BI_DIR.DOWN:
if last_bottom and klc.high > last_bi.high:
last_bi.set_end_klc(last_bottom, klc)
bi = ChanBI(last_bottom, len(bi_list), Chan_BI_DIR.UP)
last_bi.set_next(bi)
bi.set_pre(last_bi)
for klc_index in range(last_bi.end_klc.index, len(klc_list)):
bi.add_klc(klc_list[klc_index])
bi_list.append(bi)
last_top = klc
klc.set_bi(bi)
#print(klc.start_time, bi.start_time, bi.end_time, bi.dir, bi.high, bi.low)
else:
if last_bottom and last_bi.dir == Chan_BI_DIR.UP:
if last_top and klc.low < last_bi.low:
last_bi.set_end_klc(last_top, klc)
bi = ChanBI(last_top, len(bi_list), Chan_BI_DIR.DOWN)
last_bi.set_next(bi)
bi.set_pre(last_bi)
for klc_index in range(last_bi.end_klc.index, len(klc_list)):
bi.add_klc(klc_list[klc_index])
bi_list.append(bi)
last_bottom = klc
klc.set_bi(bi)
#print(klc.start_time, bi.start_time, bi.end_time, bi.dir, bi.high, bi.low)
else: else:
if fx == Chan_FX_TYPE.TOP: if fx == Chan_FX_TYPE.TOP:
if last_top: if last_top:
@@ -754,7 +787,7 @@ class ChanLun():
last_top = klc last_top = klc
#print(klc.start_time, klc.fx, bi_list[-1].dir, "Last Top Change 1") #print(klc.start_time, klc.fx, bi_list[-1].dir, "Last Top Change 1")
klc.set_klc_fx_type(Chan_KLC_FX.TOP1) klc.set_klc_fx_type(Chan_KLC_FX.TOP1)
#print(klc.end_time, klc.fx, "一类卖点Sell 1") print(klc.end_time, klc.fx, "一类卖点Sell 1")
#klc.set_fx(fx) #klc.set_fx(fx)
#klc.set_state("10") #klc.set_state("10")
bi_list[-1].add_klc(klc) bi_list[-1].add_klc(klc)
@@ -804,7 +837,7 @@ class ChanLun():
bi.add_klc(klc) bi.add_klc(klc)
bi_list.append(bi) bi_list.append(bi)
last_top = klc last_top = klc
#print(klc.end_time, klc.fx, bi_list[-1].dir, "Last Top Change 2") print(klc.end_time, klc.fx, bi_list[-1].dir, "Last Top Change 2")
klc.set_klc_fx_type(Chan_KLC_FX.TOP2) klc.set_klc_fx_type(Chan_KLC_FX.TOP2)
#klc.set_state('30') #klc.set_state('30')
bi_list[-1].add_klc(klc) bi_list[-1].add_klc(klc)
+2 -2
View File
@@ -42,7 +42,7 @@ class ChanSEG():
self.is_sure = True self.is_sure = True
self.end_time = bi.end_klc.end_time self.end_time = bi.end_klc.end_time
if sure_bi.is_sure: if sure_bi.is_sure:
self.sure_time = sure_bi.end_klc.end_time self.sure_time = sure_bi.sure_time
def pre_set_end_bi(self, bi: ChanBI): def pre_set_end_bi(self, bi: ChanBI):
self.end_bi = bi self.end_bi = bi
if bi: if bi:
@@ -57,7 +57,7 @@ class ChanSEG():
self.next = seg self.next = seg
def set_sure(self, sure_bi): def set_sure(self, sure_bi):
if sure_bi.is_sure: if sure_bi.is_sure:
self.sure_time = sure_bi.end_klc.end_time self.sure_time = sure_bi.sure_time
self.is_sure = True self.is_sure = True
def add_bi(self, bi: ChanBI): def add_bi(self, bi: ChanBI):
if len(self.bi_list) > 1: if len(self.bi_list) > 1:
+1 -1
View File
@@ -237,7 +237,7 @@ class ChanLun_BTC_30(IStrategy):
if current_rate < last_low: if current_rate < last_low:
#print(trade.open_date, last_low, current_rate, "Relay Bottom FX exit") #print(trade.open_date, last_low, current_rate, "Relay Bottom FX exit")
return "Relay Bottom FX exit" return "Relay Bottom FX exit"
def order_filled(self, pair: str, trade: Trade, order: Order, current_time: datetime, **kwargs) -> None: def order_filled1(self, pair: str, trade: Trade, order: Order, current_time: datetime, **kwargs) -> None:
""" """
Called right after an order fills. Called right after an order fills.
Will be called for all order types (entry, exit, stoploss, position adjustment). Will be called for all order types (entry, exit, stoploss, position adjustment).
+1 -1
View File
@@ -114,7 +114,7 @@ def get_crypto_kl_data(symbol, timeframe, limit=1000, start_time=None, end_time=
batch_size = 1000 batch_size = 1000
else: else:
batch_size = 1500 # 日线及以上可以获取更多 batch_size = 1500 # 日线及以上可以获取更多
batch_size = 1000 # 默认批次大小
# 初始化存储所有K线数据的列表 # 初始化存储所有K线数据的列表
all_ohlcv = [] all_ohlcv = []