def entropy(close, length=None, base=None, offset=None, **kwargs): """Indicator: Entropy (ENTP)""" # Validate Arguments length = int(length) if length and length > 0 else 10 base = float(base) if base and base > 0 else 2.0 close = verify_series(close, length) offset = get_offset(offset) if close is None: return # Calculate Result p = close / close.rolling(length).sum() entropy = (-p * npLog(p) / npLog(base)).rolling(length).sum() # Offset if offset != 0: entropy = entropy.shift(offset) # Handle fills if "fillna" in kwargs: entropy.fillna(kwargs["fillna"], inplace=True) if "fill_method" in kwargs: entropy.fillna(method=kwargs["fill_method"], inplace=True) # Name & Category entropy.name = f"ENTP_{length}" entropy.category = "statistics" return entropy
def log_max_drawdown(close: Series) -> float: """Log Max Drawdown of a series. Args: close (pd.Series): Series of 'close's >>> result = ta.log_max_drawdown(close) """ close = verify_series(close) log_return = npLog(close.iloc[-1]) - npLog(close.iloc[0]) return log_return - max_drawdown(close, method="log")
def log_geometric_mean(series: Series) -> float: """Returns the Logarithmic Geometric Mean""" n = series.size if n < 2: return 0 else: series = series.fillna(0) + 1 if npAll(series > 0): return npExp(npLog(series).sum() / n) - 1 return 0
def entropy(close, length=None, base=None, offset=None, **kwargs): """Indicator: Entropy (ENTP)""" # Validate Arguments close = verify_series(close) length = int(length) if length and length > 0 else 10 base = float(base) if base and base > 0 else 2. offset = get_offset(offset) # Calculate Result p = close / close.rolling(length).sum() entropy = (-p * npLog(p) / npLog(base)).rolling(length).sum() # Offset if offset != 0: entropy = entropy.shift(offset) # Name & Category entropy.name = f"ENTP_{length}" entropy.category = "statistics" return entropy
def jma(close, length=None, phase=None, offset=None, **kwargs): """Indicator: Jurik Moving Average (JMA)""" # Validate Arguments _length = int(length) if length and length > 0 else 7 phase = float(phase) if phase and phase != 0 else 0 close = verify_series(close, _length) offset = get_offset(offset) if close is None: return # Define base variables jma = npZeroslike(close) volty = npZeroslike(close) v_sum = npZeroslike(close) kv = det0 = det1 = ma2 = 0.0 jma[0] = ma1 = uBand = lBand = close[0] # Static variables sum_length = 10 length = 0.5 * (_length - 1) pr = 0.5 if phase < -100 else 2.5 if phase > 100 else 1.5 + phase * 0.01 length1 = max((npLog(npSqrt(length)) / npLog(2.0)) + 2.0, 0) pow1 = max(length1 - 2.0, 0.5) length2 = length1 * npSqrt(length) bet = length2 / (length2 + 1) beta = 0.45 * (_length - 1) / (0.45 * (_length - 1) + 2.0) m = close.shape[0] for i in range(1, m): price = close[i] # Price volatility del1 = price - uBand del2 = price - lBand volty[i] = max(abs(del1),abs(del2)) if abs(del1)!=abs(del2) else 0 # Relative price volatility factor v_sum[i] = v_sum[i - 1] + (volty[i] - volty[max(i - sum_length, 0)]) / sum_length avg_volty = npAverage(v_sum[max(i - 65, 0):i + 1]) d_volty = 0 if avg_volty ==0 else volty[i] / avg_volty r_volty = max(1.0, min(npPower(length1, 1 / pow1), d_volty)) # Jurik volatility bands pow2 = npPower(r_volty, pow1) kv = npPower(bet, npSqrt(pow2)) uBand = price if (del1 > 0) else price - (kv * del1) lBand = price if (del2 < 0) else price - (kv * del2) # Jurik Dynamic Factor power = npPower(r_volty, pow1) alpha = npPower(beta, power) # 1st stage - prelimimary smoothing by adaptive EMA ma1 = ((1 - alpha) * price) + (alpha * ma1) # 2nd stage - one more prelimimary smoothing by Kalman filter det0 = ((price - ma1) * (1 - beta)) + (beta * det0) ma2 = ma1 + pr * det0 # 3rd stage - final smoothing by unique Jurik adaptive filter det1 = ((ma2 - jma[i - 1]) * (1 - alpha) * (1 - alpha)) + (alpha * alpha * det1) jma[i] = jma[i-1] + det1 # Remove initial lookback data and convert to pandas frame jma[0:_length - 1] = npNaN jma = Series(jma, index=close.index) # Offset if offset != 0: jma = jma.shift(offset) # Handle fills if "fillna" in kwargs: jma.fillna(kwargs["fillna"], inplace=True) if "fill_method" in kwargs: jma.fillna(method=kwargs["fill_method"], inplace=True) # Name & Category jma.name = f"JMA_{_length}_{phase}" jma.category = "overlap" return jma
def log_max_drawdown(close:Series): """Log Max Drawdown of a series.""" close = verify_series(close) log_return = npLog(close.iloc[-1]) - npLog(close.iloc[0]) return log_return - max_drawdown(close, method="log")