Skip to content

Commit

Permalink
[GH-121] Add aroon indicator (#136)
Browse files Browse the repository at this point in the history
Add aroon oscillator.

 * Aroon Oscillator = Aroon Up - Aroon Down
 * Aroon Up = 100 * (n - periods since n-period high) / n
 * Aroon Down = 100 * (n - periods since n-period low) / n
 * n = window size

https://www.investopedia.com/terms/a/aroonoscillator.asp

The default window is 25.
jealous authored Jun 12, 2023
1 parent c96a3df commit a872eb3
Showing 3 changed files with 57 additions and 1 deletion.
20 changes: 19 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -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.5.2
VERSION: 0.5.3

## Introduction

@@ -54,6 +54,7 @@ Supported statistics/indicators are:
* StochRSI: Stochastic RSI
* WT: LazyBear's Wave Trend
* Supertrend: with the Upper Band and Lower Band
* Aroon: Aroon Oscillator

## Installation

@@ -653,6 +654,23 @@ Examples:
* `kdjk_xu_kdjd` returns a series that marks where KDJK crosses up KDJD
* `kdjk_xd_kdjd` returns a series that marks where KDJD crosses down KDJD

#### [Aroon Oscillator](https://www.investopedia.com/terms/a/aroonoscillator.asp)

The Aroon Oscillator measures the strength of a trend and
the likelihood that it will continue.

The default window is 25.

* Aroon Oscillator = Aroon Up - Aroon Down
* Aroon Up = 100 * (n - periods since n-period high) / n
* Aroon Down = 100 * (n - periods since n-period low) / n
* n = window size

Examples:
* `df['aroon']` returns Aroon oscillator with a window of 25
* `df['aroon_14']` returns Aroon oscillator with a window of 14


## Issues

We use [Github Issues](https://github.com/jealous/stockstats/issues) to track
26 changes: 26 additions & 0 deletions stockstats.py
Original file line number Diff line number Diff line change
@@ -603,6 +603,31 @@ def _get_supertrend(self, window=None):
self['supertrend_lb'] = lb
self['supertrend'] = st

def _get_aroon(self, window=None):
if window is None:
window = 25
column_name = 'aroon'
else:
window = self.get_int_positive(window)
column_name = 'aroon_{}'.format(window)

def _window_pct(s):
n = float(window)
return (n - (n - (s + 1))) / n * 100

high_since = self['high'].rolling(
min_periods=1,
window=window,
center=False).apply(np.argmax)
low_since = self['low'].rolling(
min_periods=1,
window=window,
center=False).apply(np.argmin)

aroon_up = _window_pct(high_since)
aroon_down = _window_pct(low_since)
self[column_name] = aroon_up - aroon_down

def _atr(self, window):
tr = self._tr()
return self._smma(tr, window)
@@ -1278,6 +1303,7 @@ def handler(self):
('supertrend',
'supertrend_lb',
'supertrend_ub'): self._get_supertrend,
('aroon',): self._get_aroon,
}

def __init_not_exist_column(self, key):
12 changes: 12 additions & 0 deletions test.py
Original file line number Diff line number Diff line change
@@ -726,3 +726,15 @@ def test_drop_tail(self):
assert_that(ret.iloc[-1].name, equal_to(20040831))
assert_that(stock, has_length(20))
assert_that(stock.iloc[-1].name, equal_to(20040913))

def test_aroon(self):
stock = self._supor[:50]
_ = stock['aroon']
assert_that(stock.loc[20040924, 'aroon'], equal_to(28))

_ = stock['aroon_25']
assert_that(stock.loc[20040924, 'aroon_25'], equal_to(28))

_ = stock['aroon_5']
assert_that(stock.loc[20040924, 'aroon_5'], equal_to(40))
assert_that(stock.loc[20041020, 'aroon_5'], equal_to(-80))

0 comments on commit a872eb3

Please sign in to comment.