diff --git a/README.md b/README.md
index d5769ed..d7fd1e6 100644
--- a/README.md
+++ b/README.md
@@ -24,7 +24,7 @@ Pandas TA - A Technical Analysis Library in Python 3

-_Pandas Technical Analysis_ (**Pandas TA**) is an easy to use library that leverages the Pandas library with more than 130 Indicators and Utility functions and more than 60 TA Lib Candlestick Patterns. Many commonly used indicators are included, such as: _Candle Pattern_(**cdl_pattern**), _Simple Moving Average_ (**sma**) _Moving Average Convergence Divergence_ (**macd**), _Hull Exponential Moving Average_ (**hma**), _Bollinger Bands_ (**bbands**), _On-Balance Volume_ (**obv**), _Aroon & Aroon Oscillator_ (**aroon**), _Squeeze_ (**squeeze**) and **_many more_**.
+_Pandas Technical Analysis_ (**Pandas TA**) is an easy to use library that leverages the Pandas package with more than 130 Indicators and Utility functions and more than 60 TA Lib Candlestick Patterns. Many commonly used indicators are included, such as: _Candle Pattern_(**cdl_pattern**), _Simple Moving Average_ (**sma**) _Moving Average Convergence Divergence_ (**macd**), _Hull Exponential Moving Average_ (**hma**), _Bollinger Bands_ (**bbands**), _On-Balance Volume_ (**obv**), _Aroon & Aroon Oscillator_ (**aroon**), _Squeeze_ (**squeeze**) and **_many more_**.
**Note:** _TA Lib_ must be installed to use **all** the Candlestick Patterns. ```pip install TA-Lib```. If _TA Lib_ is not installed, then only the builtin Candlestick Patterns will be available.
@@ -57,7 +57,7 @@ _Pandas Technical Analysis_ (**Pandas TA**) is an easy to use library that lever
* [Momentum](#momentum-41)
* [Overlap](#overlap-32)
* [Performance](#performance-3)
- * [Statistics](#statistics-10)
+ * [Statistics](#statistics-11)
* [Trend](#trend-18)
* [Utility](#utility-5)
* [Volatility](#volatility-14)
@@ -111,7 +111,7 @@ $ pip install pandas_ta
Latest Version
--------------
-Best choice! Version: *0.2.98b*
+Best choice! Version: *0.2.99b*
* 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
@@ -777,7 +777,7 @@ Use parameter: cumulative=**True** for cumulative results.
|  |
-### **Statistics** (10)
+### **Statistics** (11)
* _Entropy_: **entropy**
* _Kurtosis_: **kurtosis**
@@ -786,6 +786,7 @@ Use parameter: cumulative=**True** for cumulative results.
* _Quantile_: **quantile**
* _Skew_: **skew**
* _Standard Deviation_: **stdev**
+* _Think or Swim Standard Deviation All_: **tos_stdevall**
* _Variance_: **variance**
* _Z Score_: **zscore**
@@ -967,6 +968,9 @@ trading account, or fund. See ```help(ta.drawdown)```
* _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)```
diff --git a/pandas_ta/__init__.py b/pandas_ta/__init__.py
index 0fce90a..b76e208 100644
--- a/pandas_ta/__init__.py
+++ b/pandas_ta/__init__.py
@@ -65,8 +65,7 @@ Category = {
# Statistics
"statistics": [
"entropy", "kurtosis", "mad", "median", "quantile", "skew", "stdev",
- # "tos_stdevall",
- "variance", "zscore"
+ "tos_stdevall", "variance", "zscore"
],
# Trend
"trend": [
diff --git a/pandas_ta/core.py b/pandas_ta/core.py
index fcd5200..4e0fac0 100644
--- a/pandas_ta/core.py
+++ b/pandas_ta/core.py
@@ -1372,10 +1372,10 @@ class AnalysisIndicators(BasePandasObject):
result = stdev(close=close, length=length, offset=offset, **kwargs)
return self._post_process(result, **kwargs)
- # def tos_stdevall(self, length=None, stds=None, offset=None, **kwargs):
- # close = self._get_column(kwargs.pop("close", "close"))
- # result = tos_stdevall(close=close, length=length, stds=stds, offset=offset, **kwargs)
- # return self._post_process(result, **kwargs)
+ def tos_stdevall(self, length=None, stds=None, offset=None, **kwargs):
+ close = self._get_column(kwargs.pop("close", "close"))
+ result = tos_stdevall(close=close, length=length, stds=stds, offset=offset, **kwargs)
+ return self._post_process(result, **kwargs)
def variance(self, length=None, offset=None, **kwargs):
close = self._get_column(kwargs.pop("close", "close"))
diff --git a/pandas_ta/statistics/tos_stdevall.py b/pandas_ta/statistics/tos_stdevall.py
index d52a05f..13641c7 100644
--- a/pandas_ta/statistics/tos_stdevall.py
+++ b/pandas_ta/statistics/tos_stdevall.py
@@ -18,37 +18,33 @@ def tos_stdevall(close, length=None, stds=None, ddof=None, offset=None, **kwargs
ddof = int(ddof) if ddof and ddof >= 0 and ddof < length else 1
offset = get_offset(offset)
+ _props = f"TOS_STDEVALL"
if length is None:
length = close.size
- _props = f"STDEVALL"
else:
- length = int(length) if length and length > 2 else 30
+ length = int(length) if isinstance(length, int) and length > 2 else 30
close = close.iloc[-length:]
- _props = f"STDEVALL_{length}"
+ _props = f"{_props}_{length}"
close = verify_series(close, length)
if close is None: return
# Calculate Result
+ X = src_index = close.index
if isinstance(close.index, DatetimeIndex):
- close_ = npArray(close)
- np_index = npArange(length)
- m, b = npPolyfit(np_index, close_, 1)
- lr_ = m * np_index + b
- else:
- m, b = npPolyfit(close.index, close, 1)
- lr_ = m * close.index + b
+ X = npArange(length)
+ close = npArray(close)
- lr = Series(lr_, index=close.index)
- stdevall = stdev(Series(close), length=length, ddof=ddof)
- # std = npStd(close, ddof=ddof)
+ m, b = npPolyfit(X, close, 1)
+ lr = Series(m * X + b, index=src_index)
+ stdev = npStd(close, ddof=ddof)
# Name and Categorize it
- df = DataFrame({f"{_props}_LR": lr}, index=close.index)
+ df = DataFrame({f"{_props}_LR": lr}, index=src_index)
for i in stds:
- df[f"{_props}_L_{i}"] = lr - i * stdevall.iloc[-1]
- df[f"{_props}_U_{i}"] = lr + i * stdevall.iloc[-1]
+ df[f"{_props}_L_{i}"] = lr - i * stdev
+ df[f"{_props}_U_{i}"] = lr + i * stdev
df[f"{_props}_L_{i}"].name = df[f"{_props}_U_{i}"].name = f"{_props}"
df[f"{_props}_L_{i}"].category = df[f"{_props}_U_{i}"].category = "statistics"
@@ -72,8 +68,6 @@ def tos_stdevall(close, length=None, stds=None, ddof=None, offset=None, **kwargs
tos_stdevall.__doc__ = \
"""TD Ameritrade's Think or Swim Standard Deviation All (TOS_STDEV)
-**UNDER DEVELOPMENT**
-
A port of TD Ameritrade's Think or Swim Standard Deviation All 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.
@@ -83,13 +77,21 @@ Sources:
Calculation:
Default Inputs:
- length=30
- VAR = Variance
- STDEV = variance(close, length).apply(np.sqrt)
+ length=None (All), stds=[1, 2, 3], ddof=1
+ LR = Linear Regression
+ STDEV = Standard Deviation
+
+ LR = LR(close, length)
+ STDEV = STDEV(close, length, ddof)
+ for level in stds:
+ LOWER = LR - level * STDEV
+ UPPER = LR + level * STDEV
Args:
close (pd.Series): Series of 'close's
- length (int): It's period. Default: 30
+ length (int): Bars from current bar. Default: None
+ stds (list): List of Standard Deviations in increasing order from the
+ central Linear Regression line. Default: [1,2,3]
ddof (int): Delta Degrees of Freedom.
The divisor used in calculations is N - ddof,
where N represents the number of elements. Default: 1
@@ -100,5 +102,6 @@ Kwargs:
fill_method (value, optional): Type of fill method
Returns:
- pd.Series: New feature generated.
+ pd.DataFrame: Central LR, Pairs of Lower and Upper LR Lines based on
+ mulitples of the standard deviation. Default: returns 7 columns.
"""
diff --git a/setup.py b/setup.py
index 22d3cdb..fa8525a 100644
--- a/setup.py
+++ b/setup.py
@@ -19,7 +19,7 @@ setup(
"pandas_ta.volatility",
"pandas_ta.volume"
],
- version=".".join(("0", "2", "98b")),
+ version=".".join(("0", "2", "99b")),
description=long_description,
long_description=long_description,
author="Kevin Johnson",
diff --git a/tests/test_ext_indicator_statistics.py b/tests/test_ext_indicator_statistics.py
index c6a219d..0ea85be 100644
--- a/tests/test_ext_indicator_statistics.py
+++ b/tests/test_ext_indicator_statistics.py
@@ -53,15 +53,14 @@ class TestStatisticsExtension(TestCase):
self.assertIsInstance(self.data, DataFrame)
self.assertEqual(self.data.columns[-1], "STDEV_30")
- @skip
def test_tos_stdevall_ext(self):
self.data.ta.tos_stdevall(append=True)
self.assertIsInstance(self.data, DataFrame)
self.assertEqual(list(self.data.columns[-7:]), [
- "STDEVALL_LR",
- "STDEVALL_L_1", "STDEVALL_U_1",
- "STDEVALL_L_2", "STDEVALL_U_2",
- "STDEVALL_L_3", "STDEVALL_U_3"
+ "TOS_STDEVALL_LR",
+ "TOS_STDEVALL_L_1", "TOS_STDEVALL_U_1",
+ "TOS_STDEVALL_L_2", "TOS_STDEVALL_U_2",
+ "TOS_STDEVALL_L_3", "TOS_STDEVALL_U_3"
])
def test_variance_ext(self):
diff --git a/tests/test_indicator_statistics.py b/tests/test_indicator_statistics.py
index a01beda..d580a5c 100644
--- a/tests/test_indicator_statistics.py
+++ b/tests/test_indicator_statistics.py
@@ -79,21 +79,20 @@ class TestStatistics(TestCase):
except Exception as ex:
error_analysis(result, CORRELATION, ex)
- @skip
def test_tos_sdtevall(self):
result = pandas_ta.tos_stdevall(self.close)
self.assertIsInstance(result, DataFrame)
- self.assertEqual(result.name, "STDEVALL")
+ self.assertEqual(result.name, "TOS_STDEVALL")
self.assertEqual(len(result.columns), 7)
result = pandas_ta.tos_stdevall(self.close, length=30)
self.assertIsInstance(result, DataFrame)
- self.assertEqual(result.name, "STDEVALL_30")
+ self.assertEqual(result.name, "TOS_STDEVALL_30")
self.assertEqual(len(result.columns), 7)
result = pandas_ta.tos_stdevall(self.close, length=30, stds=[1, 2])
self.assertIsInstance(result, DataFrame)
- self.assertEqual(result.name, "STDEVALL_30")
+ self.assertEqual(result.name, "TOS_STDEVALL_30")
self.assertEqual(len(result.columns), 5)
def test_variance(self):