Skip to content

Commit

Permalink
update
Browse files Browse the repository at this point in the history
  • Loading branch information
vespa committed Feb 8, 2022
1 parent 25052d0 commit 0181ac3
Show file tree
Hide file tree
Showing 34 changed files with 969 additions and 57 deletions.
3 changes: 3 additions & 0 deletions Bi/CBiConfig.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
class CBi_Config:
def __init__(self, is_strict=True):
self.is_strict = is_strict
Empty file added Bi/__init__.py
Empty file.
50 changes: 50 additions & 0 deletions BuySellPoint/CBSPointConfig.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
class CBSPointConfig:
def __init__(self, **args):
self.b_conf = CPointConfig(**args)
self.s_conf = CPointConfig(**args)

def GetStragetyPara(self, is_buy, k):
if is_buy:
return self.b_conf.GetStragetyPara(k)
else:
return self.s_conf.GetStragetyPara(k)


class CPointConfig:
def __init__(self,
divergence_rate,
min_zs_cnt,
max_bs2_rate,
macd_algo,
bs1_peak,
bs_type,
stragety_para,
bsp2_follow_1,
bsp3_follow_1,
bsp2s_follow_2,
strict_bsp3,
score_thred,
):
self.divergence_rate = divergence_rate
self.min_zs_cnt = min_zs_cnt
# assert self.min_zs_cnt > 0
self.max_bs2_rate = max_bs2_rate
assert self.max_bs2_rate <= 1
self.macd_algo = macd_algo
self.bs1_peak = bs1_peak
self.target_types = bs_type
self.stragety_para = stragety_para
self.bsp2_follow_1 = bsp2_follow_1
self.bsp3_follow_1 = bsp3_follow_1
self.bsp2s_follow_2 = bsp2s_follow_2
self.strict_bsp3 = strict_bsp3
self.score_thred = score_thred

def parse_target_type(self):
if type(self.target_types) == str:
self.target_types = [t.strip() for t in self.target_types.split(",")]
for target_t in self.target_types:
assert target_t in ['1', '2', '3', '2s', '1p']

def GetStragetyPara(self, k):
return self.stragety_para[k]
78 changes: 78 additions & 0 deletions BuySellPoint/CBS_Point.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
from Bi.CBi import CBi
from common.CEnum import BI_DIR


class CBS_Point:
def __init__(self, bi: CBi, is_buy, bs_type, relate_bsp1, extrainfo={}):
self.bi = bi
self.klu = bi.get_end_klu()
self.is_buy = is_buy
self.type = [bs_type]
self.relate_bsp1 = relate_bsp1

self.extrainfo = extrainfo
self.update_extrainfo()

def __str__(self):
return f"{self.klu.time}-{self.type2str()}{'b' if self.is_buy else 's'}"

def add_type(self, bs_type, extrainfo={}):
self.type.append(bs_type)
self.add_feat(extrainfo)

def type2str(self):
return ",".join(self.type)

def has_type(self, x):
return str(x) in self.type

def qjt_type(self):
return [f"q{x}" for x in self.type]

def toJson(self):
return {
"bi": self.bi.idx,
"klu": self.klu.toJson(),
"is_buy": self.is_buy,
"type": self.type2str(),
"extrainfo": self.extrainfo,
}

def add_feat(self, inp1, inp2=None):
if inp2 is None:
assert type(inp1) == dict
self.extrainfo.update(inp1)
else:
self.extrainfo.update({inp1: inp2})

def extract_feat(self, prefix):
res = {}
for k, v in self.extrainfo.items():
if k.startswith(prefix):
res[k] = v
return res

def update_extrainfo(self):
self.extrainfo.update(self.bi.Get3KZSFeat())
self.add_feat({
"bsp_bi_klu_cnt": self.bi.get_end_klu().idx-self.bi.get_begin_klu().idx+1,
"bsp_fx_break": self.bi.get_fx_break_rate(),
})
last_klu = self.bi.get_last_klu()
if last_klu.boll:
boll = last_klu.boll
c = last_klu.close
self.add_feat({
"bsp_boll_theta": boll.theta,
"bsp_boll_mid": (c-boll.MID)/boll.MID,
"bsp_boll_up": (c-boll.UP)/boll.UP,
"bsp_boll_down": (c-boll.DOWN)/boll.DOWN,
"bsp_boll_theta_cnt": (c-boll.MID)/boll.theta, # UP和DOWN不重要,可以推导出来的
})
self.add_feat(
"bsp_boll_end",
(last_klu.low-boll.DOWN)/boll.DOWN if self.bi.dir == BI_DIR.DOWN else (boll.UP-last_klu.high)/boll.UP,
)
if self.relate_bsp1:
assert self.type2str().find("1") < 0
self.add_feat(self.relate_bsp1.extract_feat("bsp1_"))
Empty file added BuySellPoint/__init__.py
Empty file.
65 changes: 65 additions & 0 deletions KLine/CKLine.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
from combiner.CKLine_Combiner import CKLine_Combiner
from common.CEnum import KLINE_DIR, FX_TYPE


