134 lines
4.6 KiB
Python
134 lines
4.6 KiB
Python
"""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 = 12
|
|
slow = 26
|
|
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))
|