def macd(close, fast=None, slow=None, signal=None, offset=None, **kwargs): """Indicator: Moving Average, Convergence/Divergence (MACD)""" # Validate arguments fast = int(fast) if fast and fast > 0 else 12 slow = int(slow) if slow and slow > 0 else 26 signal = int(signal) if signal and signal > 0 else 9 if slow < fast: fast, slow = slow, fast close = verify_series(close, max(fast, slow, signal)) offset = get_offset(offset) if close is None: return # Calculate Result if Imports["talib"]: from talib import MACD macd, signalma, histogram = MACD(close, fast, slow) else: fastma = ema(close, length=fast) slowma = ema(close, length=slow) macd = fastma - slowma signalma = ema(close=macd.loc[macd.first_valid_index():, ], length=signal) histogram = macd - signalma # Offset if offset != 0: macd = macd.shift(offset) histogram = histogram.shift(offset) signalma = signalma.shift(offset) # Handle fills if "fillna" in kwargs: macd.fillna(kwargs["fillna"], inplace=True) histogram.fillna(kwargs["fillna"], inplace=True) signalma.fillna(kwargs["fillna"], inplace=True) if "fill_method" in kwargs: macd.fillna(method=kwargs["fill_method"], inplace=True) histogram.fillna(method=kwargs["fill_method"], inplace=True) signalma.fillna(method=kwargs["fill_method"], inplace=True) # Name and Categorize it _props = f"_{fast}_{slow}_{signal}" macd.name = f"MACD{_props}" histogram.name = f"MACDh{_props}" signalma.name = f"MACDs{_props}" macd.category = histogram.category = signalma.category = "momentum" # Prepare DataFrame to return data = { macd.name: macd, histogram.name: histogram, signalma.name: signalma } df = DataFrame(data) df.name = f"MACD{_props}" df.category = macd.category signal_indicators = kwargs.pop("signal_indicators", False) if signal_indicators: signalsdf = concat( [ df, signals( indicator=histogram, xa=kwargs.pop("xa", 0), xb=kwargs.pop("xb", None), xserie=kwargs.pop("xserie", None), xserie_a=kwargs.pop("xserie_a", None), xserie_b=kwargs.pop("xserie_b", None), cross_values=kwargs.pop("cross_values", True), cross_series=kwargs.pop("cross_series", True), offset=offset, ), signals( indicator=macd, xa=kwargs.pop("xa", 0), xb=kwargs.pop("xb", None), xserie=kwargs.pop("xserie", None), xserie_a=kwargs.pop("xserie_a", None), xserie_b=kwargs.pop("xserie_b", None), cross_values=kwargs.pop("cross_values", False), cross_series=kwargs.pop("cross_series", True), offset=offset, ), ], axis=1, ) return signalsdf else: return df
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