diff --git a/README.md b/README.md
index 7f1ce2f..c62495f 100644
--- a/README.md
+++ b/README.md
@@ -56,7 +56,7 @@ _Pandas Technical Analysis_ (**Pandas TA**) is an easy to use library that lever
* [Candles](#candles-64)
* [Cycles](#cycles-1)
* [Momentum](#momentum-41)
- * [Overlap](#overlap-33)
+ * [Overlap](#overlap-34)
* [Performance](#performance-3)
* [Statistics](#statistics-11)
* [Trend](#trend-18)
@@ -113,7 +113,7 @@ $ pip install pandas_ta
Latest Version
--------------
-Best choice! Version: *0.3.15b*
+Best choice! Version: *0.3.16b*
* Includes all fixes and updates between **pypi** and what is covered in this README.
```sh
$ pip install -U git+https://github.com/twopirllc/pandas-ta
@@ -723,7 +723,7 @@ df = df.ta.cdl_pattern(name=["doji", "inside"])
-### **Overlap** (33)
+### **Overlap** (34)
* _Arnaud Legoux Moving Average_: **alma**
* _Double Exponential Moving Average_: **dema**
@@ -749,6 +749,7 @@ df = df.ta.cdl_pattern(name=["doji", "inside"])
* _WildeR's Moving Average_: **rma**
* _Sine Weighted Moving Average_: **sinwma**
* _Simple Moving Average_: **sma**
+* _Smoothed Moving Average_: **smma**
* _Ehler's Super Smoother Filter_: **ssf**
* _Supertrend_: **supertrend**
* _Symmetric Weighted Moving Average_: **swma**
@@ -969,15 +970,16 @@ trading account, or fund. See ```help(ta.drawdown)```
* _Cross Signals_ (**xsignals**) was created by Kevin Johnson. It is a wrapper of Trade Signals that returns Trends, Trades, Entries and Exits. Cross Signals are commonly used for **bbands**, **rsi**, **zscore** crossing some value either above or below two values at different times. See ```help(ta.xsignals)```
* _Directional Movement_ (**dm**) developed by J. Welles Wilder in 1978 attempts to determine which direction the price of an asset is moving. See ```help(ta.dm)```
* _Even Better Sinewave_ (**ebsw**) measures market cycles and uses a low pass filter to remove noise. See: ```help(ta.ebsw)```
-* _Jurik Moving Average_ (**jma**) attempts to eliminate noise to see the "true" underlying activity.. See: ```help(ta.jma)```
-* _Klinger Volume Oscillator_ (**kvo**) was developed by Stephen J. Klinger. It is designed to predict price reversals in a market by comparing volume to price.. See ```help(ta.kvo)```
+* _Jurik Moving Average_ (**jma**) attempts to eliminate noise to see the "true" underlying activity. See: ```help(ta.jma)```
+* _Klinger Volume Oscillator_ (**kvo**) was developed by Stephen J. Klinger. It is designed to predict price reversals in a market by comparing volume to price. See ```help(ta.kvo)```
+* _Smoothed Moving Average_ (**smma**) can be used to confirm trends and define areas of support and resistance. See: ```help(ta.smma)```
* _Schaff Trend Cycle_ (**stc**) is an evolution of the popular MACD incorportating two cascaded stochastic calculations with additional smoothing. See ```help(ta.stc)```
* _Squeeze Pro_ (**squeeze_pro**) is an extended version of "TTM Squeeze" from John Carter. See ```help(ta.squeeze_pro)```
* _Tom DeMark's Sequential_ (**td_seq**) attempts to identify a price point where an uptrend or a downtrend exhausts itself and reverses. Currently exlcuded from ```df.ta.strategy()``` for performance reasons. See ```help(ta.td_seq)```
* _Think or Swim Standard Deviation All_ (**tos_stdevall**) indicator which
returns the standard deviation of data for the entire plot or for the interval
of the last bars defined by the length parameter. See ```help(ta.tos_stdevall)```
-* _Vertical Horizontal Filter_ (**vhf**) was created by Adam White to identify trending and ranging markets.. See ```help(ta.vhf)```
+* _Vertical Horizontal Filter_ (**vhf**) was created by Adam White to identify trending and ranging markets. See ```help(ta.vhf)```
diff --git a/pandas_ta/__init__.py b/pandas_ta/__init__.py
index 0e740b8..5da436b 100644
--- a/pandas_ta/__init__.py
+++ b/pandas_ta/__init__.py
@@ -56,8 +56,8 @@ Category = {
"overlap": [
"alma", "dema", "ema", "fwma", "hilo", "hl2", "hlc3", "hma", "ichimoku",
"jma", "kama", "linreg", "mcgd", "midpoint", "midprice", "ohlc4",
- "pwma", "rma", "sinwma", "sma", "ssf", "supertrend", "swma", "t3",
- "tema", "trima", "vidya", "vwap", "vwma", "wcp", "wma", "zlma"
+ "pwma", "rma", "sinwma", "sma", "smma", "ssf", "supertrend", "swma",
+ "t3", "tema", "trima", "vidya", "vwap", "vwma", "wcp", "wma", "zlma"
],
# Performance
"performance": ["log_return", "percent_return"],
diff --git a/pandas_ta/core.py b/pandas_ta/core.py
index fdee64a..608acd7 100644
--- a/pandas_ta/core.py
+++ b/pandas_ta/core.py
@@ -1264,6 +1264,11 @@ class AnalysisIndicators(BasePandasObject):
result = sma(close=close, length=length, offset=offset, **kwargs)
return self._post_process(result, **kwargs)
+ def smma(self, length=None, offset=None, **kwargs):
+ close = self._get_column(kwargs.pop("close", "close"))
+ result = smma(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)
diff --git a/pandas_ta/overlap/__init__.py b/pandas_ta/overlap/__init__.py
index 7a0f5ec..611c684 100644
--- a/pandas_ta/overlap/__init__.py
+++ b/pandas_ta/overlap/__init__.py
@@ -21,6 +21,7 @@ from .pwma import pwma
from .rma import rma
from .sinwma import sinwma
from .sma import sma
+from .smma import smma
from .ssf import ssf
from .supertrend import supertrend
from .swma import swma
diff --git a/pandas_ta/overlap/smma.py b/pandas_ta/overlap/smma.py
new file mode 100644
index 0000000..5fbcc54
--- /dev/null
+++ b/pandas_ta/overlap/smma.py
@@ -0,0 +1,85 @@
+# -*- coding: utf-8 -*-
+from numpy import nan as npNaN
+from pandas_ta.overlap import ma
+from pandas_ta.utils import get_offset, verify_series
+
+
+def smma(close, length=None, mamode=None, talib=None, offset=None, **kwargs):
+ """Indicator: SMoothed Moving Average (SMMA)"""
+ # Validate Arguments
+ length = int(length) if length and length > 0 else 7
+ min_periods = int(kwargs["min_periods"]) if "min_periods" in kwargs and kwargs["min_periods"] is not None else length
+ close = verify_series(close, max(length, min_periods))
+ offset = get_offset(offset)
+ mamode = mamode.lower() if isinstance(mamode, str) else "sma"
+ mode_tal = bool(talib) if isinstance(talib, bool) else True
+
+ if close is None: return
+
+ # Calculate Result
+ m = close.size
+ smma = close.copy()
+ smma[:length - 1] = npNaN
+ smma.iloc[length - 1] = ma(mamode, close[0:length], length=length, talib=mode_tal)[-1]
+
+ for i in range(length, m):
+ smma.iloc[i] = ((length - 1) * smma.iloc[i - 1] + smma.iloc[i]) / length
+
+ # Offset
+ if offset != 0:
+ smma = smma.shift(offset)
+
+ # Handle fills
+ if "fillna" in kwargs:
+ smma.fillna(kwargs["fillna"], inplace=True)
+ if "fill_method" in kwargs:
+ smma.fillna(method=kwargs["fill_method"], inplace=True)
+
+ # Name & Category
+ smma.name = f"SMMA_{length}"
+ smma.category = "overlap"
+
+ return smma
+
+
+smma.__doc__ = \
+"""SMoothed Moving Average (SMMA)
+
+The SMoothed Moving Average (SMMA) is bootstrapped by default with a Simple
+Moving Average (SMA). It tries to reduce noise rather than reduce lag. The
+SMMA takes all prices into account and uses a long lookback period. Old prices
+are never removed from the calculation, but they have only a minimal impact on
+the Moving Average due to a low assigned weight. By reducing the noise it
+removes fluctuations and plots the prevailing trend. The SMMA can be used to
+confirm trends and define areas of support and resistance. A core component of
+Bill William's Alligator indicator.
+
+Sources:
+ https://www.tradingview.com/scripts/smma/
+ https://www.sierrachart.com/index.php?page=doc/StudiesReference.php&ID=173&Name=Moving_Average_-_Smoothed
+
+Calculation:
+ Default Inputs:
+ length=10, mamode="sma"
+ MA = Moving Average
+
+ SMMA[0:length] = MA(mamode, close, length)
+ SMMA[:length] = ((length - 1) * SMMA[i] + close[i]) / length
+
+Args:
+ close (pd.Series): Series of 'close's
+ length (int): It's period. Default: 10
+ mamode (str): See ```help(ta.ma)```. Default: 'sma'
+ talib (bool): If TA Lib is installed and talib is True, Returns the TA Lib
+ version. Default: True
+ offset (int): How many periods to offset the result. Default: 0
+
+Kwargs:
+ adjust (bool): Default: True
+ presma (bool, optional): If True, uses SMA for initial value.
+ fillna (value, optional): pd.DataFrame.fillna(value)
+ fill_method (value, optional): Type of fill method
+
+Returns:
+ pd.Series: New feature generated.
+"""
diff --git a/setup.py b/setup.py
index b5f7c6f..220f3cb 100644
--- a/setup.py
+++ b/setup.py
@@ -19,7 +19,7 @@ setup(
"pandas_ta.volatility",
"pandas_ta.volume"
],
- version=".".join(("0", "3", "15b")),
+ version=".".join(("0", "3", "16b")),
description=long_description,
long_description=long_description,
author="Kevin Johnson",
diff --git a/tests/test_ext_indicator_overlap_ext.py b/tests/test_ext_indicator_overlap_ext.py
index e6bdebc..db8a6f9 100644
--- a/tests/test_ext_indicator_overlap_ext.py
+++ b/tests/test_ext_indicator_overlap_ext.py
@@ -123,6 +123,11 @@ class TestOverlapExtension(TestCase):
self.assertIsInstance(self.data, DataFrame)
self.assertEqual(self.data.columns[-1], "SMA_10")
+ def test_smma_ext(self):
+ self.data.ta.smma(append=True)
+ self.assertIsInstance(self.data, DataFrame)
+ self.assertEqual(self.data.columns[-1], "SMMA_7")
+
def test_ssf_ext(self):
self.data.ta.ssf(append=True, poles=2)
self.assertIsInstance(self.data, DataFrame)
diff --git a/tests/test_indicator_overlap.py b/tests/test_indicator_overlap.py
index 5848969..4a435aa 100644
--- a/tests/test_indicator_overlap.py
+++ b/tests/test_indicator_overlap.py
@@ -327,6 +327,11 @@ class TestOverlap(TestCase):
self.assertIsInstance(result, Series)
self.assertEqual(result.name, "SMA_10")
+ def test_smma(self):
+ result = pandas_ta.smma(self.close)
+ self.assertIsInstance(result, Series)
+ self.assertEqual(result.name, "SMMA_7")
+
def test_ssf(self):
result = pandas_ta.ssf(self.close, poles=2)
self.assertIsInstance(result, Series)