# 合并后的K线
class KLine(CKLine_Combiner):
def __init__(self, kl_unit, idx, _dir=KLINE_DIR.UP):
super(KLine, self).__init__(kl_unit, _dir)
self.idx = idx
self.kl_type = kl_unit.kl_type
# 下面是父类成员
# self.time_begin = kl_unit.time
# self.time_end = kl_unit.time
# self.high = kl_unit.high
# self.low = kl_unit.low
# self.lst = [kl_unit] # 本级别每一根单位K线
# self.dir = _dir
# self.fx = FX_TYPE.UNKNOWN
# self.pre
# self.next
# 父类方法
# try_add(self, unit_kl)
# test_combine(self, _kl)

def __str__(self):
fx_token = ""
if self.fx == FX_TYPE.TOP:
fx_token = "^"
elif self.fx == FX_TYPE.BOTTOM:
fx_token = "_"
return f"{self.idx}th{fx_token}:{self.time_begin}~{self.time_end}({self.kl_type}|{len(self.lst)}) low={self.low} high={self.high}"

def GetSubKLC(self):
# 可能会出现相邻的两个KLC的子KLC会有重复
# 因为子KLU合并时正好跨过了父KLC的结束时间边界
last_klc = None
for klu in self.lst:
for sub_klu in klu.get_children():
if sub_klu.klc != last_klc:
last_klc = sub_klu.klc
yield sub_klu.klc

def getOutlinearScore(self):
res = {}
for klu in self:
outliner_dict = klu.getOutlinearScore()
if not res:
res = outliner_dict
else:
for k, v in outliner_dict.items():
if v >= res[k]:
res[k] = v
return res

def GetNegPosCnt(self):
# 阴线, 阳线数
res = {"neg": 0, "pos": 0}
for klu in self:
if klu.close < klu.open:
res["neg"] += 1
else:
res["pos"] += 1
res["neg_rate"] = res["neg"]/float(len(self))
res["pos_rate"] = res["pos"]/float(len(self))
return res
148 changes: 148 additions & 0 deletions KLine/CKline_List.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
from .CKline_Unit import KLine_Unit
from .CKLine import KLine
from common.CEnum import KLINE_DIR
from dataSrc.CommonStockAPI import TRADE_INFO_LST
from Bi.CBiList import CBi_List
from ChanConfig import CChanConfig
from Seg.CSegListChan import CSegListChan
from Seg.CSegConfig import CSeg_Config
from Seg.CSegListDYH import CSeg_List_DYH
from Seg.CSegListDef import CSegListDef
from zs.CZSList import CZS_List
from BuySellPoint.CBSPointList import CBSPointList
from Math.OutlinerDetection import CNormOutlinerDetection


def get_seglist_instance(seg_config: CSeg_Config):
if seg_config.seg_algo == "chan":
return CSegListChan(seg_config)
elif seg_config.seg_algo == "1+1":
return CSeg_List_DYH(seg_config)
elif seg_config.seg_algo == "break":
return CSegListDef(seg_config)
else:
raise Exception(f"unsupport seg algoright:{seg_config.seg_algo}")


class CKline_List:
def __init__(self, kl_type, conf: CChanConfig):
self.kl_type = kl_type
self.config = conf
self.lst = [] # K线列表,可递归 元素KLine类型
self.bi_list = CBi_List(bi_conf=conf.bi_conf)
self.seg_list = get_seglist_instance(seg_config=conf.seg_conf)
self.segseg_list = get_seglist_instance(seg_config=conf.seg_conf)

self.zs_list = CZS_List(zs_config=conf.zs_conf)
self.segzs_list = CZS_List(zs_config=conf.zs_conf)

self.bs_point_lst = CBSPointList(bs_point_config=conf.bs_point_conf)

self.metric_model_lst = conf.GetMetricModel()

od_conf = {"win_width": conf.od_win_width,
"mean_thred": conf.od_mean_thred,
"max_zero_cnt": conf.od_max_zero_cnt,
"skip_zero": conf.od_skip_zero,
}
self.tradeinfo_outlinerdetection_dict = {
metric_name: CNormOutlinerDetection(metric_name, **od_conf) for metric_name in TRADE_INFO_LST
}

if conf.stragety_cls:
self.stragety_cls = conf.stragety_cls(conf)
else:
self.stragety_cls = None

def __getitem__(self, n):
if isinstance(n, int):
return self.lst[n]
elif isinstance(n, slice):
return self.lst[n.start:n.stop:n.step]

