Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ENH: Add new technical indicator: Fibonacci Retractment #2718

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions tests/pipeline/test_technical.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
MovingAverageConvergenceDivergenceSignal,
AnnualizedVolatility,
RSI,
FibonacciRetractment
)
from zipline.testing import check_allclose, parameter_space
from zipline.testing.fixtures import ZiplineTestCase
Expand Down Expand Up @@ -663,3 +664,32 @@ def test_volatility(self):
expected_vol,
decimal=8
)


class FibonacciRetractmentTestCase(ZiplineTestCase):
"""
Test FibonacciRetractment Calculation
"""
def test_fibo(self):

fibo = FibonacciRetractment()

nassets = 3
today = np.datetime64(1, 'ns')
assets = np.arange(nassets)

np.random.seed(100) # Seed so we get deterministic results.
test_data = np.abs(np.random.randn(15, nassets))

out = np.empty((6, nassets), dtype=float)
fibo.compute(today, assets, out, test_data)

expected = np.empty((6, 3), dtype=float)
expected[0] = [1.74976547, 1.69061683, 1.61898166]
expected[1] = [1.08414923, 1.14101903, 1.0217989]
expected[2] = [0.87854002, 0.97124798, 0.83732884]
expected[3] = [0.67293081, 0.80147694, 0.65285877]
expected[4] = [0.41853298, 0.59142123, 0.42461615]
expected[5] = [0.00731456, 0.25187914, 0.05567601]

np.testing.assert_almost_equal(out, expected, 7)
2 changes: 2 additions & 0 deletions zipline/pipeline/factors/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
RateOfChangePercentage,
RSI,
TrueRange,
FibonacciRetractment,
)

__all__ = [
Expand All @@ -58,6 +59,7 @@
'ExponentialWeightedMovingStdDev',
'Factor',
'FastStochasticOscillator',
'FibonacciRetractment',
'IchimokuKinkoHyo',
'Latest',
'LinearWeightedMovingAverage',
Expand Down
34 changes: 34 additions & 0 deletions zipline/pipeline/factors/technical.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
diff,
dstack,
inf,
apply_along_axis
)
from numexpr import evaluate

Expand Down Expand Up @@ -390,3 +391,36 @@ def compute(self, today, assets, out, close, fast_period, slow_period,

# Convenience aliases.
MACDSignal = MovingAverageConvergenceDivergenceSignal


class FibonacciRetractment(CustomFactor):
"""
FibonacciRetractment

https://www.investopedia.com/ask/answers/05/fibonacciretracement.asp

Given a period, 4 retractment levels are calculated between the peak
and the trough, where the ratio of each retractment level is based on
Fibonacci sequence.

Parameters
----------
period : int > 0, optional
The window length for the Fibonacci retractment levels calculation.
Default is 0.
"""

window_length = 15
inputs = (EquityPricing.close,)

def compute(self, today, assets, out, closes, period=0):
windowed_closes = closes[-period:]
trough = apply_along_axis(min, 0, windowed_closes)
peak = apply_along_axis(max, 0, windowed_closes)
range = peak - trough
out[0] = peak
out[1] = trough + 0.618 * range
out[2] = trough + 0.5 * range
out[3] = trough + 0.382 * range
out[4] = trough + 0.236 * range
out[5] = trough