waditu / czsc

缠中说禅技术分析工具;缠论;股票;期货;Quant;量化交易
Other
2.71k stars 941 forks source link

__update_bi函数,未成笔的无包含k数如果小于3则退出,建议放到笔破坏处理的代码后面,具体如下: #117

Open ming-mingxu opened 1 year ago

ming-mingxu commented 1 year ago

问题描述: 最近在设计信号,首先就困扰于笔的形成和破坏时机,初步写出一些信号后,观察图形时,有的地方绘图和直观预期有点出入,就花时间对代码进行了调试,遂定位到这个问题。 000733.SZ,22.8.4 10:00,1分钟基础数据,30分钟k线的更新过程: 同一k,先得到笔结束分型,此时未成笔的无包含k线为3;笔再被破坏(复活),此时最后k一定对前k构成包含,导致此时未成笔的无包含k线数变为2,执行到update_bi里面时,由于len(bars_ubi) < 3,导致本该pop的最后笔没有pop到,继而让后续计算的bars_ubi也少了(没包括最后笔的bars_ubi),最终导致找出来的破坏分型的位置偏移。 写到这里,其实脑袋里面还是没有捋出清晰的全局观,只是些片段,所以还是要感谢作者大佬辛苦提供和维护了这个平台,不容易。 以下是调整了ubi数不够3的判断位置后的代码: 留意ming注释的地方:

        """     
        原逻辑,update_bi时,ubi数不够3就退出。
        向下笔,然后k1,k2,k3先底分型,然后k3再破坏k2,ubi个数就变成2,此时update_bi,由于ubi不够3,所以后面笔破坏,bi_list.pop的代码没执行到,
        后面k4再来,虽然k1,(k2,k3),k4构成了底分型,但由于前面没有pop,后面只用这个底分型,不能成功更新笔
        期望应该是pop后,底分型前向下笔和k1,(k2,k3),k4构成的底分型,新得到一笔,而且此时应不在last_bi_extend状态。
        000733.SZ,22.8.3 14:30 作为 k1,就出现了这个情况
        """
        # ming 20230122 将3k判断后退出的代码移动到笔破坏的判断后面
        # if len(bars_ubi) < 3:
        #     return

        # 查找笔
        if not self.bi_list:
            # 第一个笔的查找
            fxs = check_fxs(bars_ubi)
            if not fxs:
                return

            fx_a = fxs[0]
            fxs_a = [x for x in fxs if x.mark == fx_a.mark]
            for fx in fxs_a:
                if (fx_a.mark == Mark.D and fx.low <= fx_a.low) \
                        or (fx_a.mark == Mark.G and fx.high >= fx_a.high):
                    fx_a = fx
            bars_ubi = [x for x in bars_ubi if x.dt >= fx_a.elements[0].dt]

            bi, bars_ubi_ = check_bi(bars_ubi)
            if isinstance(bi, BI):
                self.bi_list.append(bi)
            self.bars_ubi = bars_ubi_
            return

        last_bi = self.bi_list[-1]

        # 如果上一笔被破坏,将上一笔的bars与bars_ubi进行合并
        if (last_bi.direction == Direction.Up and bars_ubi[-1].high > last_bi.high) \
                or (last_bi.direction == Direction.Down and bars_ubi[-1].low < last_bi.low):
            bars_ubi_a = last_bi.bars[:-1] + [x for x in bars_ubi if x.dt >= last_bi.bars[-1].dt]
            self.bi_list.pop(-1)

            # ming add begin,随着3k判断且退出的后移,这里pop了最后一笔,空出来的ubi要先放好,以免return后丢了
            self.bars_ubi = bars_ubi_a 
            # 笔刚被破坏,后续的分型及成笔处理,本次可以不做了
            return
            #ming add end

        else:
            bars_ubi_a = bars_ubi

        if self.verbose and len(bars_ubi_a) > 100:
            logger.info(
                f"czsc_update_bi: {self.symbol} - {self.freq} - {bars_ubi_a[-1].dt} 未完成笔延伸数量: {len(bars_ubi_a)}")

        # ming 将原代码从上面移动到这里
        if len(bars_ubi) < 3:
            return
zengbin93 commented 1 year ago

@ming-mingxu 在 0.9.7 中修复 https://github.com/waditu/czsc/commit/acebe8c33696dbc2ecb0ebbf5fb4bdaca410bbec