"""
原逻辑,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
问题描述: 最近在设计信号,首先就困扰于笔的形成和破坏时机,初步写出一些信号后,观察图形时,有的地方绘图和直观预期有点出入,就花时间对代码进行了调试,遂定位到这个问题。 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注释的地方: