def ar(self, n: int, array: bool = False) -> Union[float, np.ndarray]: """ 人气指数 """ result = (talib.SUM(self.high_array - self.close_array, n) / talib.SUM(self.open_array - self.low_array, n)) * 100 if array: return result return result[-1]
def kdj(self, n, s, f, array=False): """KDJ指标""" c = self.close hhv = self.hhv(n) llv = self.llv(n) shl = talib.SUM(hhv - llv, s) scl = talib.SUM(c - llv, s) k = 100 * shl / scl d = talib.SMA(k, f) j = 3 * k - 2 * d if array: return k, d, j return k[-1], d[-1], j[-1]
def add_stock_index(self, df, index_list=None): close = df["close"] if "MA" in index_list: for p in self.timePeriodList: df["ma" + str(p)] = ta.MA(close, timeperiod=p) df["mam" + str(p)] = mam = df.apply( lambda row: self.mam(row, p), axis=1) df["mam" + str(p) + "_2"] = ta.SUM(mam, timeperiod=2) df["mam" + str(p) + "_3"] = ta.SUM(mam, timeperiod=3) df['vol'] = df['volume'] / ta.MA(df['volume'], timeperiod=60) df['atr'] = ta.ATR(df['high'], df['low'], close, timeperiod=1) / close.shift(1) return df
def chop(candles: np.ndarray, period: int = 14, scalar: float = 100, drift: int = 1, sequential: bool = False) -> Union[float, np.ndarray]: """ Choppiness Index (CHOP) :param candles: np.ndarray :param period: int - default: 30 :param sequential: bool - default=False :return: float | np.ndarray """ candles = slice_candles(candles, sequential) candles_close = candles[:, 2] candles_high = candles[:, 3] candles_low = candles[:, 4] atr_sum = talib.SUM( talib.ATR(candles_high, candles_low, candles_close, timeperiod=drift), period) hh = talib.MAX(candles_high, period) ll = talib.MIN(candles_low, period) res = (scalar * (np.log10(atr_sum) - np.log10(hh - ll))) / np.log10(period) return res if sequential else res[-1]
def __recoundAvgVol(self): """计算平均成交量""" # 1、lineBar满足长度才执行计算 if self.inputVolLen <= 0: # 不计算 return if len(self.lineBar) < self.inputVolLen + 1: self.debugCtaLog(u'数据未充分,当前Bar数据数量:{0},计算Avg Vol需要:{1}'.format( len(self.lineBar), self.inputVolLen + 1)) return if self.mode == self.TICK_MODE: listVol = [ x.volume for x in self.lineBar[-self.inputVolLen - 1:-1] ] else: listVol = [x.volume for x in self.lineBar[-self.inputVolLen:]] sumVol = ta.SUM(numpy.array(listVol, dtype=float), timeperiod=self.inputVolLen)[-1] avgVol = round(sumVol / self.inputVolLen, 0) self.lineAvgVol.append(avgVol)
def ui(candles: np.ndarray, period: int = 14, scalar: float = 100, source_type: str = "close", sequential: bool = False) -> Union[float, np.ndarray]: """ Ulcer Index (UI) :param candles: np.ndarray :param period: int - default: 14 :param scalar: float - default: 100 :param source_type: str - default: "close" :param sequential: bool - default: False :return: float | np.ndarray """ candles = slice_candles(candles, sequential) source = get_candle_source(candles, source_type=source_type) highest_close = talib.MAX(source, period) downside = scalar * (source - highest_close) downside /= highest_close d2 = downside * downside res = np.sqrt(talib.SUM(d2, period) / period) return res if sequential else res[-1]
def Math_Operators(dataframe): #Math Operator Functions #ADD - Vector Arithmetic Add df[f'{ratio}_ADD'] = talib.ADD(High, Low) #c - Vector Arithmetic Div df[f'{ratio}_ADD'] = talib.DIV(High, Low) #MAX - Highest value over a specified period df[f'{ratio}_MAX'] = talib.MAX(Close, timeperiod=30) #MAXINDEX - Index of Highest value over a specified period #integer = MAXINDEX(Close, timeperiod=30) #MIN - Lowest value over a specified period df[f'{ratio}_MIN'] = talib.MIN(Close, timeperiod=30) #MININDEX - Index of Lowest value over a specified period integer = talib.MININDEX(Close, timeperiod=30) #MINMAX - Lowest and Highest values over a specified period min, max = talib.MINMAX(Close, timeperiod=30) #MINMAXINDEX - Indexes of Lowest and Highest values over a specified period minidx, maxidx = talib.MINMAXINDEX(Close, timeperiod=30) #MULT - Vector Arithmetic Mult df[f'{ratio}_MULT'] = talib.MULT(High, Low) #SUB - Vector Arithmetic Substraction df[f'{ratio}_SUB'] = talib.SUB(High, Low) #SUM - Summation df[f'{ratio}_SUM'] = talib.SUM(Close, timeperiod=30) return
def pfe(candles: np.ndarray, period: int = 10, smoothing: int = 5, source_type: str = "close", sequential: bool = False) -> Union[float, np.ndarray]: """ Polarized Fractal Efficiency (PFE) :param candles: np.ndarray :param period: int - default: 10 :param smoothing: int - default: 5 :param source_type: str - default: "close" :param sequential: bool - default=False :return: float | np.ndarray """ candles = slice_candles(candles, sequential) source = get_candle_source(candles, source_type=source_type) ln = period - 1 diff = np.diff(source, ln) a = np.sqrt(np.power(diff, 2) + np.power(period, 2)) b = talib.SUM(np.sqrt(1 + np.power(np.diff(source, 1), 2)), ln) pfetmp = 100 * same_length(source, a) / same_length(source, b) res = talib.EMA(np.where(same_length(source, diff) > 0, pfetmp, -pfetmp), smoothing) return res if sequential else res[-1]
def kamaSignal(self, am, paraDict): kamaFastest = paraDict['kamaFastest'] kamaSlowest = paraDict['kamaSlowest'] kamaPeriod = paraDict['kamaPeriod'] smaPeriod = paraDict['smaPeriod'] if len(self.kamaList) == 0: self.kamaList.append(ta.MA(am.close, kamaPeriod)[-1]) elif len(self.kamaList): change = np.abs(am.close[kamaPeriod:] - am.close[:-kamaPeriod]) volatility = ta.SUM(np.abs(am.close[1:] - am.close[:-1]), kamaPeriod) er = change[-kamaPeriod:] / volatility[-kamaPeriod:] smooth = er[-1] * (2 / (kamaFastest + 1)) + (1 - er[-1]) * ( 2 / (kamaSlowest + 1)) sc = smooth**2 newKama = self.kamaList[-1] + sc * (am.close[-1] - self.kamaList[-1]) self.kamaList.append(newKama) if len(self.kamaList) > (kamaPeriod + 1): self.kamaList.pop(0) sma = ta.MA(am.close, smaPeriod) kamaDirection = 0 if sma[-1] > self.kamaList[-1]: kamaDirection = 1 elif sma[-1] < self.kamaList[-1]: kamaDirection = -1 return kamaDirection, self.kamaList[-1], sma[-1]
def start_5(self, codes, n): time0 = time.time() self.Rice = interface_Rice() self.Record = stock_orderForm() Base = stock_baseInfo() self.dict = Base.getDict(isBound=0) #l = [str(c) for c in self.Rice.getValidDate1(start='1999-01-01', end=public.getDate())] #self.validDates= pd.Series(l,name='date') #print(self.validDates) dfs = self.Rice.get_financials(codes, years=20) for c in codes: if c not in dfs.keys(): continue self.uid = '%s_stock5' % (c) df = dfs[c] df = df.iloc[::-1] df.loc[:, 'code'] = c #df['code'] = c df['date'] = df['announce_date'].apply(lambda x: public.parseTime( str(x), format='%Y%m%d', style='%Y-%m-%d') if not np.isnan(x) else '') df['powm'] = df['adjusted_return_on_equity_diluted'].apply( lambda x: 1 if x >= self.incomeRatioLine else 0) df['sum'] = ta.SUM(df['powm'], timeperiod=5) if self.keyCode == c: print(df) self.saveStage(df) print(n, 'finished time:', time.time() - time0)
def strthindi(bars, timeperiod): rr = bars['Close'].pct_change() # tmp0 = rr[rr > 0] tmp0 = rr.apply(lambda x: x if x > 0 else 0.0) tmp1 = talib.SUM(tmp0.values, timeperiod=timeperiod) tmp1 = pd.Series(tmp1, index=tmp0.index) tmp2 = talib.SUM(rr.abs().values, timeperiod=timeperiod) tmp2 = pd.Series(tmp2, index=rr.index) rrsi = tmp1 / tmp2 rrsi = pd.Series(rrsi, index=rr.index) rrsi.name = bars['code'].iloc[0] rmean = talib.SUM(rr.values, timeperiod=timeperiod) rmean = pd.Series(rmean, index=rr.index) rmean.name = bars['code'].iloc[0] # print(rrsi) # print(type(rrsi)) return rrsi
def handle_bar(context, bar_dict): price = history_bars(context.s1, context.PERIOD + 1, '1d', 'close') volume = history_bars(context.s1, context.PERIOD + 1, '1d', 'volume') denominator = price * volume #!!!talib.SUM是加总函数,这个还从未遇到过;同时注意这里没有用滚动函数,因为该引擎本身就是个循环滚动的 VWAP = talib.SUM(denominator, context.PERIOD) / talib.SUM( volume, context.PERIOD) cur_position = context.portfolio.positions[context.s1].quantity shares = context.portfolio.cash / bar_dict[context.s1].close if price[-1] < VWAP[-1] and cur_position > 0: order_target_value(context.s1, 0) if price[-1] > VWAP[-1]: order_shares(context.s1, shares)
def Cal_ARBR(inputs,N=26): """ BR:=SUM(MAX(0,HIGH-REF(CLOSE,1)),N)/SUM(MAX(0,REF(CLOSE,1)-LOW),N)*100; AR:=SUM(HIGH-OPEN,N)/SUM(OPEN-LOW,N)*100; BR〈40 OR AR<40; """ OPEN = inputs['open'] CLOSE = inputs['close'] HIGH = inputs['high'] LOW = inputs['low'] CLOSE_REF_1 = REF(CLOSE,1) t1 = HIGH-CLOSE_REF_1 t1[t1<0] = 0 t2 = CLOSE_REF_1-LOW t2[t2<0] = 0 BR = talib.SUM(t1,N)/talib.SUM(t2,N)*100.0 AR = talib.SUM(HIGH-OPEN,N) / talib.SUM(OPEN-LOW,N) * 100.0 #ARBR = (BR<40) * (AR<40) return AR,BR
def higher_order_moment(self, moment_order, n, array=False): """因为收益率均值较小,此处返回高阶原点矩""" # 对数收益率序列,长度size-1 log_r = self.log_return(True) # 原点矩 result = talib.SUM(log_r**moment_order, n)/n if array: return result return result[-1]
def __init__(self, series, period): if isinstance(series, NumericSeries): series = series.series try: series[np.isinf(series)] = 0 series = talib.SUM(series, period) except Exception as e: raise FormulaException(e) super(SumSeries, self).__init__(series) self.extra_create_kwargs["period"] = period
def bias_SMA_Accumulated_signal(self, ma_len, window_len, std_n, array=False): """价格-均线l窗口std通道信号""" signal = np.zeros(self.size) bias = self.close - talib.SMA(self.close, ma_len) bias_Accu = talib.SUM(bias, window_len) bias_var = talib.VAR(bias, ma_len) bias_Accu_std = talib.SQRT(talib.SUM(bias_var, window_len)) for i in range(self.size): if bias_Accu[i] > std_n * bias_Accu_std[i]: signal[i] = 1 elif bias_Accu[i] < -1 * std_n * bias_Accu_std[i]: signal[i] = -1 else: signal[i] = 0 if array: return signal return signal[-1]
def std_zdf_tp(df0, n, m, l): df = df0.copy() df['tp'] = 0 df['bd'] = df['close'] - df['open'] df['std'] = talib.STDDEV(df['bd'], n) * m df.loc[df['bd'] > df['std'], 'tp'] = 1 df['tp'] = talib.SUM(df['tp'], l) return df['tp']
def SUM(close, timeperiod=30): ''' Summation 周期内求和 分组: Math Operator 数学运算符 简介: real = SUM(close, timeperiod=30) ''' return talib.SUM(close, timeperiod)
def Cal_VR(inputs,N=26, M=6): """ TH:=SUM(IF(CLOSE>REF(CLOSE,1),VOL,0),N); TL:=SUM(IF(CLOSE<REF(CLOSE,1),VOL,0),N); TQ:=SUM(IF(CLOSE=REF(CLOSE,1),VOL,0),N); VR:100*(TH*2+TQ)/(TL*2+TQ); MAVR:MA(VR,M); """ CLOSE = inputs['close'] CLOSE_REF_1 = REF(CLOSE,1) VOL = inputs['volume'] TH = talib.SUM( ( CLOSE>CLOSE_REF_1 ) * VOL, N) TL = talib.SUM( ( CLOSE<CLOSE_REF_1 ) * VOL, N) TQ = talib.SUM( ( CLOSE==CLOSE_REF_1 ) * VOL, N) VR = 100*(TH*2+TQ)/(TL*2+TQ) if sum(np.isnan(VR))==len(VR): MAVR=np.zeros(VR.shape) * np.nan else: MAVR=talib.SMA(VR, M) return VR,MAVR
def Cal_PSY(inputs,N=12,M=6): """ PSY:COUNT(CLOSE>REF(CLOSE,1),N)/N*100; PSYMA:MA(PSY,M); """ CLOSE = inputs['close'] NN = min(len(CLOSE),N) #PSY = sum((CLOSE>REF(CLOSE,1))[-1*NN:]) / NN * 100.0 if NN<2: PSY = np.array([0.0]) else: PSY = talib.SUM( 1.0*(CLOSE>REF(CLOSE,1)), NN) / NN * 100.0 return PSY
def rebalance(context, data): history = data.history(assets=context.asset, fields=['open', 'high', 'low', 'close'], bar_count=context.bar_count, frequency='1d') date = history.index.values[-1] open = history['open'].values high = history['high'].values low = history['low'].values HO = high - open OL = open - low ar = ta.SUM(HO, timeperiod=context.period) / ta.SUM( OL, timeperiod=context.period) * 100 buy_signal_triggered = False sell_signal_triggered = False price = data[context.asset].price record(price=price) if ar[-1] < context.over_sell: buy_signal_triggered = True elif ar[-1] > context.over_buy: sell_signal_triggered = True current_position = context.portfolio.positions[context.asset].amount if buy_signal_triggered and current_position == 0: print(str(date) + '==>Buy') order_target_percent(context.asset, 0.5) elif sell_signal_triggered and current_position > 0: print(str(date) + '==>Sell') order_target_percent(context.asset, 0.0) else: print("No trading")
def feature(self, data_fed, nperiod): stk_data = data_fed['tick_data'].dropna() price_series = stk_data['Mid'].astype(float) if len(price_series) < 1: return price_series n = nperiod N = nperiod * 3 price = price_series.values ref_price = price_series.shift(1).fillna(0).values res = ta.SUM((price > ref_price).astype(float), N) res = np.where(np.isfinite(res), res, 0) result = pd.Series(ta.MA(res, N), index=price_series.index) return result
def dsEnvUp(self, am, paraDict): dsPeriod = paraDict['dsPeriod'] dsSmaPeriod = paraDict['dsSmaPeriod'] dsLmaPeriod = paraDict['dsLmaPeriod'] dsthreshold = paraDict['dsThreshold'] density = (ta.MAX(am.high, dsPeriod)-ta.MIN(am.low, dsPeriod))/ta.SUM(am.high-am.low, dsPeriod) dsSma = ta.EMA(density, dsSmaPeriod) dsLma = ta.MA(density, dsLmaPeriod) dsUp = dsSma[-1]>dsLma[-1] dsCan = (dsSma[-1]>dsthreshold) dsTrendEnv = True if dsUp and dsCan else False return dsTrendEnv, dsSma, dsLma
def mab(candles: np.ndarray, fast_period: int = 10, slow_period: int = 50, devup: float = 1, devdn: float = 1, fast_matype: int = 0, slow_matype: int = 0, source_type: str = "close", sequential: bool = False) -> MAB: """ Moving Average Bands :param candles: np.ndarray :param fast_period: int - default: 10 :param slow_period: int - default: 50 :param devup: float - default: 1 :param devdn: float - default: 1 :param fast_matype: int - default: 0 :param slow_matype: int - default: 0 :param source_type: str - default: "close" :param sequential: bool - default: False :return: MAB(upperband, middleband, lowerband) """ candles = slice_candles(candles, sequential) source = get_candle_source(candles, source_type=source_type) fastEma = ma(source, period=fast_period, matype=fast_matype, sequential=True) slowEma = ma(source, period=slow_period, matype=slow_matype, sequential=True) sqAvg = talib.SUM(np.power(fastEma - slowEma, 2), fast_period) / fast_period dev = np.sqrt(sqAvg) middlebands = fastEma upperbands = slowEma + devup * dev lowerbands = slowEma - devdn * dev if sequential: return MAB(upperbands, middlebands, lowerbands) else: return MAB(upperbands[-1], middlebands[-1], lowerbands[-1])
def moveff(bars, timeperiod, col='Close'): mov = np.diff(bars[col].values) # 执行的是后一个元素减去前一个元素 mov = np.abs(mov) mov = np.insert(mov, 0, np.NaN) # print(mov[:10]) movpath = talib.SUM(mov, timeperiod=timeperiod) # print(movpath[:10]) movrange = talib.MAX(bars[col].values, timeperiod=timeperiod) - \ talib.MIN(bars[col].values, timeperiod=timeperiod) # print(movrange[:10]) moveff_ = movrange / movpath moveff_ = pd.Series(moveff_, index=bars.index) moveff_.name = bars['code'].iloc[0] # print(moveff_) return moveff_
def feature(self, data_fed, nperiod): stk_data = data_fed['tick_data'].dropna() tran_vol = stk_data['TransactionVol'].astype(float) price_series = stk_data['Mid'].astype(float) N = nperiod * 3 M = nperiod if len(tran_vol) < 1: return tran_vol ref_price = price_series.shift(1).fillna(0) VA = np.sign(price_series.values - ref_price.values) * tran_vol.values OBV = ta.SUM(VA, M) MAOBV = ta.MA(OBV, N) STDOBV = ta.STDDEV(OBV, N) res = pd.Series((OBV - MAOBV)) / pd.Series(STDOBV) result = pd.Series(array_clean(res.values), index=price_series.index) return result
def dsEnv(self, am, paraDict): dsPeriod = paraDict['dsPeriod'] dsSmaPeriod = paraDict['dsSmaPeriod'] dsLmaPeriod = paraDict['dsLmaPeriod'] dsthreshold = paraDict['dsThreshold'] density = (ta.MAX(am.high, dsPeriod) - ta.MIN( am.low, dsPeriod)) / ta.SUM(am.high - am.low, dsPeriod) dsSma = ta.MA(density, dsSmaPeriod) dsLma = ta.MA(density, dsLmaPeriod) dsUp = dsSma[-1] > dsLma[-1] dsCan = dsSma[-1] > dsthreshold preferTrade = dsUp and dsCan canTrade = dsCan return preferTrade, canTrade, dsSma, dsLma
def erSignalCal(self, am, paraDict): atrPeriod = paraDict['atrPeriod'] er_atrPeriod = paraDict['er_atrPeriod'] erThreshold_low = paraDict['erThreshold_low'] erThreshold_high = paraDict['erThreshold_high'] erMaPeriod = paraDict['erMaPeriod'] erPeriod = int(er_atrPeriod * atrPeriod) direction = ta.MOM(am.close, erPeriod) volatility = ta.SUM(np.abs(ta.MOM(am.close, 1)), erPeriod) er = direction / volatility erMa = ta.MA(er, erMaPeriod) if erMa[-1] >= erThreshold_low and erMa[-1] <= erThreshold_high: erSignal = 1 elif erMa[-1] <= -erThreshold_low and erMa[-1] >= -erThreshold_high: erSignal = -1 else: erSignal = 0 return erSignal, er
def maaq(candles: np.ndarray, period: int = 11, fast_period: int = 2, slow_period: int = 30, source_type: str = "close", sequential: bool = False) -> Union[float, np.ndarray]: """ Moving Average Adaptive Q :param candles: np.ndarray :param period: int - default: 11 :param fast_period: int - default: 2 :param slow_period: int - default: 30 :param source_type: str - default: "close" :param sequential: bool - default: False :return: float | np.ndarray """ # Accept normal array too. if len(candles.shape) == 1: source = candles else: candles = slice_candles(candles, sequential) source = get_candle_source(candles, source_type=source_type) source = source[~np.isnan(source)] diff = np.abs(source - np_shift(source, 1, np.nan)) signal = np.abs(source - np_shift(source, period, np.nan)) noise = talib.SUM(diff, period) with np.errstate(divide='ignore'): ratio = np.where(noise == 0, 0, signal / noise) fastSc = 2 / (fast_period + 1) slowSc = 2 / (slow_period + 1) temp = np.power((ratio * fastSc) + slowSc, 2) res = maaq_fast(source, temp, period) res = same_length(candles, res) return res if sequential else res[-1]
def calExitFilter(self, am, kind, period, threshold, cmiMAPeriod, gene4): if kind == 0: self.exitFilter = 1 elif kind == 1: self.exitFilter = 1 if (ta.ADX(am.high, am.low, am.close, period)[-1] > threshold) else 0 elif kind == 2: diff = np.insert(abs(am.close[period:] - am.close[:-period]), 0, [0 for _ in range(period)]) de = np.insert(ta.SUM(abs(am.close[1:] - am.close[:-1]), period), 0, 0) ER = ta.DIV(diff, de) * 100 self.exitFilter = 1 if (ER[-1] > threshold) else 0 elif kind == 3: diff = np.insert(abs(am.close[period:] - am.close[:-period]), 0, [0 for _ in range(period)]) de = ta.MAX(am.close, period) - ta.MIN(am.close, period) cmi = ta.MA(ta.DIV(diff, de) * 100, cmiMAPeriod) self.exitFilter = 1 if (cmi[-1] > threshold) else 0