The Fractal Indicator — Detecting Tops & Bottoms in Markets.

Insights from Chaos Theory Applied to Trading. A Study in Python.


Sofienne Kaabar

3 years ago | 9 min read

The efficient market hypothesis fails to account for the many anomalies and recurring exploitable patterns within financial assets. This is why active portfolio management is still the dominant party when compared to passive investing.

Financial markets are not perfectly random, they are random-like, i.e. they exhibit a low signal-to-noise ratio. In other words, it is hard to predict the markets and even harder to be consistently profitable. However, the word hard does not mean impossible.

In this article we will learn about Chaos theory and how its definition is used in the financial markets. Then, we will develop an indicator that uses a formula close to the Rescaled Range calculation which is often related to fractal mathematics, albeit simpler in nature. After all, we do not need to overcomplicate things to understand how the market moves.

If you would like to see more exotic techniques to trade the markets, feel free to check out this article I have recently written:

Introduction to Chaos Theory

Chaos Theory is a very complex mathematical field that has the job of explaining the effects of very small factors. The Butterfly Effect comes to mind when thinking of Chaos Theory. The mentioned effect is the phenomenon where insignificant factors can lead to extreme changes.

A chaotic system is an environment that alternates between predictability and randomness, and this is the closest explanation that we have so far for the financial markets. The efficient market hypothesis fails to thoroughly explain the market dynamics and it is better for now to stick to real trading results and historical performances as a judge for whether markets are predictable or not.

The early experiments with Chaos Theory occurred with Edward Lorenz, a meteorologist who wanted to simulate weather sequences by incorporating different variables such as temperature and wind speed. Lorenz noticed that whenever he made tiny adjustments in the variables, the final results were extremely different.

This was the first proof of the Butterfly Effect which is one of the pillars of Chaos Theory.

The assumption in Chaos Theory vis-a-vis financial markets is that price is the last thing to change and that the current price is the most important information.

As stated above, Lorenz has proven that chaotic systems are impacted by the slightest changes in their variables. This makes us think about the time where if a certain financial information does not get released or is a bit different, where would the market trade?

Emotions and independent situations all contribute to determining the market price as well. Imagine if a giant hedge fund changed its mind from buying the EUR versus the USD at the last minute and that this information has gone out to the public.

Many traders who would have wanted to ride the giant bullish trend along the hedge fund would have eventually changed their minds and this could actually have caused the EURUSD price to go down in value. This is why I give great weight to Market Sentiment Analysis through some tools like the COT report.

But none of this is pertinent to what I am trying to present. The reason I am talking about Chaos Theory is because the indicator I am showing below uses a formula related to this field. Even though the financial applications of Chaos Theory remain vague and a little unbacked, it should not stop us from trying out new things. With that being said, we can start designing our Fractal Indicator.

The Fractal Indicator

British hydrologist Harold Edwin Hurst introduced a measure of variability of time series across the period of time analyzed. This measure is called the Rescaled Range Analysis which is the basis of our Fractal Indicator. Here is how to calculate Rescaled Range:

Image by Author.

The Rescaled Range formula is very interesting as it takes into account the volatility (S), the mean (X-bar), and the range of the data to analyze its properties. What the above formula says is that, we have to calculate the range between the mini ranges of the maximum and minimum values and then divide them by the Standard Deviation, which in this case is the proxy for volatility.

As I am a perpetual fan of do-it-yourself and tweak-it-yourself, I have modified the formula to have the following sense which we will later see together in a step-by-step method:

Incorporating the highs and the lows could give us a clearer picture on volatility, which is why we will first calculate an exponential moving average on both the lows and highs for the previous X period and then calculate their respective standard deviation i.e. volatility.
Next, we will calculate the first range where we will subtract the current high from the average high measured by the exponential moving average in the first step and then do the same thing with the low. After that, we will calculate a rolling maximum for the first range (the high minus its average) and a rolling minimum for the second range (the low minus its average).
Then, we subtract the the high rolling maximum from the low rolling minimum before rescaling by dividing the result by the average between the two standard deviations calculated above for the highs and lows.
This is all done using the following function that requires an OHLC array with a few columns to spare:

def fractal_indicator(Data, high, low, ema_lookback, min_max_lookback, where):

Data = ema(Data, 2, ema_lookback, high, where)
Data = ema(Data, 2, ema_lookback, low, where + 1)

Data = volatility(Data, ema_lookback, high, where + 2)
Data = volatility(Data, ema_lookback, low, where + 3)

