from datetime import timedelta import numpy as np import pandas as pd import talib.abstract as ta from pandas import DataFrame from technical.util import resample_to_interval 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 from chanlun.pipeline.builders.bi import BiBuilderMixin from chanlun.pipeline.builders.bsp import BspBuilderMixin from chanlun.pipeline.builders.incremental import IncrementalBuilderMixin from chanlun.pipeline.builders.indicators import IndicatorsBuilderMixin from chanlun.pipeline.builders.kline import KlineBuilderMixin from chanlun.pipeline.builders.seg import SegBuilderMixin from chanlun.pipeline.builders.zs import ZsBuilderMixin class TF_DF(IndicatorsBuilderMixin, KlineBuilderMixin, BiBuilderMixin, SegBuilderMixin, ZsBuilderMixin, BspBuilderMixin, IncrementalBuilderMixin): def __init__(self, df=None, interval=0, timeframe=None): if df is not None: self.init_TF_DF(df, interval, timeframe) def init_TF_DF(self, df, interval, timeframe): self.timeframe = timeframe self.interval = interval # 检查 DataFrame 是否为空或没有 date 列 if df is None or df.empty: raise ValueError(f"DataFrame for {timeframe} is empty. Please download data first.") if 'date' not in df.columns: raise ValueError(f"DataFrame for {timeframe} missing 'date' column. Columns: {df.columns.tolist()}") # interval=1 时不需要重采样 if interval == 1: self.dataframe = df.copy() else: self.dataframe = resample_to_interval(df, interval) #print(self.timeframe, len(self.dataframe)) self.dataframe = self.add_indicators(self.dataframe) self.klu_list = [] self.klc_list = [] self.bi_list = [] self.zs_list = [] self.bi_zs_list = [] self.bsp_list = [] self.seg_list = [] self.klc_fx_list = [] self.klu_list = self.cal_kl_data(self.dataframe) self.klc_list = self.get_klc_list(self.klu_list) self.bi_list = self.cal_bi_list(self.klc_list) self.bi_zs_list = self.cal_bi_zs_list_pure(self.bi_list) self.seg_list = self.get_seg_list(self.bi_list) self.zs_list = self.get_zs_list(self.bi_list, self.seg_list) self.big_zs_list = self.get_big_zs_list(self.zs_list) # get_klc_list 内已算过 ChanMACD,直接复用 self.chanmacd = getattr(self, '_last_chan_macd', None) if self.chanmacd is None: self.chanmacd = ChanMACD(self.klu_list) self.klu_list = self.chanmacd.klu_list def get_current_klc(self): if len(self.klc_list) > 0: return self.klc_list[-2] return None