def bbands(close, length=None, std=None, mamode=None, ddof=0, offset=None, **kwargs): """Indicator: Bollinger Bands (BBANDS)""" # Validate arguments length = int(length) if length and length > 0 else 5 std = float(std) if std and std > 0 else 2.0 mamode = mamode if isinstance(mamode, str) else "sma" ddof = int(ddof) if ddof >= 0 and ddof < length else 1 close = verify_series(close, length) offset = get_offset(offset) if close is None: return # Calculate Result if Imports["talib"]: from talib import BBANDS upper, mid, lower = BBANDS(close, length) else: standard_deviation = stdev(close=close, length=length, ddof=ddof) deviations = std * standard_deviation # deviations = std * standard_deviation.loc[standard_deviation.first_valid_index():,] mid = ma(mamode, close, length=length, **kwargs) lower = mid - deviations upper = mid + deviations ulr = non_zero_range(upper, lower) bandwidth = 100 * ulr / mid percent = non_zero_range(close, lower) / ulr # Offset if offset != 0: lower = lower.shift(offset) mid = mid.shift(offset) upper = upper.shift(offset) bandwidth = bandwidth.shift(offset) percent = bandwidth.shift(offset) # Handle fills if "fillna" in kwargs: lower.fillna(kwargs["fillna"], inplace=True) mid.fillna(kwargs["fillna"], inplace=True) upper.fillna(kwargs["fillna"], inplace=True) bandwidth.fillna(kwargs["fillna"], inplace=True) percent.fillna(kwargs["fillna"], inplace=True) if "fill_method" in kwargs: lower.fillna(method=kwargs["fill_method"], inplace=True) mid.fillna(method=kwargs["fill_method"], inplace=True) upper.fillna(method=kwargs["fill_method"], inplace=True) bandwidth.fillna(method=kwargs["fill_method"], inplace=True) percent.fillna(method=kwargs["fill_method"], inplace=True) # Name and Categorize it lower.name = f"BBL_{length}_{std}" mid.name = f"BBM_{length}_{std}" upper.name = f"BBU_{length}_{std}" bandwidth.name = f"BBB_{length}_{std}" percent.name = f"BBP_{length}_{std}" upper.category = lower.category = "volatility" mid.category = bandwidth.category = upper.category # Prepare DataFrame to return data = { lower.name: lower, mid.name: mid, upper.name: upper, bandwidth.name: bandwidth, percent.name: percent } bbandsdf = DataFrame(data) bbandsdf.name = f"BBANDS_{length}_{std}" bbandsdf.category = mid.category return bbandsdf
def priceTechnicalIndicator(value, tot_lags, prefix): lags = np.array(tot_lags) lags = lags[lags >= 2] data_result = pd.DataFrame([]) # MA series for lag in lags: # SMA sma = pd.Series(SMA(value, timeperiod=lag), name='%sMA_%dD' % (prefix, lag)) data_result = pd.concat([data_result, sma], axis=1) # SMA derivatives tmp = ma_derivative_indicator(value, sma, 'MA', lag, prefix) data_result = data_result.join(tmp) # EMA ema = pd.Series(EMA(value, lag), name='%sEMA_%dD' % (prefix, lag)) data_result = data_result.join(ema) # EMA derivatives tmp = ma_derivative_indicator(value, ema, 'EMA', lag, prefix) data_result = data_result.join(tmp) # WMA wma = pd.Series(WMA(value, lag), name='%sWMA_%dD' % (prefix, lag)) data_result = data_result.join(wma) # WMA derivatives tmp = ma_derivative_indicator(value, wma, 'WMA', lag, prefix) data_result = data_result.join(tmp) # change percent lags = tot_lags for lag in lags: tmp = pd.Series(value.diff(lag) / value.shift(lag), name='%sRET_%dD' % (prefix, lag)) data_result = data_result.join(tmp) # volatility lags = np.array(tot_lags) lags = lags[lags >= 5] for lag in lags: tmp = pd.Series(value.rolling(window=lag).std(), name='%sSTD_%dD' % (prefix, lag)) data_result = data_result.join(tmp) # technical indicators lags = [7, 14, 21, 28] # ****** 待修改,技术指标的参数只用最常用的一套 for lag in lags: # bollinger brands tmp_upper, tmp_middle, tmp_lower = BBANDS(value, lag, 2, 2) tmp_upper.name = '%sBBANDS_UPPER_%dD' % (prefix, lag) tmp_lower.name = '%sBBANDS_LOWER_%dD' % (prefix, lag) data_result = data_result.join(tmp_upper) data_result = data_result.join(tmp_lower) # MACD tmp, tmp_signal, tmp_hist = MACD(value, 12, 26, lag) tmp.name = '%sMACD_DIF_12_26D' % prefix # macd 对应 macd_dif 线 tmp_signal.name = '%sMACD_DEA_12_26_%dD' % (prefix, lag) # macd_signal 对应 macd_dea 线 tmp_hist = 2 * tmp_hist tmp_hist.name = '%sMACD_12_26_%dD' % (prefix, lag) # 2 * macd_hist 对应 macd 线 if tmp.name not in data_result.columns: # macd_dif is the same for all lags data_result = data_result.join(tmp) data_result = data_result.join(tmp_signal) data_result = data_result.join(tmp_hist) return data_result