Initial commit
This commit is contained in:
@@ -0,0 +1,78 @@
|
||||
from typing import Dict, List, Optional
|
||||
|
||||
from Common.CEnum import BSP_TYPE, MACD_ALGO
|
||||
from Common.func_util import _parse_inf
|
||||
|
||||
|
||||
class CBSPointConfig:
|
||||
def __init__(self, **args):
|
||||
self.b_conf = CPointConfig(**args)
|
||||
self.s_conf = CPointConfig(**args)
|
||||
|
||||
def GetBSConfig(self, is_buy):
|
||||
return self.b_conf if is_buy else self.s_conf
|
||||
|
||||
|
||||
class CPointConfig:
|
||||
def __init__(self,
|
||||
divergence_rate,
|
||||
min_zs_cnt,
|
||||
bsp1_only_multibi_zs,
|
||||
max_bs2_rate,
|
||||
macd_algo,
|
||||
bs1_peak,
|
||||
bs_type,
|
||||
bsp2_follow_1,
|
||||
bsp3_follow_1,
|
||||
bsp3_peak,
|
||||
bsp2s_follow_2,
|
||||
max_bsp2s_lv,
|
||||
strict_bsp3,
|
||||
):
|
||||
self.divergence_rate = divergence_rate
|
||||
self.min_zs_cnt = min_zs_cnt
|
||||
self.bsp1_only_multibi_zs = bsp1_only_multibi_zs
|
||||
self.max_bs2_rate = max_bs2_rate
|
||||
assert self.max_bs2_rate <= 1
|
||||
self.SetMacdAlgo(macd_algo)
|
||||
self.bs1_peak = bs1_peak
|
||||
self.tmp_target_types = bs_type
|
||||
self.target_types: List[BSP_TYPE] = []
|
||||
self.bsp2_follow_1 = bsp2_follow_1
|
||||
self.bsp3_follow_1 = bsp3_follow_1
|
||||
self.bsp3_peak = bsp3_peak
|
||||
self.bsp2s_follow_2 = bsp2s_follow_2
|
||||
self.max_bsp2s_lv: Optional[int] = max_bsp2s_lv
|
||||
self.strict_bsp3 = strict_bsp3
|
||||
|
||||
def parse_target_type(self):
|
||||
_d: Dict[str, BSP_TYPE] = {x.value: x for x in BSP_TYPE}
|
||||
if isinstance(self.tmp_target_types, str):
|
||||
self.tmp_target_types = [t.strip() for t in self.tmp_target_types.split(",")]
|
||||
for target_t in self.tmp_target_types:
|
||||
assert target_t in ['1', '2', '3a', '2s', '1p', '3b']
|
||||
self.target_types = [_d[_type] for _type in self.tmp_target_types]
|
||||
|
||||
def SetMacdAlgo(self, macd_algo):
|
||||
_d = {
|
||||
"area": MACD_ALGO.AREA,
|
||||
"peak": MACD_ALGO.PEAK,
|
||||
"full_area": MACD_ALGO.FULL_AREA,
|
||||
"diff": MACD_ALGO.DIFF,
|
||||
"slope": MACD_ALGO.SLOPE,
|
||||
"amp": MACD_ALGO.AMP,
|
||||
"amount": MACD_ALGO.AMOUNT,
|
||||
"volumn": MACD_ALGO.VOLUMN,
|
||||
"amount_avg": MACD_ALGO.AMOUNT_AVG,
|
||||
"volumn_avg": MACD_ALGO.VOLUMN_AVG,
|
||||
"turnrate_avg": MACD_ALGO.AMOUNT_AVG,
|
||||
"rsi": MACD_ALGO.RSI,
|
||||
}
|
||||
self.macd_algo = _d[macd_algo]
|
||||
|
||||
def set(self, k, v):
|
||||
v = _parse_inf(v)
|
||||
if k == "macd_algo":
|
||||
self.SetMacdAlgo(v)
|
||||
else:
|
||||
exec(f"self.{k} = {v}")
|
||||
@@ -0,0 +1,342 @@
|
||||
from typing import Dict, Generic, List, Optional, TypeVar, Union, overload
|
||||
|
||||
from Bi.Bi import CBi
|
||||
from Bi.BiList import CBiList
|
||||
from Common.CEnum import BSP_TYPE
|
||||
from Common.func_util import has_overlap
|
||||
from Seg.Seg import CSeg
|
||||
from Seg.SegListComm import CSegListComm
|
||||
from ZS.ZS import CZS
|
||||
|
||||
from .BS_Point import CBS_Point
|
||||
from .BSPointConfig import CBSPointConfig, CPointConfig
|
||||
|
||||
LINE_TYPE = TypeVar('LINE_TYPE', CBi, CSeg[CBi])
|
||||
LINE_LIST_TYPE = TypeVar('LINE_LIST_TYPE', CBiList, CSegListComm[CBi])
|
||||
|
||||
|
||||
class CBSPointList(Generic[LINE_TYPE, LINE_LIST_TYPE]):
|
||||
def __init__(self, bs_point_config: CBSPointConfig):
|
||||
self.lst: List[CBS_Point[LINE_TYPE]] = []
|
||||
self.bsp_dict: Dict[int, CBS_Point[LINE_TYPE]] = {}
|
||||
self.bsp1_lst: List[CBS_Point[LINE_TYPE]] = []
|
||||
self.config = bs_point_config
|
||||
self.last_sure_pos = -1
|
||||
|
||||
def __iter__(self):
|
||||
yield from self.lst
|
||||
|
||||
def __len__(self):
|
||||
return len(self.lst)
|
||||
|
||||
@overload
|
||||
def __getitem__(self, index: int) -> CBS_Point: ...
|
||||
|
||||
@overload
|
||||
def __getitem__(self, index: slice) -> List[CBS_Point]: ...
|
||||
|
||||
def __getitem__(self, index: Union[slice, int]) -> Union[List[CBS_Point], CBS_Point]:
|
||||
return self.lst[index]
|
||||
|
||||
def cal(self, bi_list: LINE_LIST_TYPE, seg_list: CSegListComm[LINE_TYPE]):
|
||||
self.lst = [bsp for bsp in self.lst if bsp.klu.idx <= self.last_sure_pos]
|
||||
self.bsp_dict = {bsp.bi.get_end_klu().idx: bsp for bsp in self.lst}
|
||||
self.bsp1_lst = [bsp for bsp in self.bsp1_lst if bsp.klu.idx <= self.last_sure_pos]
|
||||
|
||||
self.cal_seg_bs1point(seg_list, bi_list)
|
||||
self.cal_seg_bs2point(seg_list, bi_list)
|
||||
self.cal_seg_bs3point(seg_list, bi_list)
|
||||
|
||||
self.update_last_pos(seg_list)
|
||||
|
||||
def update_last_pos(self, seg_list: CSegListComm):
|
||||
self.last_sure_pos = -1
|
||||
for seg in seg_list[::-1]:
|
||||
if seg.is_sure:
|
||||
self.last_sure_pos = seg.end_bi.get_begin_klu().idx
|
||||
return
|
||||
|
||||
def seg_need_cal(self, seg: CSeg):
|
||||
return seg.end_bi.get_end_klu().idx > self.last_sure_pos
|
||||
|
||||
def add_bs(
|
||||
self,
|
||||
bs_type: BSP_TYPE,
|
||||
bi: LINE_TYPE,
|
||||
relate_bsp1: Optional[CBS_Point],
|
||||
is_target_bsp: bool = True,
|
||||
feature_dict=None,
|
||||
):
|
||||
is_buy = bi.is_down()
|
||||
if exist_bsp := self.bsp_dict.get(bi.get_end_klu().idx):
|
||||
assert exist_bsp.is_buy == is_buy
|
||||
exist_bsp.add_another_bsp_prop(bs_type, relate_bsp1)
|
||||
return
|
||||
if bs_type not in self.config.GetBSConfig(is_buy).target_types:
|
||||
is_target_bsp = False
|
||||
|
||||
if is_target_bsp or bs_type in [BSP_TYPE.T1, BSP_TYPE.T1P]:
|
||||
bsp = CBS_Point[LINE_TYPE](
|
||||
bi=bi,
|
||||
is_buy=is_buy,
|
||||
bs_type=bs_type,
|
||||
relate_bsp1=relate_bsp1,
|
||||
feature_dict=feature_dict,
|
||||
)
|
||||
else:
|
||||
return
|
||||
if is_target_bsp:
|
||||
self.lst.append(bsp)
|
||||
self.bsp_dict[bi.get_end_klu().idx] = bsp
|
||||
if bs_type in [BSP_TYPE.T1, BSP_TYPE.T1P]:
|
||||
self.bsp1_lst.append(bsp)
|
||||
|
||||
def cal_seg_bs1point(self, seg_list: CSegListComm[LINE_TYPE], bi_list: LINE_LIST_TYPE):
|
||||
for seg in seg_list:
|
||||
if not self.seg_need_cal(seg):
|
||||
continue
|
||||
self.cal_single_bs1point(seg, bi_list)
|
||||
|
||||
def cal_single_bs1point(self, seg: CSeg[LINE_TYPE], bi_list: LINE_LIST_TYPE):
|
||||
BSP_CONF = self.config.GetBSConfig(seg.is_down())
|
||||
zs_cnt = seg.get_multi_bi_zs_cnt() if BSP_CONF.bsp1_only_multibi_zs else len(seg.zs_lst)
|
||||
is_target_bsp = (BSP_CONF.min_zs_cnt <= 0 or zs_cnt >= BSP_CONF.min_zs_cnt)
|
||||
if len(seg.zs_lst) > 0 and \
|
||||
not seg.zs_lst[-1].is_one_bi_zs() and \
|
||||
((seg.zs_lst[-1].bi_out and seg.zs_lst[-1].bi_out.idx >= seg.end_bi.idx) or seg.zs_lst[-1].bi_lst[-1].idx >= seg.end_bi.idx) \
|
||||
and seg.end_bi.idx - seg.zs_lst[-1].get_bi_in().idx > 2:
|
||||
self.treat_bsp1(seg, BSP_CONF, is_target_bsp)
|
||||
else:
|
||||
self.treat_pz_bsp1(seg, BSP_CONF, bi_list, is_target_bsp)
|
||||
|
||||
def treat_bsp1(self, seg: CSeg[LINE_TYPE], BSP_CONF: CPointConfig, is_target_bsp: bool):
|
||||
last_zs = seg.zs_lst[-1]
|
||||
break_peak, _ = last_zs.out_bi_is_peak(seg.end_bi.idx)
|
||||
if BSP_CONF.bs1_peak and not break_peak:
|
||||
is_target_bsp = False
|
||||
is_diver, divergence_rate = last_zs.is_divergence(BSP_CONF, out_bi=seg.end_bi)
|
||||
if not is_diver:
|
||||
is_target_bsp = False
|
||||
feature_dict = {'divergence_rate': divergence_rate}
|
||||
self.add_bs(bs_type=BSP_TYPE.T1, bi=seg.end_bi, relate_bsp1=None, is_target_bsp=is_target_bsp, feature_dict=feature_dict)
|
||||
|
||||
def treat_pz_bsp1(self, seg: CSeg[LINE_TYPE], BSP_CONF: CPointConfig, bi_list: LINE_LIST_TYPE, is_target_bsp):
|
||||
last_bi = seg.end_bi
|
||||
pre_bi = bi_list[last_bi.idx-2]
|
||||
if last_bi.seg_idx != pre_bi.seg_idx:
|
||||
return
|
||||
if last_bi.dir != seg.dir:
|
||||
return
|
||||
if last_bi.is_down() and last_bi._low() > pre_bi._low(): # 创新低
|
||||
return
|
||||
if last_bi.is_up() and last_bi._high() < pre_bi._high(): # 创新高
|
||||
return
|
||||
in_metric = pre_bi.cal_macd_metric(BSP_CONF.macd_algo, is_reverse=False)
|
||||
out_metric = last_bi.cal_macd_metric(BSP_CONF.macd_algo, is_reverse=True)
|
||||
is_diver, divergence_rate = out_metric <= BSP_CONF.divergence_rate*in_metric, out_metric/(in_metric+1e-7)
|
||||
if not is_diver:
|
||||
is_target_bsp = False
|
||||
if isinstance(bi_list, CBiList):
|
||||
assert isinstance(last_bi, CBi) and isinstance(pre_bi, CBi)
|
||||
feature_dict = {'divergence_rate': divergence_rate}
|
||||
self.add_bs(bs_type=BSP_TYPE.T1P, bi=last_bi, relate_bsp1=None, is_target_bsp=is_target_bsp, feature_dict=feature_dict)
|
||||
|
||||
def cal_seg_bs2point(self, seg_list: CSegListComm[LINE_TYPE], bi_list: LINE_LIST_TYPE):
|
||||
bsp1_bi_idx_dict = {bsp.bi.idx: bsp for bsp in self.bsp1_lst}
|
||||
for seg in seg_list:
|
||||
config = self.config.GetBSConfig(seg.is_down())
|
||||
if BSP_TYPE.T2 not in config.target_types and BSP_TYPE.T2S not in config.target_types:
|
||||
continue
|
||||
self.treat_bsp2(seg, bsp1_bi_idx_dict, seg_list, bi_list)
|
||||
|
||||
def treat_bsp2(self, seg: CSeg, bsp1_bi_idx_dict, seg_list: CSegListComm[LINE_TYPE], bi_list: LINE_LIST_TYPE):
|
||||
if not self.seg_need_cal(seg):
|
||||
return
|
||||
if len(seg_list) > 1:
|
||||
BSP_CONF = self.config.GetBSConfig(seg.is_down())
|
||||
bsp1_bi = seg.end_bi
|
||||
bsp1_bi_idx = bsp1_bi.idx
|
||||
real_bsp1 = bsp1_bi_idx_dict.get(bsp1_bi.idx)
|
||||
if bsp1_bi.idx + 2 >= len(bi_list):
|
||||
return
|
||||
break_bi = bi_list[bsp1_bi.idx + 1]
|
||||
bsp2_bi = bi_list[bsp1_bi.idx + 2]
|
||||
else:
|
||||
BSP_CONF = self.config.GetBSConfig(seg.is_up())
|
||||
bsp1_bi, real_bsp1 = None, None
|
||||
bsp1_bi_idx = -1
|
||||
if len(bi_list) == 1:
|
||||
return
|
||||
bsp2_bi = bi_list[1]
|
||||
break_bi = bi_list[0]
|
||||
if BSP_CONF.bsp2_follow_1 and bsp1_bi_idx not in [bsp.bi.idx for bsp in self.bsp_dict.values()]: # check bsp2_follow_1
|
||||
return
|
||||
retrace_rate = bsp2_bi.amp()/break_bi.amp()
|
||||
bsp2_flag = retrace_rate <= BSP_CONF.max_bs2_rate
|
||||
if bsp2_flag:
|
||||
self.add_bs(bs_type=BSP_TYPE.T2, bi=bsp2_bi, relate_bsp1=real_bsp1) # type: ignore
|
||||
elif BSP_CONF.bsp2s_follow_2:
|
||||
return
|
||||
if BSP_TYPE.T2S not in self.config.GetBSConfig(seg.is_down()).target_types:
|
||||
return
|
||||
self.treat_bsp2s(seg_list, bi_list, bsp2_bi, break_bi, real_bsp1, BSP_CONF) # type: ignore
|
||||
|
||||
def treat_bsp2s(
|
||||
self,
|
||||
seg_list: CSegListComm,
|
||||
bi_list: LINE_LIST_TYPE,
|
||||
bsp2_bi: LINE_TYPE,
|
||||
break_bi: LINE_TYPE,
|
||||
real_bsp1: Optional[CBS_Point],
|
||||
BSP_CONF: CPointConfig,
|
||||
):
|
||||
bias = 2
|
||||
_low, _high = None, None
|
||||
while bsp2_bi.idx + bias < len(bi_list): # 计算类二
|
||||
bsp2s_bi = bi_list[bsp2_bi.idx + bias]
|
||||
assert bsp2s_bi.seg_idx is not None and bsp2_bi.seg_idx is not None
|
||||
if BSP_CONF.max_bsp2s_lv is not None and bias/2 > BSP_CONF.max_bsp2s_lv:
|
||||
break
|
||||
if bsp2s_bi.seg_idx != bsp2_bi.seg_idx and (bsp2s_bi.seg_idx < len(seg_list)-1 or bsp2s_bi.seg_idx - bsp2_bi.seg_idx >= 2 or seg_list[bsp2_bi.seg_idx].is_sure):
|
||||
break
|
||||
if bias == 2:
|
||||
if not has_overlap(bsp2_bi._low(), bsp2_bi._high(), bsp2s_bi._low(), bsp2s_bi._high()):
|
||||
break
|
||||
_low = max([bsp2_bi._low(), bsp2s_bi._low()])
|
||||
_high = min([bsp2_bi._high(), bsp2s_bi._high()])
|
||||
elif not has_overlap(_low, _high, bsp2s_bi._low(), bsp2s_bi._high()):
|
||||
break
|
||||
|
||||
if bsp2s_break_bsp1(bsp2s_bi, break_bi):
|
||||
break
|
||||
retrace_rate = abs(bsp2s_bi.get_end_val()-break_bi.get_end_val())/break_bi.amp()
|
||||
if retrace_rate > BSP_CONF.max_bs2_rate:
|
||||
break
|
||||
|
||||
self.add_bs(bs_type=BSP_TYPE.T2S, bi=bsp2s_bi, relate_bsp1=real_bsp1) # type: ignore
|
||||
bias += 2
|
||||
|
||||
def cal_seg_bs3point(self, seg_list: CSegListComm[LINE_TYPE], bi_list: LINE_LIST_TYPE):
|
||||
bsp1_bi_idx_dict = {bsp.bi.idx: bsp for bsp in self.bsp1_lst}
|
||||
for seg in seg_list:
|
||||
if not self.seg_need_cal(seg):
|
||||
continue
|
||||
config = self.config.GetBSConfig(seg.is_down())
|
||||
if BSP_TYPE.T3A not in config.target_types and BSP_TYPE.T3B not in config.target_types:
|
||||
continue
|
||||
if len(seg_list) > 1:
|
||||
bsp1_bi = seg.end_bi
|
||||
bsp1_bi_idx = bsp1_bi.idx
|
||||
BSP_CONF = self.config.GetBSConfig(seg.is_down())
|
||||
real_bsp1 = bsp1_bi_idx_dict.get(bsp1_bi.idx)
|
||||
next_seg_idx = seg.idx+1
|
||||
next_seg = seg.next # 可能为None, 所以并不一定可以保证next_seg_idx == next_seg.idx
|
||||
else:
|
||||
next_seg = seg
|
||||
next_seg_idx = seg.idx
|
||||
bsp1_bi, real_bsp1 = None, None
|
||||
bsp1_bi_idx = -1
|
||||
BSP_CONF = self.config.GetBSConfig(seg.is_up())
|
||||
if BSP_CONF.bsp3_follow_1 and bsp1_bi_idx not in [bsp.bi.idx for bsp in self.bsp_dict.values()]:
|
||||
continue
|
||||
if next_seg:
|
||||
self.treat_bsp3_after(seg_list, next_seg, BSP_CONF, bi_list, real_bsp1, bsp1_bi_idx, next_seg_idx)
|
||||
self.treat_bsp3_before(seg_list, seg, next_seg, bsp1_bi, BSP_CONF, bi_list, real_bsp1, next_seg_idx)
|
||||
|
||||
def treat_bsp3_after(
|
||||
self,
|
||||
seg_list: CSegListComm[LINE_TYPE],
|
||||
next_seg: CSeg[LINE_TYPE],
|
||||
BSP_CONF: CPointConfig,
|
||||
bi_list: LINE_LIST_TYPE,
|
||||
real_bsp1,
|
||||
bsp1_bi_idx,
|
||||
next_seg_idx
|
||||
):
|
||||
first_zs = next_seg.get_first_multi_bi_zs()
|
||||
if first_zs is None:
|
||||
return
|
||||
if BSP_CONF.strict_bsp3 and first_zs.get_bi_in().idx != bsp1_bi_idx+1:
|
||||
return
|
||||
if first_zs.bi_out is None or first_zs.bi_out.idx+1 >= len(bi_list):
|
||||
return
|
||||
bsp3_bi = bi_list[first_zs.bi_out.idx+1]
|
||||
if bsp3_bi.parent_seg is None:
|
||||
if next_seg.idx != len(seg_list)-1:
|
||||
return
|
||||
elif bsp3_bi.parent_seg.idx != next_seg.idx:
|
||||
if len(bsp3_bi.parent_seg.bi_list) >= 3:
|
||||
return
|
||||
if bsp3_bi.dir == next_seg.dir:
|
||||
return
|
||||
if bsp3_bi.seg_idx != next_seg_idx and next_seg_idx < len(seg_list)-2:
|
||||
return
|
||||
if bsp3_back2zs(bsp3_bi, first_zs):
|
||||
return
|
||||
bsp3_peak_zs = bsp3_break_zspeak(bsp3_bi, first_zs)
|
||||
if BSP_CONF.bsp3_peak and not bsp3_peak_zs:
|
||||
return
|
||||
self.add_bs(bs_type=BSP_TYPE.T3A, bi=bsp3_bi, relate_bsp1=real_bsp1) # type: ignore
|
||||
|
||||
def treat_bsp3_before(
|
||||
self,
|
||||
seg_list: CSegListComm[LINE_TYPE],
|
||||
seg: CSeg[LINE_TYPE],
|
||||
next_seg: Optional[CSeg[LINE_TYPE]],
|
||||
bsp1_bi: Optional[LINE_TYPE],
|
||||
BSP_CONF: CPointConfig,
|
||||
bi_list: LINE_LIST_TYPE,
|
||||
real_bsp1,
|
||||
next_seg_idx
|
||||
):
|
||||
cmp_zs = seg.get_final_multi_bi_zs()
|
||||
if cmp_zs is None:
|
||||
return
|
||||
if not bsp1_bi:
|
||||
return
|
||||
if BSP_CONF.strict_bsp3 and (cmp_zs.bi_out is None or cmp_zs.bi_out.idx != bsp1_bi.idx):
|
||||
return
|
||||
end_bi_idx = cal_bsp3_bi_end_idx(next_seg)
|
||||
for bsp3_bi in bi_list[bsp1_bi.idx+2::2]:
|
||||
if bsp3_bi.idx > end_bi_idx:
|
||||
break
|
||||
assert bsp3_bi.seg_idx is not None
|
||||
if bsp3_bi.seg_idx != next_seg_idx and bsp3_bi.seg_idx < len(seg_list)-1:
|
||||
break
|
||||
if bsp3_back2zs(bsp3_bi, cmp_zs): # type: ignore
|
||||
continue
|
||||
self.add_bs(bs_type=BSP_TYPE.T3B, bi=bsp3_bi, relate_bsp1=real_bsp1) # type: ignore
|
||||
break
|
||||
|
||||
def getLastestBspList(self) -> List[CBS_Point[LINE_TYPE]]:
|
||||
if len(self.lst) == 0:
|
||||
return []
|
||||
return sorted(self.lst, key=lambda bsp: bsp.bi.idx, reverse=True)
|
||||
|
||||
|
||||
def bsp2s_break_bsp1(bsp2s_bi: LINE_TYPE, bsp2_break_bi: LINE_TYPE) -> bool:
|
||||
return (bsp2s_bi.is_down() and bsp2s_bi._low() < bsp2_break_bi._low()) or \
|
||||
(bsp2s_bi.is_up() and bsp2s_bi._high() > bsp2_break_bi._high())
|
||||
|
||||
|
||||
def bsp3_back2zs(bsp3_bi: LINE_TYPE, zs: CZS) -> bool:
|
||||
return (bsp3_bi.is_down() and bsp3_bi._low() < zs.high) or (bsp3_bi.is_up() and bsp3_bi._high() > zs.low)
|
||||
|
||||
|
||||
def bsp3_break_zspeak(bsp3_bi: LINE_TYPE, zs: CZS) -> bool:
|
||||
return (bsp3_bi.is_down() and bsp3_bi._high() >= zs.peak_high) or (bsp3_bi.is_up() and bsp3_bi._low() <= zs.peak_low)
|
||||
|
||||
|
||||
def cal_bsp3_bi_end_idx(seg: Optional[CSeg[LINE_TYPE]]):
|
||||
if not seg:
|
||||
return float("inf")
|
||||
if seg.get_multi_bi_zs_cnt() == 0 and seg.next is None:
|
||||
return float("inf")
|
||||
end_bi_idx = seg.end_bi.idx-1
|
||||
for zs in seg.zs_lst:
|
||||
if zs.is_one_bi_zs():
|
||||
continue
|
||||
if zs.bi_out is not None:
|
||||
end_bi_idx = zs.bi_out.idx
|
||||
break
|
||||
return end_bi_idx
|
||||
@@ -0,0 +1,38 @@
|
||||
from typing import Dict, Generic, List, Optional, TypeVar, Union
|
||||
|
||||
from Bi.Bi import CBi
|
||||
from ChanModel.Features import CFeatures
|
||||
from Common.CEnum import BSP_TYPE
|
||||
from Seg.Seg import CSeg
|
||||
|
||||
LINE_TYPE = TypeVar('LINE_TYPE', CBi, CSeg)
|
||||
|
||||
|
||||
class CBS_Point(Generic[LINE_TYPE]):
|
||||
def __init__(self, bi: LINE_TYPE, is_buy, bs_type: BSP_TYPE, relate_bsp1: Optional['CBS_Point'], feature_dict=None):
|
||||
self.bi: LINE_TYPE = bi
|
||||
self.klu = bi.get_end_klu()
|
||||
self.is_buy = is_buy
|
||||
self.type: List[BSP_TYPE] = [bs_type]
|
||||
self.relate_bsp1 = relate_bsp1
|
||||
|
||||
self.bi.bsp = self # type: ignore
|
||||
self.features = CFeatures(feature_dict)
|
||||
|
||||
self.is_segbsp = False
|
||||
|
||||
def add_type(self, bs_type: BSP_TYPE):
|
||||
self.type.append(bs_type)
|
||||
|
||||
def type2str(self):
|
||||
return ",".join([x.value for x in self.type])
|
||||
|
||||
def add_another_bsp_prop(self, bs_type: BSP_TYPE, relate_bsp1):
|
||||
self.add_type(bs_type)
|
||||
if self.relate_bsp1 is None:
|
||||
self.relate_bsp1 = relate_bsp1
|
||||
elif relate_bsp1 is not None:
|
||||
assert self.relate_bsp1.klu.idx == relate_bsp1.klu.idx
|
||||
|
||||
def add_feat(self, inp1: Union[str, Dict[str, float], Dict[str, Optional[float]], 'CFeatures'], inp2: Optional[float] = None):
|
||||
self.features.add_feat(inp1, inp2)
|
||||
Reference in New Issue
Block a user