mirror of
https://github.com/wassname/pandas-ta.git
synced 2026-09-09 11:28:26 +08:00
BLD ehlers super smoother filter added
This commit is contained in:
@@ -461,7 +461,7 @@ print(bothhl2.name) # "pre_HL2_post"
|
||||
|:--------:|
|
||||
|  |
|
||||
|
||||
### **Overlap** (27)
|
||||
### **Overlap** (28)
|
||||
|
||||
* _Double Exponential Moving Average_: **dema**
|
||||
* _Exponential Moving Average_: **ema**
|
||||
@@ -482,6 +482,7 @@ print(bothhl2.name) # "pre_HL2_post"
|
||||
* _WildeR's Moving Average_: **rma**
|
||||
* _Sine Weighted Moving Average_: **sinwma**
|
||||
* _Simple Moving Average_: **sma**
|
||||
* _Ehler's Super Smoother Filter_: **ssf**
|
||||
* _Supertrend_: **supertrend**
|
||||
* _Symmetric Weighted Moving Average_: **swma**
|
||||
* _T3 Moving Average_: **t3**
|
||||
@@ -621,6 +622,7 @@ trading account, or fund..
|
||||
* _Quantitative Qualitative Estimation_ (**qqe**) The Quantitative Qualitative Estimation (QQE) is like SuperTrend for a Smoothed RSI. See: ```help(ta.qqe)```
|
||||
* _SMI Ergodic_ (**smi**) Developed by William Blau, the SMI Ergodic Indicator is the same as the True Strength Index (TSI) except the SMI includes a signal line and oscillator.
|
||||
* _Squeeze_ (**squeeze**). A Momentum indicator. Both John Carter's TTM **and** Lazybear's TradingView versions are implemented. The default is John Carter's, or ```lazybear=False```. Set ```lazybear=True``` to enable Lazybear's.
|
||||
* _Ehler's Super Smoother Filter_ (**ssf**). Ehler's solution to reduce lag and remove aliasing noise compared to other common moving average indicators. See: ```help(ta.ssf)```
|
||||
* _Stochastic RSI_ (**stochrsi**) "Stochastic RSI and Dynamic Momentum Index" was created by Tushar Chande and Stanley Kroll. In line with Trading View's calculation. See: ```help(ta.stochrsi)```
|
||||
* _TTM Trend_ (**ttm_trend**). A trend indicator inspired from John Carter's book "Mastering the Trade"
|
||||
issue of Stocks & Commodities Magazine. It is a moving average based trend
|
||||
|
||||
@@ -49,21 +49,21 @@ Category = {
|
||||
"overlap": [
|
||||
"dema", "ema", "fwma", "hilo", "hl2", "hlc3", "hma", "ichimoku",
|
||||
"kama", "linreg", "midpoint", "midprice", "ohlc4", "pwma", "rma",
|
||||
"sinwma", "sma", "supertrend", "swma", "t3", "tema", "trima", "vwap",
|
||||
"vwma", "wcp", "wma", "zlma"
|
||||
"sinwma", "sma", "ssf", "supertrend", "swma", "t3", "tema", "trima",
|
||||
"vwap", "vwma", "wcp", "wma", "zlma"
|
||||
],
|
||||
# Performance
|
||||
"performance": ["log_return", "percent_return", "trend_return"],
|
||||
# Statistics
|
||||
"statistics": [
|
||||
"entropy", "kurtosis", "mad", "median", "quantile", "skew",
|
||||
"stdev", "variance", "zscore"
|
||||
"entropy", "kurtosis", "mad", "median", "quantile", "skew", "stdev",
|
||||
"variance", "zscore"
|
||||
],
|
||||
# Trend
|
||||
"trend": [
|
||||
"adx", "amat", "aroon", "chop", "cksp", "decay", "decreasing",
|
||||
"dpo", "increasing", "long_run", "psar", "qstick", "short_run",
|
||||
"ttm_trend", "vortex"
|
||||
"adx", "amat", "aroon", "chop", "cksp", "decay", "decreasing", "dpo",
|
||||
"increasing", "long_run", "psar", "qstick", "short_run", "ttm_trend",
|
||||
"vortex"
|
||||
],
|
||||
# Volatility
|
||||
"volatility": [
|
||||
|
||||
@@ -1057,6 +1057,11 @@ class AnalysisIndicators(BasePandasObject):
|
||||
result = sma(close=close, length=length, offset=offset, **kwargs)
|
||||
return self._post_process(result, **kwargs)
|
||||
|
||||
def ssf(self, length=None, poles=None, offset=None, **kwargs):
|
||||
close = self._get_column(kwargs.pop("close", "close"))
|
||||
result = ssf(close=close, length=length, poles=poles, offset=offset, **kwargs)
|
||||
return self._post_process(result, **kwargs)
|
||||
|
||||
def supertrend(self, length=None, multiplier=None, offset=None, **kwargs):
|
||||
high = self._get_column(kwargs.pop("high", "high"))
|
||||
low = self._get_column(kwargs.pop("low", "low"))
|
||||
|
||||
@@ -16,6 +16,7 @@ from .pwma import pwma
|
||||
from .rma import rma
|
||||
from .sinwma import sinwma
|
||||
from .sma import sma
|
||||
from .ssf import ssf
|
||||
from .supertrend import supertrend
|
||||
from .swma import swma
|
||||
from .t3 import t3
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from numpy import cos as npCos
|
||||
from numpy import exp as npExp
|
||||
from numpy import pi as npPi
|
||||
from numpy import sqrt as npSqrt
|
||||
from pandas import Series
|
||||
from pandas_ta.utils import get_offset, verify_series
|
||||
|
||||
|
||||
def ssf(close, length=None, poles=None, offset=None, **kwargs):
|
||||
"""Indicator: Ehler's Super Smoother Filter (SSF)"""
|
||||
# Validate Arguments
|
||||
close = verify_series(close)
|
||||
length = int(length) if length and length > 0 else 10
|
||||
poles = int(poles) if poles in [2, 3] else 2
|
||||
offset = get_offset(offset)
|
||||
|
||||
# Calculate Result
|
||||
m = close.size
|
||||
ssf = close.copy()
|
||||
ssf[poles:] = 0
|
||||
|
||||
if poles == 3:
|
||||
x = npPi / length # x = PI / n
|
||||
a0 = npExp(-x) # e^(-x)
|
||||
b0 = 2 * a0 * npCos(npSqrt(3) * x) # 2e^(-x)*cos(3^(.5) * x)
|
||||
c0 = a0 * a0 # e^(-2x)
|
||||
|
||||
c4 = c0 * c0 # e^(-4x)
|
||||
c3 = -c0 * (1 + b0) # -e^(-2x) * (1 + 2e^(-x)*cos(3^(.5) * x))
|
||||
c2 = c0 + b0 # e^(-2x) + 2e^(-x)*cos(3^(.5) * x)
|
||||
c1 = 1 - c2 - c3 - c4
|
||||
|
||||
for i in range(0, m):
|
||||
ssf.iloc[i] = c1 * close.iloc[i] + c2 * ssf.iloc[i - 1] + c3 * ssf.iloc[i - 2] + c4 * ssf.iloc[i - 3]
|
||||
|
||||
else: # poles == 2
|
||||
x = npPi * npSqrt(2) / length # x = PI * 2^(.5) / n
|
||||
a0 = npExp(-x) # e^(-x)
|
||||
a1 = -a0 * a0 # -e^(-2x)
|
||||
b1 = 2 * a0 * npCos(x) # 2e^(-x)*cos(x)
|
||||
c1 = 1 - a1 - b1 # e^(-2x) - 2e^(-x)*cos(x) + 1
|
||||
|
||||
for i in range(0, m):
|
||||
ssf.iloc[i] = c1 * close.iloc[i] + b1 * ssf.iloc[i - 1] + a1 * ssf.iloc[i - 2]
|
||||
|
||||
# Offset
|
||||
if offset != 0:
|
||||
ssf = ssf.shift(offset)
|
||||
|
||||
# Name & Category
|
||||
ssf.name = f"SSF_{length}_{poles}"
|
||||
ssf.category = "overlap"
|
||||
|
||||
return ssf
|
||||
|
||||
|
||||
ssf.__doc__ = \
|
||||
"""Ehler's Super Smoother Filter (SSF)
|
||||
|
||||
Ehler's solution to reduce lag and remove aliasing noise with his research in
|
||||
aerospace analog filter design. © 2013 John F. Ehlers
|
||||
|
||||
Sources:
|
||||
http://www.stockspotter.com/files/PredictiveIndicators.pdf
|
||||
https://www.tradingview.com/script/VdJy0yBJ-Ehlers-Super-Smoother-Filter/
|
||||
https://www.mql5.com/en/code/588
|
||||
https://www.mql5.com/en/code/589
|
||||
|
||||
Calculation:
|
||||
Default Inputs:
|
||||
length=10, poles=[2, 3]
|
||||
|
||||
Args:
|
||||
close (pd.Series): Series of 'close's
|
||||
length (int): It's period. Default: 10
|
||||
poles (int): The number of poles to use, either 2 or 3. Default: 2
|
||||
offset (int): How many periods to offset the result. Default: 0
|
||||
|
||||
Kwargs:
|
||||
fillna (value, optional): pd.DataFrame.fillna(value)
|
||||
fill_method (value, optional): Type of fill method
|
||||
|
||||
Returns:
|
||||
pd.Series: New feature generated.
|
||||
"""
|
||||
@@ -17,7 +17,7 @@ setup(
|
||||
"pandas_ta.volatility",
|
||||
"pandas_ta.volume"
|
||||
],
|
||||
version=".".join(("0", "2", "25b")),
|
||||
version=".".join(("0", "2", "26b")),
|
||||
description=long_description,
|
||||
long_description=long_description,
|
||||
author="Kevin Johnson",
|
||||
|
||||
@@ -103,6 +103,15 @@ class TestOverlapExtension(TestCase):
|
||||
self.assertIsInstance(self.data, DataFrame)
|
||||
self.assertEqual(self.data.columns[-1], "SMA_10")
|
||||
|
||||
def test_ssf_ext(self):
|
||||
self.data.ta.ssf(append=True, poles=2)
|
||||
self.assertIsInstance(self.data, DataFrame)
|
||||
self.assertEqual(self.data.columns[-1], "SSF_10_2")
|
||||
|
||||
self.data.ta.ssf(append=True, poles=3)
|
||||
self.assertIsInstance(self.data, DataFrame)
|
||||
self.assertEqual(self.data.columns[-1], "SSF_10_3")
|
||||
|
||||
def test_swma_ext(self):
|
||||
self.data.ta.swma(append=True)
|
||||
self.assertIsInstance(self.data, DataFrame)
|
||||
|
||||
@@ -242,6 +242,15 @@ class TestOverlap(TestCase):
|
||||
except Exception as ex:
|
||||
error_analysis(result, CORRELATION, ex)
|
||||
|
||||
def test_ssf(self):
|
||||
result = pandas_ta.ssf(self.close, poles=2)
|
||||
self.assertIsInstance(result, Series)
|
||||
self.assertEqual(result.name, "SSF_10_2")
|
||||
|
||||
result = pandas_ta.ssf(self.close, poles=3)
|
||||
self.assertIsInstance(result, Series)
|
||||
self.assertEqual(result.name, "SSF_10_3")
|
||||
|
||||
def test_swma(self):
|
||||
result = pandas_ta.swma(self.close)
|
||||
self.assertIsInstance(result, Series)
|
||||
|
||||
Reference in New Issue
Block a user