Data[:, where + 4] = Data[:, high] - Data[:, where]
Data[:, where + 5] = Data[:, low] - Data[:, where + 1]for i in range(len(Data)):
Data[i, where + 6] = max(Data[i - min_max_lookback + 1:i + 1, where + 4])

except ValueError:

for i in range(len(Data)):
Data[i, where + 7] = min(Data[i - min_max_lookback + 1:i + 1, where + 5])

except ValueError:

Data[:, where + 8] = (Data[:, where + 2] + Data[:, where + 3]) / 2
Data[:, where + 9] = (Data[:, where + 6] - Data[:, where + 7]) / Data[:, where + 8]

return Data

So, it becomes clear, the Fractal Indicator is simply a reformed version of the Rescaled Range formula created by Harold Hurst.

If you want to add columns to your array, you can use the below function:

def adder(Data, times):

for i in range(1, times + 1):

z = np.zeros((len(Data), 1), dtype = float)
Data = np.append(Data, z, axis = 1)return Data

EURUSD Hourly Data in the first panel and the Fractal Indicator(20, 14) in the second panel. (Image by Author)

We have to understand how to use the Fractal Indicator. From charting, it is clear that we can find extreme values around the lower extremity which is 1.00 (or slightly lower depending on the parameters used below). We can call this, the Fractal Threshold.

Hence, a reasonable trading strategy can have the following conditions:

  • Every time the Fractal Indicator reaches the 1.00 threshold while the market price has been trending downwards, we can expect that there will be a structural break in the market price, i.e. a short-term reversal to the upside. We should initiate a long position.
  • Every time the Fractal Indicator reaches the 1.00 threshold while the market price has been trending upwards, we can expect that there will be a structural break in the market price, i.e. a short-term reversal to the downside. We should initiate a short position.
trend = 10
def signal(Data, what, closing, buy, sell):

for i in range(len(Data)):

if Data[i, what] < barrier and Data[i, closing] < Data[i - trend, closing]:
Data[i, buy] = 1

if Data[i, what] < barrier and Data[i, closing] > Data[i - trend, closing]:
Data[i, sell] = -1# The trend variable is the algorithm's way to see whether the market price has been trending down or up. This is to known what position to initiate (long/short) as the Fractal Indicator only shows a uniform signal which is the event of reaching 1.00# The Data variable refers to the OHLC array
# The what variable refers to the Fractal Indicator
# The closing variable refers to the closing price
# The buy variable refers to where we should place long orders
# The sell variable refers to where we should place short orders

It is worth noting that we can develop a miniature nomenclature to describe the Fractal Indicator. Notice how we have two variables, the lookback period on the exponential moving average and the lookback period on the normalization range period:

  • The first variable is simply the moving average’s calculation period.
  • The second variable is simply the range’s observation period.

Hence, a Fractal Indicator with an exponential moving average period of 20 and a normalization lookback period of 14 can be written as FI(20, 14).

USDCHF M15 Data in the first panel and the Fractal Indicator(20, 14) in the second panel. (Image by Author)

Back-testing a Strategy

The beauty of this indicator is that it is different from other technical indicator. This means that it is not correlated to the known ones such as the RSI or the MACD oscillator which are all correlated to each other. An uncorrelated indicator gives us more conviction as it confirms our view using another road. Remember that it is better to have two opinions than just one opinion.

Keeping in mind the above trading conditions, we can add the same risk management system I always use in my articles and see what kind of added-value it provides. The back-tested data is Hourly.

Performance Summary Table (Image by Author)

Equity Curves following the Fractal Indicator strategy. (Image by Author)

Visibly, it is not bad and can even be optimized in many ways. Systematically, it shows potential.

We can also choose a longer lookback period so that we smooth out the indicator in case we want to use it in discretionary way.

EURUSD M15 Data in the first panel and the Fractal Indicator(21, 13) in the second panel. (Image by Author)

Which gives us the following signals:

Signal chart on the EURUSD following the Fractal Indicator(21, 13). (Image by Author)


Why was this article written? It is certainly not a spoon-feeding method or the way to a profitable strategy. If you follow my articles, you will notice that I place more emphasize on how to do it instead of here it is and that I also provide functions not full replicable code. In the financial industry, you should combine the pieces yourself from other exogenous information and data, only then, will you master the art of research and trading.

I always advise you to do the proper back-tests and understand any risks relating to trading. For example, the above results are not very indicative as the spread we have used is very competitive and may be considered hard to constantly obtain in the retail trading world (but not impossible).

However, with institutional bid/ask spreads, it may be possible to lower the costs such as that a systematic medium-frequency strategy starts being very profitable.


Created by

Sofienne Kaabar

FX Trader | Author of the Book of The Book of Back-Tests







Related Articles