"""TF_DF builder mixin — 由 split_tfdf_builders 自动生成,逻辑与原 TF_DF 一致。""" from __future__ import annotations from datetime import timedelta from decimal import Decimal import numpy as np import pandas as pd from pandas import DataFrame from chanlun.core.ChanBI import ChanBI from chanlun.core.ChanBIZS import ChanBIZS from chanlun.core.ChanBSP import ChanBSP from chanlun.core.ChanEnum import ( Chan_BI_DIR, Chan_BSP_DIR, Chan_BSP_TYPE, Chan_FX_TYPE, Chan_K_DIR, Chan_KLC_FX, Chan_KLC_STATE, Chan_KLINE_DIR, Chan_KLU_PATTERN, Chan_PRICE_TREND, Chan_SEG_DIR, Chan_ZS_DIR, ) from chanlun.core.ChanKLC import ChanKLC from chanlun.core.ChanKLU import ChanKLU from chanlun.core.ChanSBI import ChanSBI from chanlun.core.ChanSEG import ChanSEG from chanlun.core.ChanZS import ChanZS, ChanZS_Big from chanlun.indicators.ChanMACD import ChanMACD class SegBuilderMixin: def get_seg_list(self, bi_list): seg_list = [] up_bi_list = [] down_bi_list = [] last_up_bi = None last_down_bi = None last_up_sbi = None last_down_sbi = None last_seg = None up_sbi_list = [] down_sbi_list = [] look_for_bottom = False look_for_top = False for bi in bi_list: #print(len(up_sbi_list), len(down_sbi_list)) if len(seg_list) > 0: # Last seg is up if last_seg.dir == Chan_SEG_DIR.UP: if bi.dir == Chan_BI_DIR.DOWN: if len(down_sbi_list) > 1: # Check down sbi inclusion included = last_down_sbi.check_bi_included(bi) if not included: down_sbi = ChanSBI(bi, len(down_sbi_list), bi.dir) last_down_sbi.set_next(down_sbi) last_down_sbi.set_end_bi(last_down_bi) down_sbi.set_pre(last_down_sbi) down_sbi_list.append(down_sbi) fx = last_down_sbi.check_fx() # Found top if fx == Chan_FX_TYPE.TOP: if look_for_top: seg_list[-2].set_sure(bi) look_for_top = False #print(bi.start_time, look_for_top, "UP 1") # Has gap and search for bottom fx if last_down_sbi.has_fx_gap: look_for_bottom = True last_seg.pre_set_end_bi(bi_list[last_down_sbi.start_bi.index - 1]) seg = ChanSEG(last_down_sbi.start_bi, len(seg_list), Chan_SEG_DIR.DOWN, bi) seg_list.append(seg) last_seg.set_next(seg) seg.set_pre(last_seg) last_seg = seg up_sbi_list = [] last_up_sbi = ChanSBI(last_up_bi, len(up_sbi_list), last_up_bi.dir) up_sbi_list.append(last_up_sbi) #up_sbi_list.append(last_up_sbi) #print(last_up_bi.start_time, last_up_sbi.start_bi.start_time, "Reset up sbi list 1") #print(bi.start_time, look_for_top, "UP 2") # No gap end SEG else: if look_for_bottom: look_for_bottom = False last_seg.set_start_bi(last_down_sbi.start_bi) seg_list[-2].set_end_bi(bi_list[last_down_sbi.start_bi.index - 1], bi) up_sbi_list = [] last_up_sbi = ChanSBI(last_up_bi, len(up_sbi_list), last_up_bi.dir) up_sbi_list.append(last_up_sbi) last_seg.add_bi(bi) #up_sbi_list.append(last_up_sbi) #print(last_up_bi.start_time, last_up_sbi.start_bi.start_time, "Reset up sbi list 2") #print(bi.start_time, look_for_top, "UP 3") else: last_seg.set_end_bi(bi_list[last_down_sbi.start_bi.index - 1], bi) seg = ChanSEG(last_down_sbi.start_bi, len(seg_list), Chan_SEG_DIR.DOWN, bi) seg_list.append(seg) last_seg.set_next(seg) seg.set_pre(last_seg) last_seg = seg #print(last_down_sbi.end_bi.start_time, "Normal UP SEG", last_up_sbi.start_bi.start_time, bi.start_time) #l_up_sbi = up_sbi_list[-1] up_sbi_list = [] last_up_sbi = ChanSBI(last_up_bi, len(up_sbi_list), last_up_bi.dir) up_sbi_list.append(last_up_sbi) #up_sbi_list.append(last_up_sbi) #print(last_up_bi.start_time, last_up_sbi.start_bi.start_time, "Reset up sbi list 3") last_down_sbi = down_sbi last_seg.add_bi(bi) else: if len(down_sbi_list) == 1: included = last_down_sbi.check_bi_included(bi) if not included: down_sbi = ChanSBI(bi, len(down_sbi_list), bi.dir) last_down_sbi.set_next(down_sbi) last_down_sbi.set_end_bi(last_down_bi) down_sbi.set_pre(last_down_sbi) down_sbi_list.append(down_sbi) last_down_sbi = down_sbi #print(bi.start_time, look_for_top, "UP 4") last_seg.add_bi(bi) else: last_down_sbi = ChanSBI(bi, len(down_sbi_list), bi.dir) down_sbi_list.append(last_down_sbi) last_seg.add_bi(bi) #print(bi.start_time, look_for_top, "UP 5") else: if last_up_sbi: included = last_up_sbi.check_bi_included(bi) if not included: up_sbi = ChanSBI(bi, len(up_sbi_list), bi.dir) last_up_sbi.set_next(up_sbi) last_up_sbi.set_end_bi(last_up_bi) up_sbi.set_pre(last_up_sbi) up_sbi_list.append(up_sbi) last_up_sbi = up_sbi #print(bi.start_time, look_for_top, "UP 6") last_seg.add_bi(bi) # Last seg is down else: if bi.dir == Chan_BI_DIR.UP: if len(up_sbi_list) > 1: # Check down sbi inclusion included = last_up_sbi.check_bi_included(bi) if not included: up_sbi = ChanSBI(bi, len(up_sbi_list), bi.dir) last_up_sbi.set_next(up_sbi) last_up_sbi.set_end_bi(last_up_bi) up_sbi.set_pre(last_up_sbi) up_sbi_list.append(up_sbi) fx = last_up_sbi.check_fx() # Found bottom if fx == Chan_FX_TYPE.BOTTOM: if look_for_bottom: seg_list[-2].set_sure(bi) look_for_bottom = False #print(bi.start_time, look_for_top, "DOWN 1") # Has gap and search for bottom fx if last_up_sbi.has_fx_gap: look_for_top = True last_seg.pre_set_end_bi(bi_list[last_up_sbi.start_bi.index - 1]) seg = ChanSEG(last_up_sbi.start_bi, len(seg_list), Chan_SEG_DIR.UP, bi) seg_list.append(seg) last_seg.set_next(seg) seg.set_pre(last_seg) last_seg = seg down_sbi_list = [] last_down_sbi = ChanSBI(last_down_bi, len(down_sbi_list), last_down_bi.dir) down_sbi_list.append(last_down_sbi) #down_sbi_list.append(last_down_sbi) #print(last_down_bi.start_time, last_down_sbi.start_bi.start_time, "Reset down sbi list 1") #print(bi.start_time, look_for_top, "DOWN 2") # No gap end SEG else: if look_for_top: look_for_top = False last_seg.set_start_bi(last_up_sbi.start_bi) seg_list[-2].set_end_bi(bi_list[last_up_sbi.start_bi.index - 1], bi) down_sbi_list = [] last_down_sbi = ChanSBI(last_down_bi, len(down_sbi_list), last_down_bi.dir) down_sbi_list.append(last_down_sbi) last_seg.add_bi(bi) #down_sbi_list.append(last_down_sbi) #print(last_down_bi.start_time, last_down_sbi.start_bi.start_time, "Reset down sbi list 2") #print(bi.start_time, look_for_top, "DOWN 3") else: last_seg.set_end_bi(bi_list[last_up_sbi.start_bi.index - 1], bi) seg = ChanSEG(last_up_sbi.start_bi, len(seg_list), Chan_SEG_DIR.UP, bi) #print(last_up_sbi.start_bi.start_time) last_seg.set_next(seg) seg.set_pre(last_seg) seg_list.append(seg) last_seg = seg #print(last_up_sbi.end_bi.start_time, "Normal DOWN SEG", last_down_sbi.start_bi.start_time, bi.start_time) down_sbi_list = [] last_down_sbi = ChanSBI(last_down_bi, len(down_sbi_list), last_down_bi.dir) down_sbi_list.append(last_down_sbi) #down_sbi_list.append(last_down_sbi) #print(last_down_bi.start_time, last_down_sbi.start_bi.start_time, "Reset down sbi list 3") last_up_sbi = up_sbi last_seg.add_bi(bi) else: if len(up_sbi_list) == 1: #last_up_sbi = up_sbi_list[-1] included = last_up_sbi.check_bi_included(bi) if not included: up_sbi = ChanSBI(bi, len(up_sbi_list), bi.dir) last_up_sbi.set_next(up_sbi) last_up_sbi.set_end_bi(last_up_bi) up_sbi.set_pre(last_up_sbi) up_sbi_list.append(up_sbi) last_up_sbi = up_sbi last_seg.add_bi(bi) #print(bi.start_time, look_for_top, "DOWN 4") else: last_up_sbi = ChanSBI(bi, len(up_sbi_list), bi.dir) up_sbi_list.append(last_up_sbi) last_seg.add_bi(bi) #print(bi.start_time, look_for_top, "DOWN 5") else: if last_down_sbi: included = last_down_sbi.check_bi_included(bi) if not included: down_sbi = ChanSBI(bi, len(down_sbi_list), bi.dir) last_down_sbi.set_next(down_sbi) last_down_sbi.set_end_bi(last_down_bi) down_sbi.set_pre(last_down_sbi) down_sbi_list.append(down_sbi) last_down_sbi = down_sbi last_seg.add_bi(bi) #print(bi.start_time, look_for_top, look_for_bottom, "DOWN 6") # len(seg_list) = 0 else: if bi.check_overlap(): if bi.dir == Chan_BI_DIR.UP: seg = ChanSEG(bi, len(seg_list), Chan_SEG_DIR.UP, bi) last_up_bi = bi last_up_sbi = ChanSBI(bi, len(up_sbi_list), bi.dir) seg_list.append(seg) last_seg = seg #print(bi.start_time, 'Create first UP SEG') else: seg = ChanSEG(bi, len(seg_list), Chan_SEG_DIR.DOWN, bi) last_down_bi = bi last_down_sbi = ChanSBI(bi, len(down_sbi_list), bi.dir) seg_list.append(seg) last_seg = seg #print(bi.start_time, 'Create first DOWN SEG') if bi.dir == Chan_BI_DIR.UP: last_up_bi = bi up_bi_list.append(bi) else: last_down_bi = bi down_bi_list.append(bi) """ if len(seg_list) > 1: seg = seg_list[-1] last_seg = seg_list[-2] last_seg_bi = last_seg.bi_list[-3] bi_index = seg.start_bi.index for i in range(bi_index, len(bi_list) - 1): # last seg is down if seg.dir == Chan_SEG_DIR.UP: if bi_list[i].dir == Chan_BI_DIR.UP: last_seg_peak = last_seg_bi.high if bi_list[i].high > last_seg_peak: # The confirmed print("Last UP seg is broken, create a new seg. 1") seg.pre_set_end_bi(bi_list[i]) seg = ChanSEG(bi_list[i+1], len(seg_list), Chan_SEG_DIR.DOWN, bi) seg_list.append(seg) last_seg = seg_list[-2] if len(last_seg.bi_list) > 3: last_seg_bi = last_seg.bi_list[-3] else: if bi_list[i].dir == Chan_BI_DIR.DOWN: last_seg_peak = last_seg_bi.low if bi_list[i].low < last_seg_peak: print("Last DOWN seg is broken, create a new seg. 1") seg.pre_set_end_bi(bi_list[i]) seg = ChanSEG(bi_list[i+1], len(seg_list), Chan_SEG_DIR.UP, bi) seg_list.append(seg) last_seg = seg_list[-2] if len(last_seg.bi_list) > 3: last_seg_bi = last_seg.bi_list[-3] else: if len(seg_list) == 1: last_seg = seg_list[-1] bi_index = last_seg.bi_list[0].index for i in range(bi_index, len(bi_list) - 1): if i > bi_index + 2: last_seg_peak = bi_list[i-2].high # last seg is down if last_seg.dir == Chan_SEG_DIR.DOWN: if bi_list[i].dir == Chan_BI_DIR.UP: if bi_list[i].high > last_seg_peak: print("Last seg is broken, create a new seg. 2") last_seg.pre_set_end_bi(bi_list[i-1]) seg = ChanSEG(bi_list[i], len(seg_list), Chan_SEG_DIR.UP, bi) seg_list.append(seg) last_seg = seg last_seg_bi = bi_list[i] break """ #self.cal_bi_zs(seg_list) return seg_list