From febcde6624a5143e817238aef6f0e40e6679b35a Mon Sep 17 00:00:00 2001 From: Cedric Zhuang Date: Fri, 7 Jul 2023 23:15:22 +0800 Subject: [PATCH] [GH-163] Add Inertia Indicator (#164) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In financial markets, the concept of inertia was given by Donald Dorsey in the 1995 issue of Technical Analysis of Stocks and Commodities through the Inertia Indicator. The Inertia Indicator is moment-based and is an extension of Dorsey’s Relative Volatility Index (RVI). Formular: * inertia = n periods linear regression of RVGI Examples: * `df['inertia']` retrieves the inertia of 20 periods linear regression of 14 periods RVGI * `df['inertia_10']` retrieves the inertia of 10 periods linear regression of 14 periods RVGI --- README.md | 17 ++++++++++++++++- stockstats.py | 21 +++++++++++++++++++++ test.py | 21 +++++++++++++++++++++ 3 files changed, 58 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index c7b0491..4e93595 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ [![codecov](https://codecov.io/gh/jealous/stockstats/branch/master/graph/badge.svg?token=IFMD1pVJ7T)](https://codecov.io/gh/jealous/stockstats) [![pypi](https://img.shields.io/pypi/v/stockstats.svg)](https://pypi.python.org/pypi/stockstats) -VERSION: 0.6.0 +VERSION: 0.6.1 ## Introduction @@ -67,6 +67,7 @@ Supported statistics/indicators are: * ERI: Elder-Ray Index * FTR: the Gaussian Fisher Transform Price Reversals indicator * RVGI: Relative Vigor Index +* Inertia: Inertia Indicator ## Installation @@ -960,6 +961,20 @@ Examples: * `df['rvgi_5']` retrieves the RVGI line of window 5 * `df['rvgis_5']` retrieves the RVGI signal line of window 5 +#### [Inertia Indicator](https://theforexgeek.com/inertia-indicator/) + +In financial markets, the concept of inertia was given by Donald Dorsey +in the 1995 issue of Technical Analysis of Stocks and Commodities +through the Inertia Indicator. The Inertia Indicator is moment-based +and is an extension of Dorsey’s Relative Volatility Index (RVI). + +Formular: +* inertia = n periods linear regression of RVGI + +Examples: +* `df['inertia']` retrieves the inertia of 20 periods linear regression of 14 periods RVGI +* `df['inertia_10']` retrieves the inertia of 10 periods linear regression of 14 periods RVGI + ## Issues We use [Github Issues](https://github.com/jealous/stockstats/issues) to track diff --git a/stockstats.py b/stockstats.py index 9e6e0bf..739357c 100644 --- a/stockstats.py +++ b/stockstats.py @@ -60,6 +60,7 @@ class StockStatsError(Exception): 'eribear': 13, 'eribull': 13, 'ichimoku': (9, 26, 52), + 'inertia': (20, 14), 'ftr': 9, 'kama': (10, 5, 34), # window, fast, slow 'kdjd': 9, @@ -1534,6 +1535,25 @@ def _get_rvgi(self, meta: _Meta): self[meta.name] = rvgi self[meta.name_ex('s')] = rvgi_s + def _inertia(self, window: int, rvgi_window: int) -> pd.Series: + """ Inertia Indicator + + https://theforexgeek.com/inertia-indicator/ + + In financial markets, the concept of inertia was given by Donald Dorsey + in the 1995 issue of Technical Analysis of Stocks and Commodities + through the Inertia Indicator. The Inertia Indicator is moment-based + and is an extension of Dorsey’s Relative Volatility Index (RVI). + """ + rvgi = self._rvgi(rvgi_window) + value = self.linear_reg(rvgi, window) + value.iloc[:max(window, rvgi_window) + 2] = 0 + return value + + def _get_inertia(self, meta: _Meta): + value = self._inertia(meta.int0, meta.int1) + self[meta.name] = value + @staticmethod def parse_column_name(name): m = re.match(r'(.*)_([\d\-+~,.]+)_(\w+)', name) @@ -1678,6 +1698,7 @@ def handler(self): ('eribull', 'eribear'): self._get_eri, ('ftr',): self._get_ftr, ('rvgi', 'rvgis'): self._get_rvgi, + ('inertia',): self._get_inertia, } def __init_not_exist_column(self, key): diff --git a/test.py b/test.py index d9e1fba..33ec9fa 100644 --- a/test.py +++ b/test.py @@ -1016,3 +1016,24 @@ def test_change_group_window_defaults(self): assert_that(macd[i], equal_to(ref[i])) stockstats.set_dft_window('macd', orig) + + def test_inertia(self): + stock = self.get_stock_90days() + inertia = stock['inertia'] + assert_that(inertia[20110209], equal_to(0)) + assert_that(inertia[20110210], near_to(-0.024856)) + assert_that(inertia[20110304], near_to(0.155576)) + + inertia_dft = stock['inertia_20,14'] + assert_that(inertia_dft[20110209], equal_to(0)) + assert_that(inertia_dft[20110210], near_to(-0.024856)) + assert_that(inertia_dft[20110304], near_to(0.155576)) + + inertia14 = stock['inertia_20'] + assert_that(inertia14[20110209], equal_to(0)) + assert_that(inertia14[20110210], near_to(-0.024856)) + assert_that(inertia14[20110304], near_to(0.155576)) + + inertia10 = stock['inertia_10'] + assert_that(inertia10[20110209], near_to(0.011085)) + assert_that(inertia10[20110210], near_to(-0.014669))