def short(self, cols, strict=True, inplace=False, sig_name=None): rdf = DataFrame() for i in range(1, len(cols)): name = cols[i - 1] + '_' + cols[i] rdf[name] = StockSeries(self.df[cols[i - 1]]).lower_than( self.df[cols[i]], strict) rdf[name] = rdf[name].map(lambda x: True if x == 1 else False) signal = rdf.all(axis=1).map(lambda x: 1 if x is True else 0) if inplace: if sig_name is None: sig_name = 'short_' + '_'.join(cols) self.df[sig_name] = signal else: return StockSeries(signal)
def decrease(self, cols, strict=True, inplace=False, sig_name=None): if isinstance(cols, str): signal = StockSeries(self.df[cols]).increase(strict) else: rdf = DataFrame() for col in cols: rdf[col] = StockSeries(self.df[col]).wave(strict).map( lambda x: True if x < 0 else False) signal = rdf.all(axis=1).map(lambda x: 1 if x is True else 0) if inplace: if sig_name is None: sig_name = 'decrease_' + '_'.join(cols) self.df[sig_name] = signal else: return StockSeries(signal)
def llv(self, n=5, col='close', inplace=False): llv_s = self.df[col].rolling(center=False, window=n).min() col_name = self._get_name(col + '_LLV_' + str(n)) if inplace: self.df[col_name] = llv_s else: return StockSeries(llv_s, col_name)
def hhv(self, n=5, col='close', inplace=False): hhv_s = self.df[col].rolling(center=False, window=n).max() col_name = self._get_name(col + '_HHV_' + str(n)) if inplace: self.df[col_name] = hhv_s else: return StockSeries(hhv_s, col_name)
def expma(self, n=5, col='close', inplace=False): expma_s = round(self.df[col].ewm(span=n, adjust=False).mean(), 2) col_name = self._get_name(col + '_EXPMA_' + str(n)) if inplace: self.df[col_name] = expma_s else: return StockSeries(expma_s, col_name)
def ma(self, n=5, col='close', inplace=False): ma_s = round(self.df[col].rolling(center=False, window=n).mean(), 2) col_name = self._get_name(col + '_MA_' + str(n)) if inplace: self.df[col_name] = ma_s else: return StockSeries(ma_s, col_name)
def __getitem__(self, x): if isinstance(x, str): return StockSeries(self.df[x], x) elif isinstance(x, list): return StockDataFrame(self.df[x]) else: raise OSError('Error: Unexpected index for StockDataFrame.')
def rsi(self, n=6, inplace=False): rsi_n = talib.RSI(tdf['close'].values, timeperiod=n) rsi_s = round(pd.Series(rsi_n, index=self.df.index).fillna(0), 1) col_name = 'RSI_' + str(n) if inplace: self.df[col_name] = rsi_s else: return StockSeries(rsi_s, col_name)
def wr(self, period=14, inplace=False): high = self.df['high'].values low = self.df['low'].values close = self.df['close'].values wr_n = talib.WILLR(high, low, close, period) * -1 wr_s = pd.Series(wr_n, index=self.df.index) col_name = 'WR_' + str(period) if inplace: self.df[col_name] = wr_s else: return StockSeries(wr_s, col_name)
def bbi(self, nums=[3, 6, 12, 24], col='close', inplace=False): ma = DataFrame() for n in nums: ma[n] = round(self.ma(n, col), 2) bbi_s = round(ma[nums].apply(sum, axis=1) / 4, 2) col_name = self._get_name(col + '_BBI_' + str(n)) if inplace: self.df[col_name] = bbi_s else: return StockSeries(bbi_s, col_name)
def _last_min_simple(self, n=3, col='close', inplace=False): # n: 平滑天数,小于n天的波动被忽略 s = self.df[col] l = len(s) keep_wave_days = [0 for _ in range(l)] last_min_s = self.df[col].copy(deep=True) up = True for i in range(1, l): if s[i - 1] < s[i]: if up: keep_wave_days[i] = keep_wave_days[i - 1] + 1 else: keep_wave_days[i] = 1 up = True else: if up: keep_wave_days[i] = -1 up = False else: keep_wave_days[i] = keep_wave_days[i - 1] - 1 for i in range(1, l): if keep_wave_days[i] == 1: if i == 1: last_min_s[i] = last_min_s[i - 1] #NOTE:前一天那轮的连续下跌时间较短,讨论 elif -keep_wave_days[i - 1] < n: last_max_idx = i - 1 - abs(keep_wave_days[i - 1]) last_min_idx = last_max_idx - abs( keep_wave_days[last_max_idx]) # 考虑可能的越界,应该不存在,s[0] = 0 #if last_min_idx < 0: # print(i) # last_min_s[i] = s[i-1] #NOTE: 【前一天(低点)】低于【上轮的低点】,认新低 if s[i - 1] < s[last_min_idx]: last_min_s[i] = s[i - 1] #NOTE: 上一轮的低点更低,前一天认为是短时波动,抹平 else: last_min_s[i] = last_min_s[last_max_idx] #NOTE:前一天那轮的连续下跌超过n天,直接认定前一天为新低 else: last_min_s[i] = s[i - 1] else: last_min_s[i] = last_min_s[i - 1] if inplace: self.df[self._get_name(col + '_LASTMIN_' + str(n))] = last_min_s else: return StockSeries(last_min_s)
def last_max(self, n=5, col='close', inplace=False): # n: 平滑天数,小于n天的波动被忽略 s = self.df[col] l = len(s) keep_wave_days = [0 for _ in range(l)] last_max_s = self.df[col].copy(deep=True) up = True for i in range(1, l): if s[i - 1] < s[i]: if up: keep_wave_days[i] = keep_wave_days[i - 1] + 1 else: keep_wave_days[i] = 1 up = True else: if up: keep_wave_days[i] = -1 up = False else: keep_wave_days[i] = keep_wave_days[i - 1] - 1 for i in range(1, l): if keep_wave_days[i] == -1: if i == 1: last_max_s[i] = last_max_s[i - 1] #NOTE:前一天那轮的连续上涨时间较短,讨论 elif keep_wave_days[i - 1] < n: last_min_idx = i - 1 - abs(keep_wave_days[i - 1]) last_max_idx = last_min_idx - abs( keep_wave_days[last_min_idx]) # 考虑可能的越界 if last_max_idx < 0: print(i) last_max_s[i] = s[i - 1] #NOTE: 【前一天(高点)】高于【上轮的高点】,讨论 if s[i - 1] > s[last_max_idx]: #last_max_s[i] = s[i-1] #NOTE: 看三段的长度是否超过n,如果三短时间很短,并且涨多跌少,讨论 if i-1 - last_max_idx + abs(keep_wave_days[last_max_idx]) < n and \ abs(keep_wave_days[i-1]+keep_wave_days[last_max_idx]) > abs(keep_wave_days[last_min_idx]): #NOTE: 还没涨超【上轮高点】的last_max_s,可能是震荡或慢涨没见顶,先保持之前的last_max_s if s[i - 1] < last_max_s[last_max_idx]: last_max_s[i] = last_max_s[last_min_idx] #NOTE: 涨超了【上轮高点的last_max_s,创新高了直接认 else: last_max_s[i] = s[i - 1] #NOTE:超过n了,认为是确立上涨趋势,上轮下跌是短期波动,直接认新高 else: last_max_s[i] = s[i - 1] #NOTE: 上一轮的高点更高,前一天认为是短时反抽,抹平 else: last_max_s[i] = last_max_s[last_min_idx] #NOTE:前一天那轮的连续上涨超过n天,直接认定前一天为新高 else: last_max_s[i] = s[i - 1] else: last_max_s[i] = last_max_s[i - 1] col_name = self._get_name(col + '_LASTMAX_' + str(n)) if inplace: self.df[col_name] = last_max_s else: return StockSeries(last_max_s, col_name)
def last_min(self, n=5, col='close', inplace=False): # n: 平滑天数,小于n天的波动被忽略 s = self.df[col] l = len(s) keep_wave_days = [0 for _ in range(l)] last_min_s = self.df[col].copy(deep=True) up = True for i in range(1, l): if s[i - 1] < s[i]: if up: keep_wave_days[i] = keep_wave_days[i - 1] + 1 else: keep_wave_days[i] = 1 up = True else: if up: keep_wave_days[i] = -1 up = False else: keep_wave_days[i] = keep_wave_days[i - 1] - 1 for i in range(1, l): if keep_wave_days[i] == 1: if i == 1: last_min_s[i] = last_min_s[i - 1] #NOTE:前一天那轮的连续下跌时间较短,讨论 elif -keep_wave_days[i - 1] < n: last_max_idx = i - 1 - abs(keep_wave_days[i - 1]) last_min_idx = last_max_idx - abs( keep_wave_days[last_max_idx]) # 考虑可能的越界 if last_min_idx < 0: print(i) last_min_s[i] = s[i - 1] #NOTE: 【前一天(低点)】低于【上轮的低点】,讨论 if s[i - 1] < s[last_min_idx]: #last_min_s[i] = s[i-1] #NOTE: 看三段的长度是否超过n,如果三短时间很短,并且跌多涨少,讨论 if i-1 - last_min_idx + abs(keep_wave_days[last_min_idx]) < n and \ abs(keep_wave_days[i-1]+keep_wave_days[last_min_idx]) > keep_wave_days[last_max_idx]: #NOTE: 还没跌超【上轮低点】的last_min_s,可能是震荡或阴跌没见底,先保持之前的last_min_s if s[i - 1] > last_min_s[last_min_idx]: last_min_s[i] = last_min_s[last_max_idx] #NOTE: 跌超了【上轮低点的last_min_s,之前累积的阴跌太多,认低点 else: last_min_s[i] = s[i - 1] #NOTE:超过n了,认为是下跌趋势,上轮上涨是短期波动,直接认新低 else: last_min_s[i] = s[i - 1] #NOTE: 上一轮的低点更低,前一天认为是短时波动,抹平 else: last_min_s[i] = last_min_s[last_max_idx] #NOTE:前一天那轮的连续下跌超过n天,直接认定前一天为新低 else: last_min_s[i] = s[i - 1] else: last_min_s[i] = last_min_s[i - 1] col_name = self._get_name(col + '_LASTMIN_' + str(n)) if inplace: self.df[col_name] = last_min_s else: return StockSeries(last_min_s, col_name)