Closed appleman4000 closed 1 week ago
如果新k线,没有触发末尾笔发生变化,是否就不用调整呢 ———————————————————————————————— 就是这样实现的
cal_seg计算是最复杂的,但只做增量计算,可以看下随着数量的增加,它的耗时增加是o(?) CBSPointList.cal这个计算每次计算都有一些涉及到全量计算,这个是已知问题,早期糟糕的设计导致的,调整的话除了比较麻烦外,还会对大家当前查找bsp的使用产生影响。(我记一下,空了可以搞个新分支来看看)
如图耗时对应代码: def cal_seg(bi_list, seg_list): 总耗时:87秒 seg_list.update(bi_list) : 耗时47秒
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.set_seg_idx(bi_seg_idx_dict.get(bi.idx, len(seg_list))) # 找不到的应该都是最后一个线段的
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:
bi.set_seg_idx(cur_seg.idx)
continue
else:
assert cur_seg.pre
cur_seg = cur_seg.pre
bi.set_seg_idx(cur_seg.idx)
简单搞了一版,可以帮忙一起验一下性能和正确性。
可读性还比较差,确认没问题了再慢慢优化。。
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:
bi.set_seg_idx(cur_seg.idx)
continue
更改下先后顺序
if bi.idx >= cur_seg.start_bi.idx:
bi.set_seg_idx(cur_seg.idx)
continue
if bi.idx >= cur_seg.end_bi.idx:
bi.set_seg_idx(cur_seg.idx+1)
continue
之后,和之前版本实验结果一致,且耗时几乎等于0,提升效果明显
顺序不能改,满足后者的一定会满足前者。
顺序不改的 Debug/strategy_demo.py 打印出来的交易记录不一致
昨天那个有点问题,顺序还是不能换,第一个大于等于要改成大于:
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:
bi.set_seg_idx(cur_seg.idx)
continue
可以了,结果一致
还有个优化点: 1、CBSPointList.cal 里面有三类买卖点的计算,这个也可以优化 如果我在config里面只配置了1,1p,是不用计算2和3类买卖点的 对于,只生成一类训练样本场景,可以加速 2、CBSPointList.cal 下面两句代码也是全量遍历,是否可以参考上面你写的思路,逆序+退出条件做增量更新呢
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}
还有个优化点: 1、CBSPointList.cal 里面有三类买卖点的计算,这个也可以优化 如果我在config里面只配置了1,1p,是不用计算2和3类买卖点的 对于,只生成一类训练样本场景,可以加速 2、CBSPointList.cal 下面两句代码也是全量遍历,是否可以参考上面你写的思路,逆序+退出条件做增量更新呢
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}
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]
for i in range(len(self.lst) - 1, -1, -1):
if self.lst[i].klu.idx > self.last_sure_pos:
if self.lst[i].bi.get_end_klu().idx in self.bsp_dict:
del self.bsp_dict[self.lst[i].bi.get_end_klu().idx]
del self.lst[i]
else:
if self.lst[i].bi.get_end_klu().idx not in self.bsp_dict:
self.bsp_dict[self.lst[i].bi.get_end_klu().idx] = self.lst[i]
else:
break
for i in range(len(self.bsp1_lst) - 1, -1, -1):
if self.bsp1_lst[i].klu.idx > self.last_sure_pos:
del self.bsp1_lst[i]
else:
break
if BSP_TYPE.T1 in self.config.b_conf.target_types or BSP_TYPE.T1 in self.config.s_conf.target_types or \
BSP_TYPE.T1P in self.config.b_conf.target_types or BSP_TYPE.T1P in self.config.s_conf.target_types:
self.cal_seg_bs1point(seg_list, bi_list)
if BSP_TYPE.T2 in self.config.b_conf.target_types or BSP_TYPE.T2 in self.config.s_conf.target_types or \
BSP_TYPE.T2S in self.config.b_conf.target_types or BSP_TYPE.T2S in self.config.s_conf.target_types:
self.cal_seg_bs2point(seg_list, bi_list)
if BSP_TYPE.T3A in self.config.b_conf.target_types or BSP_TYPE.T3A in self.config.s_conf.target_types or \
BSP_TYPE.T3B in self.config.b_conf.target_types or BSP_TYPE.T3B in self.config.s_conf.target_types:
self.cal_seg_bs3point(seg_list, bi_list)
self.update_last_pos(seg_list)
我修改了一版,你看下是否可行
1类是无论如何要算的;
2,3类由于可以配置只算2买不算2卖这种,故不适合在cal
中实现;
参见 commit:https://github.com/Vespa314/chan.py/commit/cfc25b053dbe9dbdbf7b6224b81631ccb6c75dbf
report.zip cal_seg和CBSPointList.cal这两个方法,占用了整个耗时的75%以上,具体函数见附件测试报告 可能的原因是,但喂给新K线时,都是全量重新计算笔和线段、线段的线段的对应关系 1、如果新k线,没有触发末尾笔发生变化,是否就不用调整呢 2、如果末尾笔发生变化,可能会触发末尾线段、末尾线段的线段,中枢等连锁触发计算,不应该把所有笔和线段重新遍历一遍(时间复杂度为O(n2))