Skip to content

Commit

Permalink
Merge pull request #1258 from femtoghoti/add_aroon_indicator
Browse files Browse the repository at this point in the history
ENH: Add Aroon indicator.
  • Loading branch information
llllllllll committed Jun 4, 2016
2 parents 7d1c797 + 696e81b commit af38b02
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 1 deletion.
38 changes: 37 additions & 1 deletion tests/pipeline/test_technical.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
from __future__ import division

from nose_parameterized import parameterized
import numpy as np
import pandas as pd
import talib
Expand All @@ -7,7 +10,7 @@
from zipline.pipeline.data import USEquityPricing
from zipline.pipeline.engine import SimplePipelineEngine
from zipline.pipeline.term import AssetExists
from zipline.pipeline.factors import BollingerBands
from zipline.pipeline.factors import BollingerBands, Aroon
from zipline.testing import ExplodingObject, parameter_space
from zipline.testing.fixtures import WithAssetFinder, ZiplineTestCase
from zipline.testing.predicates import assert_equal
Expand Down Expand Up @@ -138,3 +141,36 @@ def test_bollinger_bands_output_ordering(self):
self.assertIs(lower, bbands.lower)
self.assertIs(middle, bbands.middle)
self.assertIs(upper, bbands.upper)


class AroonTestCase(ZiplineTestCase):
window_length = 10
nassets = 5
dtype = [('down', 'f8'), ('up', 'f8')]

@parameterized.expand([
(np.arange(window_length),
np.arange(window_length) + 1,
np.recarray(shape=(nassets,), dtype=dtype,
buf=np.array([0, 100] * nassets, dtype='f8'))),
(np.arange(window_length, 0, -1),
np.arange(window_length, 0, -1) - 1,
np.recarray(shape=(nassets,), dtype=dtype,
buf=np.array([100, 0] * nassets, dtype='f8'))),
(np.array([10, 10, 10, 1, 10, 10, 10, 10, 10, 10]),
np.array([1, 1, 1, 1, 1, 10, 1, 1, 1, 1]),
np.recarray(shape=(nassets,), dtype=dtype,
buf=np.array([100 * 3 / 9, 100 * 5 / 9] * nassets,
dtype='f8'))),
])
def test_aroon_basic(self, lows, highs, expected_out):
aroon = Aroon(window_length=self.window_length)
today = pd.Timestamp('2014', tz='utc')
assets = pd.Index(np.arange(self.nassets, dtype=np.int64))
shape = (self.nassets,)
out = np.recarray(shape=shape, dtype=self.dtype,
buf=np.empty(shape=shape, dtype=self.dtype))

aroon.compute(today, assets, out, lows, highs)

assert_equal(out, expected_out)
2 changes: 2 additions & 0 deletions zipline/pipeline/factors/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
BusinessDaysUntilNextExDate,
)
from .technical import (
Aroon,
AverageDollarVolume,
BollingerBands,
EWMA,
Expand All @@ -32,6 +33,7 @@
)

__all__ = [
'Aroon',
'AverageDollarVolume',
'BollingerBands',
'BusinessDaysSince13DFilingsDate',
Expand Down
43 changes: 43 additions & 0 deletions zipline/pipeline/factors/technical.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
Technical Analysis Factors
--------------------------
"""
from __future__ import division

from numbers import Number
from numpy import (
abs,
Expand Down Expand Up @@ -31,6 +33,7 @@
from zipline.utils.input_validation import expect_types
from zipline.utils.math_utils import (
nanargmax,
nanargmin,
nanmax,
nanmean,
nanstd,
Expand Down Expand Up @@ -739,3 +742,43 @@ def compute(self, today, assets, out, close, k):
out.middle = middle = nanmean(close, axis=0)
out.upper = middle + difference
out.lower = middle - difference


class Aroon(CustomFactor):
"""
Aroon technical indicator.
https://www.fidelity.com/learning-center/trading-investing/technical
-analysis/technical-indicator-guide/aroon-indicator
**Defaults Inputs:** USEquityPricing.low, USEquityPricing.high
Parameters
----------
window_length : int > 0
Length of the lookback window over which to compute the Aroon
indicator.
"""

inputs = (USEquityPricing.low, USEquityPricing.high)
outputs = ('down', 'up')

def compute(self, today, assets, out, lows, highs):
wl = self.window_length
high_date_index = nanargmax(highs, axis=0)
low_date_index = nanargmin(lows, axis=0)
evaluate(
'(100 * high_date_index) / (wl - 1)',
local_dict={
'high_date_index': high_date_index,
'wl': wl,
},
out=out.up,
)
evaluate(
'(100 * low_date_index) / (wl - 1)',
local_dict={
'low_date_index': low_date_index,
'wl': wl,
},
out=out.down,
)

0 comments on commit af38b02

Please sign in to comment.