"""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 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 class IndicatorsBuilderMixin: def get_ema52(self, index=-1): if self.klu_list: ema52_value = self.klu_list[index].ema52 # 处理NaN值 if pd.isna(ema52_value) or ema52_value is None: return None return float(ema52_value) return None def get_ema24(self, index=-1): if self.klu_list: ema24_value = self.klu_list[index].ema24 # 处理NaN值 if pd.isna(ema24_value) or ema24_value is None: return None return float(ema24_value) return None def add_indicators(self, df): fast = 26 slow = 52 period = 9 macd = ta.MACD(df, fastperiod=fast, slowperiod=slow, signalperiod=period) bb365 = ta.BBANDS(df, timeperiod=365, nbdevup=3.0, nbdevdn=3.0, matype=0) bb120 = ta.BBANDS(df, timeperiod=120, nbdevup=3.0, nbdevdn=3.0, matype=0) bb30 = ta.BBANDS(df, timeperiod=41, nbdevup=2.3, nbdevdn=2.3, matype=0) bb302 = ta.BBANDS(df, timeperiod=41, nbdevup=2.0, nbdevdn=2.0, matype=0) bb30 = ta.BBANDS(df, timeperiod=20, nbdevup=2.0, nbdevdn=2.0, matype=0) bb302 = ta.BBANDS(df, timeperiod=20, nbdevup=2.0, nbdevdn=2.0, matype=0) bb2633 = ta.BBANDS(df, timeperiod=26, nbdevup=3.0, nbdevdn=3.0, matype=0) # 计算布林带中轨(移动平均线) bb30_middle = ta.SMA(df, timeperiod=90) # 手动计算布林带 %B 指标 (BBP) # %B = (Price - Lower Band) / (Upper Band - Lower Band) bbp365 = (df['close'] - bb365['lowerband']) / (bb365['upperband'] - bb365['lowerband']) bbp120 = (df['close'] - bb120['lowerband']) / (bb120['upperband'] - bb120['lowerband']) bbp30 = (df['close'] - bb30['lowerband']) / (bb30['upperband'] - bb30['lowerband']) bbp302 = (df['close'] - bb302['lowerband']) / (bb302['upperband'] - bb302['lowerband']) bbp2633 = (df['close'] - bb2633['lowerband']) / (bb2633['upperband'] - bb2633['lowerband']) df['bb2633upper'] = bb2633['upperband'] df['bb2633lower'] = bb2633['lowerband'] df['bbp2633'] = bbp2633 df['bb2633middle'] = bb2633['middleband'] df['atr'] = ta.ATR(df, timeperiod=14) df['bbup365'] = bb365['upperband'] df['bblow365'] = bb365['lowerband'] df['bbp365'] = bbp365 df['bbup120'] = bb120['upperband'] df['bblow120'] = bb120['lowerband'] df['bbp120'] = bbp120 df['bbup30'] = bb30['upperband'] df['bblow30'] = bb30['lowerband'] df['bbmiddle30'] = bb30_middle # 添加bb30中轨 df['bbp30'] = bbp30 df['bbup302'] = bb302['upperband'] df['bblow302'] = bb302['lowerband'] df['bbp302'] = bbp302 df['macd'] = macd['macd'] df['macdsignal'] = macd['macdsignal'] df['macdhist'] = macd['macdhist'] df['ema5'] = ta.EMA(df, timeperiod=5) df['ema10'] = ta.EMA(df, timeperiod=10) df['ema24'] = ta.EMA(df, timeperiod=24) df['ema52'] = ta.EMA(df, timeperiod=52) df['ema104'] = ta.EMA(df, timeperiod=104) df['ema156'] = ta.EMA(df, timeperiod=156) df['ema208'] = ta.EMA(df, timeperiod=208) df['ema26'] = ta.EMA(df, timeperiod=26) df['ema13'] = ta.EMA(df, timeperiod=13) df['ema7'] = ta.EMA(df, timeperiod=7) df['rsi'] = ta.RSI(df, timeperiod=14) df['volume_ratio'] = self.cal_volume_ratio(df) return df def get_ema_state(self, dataframe): klu_list = self.get_klu_list(dataframe) klc_list = self.get_klc_list(klu_list) bi_list = self.cal_bi_list(klc_list) klu_state_list = [] for klu in klu_list: if klu.near0_return == 1: klu_state_list.append("1") elif klu.near0_return == 9: klu_state_list.append("-1") elif klu.candle_dir == Chan_K_DIR.BULL: klu_state_list.append("2") elif klu.candle_dir == Chan_K_DIR.BEAR: klu_state_list.append("-2") else: klu_state_list.append("0") return klu_state_list def get_decimal(self, value): return Decimal("{:.2f}".format(value))