Files
2025-06-10 01:16:09 +08:00

192 lines
7.4 KiB
Python

import copy
from typing import List, Union, overload
from Bi.Bi import CBi
from Bi.BiList import CBiList
from BuySellPoint.BSPointList import CBSPointList
from ChanConfig import CChanConfig
from Common.CEnum import KLINE_DIR, SEG_TYPE
from Common.ChanException import CChanException, ErrCode
from Seg.Seg import CSeg
from Seg.SegConfig import CSegConfig
from Seg.SegListComm import CSegListComm
from ZS.ZSList import CZSList
from .KLine import CKLine
from .KLine_Unit import CKLine_Unit
def get_seglist_instance(seg_config: CSegConfig, lv) -> CSegListComm:
if seg_config.seg_algo == "chan":
from Seg.SegListChan import CSegListChan
return CSegListChan(seg_config, lv)
elif seg_config.seg_algo == "1+1":
print(f'Please avoid using seg_algo={seg_config.seg_algo} as it is deprecated and no longer maintained.')
from Seg.SegListDYH import CSegListDYH
return CSegListDYH(seg_config, lv)
elif seg_config.seg_algo == "break":
print(f'Please avoid using seg_algo={seg_config.seg_algo} as it is deprecated and no longer maintained.')
from Seg.SegListDef import CSegListDef
return CSegListDef(seg_config, lv)
else:
raise CChanException(f"unsupport seg algoright:{seg_config.seg_algo}", ErrCode.PARA_ERROR)
class CKLine_List:
def __init__(self, kl_type, conf: CChanConfig):
self.kl_type = kl_type
self.config = conf
self.lst: List[CKLine] = [] # K线列表,可递归 元素KLine类型
self.bi_list = CBiList(bi_conf=conf.bi_conf)
self.seg_list: CSegListComm[CBi] = get_seglist_instance(seg_config=conf.seg_conf, lv=SEG_TYPE.BI)
self.segseg_list: CSegListComm[CSeg[CBi]] = get_seglist_instance(seg_config=conf.seg_conf, lv=SEG_TYPE.SEG)
self.zs_list = CZSList(zs_config=conf.zs_conf)
self.segzs_list = CZSList(zs_config=conf.zs_conf)
self.bs_point_lst = CBSPointList[CBi, CBiList](bs_point_config=conf.bs_point_conf)
self.seg_bs_point_lst = CBSPointList[CSeg, CSegListComm](bs_point_config=conf.seg_bs_point_conf)
self.metric_model_lst = conf.GetMetricModel()
self.step_calculation = self.need_cal_step_by_step()
def __deepcopy__(self, memo):
new_obj = CKLine_List(self.kl_type, self.config)
memo[id(self)] = new_obj
for klc in self.lst:
klus_new = []
for klu in klc.lst:
new_klu = copy.deepcopy(klu, memo)
memo[id(klu)] = new_klu
if klu.pre is not None:
new_klu.set_pre_klu(memo[id(klu.pre)])
klus_new.append(new_klu)
new_klc = CKLine(klus_new[0], idx=klc.idx, _dir=klc.dir)
new_klc.set_fx(klc.fx)
new_klc.kl_type = klc.kl_type
for idx, klu in enumerate(klus_new):
klu.set_klc(new_klc)
if idx != 0:
new_klc.add(klu)
memo[id(klc)] = new_klc
if new_obj.lst:
new_obj.lst[-1].set_next(new_klc)
new_klc.set_pre(new_obj.lst[-1])
new_obj.lst.append(new_klc)
new_obj.bi_list = copy.deepcopy(self.bi_list, memo)
new_obj.seg_list = copy.deepcopy(self.seg_list, memo)
new_obj.segseg_list = copy.deepcopy(self.segseg_list, memo)
new_obj.zs_list = copy.deepcopy(self.zs_list, memo)
new_obj.segzs_list = copy.deepcopy(self.segzs_list, memo)
new_obj.bs_point_lst = copy.deepcopy(self.bs_point_lst, memo)
new_obj.metric_model_lst = copy.deepcopy(self.metric_model_lst, memo)
new_obj.step_calculation = copy.deepcopy(self.step_calculation, memo)
new_obj.seg_bs_point_lst = copy.deepcopy(self.seg_bs_point_lst, memo)
return new_obj
@overload
def __getitem__(self, index: int) -> CKLine: ...
@overload
def __getitem__(self, index: slice) -> List[CKLine]: ...
def __getitem__(self, index: Union[slice, int]) -> Union[List[CKLine], CKLine]:
return self.lst[index]
def __len__(self):
return len(self.lst)
def cal_seg_and_zs(self):
if not self.step_calculation:
self.bi_list.try_add_virtual_bi(self.lst[-1])
cal_seg(self.bi_list, self.seg_list)
self.zs_list.cal_bi_zs(self.bi_list, self.seg_list)
update_zs_in_seg(self.bi_list, self.seg_list, self.zs_list) # 计算seg的zs_lst,以及中枢的bi_in, bi_out
cal_seg(self.seg_list, self.segseg_list)
self.segzs_list.cal_bi_zs(self.seg_list, self.segseg_list)
update_zs_in_seg(self.seg_list, self.segseg_list, self.segzs_list) # 计算segseg的zs_lst,以及中枢的bi_in, bi_out
# 计算买卖点
self.seg_bs_point_lst.cal(self.seg_list, self.segseg_list) # 线段线段买卖点
self.bs_point_lst.cal(self.bi_list, self.seg_list) # 再算笔买卖点
def need_cal_step_by_step(self):
return self.config.trigger_step
def add_single_klu(self, klu: CKLine_Unit):
klu.set_metric(self.metric_model_lst)
if len(self.lst) == 0:
self.lst.append(CKLine(klu, idx=0))
else:
_dir = self.lst[-1].try_add(klu)
if _dir != KLINE_DIR.COMBINE: # 不需要合并K线
self.lst.append(CKLine(klu, idx=len(self.lst), _dir=_dir))
if len(self.lst) >= 3:
self.lst[-2].update_fx(self.lst[-3], self.lst[-1])
if self.bi_list.update_bi(self.lst[-2], self.lst[-1], self.step_calculation) and self.step_calculation:
self.cal_seg_and_zs()
elif self.step_calculation and self.bi_list.try_add_virtual_bi(self.lst[-1], need_del_end=True): # 这里的必要性参见issue#175
self.cal_seg_and_zs()
def klu_iter(self, klc_begin_idx=0):
for klc in self.lst[klc_begin_idx:]:
yield from klc.lst
def cal_seg(bi_list, seg_list: CSegListComm):
seg_list.update(bi_list)
sure_seg_cnt = 0
if len(seg_list) == 0:
for bi in bi_list:
bi.set_seg_idx(0)
return
begin_seg: CSeg = seg_list[-1]
for seg in seg_list[::-1]:
if seg.is_sure:
sure_seg_cnt += 1
else:
sure_seg_cnt = 0
begin_seg = seg
if sure_seg_cnt > 2:
break
cur_seg: CSeg = seg_list[-1]
for bi in bi_list[::-1]:
if bi.seg_idx is not None and bi.idx < begin_seg.start_bi.idx:
break
if bi.idx > cur_seg.end_bi.idx:
bi.set_seg_idx(cur_seg.idx+1)
continue
if bi.idx < cur_seg.start_bi.idx:
assert cur_seg.pre
cur_seg = cur_seg.pre
bi.set_seg_idx(cur_seg.idx)
def update_zs_in_seg(bi_list, seg_list, zs_list):
sure_seg_cnt = 0
for seg in seg_list[::-1]:
if seg.ele_inside_is_sure:
break
if seg.is_sure:
sure_seg_cnt += 1
seg.clear_zs_lst()
for zs in zs_list[::-1]:
if zs.end.idx < seg.start_bi.get_begin_klu().idx:
break
if zs.is_inside(seg):
seg.add_zs(zs)
assert zs.begin_bi.idx > 0
zs.set_bi_in(bi_list[zs.begin_bi.idx-1])
if zs.end_bi.idx+1 < len(bi_list):
zs.set_bi_out(bi_list[zs.end_bi.idx+1])
zs.set_bi_lst(list(bi_list[zs.begin_bi.idx:zs.end_bi.idx+1]))
if sure_seg_cnt > 2:
if not seg.ele_inside_is_sure:
seg.ele_inside_is_sure = True