def __len__(self):
return len(self.lst)

def cal_seg_and_zs(self):
cal_seg(self.bi_list, self.seg_list)
self.zs_list.cal_bi_zs(self.bi_list, self.seg_list)
cal_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)
cal_zs_in_seg(self.seg_list, self.segseg_list, self.segzs_list) # 计算segseg的zs_lst,以及中枢的bi_in, bi_out

self.cal_klc_in_bi() # 计算每一笔里面的 klc列表
self.figure_bs_point()

def figure_bs_point(self):
self.bs_point_lst.cal(self.bi_list, self.seg_list)

def add_single_klu(self, klu: KLine_Unit):
klu.set_metric(self.metric_model_lst)
klu.update_outliner(self.tradeinfo_outlinerdetection_dict)
if len(self.lst) == 0:
self.lst.append(KLine(klu, idx=0))
else:
_dir = self.lst[-1].try_add(klu)
if _dir != KLINE_DIR.COMBINE: # 不需要合并K线
self.lst.append(KLine(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]):
if self.config.triger_step or (self.stragety_cls is not None and self.stragety_cls.conf.only_judge_last is False): # 回放模式
self.cal_seg_and_zs()
else:
if self.bi_list.try_add_virtual_bi(self.lst[-1]):
if self.config.triger_step or (self.stragety_cls is not None and self.stragety_cls.conf.only_judge_last is False): # 回放模式
self.cal_seg_and_zs()

def klu_iter(self):
for klc in self.lst:
for klu in klc.lst:
yield klu

def cal_klc_in_bi(self):
for bi in self.bi_list:
bi.klc_lst = self[bi.begin_klc.idx:bi.end_klc.idx+1]

def toJson(self):
res = {
"bi_list": self.bi_list.toJson(),
"seg_list": self.seg_list.toJson(),
"zs_list": self.zs_list.toJson(),
"bsp_list": self.bs_point_lst.toJson(),
}
if self.stragety_cls:
res.update({"stragety": self.stragety_cls.toJson()})
return res

def cal_cbsp_summary(self):
if self.stragety_cls:
self.stragety_cls.summary(self)


def cal_seg(bi_list, seg_list):
seg_list.update(bi_list)
# 计算每一笔属于哪个线段
bi_seg_idx_dict = {}
for seg_idx, seg in enumerate(seg_list):
for i in range(seg.start_bi.idx, seg.end_bi.idx+1):
bi_seg_idx_dict[i] = seg_idx
for bi in bi_list:
bi.seg_idx = bi_seg_idx_dict.get(bi.idx, len(seg_list)) # 找不到的应该都是最后一个线段的


def cal_zs_in_seg(bi_list, seg_list, zs_list):
for seg in seg_list:
seg.clear_zs_lst()
for zs in zs_list:
if zs.is_inside(seg):
seg.add_zs(zs)
assert zs.begin_bi.idx > 0
zs.bi_in = bi_list[zs.begin_bi.idx-1]
if zs.end_bi.idx+1 < len(bi_list):
zs.bi_out = bi_list[zs.end_bi.idx+1]
zs.bi_lst = []
for bi in bi_list[zs.begin_bi.idx:zs.end_bi.idx+1]:
zs.bi_lst.append(bi)
34 changes: 34 additions & 0 deletions KLine/CTradeInfo.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
from dataSrc.CommonStockAPI import CCommonStockApi, TRADE_INFO_LST


class CTradeInfo:
def __init__(self, info: dict):
self.metric = {}
self.od_score = {}
self.od_mean = {}
for metric_name in TRADE_INFO_LST:
self.metric[metric_name] = info.get(metric_name, None)
self.od_score[metric_name] = None
self.od_mean[metric_name] = None

def __str__(self):
return " ".join([f"{metric_name}:{value}" for metric_name, value in self.metric.items()])

def toJson(self):
return {
"metric": self.metric,
"od_score": self.od_score,
}

def update_od(self, tradeinfo_outlinerdetection_dict: dict) -> None:
for metric_name, model in tradeinfo_outlinerdetection_dict.items():
self.od_score[metric_name] = model.add(self.metric[metric_name])
self.od_mean[metric_name] = model.mean

def getOutlinearScore(self):
return {
"volume_outlinear_score": self.od_score[CCommonStockApi.FIELD_VOLUME],
"turnover_outlinear_score": self.od_score[CCommonStockApi.FIELD_TURNOVER],
"turnover_rate_outlinear_score": self.od_score[CCommonStockApi.FIELD_TURNRATE],
"turnover_rate": self.metric[CCommonStockApi.FIELD_TURNRATE],
}
Empty file added KLine/__init__.py
Empty file.
Loading

0 comments on commit 0181ac3

Please sign in to comment.