Change some klc and bi recognition
This commit is contained in:
+13
-1
@@ -10,8 +10,12 @@ class Chan_DATA_SRC(Enum):
|
||||
class Chan_ZS_DIR(Enum):
|
||||
UP = auto()
|
||||
DOWN = auto()
|
||||
|
||||
class Chan_K_DIR(Enum):
|
||||
BULL = auto()
|
||||
BEAR = auto()
|
||||
CROSS = auto()
|
||||
class Chan_KL_TYPE(Enum):
|
||||
K_1S = auto()
|
||||
K_1M = auto()
|
||||
K_DAY = auto()
|
||||
K_WEEK = auto()
|
||||
@@ -21,6 +25,14 @@ class Chan_KL_TYPE(Enum):
|
||||
K_15M = auto()
|
||||
K_30M = 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_QUARTER = auto()
|
||||
|
||||
|
||||
+54
-24
@@ -1,7 +1,7 @@
|
||||
import copy
|
||||
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 ChanCTime
|
||||
|
||||
@@ -31,7 +31,15 @@ class ChanKLC():
|
||||
self.rsi = klu.rsi
|
||||
self.volume_ratio = klu.volume_ratio
|
||||
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):
|
||||
#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
|
||||
@@ -41,6 +49,10 @@ class ChanKLC():
|
||||
self.end_klu = klu
|
||||
self.end_time = klu.time
|
||||
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)):
|
||||
self.volume += self.klus[index].volume
|
||||
self.rsi += self.klus[index].rsi
|
||||
@@ -50,16 +62,31 @@ class ChanKLC():
|
||||
self.volume_ratio = self.volume_ratio / len(self.klus)
|
||||
self.volume = self.volume / len(self.klus)
|
||||
self.macdhist = self.macdhist / len(self.klus)
|
||||
self.cal_self_strength()
|
||||
def cal_self_strength(self):
|
||||
strength = 0
|
||||
if self.klus:
|
||||
if len(self.klus) == 1:
|
||||
strength = 1
|
||||
else:
|
||||
if len(self.klus) > 1:
|
||||
strength = 0
|
||||
self.strength_list.append(strength)
|
||||
def cal_shape_1(self):
|
||||
for index in range(1, len(self.klus)):
|
||||
self.body += self.klus[index].body
|
||||
self.upper_shadow += self.klus[index].upper_shadow
|
||||
self.lower_shadow += self.klus[index].lower_shadow
|
||||
self.body_ratio += self.klus[index].body_ratio
|
||||
self.upper_shadow_ratio += self.klus[index].upper_shadow_ratio
|
||||
self.lower_shadow_ratio += self.klus[index].lower_shadow_ratio
|
||||
self.range += self.klus[index].range
|
||||
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):
|
||||
self.next = klc
|
||||
def set_pre(self, klc):
|
||||
@@ -1171,10 +1198,20 @@ class ChanKLC():
|
||||
|
||||
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):
|
||||
strength = 0
|
||||
if self.fx == Chan_FX_TYPE.UNKNOWN or not self.pre or not self.next:
|
||||
if not self.end_klu:
|
||||
return 0
|
||||
if self.fx == Chan_FX_TYPE.UNKNOWN or not self.pre or not self.next:
|
||||
return strength
|
||||
else:
|
||||
if self.pre and self.next:
|
||||
klc1 = self.pre
|
||||
@@ -1182,34 +1219,27 @@ class ChanKLC():
|
||||
klc3 = self.next
|
||||
if self.bi:
|
||||
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:
|
||||
return 0
|
||||
return strength
|
||||
if self.bi.dir == Chan_BI_DIR.UP:
|
||||
if self.klc_fx_type == Chan_KLC_FX.TOP1:
|
||||
strength += self.check_bi_end(self.bi)
|
||||
elif self.klc_fx_type == Chan_KLC_FX.TOP2:
|
||||
strength += self.check_bi_end(self.bi)
|
||||
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)
|
||||
elif self.klc_fx_type == Chan_KLC_FX.BOTTOM2:
|
||||
strength += self.check_bi_end(self.bi)
|
||||
else:
|
||||
return 0
|
||||
return strength
|
||||
return strength
|
||||
def check_bi_end(self, bi):
|
||||
if bi.dir == Chan_BI_DIR.UP:
|
||||
return 1
|
||||
else:
|
||||
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):
|
||||
"""
|
||||
基于专业缠论理论的分型强度评估体系
|
||||
|
||||
+23
-1
@@ -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:
|
||||
def __init__(self, time, open, high, low, close, volume):
|
||||
# _time, _close, _open, _high, _low, _extra_info={}
|
||||
@@ -34,6 +34,28 @@ class ChanKLU:
|
||||
self.fx_confirmed = False # 分型是否确认
|
||||
self.klu_type = None
|
||||
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):
|
||||
"""
|
||||
计算K线类型:大阳线、大阴线、小阳线、小阴线
|
||||
|
||||
+38
-5
@@ -312,6 +312,7 @@ class ChanLun():
|
||||
self.last_peak['low'] = l
|
||||
#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:
|
||||
@@ -571,6 +572,13 @@ class ChanLun():
|
||||
else:
|
||||
last_down_bi = 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
|
||||
|
||||
def get_bi_zs_list(self, bi_list):
|
||||
@@ -729,12 +737,37 @@ class ChanLun():
|
||||
last_bottom = None
|
||||
for klc in klc_list:
|
||||
fx = self.check_fx(klc)
|
||||
|
||||
# Do nothing
|
||||
if 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])
|
||||
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")
|
||||
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:
|
||||
if fx == Chan_FX_TYPE.TOP:
|
||||
if last_top:
|
||||
@@ -754,7 +787,7 @@ class ChanLun():
|
||||
last_top = klc
|
||||
#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.end_time, klc.fx, "一类卖点Sell 1")
|
||||
print(klc.end_time, klc.fx, "一类卖点Sell 1")
|
||||
#klc.set_fx(fx)
|
||||
#klc.set_state("10")
|
||||
bi_list[-1].add_klc(klc)
|
||||
@@ -804,7 +837,7 @@ class ChanLun():
|
||||
bi.add_klc(klc)
|
||||
bi_list.append(bi)
|
||||
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_state('30')
|
||||
bi_list[-1].add_klc(klc)
|
||||
|
||||
+2
-2
@@ -42,7 +42,7 @@ class ChanSEG():
|
||||
self.is_sure = True
|
||||
self.end_time = bi.end_klc.end_time
|
||||
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):
|
||||
self.end_bi = bi
|
||||
if bi:
|
||||
@@ -57,7 +57,7 @@ class ChanSEG():
|
||||
self.next = seg
|
||||
def set_sure(self, sure_bi):
|
||||
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
|
||||
def add_bi(self, bi: ChanBI):
|
||||
if len(self.bi_list) > 1:
|
||||
|
||||
@@ -237,7 +237,7 @@ class ChanLun_BTC_30(IStrategy):
|
||||
if current_rate < last_low:
|
||||
#print(trade.open_date, last_low, current_rate, "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.
|
||||
Will be called for all order types (entry, exit, stoploss, position adjustment).
|
||||
|
||||
+1
-1
@@ -114,7 +114,7 @@ def get_crypto_kl_data(symbol, timeframe, limit=1000, start_time=None, end_time=
|
||||
batch_size = 1000
|
||||
else:
|
||||
batch_size = 1500 # 日线及以上可以获取更多
|
||||
|
||||
batch_size = 1000 # 默认批次大小
|
||||
# 初始化存储所有K线数据的列表
|
||||
all_ohlcv = []
|
||||
|
||||
|
||||
Reference in New Issue
Block a user