Indicator · Pine Script v5 · Own pane

Hurst Exponent - Detrended Fluctuation Analysis

by Teerth1· code credited to balipour

Estimates the Hurst exponent with detrended fluctuation analysis on log returns, indicating whether recent price behaviour leans toward trending or mean reverting around a 0.5 mid line.

View on GitHub

GitHub stars1on the repository
Pine versionv5runs as is
Lines of code191
Settings20inputs
LicenceNone statedfile: MPL-2.0
Last update6 months ago10 Apr 2026

Add It to Your TradingView Chart

  1. 1Copy the scriptPress Copy script above, or the copy button on the code below.
  2. 2Open the Pine EditorOpen a TradingView chart and choose Pine Editor at the bottom of the screen.
  3. 3Paste over the templateCreate a new indicator, select all of the template text and paste. Press Save and give it a name.
  4. 4Add it to the chartPress Add to chart, then adjust the settings with the gear icon next to its name.

Source Code

191 lines of Pine Script v5 from deal-api/src/main/resources/PineScript/Hurst Exponent - Detrended Fluctuation Analysis.pine, published under MPL-2.0 (file header). Keep the author's credit and licence lines when you reuse it.

Hurst Exponent - Detrended Fluctuation Analysis.pine
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © balipour

//@version=5
indicator('Hurst Exponent - Detrended Fluctuation Analysis', 'BA🐷HE (DFA)', precision=3, max_bars_back=5000)

//Input Strings
group1 = 'Sample Settings'
group2 = 'Log Scaling'
group3 = 'Style'
L = 'Line'
CL = 'Columns'
Ci = 'Circles'
ON = 'On'
OFF = 'Off'
//Inputs{

useRange = input.string('ALL', 'Date Range', options=['HOURS', 'DAYS', 'WEEKS', 'ALL'], inline='Date', group=group1)
number = input.float(300, 'Number', minval=0, group=group1, inline='Date', tooltip='Select Script Calculation Date to Reduce loading time when using high lookback')
len = input.int(100, 'Sample Size', minval=40, group=group1, tooltip='lookback period for HE, Optimal Size > 50, Larger Size More Accurate and More lag')
showma = input.bool(false, 'Show Filter', inline='Show MA')
slen = input.int(18, 'Length', minval=4, inline='Show MA', tooltip='Smoothed Moving Averge of HE')
Bsc = input.int(8, 'Base Scale', options=[4, 8, 16], inline='Base Scale', group=group2)
Msc = input.int(2, 'Max Scale', options=[2, 4], inline='Base Scale', group=group2, tooltip='Select larger Value(Max and Base scale) when Sample Size is larger')
stl = input.string(Ci, 'Plot Style ', inline='Plot Style', options=[Ci, L, CL], group=group3)
lT = input.int(1, 'Line Thickness', inline='Plot Style', options=[1, 2, 3], group=group3)
c_ma = input.color(color.orange, 'MA', inline='MA', group=group3)
lTma = input.int(1, 'Line Thickness', inline='MA', options=[1, 2, 3], group=group3)
c_t = input.color(color.aqua, '> 0.5', inline='> 0.5', group=group3)
c_m = input.color(#FF0080ff, '< 0.5', inline='> 0.5', group=group3)
c_st = input.color(color.lime, 'Significant Trend', inline='Significant Trend', group=group3)
c_sm = input.color(color.yellow, 'Significant Mean Reversion', inline='Significant Trend', group=group3)
c_cv = input.color(color.white, 'Confidence Interval', inline='Confidence Interval', group=group3)
c_mid = input.color(color.white, 'Mid Line', inline='Confidence Interval', group=group3)
dt = input.string(ON, 'Show Table', options=[ON, OFF], inline='table', group=group3) == ON
bg = input.string(ON, 'Dark Background', options=[OFF, ON], group=group3) == ON
tsize = input.string('normal', 'Size', options=['tiny', 'small', 'normal', 'large', 'huge', 'auto'], inline='table', group=group3)

//Background Color
bgcolor(bg ? color.new(#000000, 20) : na, title='Dark Background', transp=90)

//Start Time Calculation (Credit to Allanster)
oneHour = 60 * 60 * 1000
oneDay = 24 * 60 * 60 * 1000
oneWeek = 7 * oneDay
present = timenow
start = useRange == 'HOURS' ? present - number * oneHour : useRange == 'DAYS' ? present - number * oneDay : useRange == 'WEEKS' ? present - number * oneWeek : na

//Condition to save Computing time
t = useRange == 'ALL' ? true : time >= start


//Declaration
int Min = Bsc
int Max = Msc
var fluc = array.new_float(10)
var scale = array.new_float(10)
float slope = na

//Functions
ss(Series, Period) =>  // Super Smoother Function
    var PI = 2.0 * math.asin(1.0)
    var SQRT2 = math.sqrt(2.0)
    lambda = PI * SQRT2 / Period
    a1 = math.exp(-lambda)
    coeff2 = 2.0 * a1 * math.cos(lambda)
    coeff3 = -math.pow(a1, 2.0)
    coeff1 = 1.0 - coeff2 - coeff3
    filt1 = 0.0
    filt1 := coeff1 * (Series + nz(Series[1])) * 0.5 + coeff2 * nz(filt1[1]) + coeff3 * nz(filt1[2])
    filt1

//}

//Calculation{

//Log Return
r = math.log(close / close[1])
//Mean of Log Return
mean = ta.sma(r, len)

//Cumulative Sum
var csum = array.new_float(len)
if t
    sum = 0.0
    for i = 0 to len - 1 by 1
        sum := r[i] - mean + sum
        array.set(csum, i, sum)

//Root Mean Sum (FLuctuation) function linear trend to calculate error between linear trend and cumulative sum
RMS(N1, N) =>
    if t
        //Slicing the array into different segments
        var seq = array.new_float(N)
        int count = 0
        for i = 0 to N - 1 by 1
            count += 1
            array.set(seq, i, count)
        y = array.slice(csum, N1, N1 + N)

        //Linear regression measuing trend (N/(N-1) for sample unbiased adjustedment)
        sdx = array.stdev(seq) * math.sqrt(N / (N - 1))
        sdy = array.stdev(y) * math.sqrt(N / (N - 1))
        cov = array.covariance(seq, y) * (N / (N - 1))

        //Linear Regression Root Mean Square Error (Detrend)
        r2 = math.pow(cov / (sdx * sdy), 2)
        rms = math.sqrt(1 - r2) * sdy
        rms

//Average of Root Mean Sum Measured each block (Log Scale)
Arms(bar) =>
    if t
        num = math.floor(len / bar)
        sumr = 0.0
        for i = 0 to num - 1 by 1
            sumr += RMS(i * bar, bar)
            sumr
        //Log Scale
        avg = math.log10(sumr / num)
        avg

//Approximating Log Scale Function (Saves Sample Size)
fs(x) =>
    if t
        math.round(Min * math.pow(math.pow(len / (Max * Min), 0.1111111111), x))

if t
    //Set Ten points of Root Mean Square Average along the Y log axis
    array.set(fluc, 0, Arms(fs(0)))
    array.set(fluc, 1, Arms(fs(1)))
    array.set(fluc, 2, Arms(fs(2)))
    array.set(fluc, 3, Arms(fs(3)))
    array.set(fluc, 4, Arms(fs(4)))
    array.set(fluc, 5, Arms(fs(5)))
    array.set(fluc, 6, Arms(fs(6)))
    array.set(fluc, 7, Arms(fs(7)))
    array.set(fluc, 8, Arms(fs(8)))
    array.set(fluc, 9, Arms(fs(9)))

    //Set Ten Points of data scale along the X log axis
    for i = 0 to 9 by 1
        array.set(scale, i, math.log10(fs(i)))

    //SLope Measured From RMS and Scale on Log log plot using linear regression
    slope := array.covariance(scale, fluc) / array.variance(scale)
    slope

//Moving Average Smoothed Hurst Exponent 
smooth = showma ? ss(slope, slen) : na

//Critical Value based on Confidence Interval (95% Confidence)
ci = 1.645 * (0.3912 / math.pow(len, 0.3))
//Expected Value plus Crtical Value
cu = 0.5 + ci
cd = 0.5 - ci

//}

//Plots{

//plotstyle
pstyle = stl == L ? plot.style_linebr : stl == CL ? plot.style_columns : stl == Ci ? plot.style_circles : plot.style_line

//Color of HE
c = slope > cu ? c_st : slope >= 0.5 ? c_t : slope < cd ? c_sm : slope < 0.5 ? c_m : na
//Text of Table
text_1 = slope > cu ? 'Significant Trend' : slope >= 0.5 ? 'Trend' : slope < cd ? 'Significant Mean Reversion' : slope < 0.5 ? 'Mean Reversion' : na

//Plotting
plot(slope, 'Hurst Exponent', color=c, style=pstyle, linewidth=lT)

plot(cu, 'Confidence Interval', color=c_cv, trackprice=true, show_last=1)
plot(cd, 'Confidence Interval', color=c_cv, trackprice=true, show_last=1)

plot(smooth, 'MA', color=c_ma, linewidth=lTma)

//0.5 Mid Level
line mid = na
if barstate.islast
    mid := line.new(bar_index - 1, 0.5, bar_index, 0.5, xloc.bar_index, extend.left, color=c_mid, style=line.style_dashed)
    line.delete(mid[1])

//Table
var table htable = table.new(position.middle_right, 2, 2, bgcolor=color.new(color.black, 100), frame_color=#000000, frame_width=2, border_color=color.new(color.black, 100), border_width=3)
if barstate.islast and dt
    table.cell(htable, column=0, row=0, text='Hurst Exponent:', text_color=color.white, bgcolor=color.new(color.gray, 50), text_size=tsize)
    table.cell(htable, column=1, row=0, text=str.tostring(math.round(slope, 3)), text_color=c, bgcolor=color.new(c, 85), text_size=tsize)
    table.cell(htable, column=0, row=1, text='State:', text_color=color.white, bgcolor=color.new(color.gray, 50), text_size=tsize)
    table.cell(htable, column=1, row=1, text=text_1, text_color=c, bgcolor=color.new(c, 85), text_size=tsize)
//}

Overview

Inputs set the sample size, base and maximum scales, an optional smoothing filter and a date range that limits computation. Colours mark significant trend or mean reversion against a confidence interval, with an optional table. It plots in a separate pane without trade signals.

Details

Published by

Teerth1 on GitHub

Code credit

balipour, as written in the script's header

Type

Indicator, Pine Script v5

Draws

Separate pane below the chart

Category

Trend, Mean reversion

Markets

Any symbol

Timeframes

Any timeframe

Risk Notes

No repainting, lookahead or stacked entries were found in its code or README. That says nothing about how well it works: test it first.

Settings

The inputs you can change from the gear icon on the chart. Defaults are the author's.

SettingTypeDefaultVariable
Date RangestringALLuseRange
Numberfloat300number
Sample Sizeint100len
Show Filterboolfalseshowma
Lengthint18slen
Base Scaleint8Bsc
Max Scaleint2Msc
Plot Style stringCistl
Line Thicknessint1lT
MAcolorcolor.orangec_ma
Line Thicknessint1lTma
> 0.5colorcolor.aquac_t
Show all 20 settings
SettingTypeDefaultVariable
< 0.5color#FF0080ffc_m
Significant Trendcolorcolor.limec_st
Significant Mean Reversioncolorcolor.yellowc_sm
Confidence Intervalcolorcolor.whitec_cv
Mid Linecolorcolor.whitec_mid
Show TablestringONdt
Dark BackgroundstringONbg
Sizestringnormaltsize
Third-party code. ForexR did not write, test or endorse this script, and the summary above was generated automatically from its code and README. Indicators describe the past, and a strategy's backtest can look better than live trading, especially when a script repaints. Check it in the Strategy Tester and on a demo account before you rely on it.

Similar Pine Scripts

99 stars

The Augmented Dickey-Fuller indicator calculates statistical stationarity and tests for unit roots in price series over a rolling window. It performs ordinary least squares regression on differenced historical price data to compute a t-statistic and an estimat

Indicator v6 Mean reversionTrend
Updated 4 weeks ago · Apache-2.0 GitHub repository of ADF - Augmented Dickey-Fuller Test

AutoCorrelation Function

by Anderson-ALGO
9 stars

This indicator calculates sample autocorrelation across multiple lag intervals for a selected price series. It computes correlation values over a user-specified lookback period using raw prices, log returns, absolute log returns, or squared log returns. Plotte

Indicator v4 TrendMean reversion
Updated 5 years ago · None stated GitHub repository of AutoCorrelation Function

Calculates a composite carry and decay oscillator fusing impulse-autocorrelation half-life, a Hurst exponent approximation, path efficiency, and range expansion ratios. It evaluates whether an impulse is likely to persist or mean-revert, plotting the oscillato

Indicator v6 TrendOscillators & momentum
Updated 2 days ago · MIT GitHub repository of Market Memory & Decay Oscillator [WavesUnchained]

MACD x RSI Study

by jerryinyang
5 stars

This indicator combines MACD and RSI to generate pullback signals on forex pairs. It plots MACD line, signal line and histogram alongside RSI and Wave Trend oscillator. Higher-timeframe MACD provides trend bias while RSI identifies overbought and oversold zone

Indicator v4 Oscillators & momentumMoving averages
Updated 2 years ago · None stated GitHub repository of MACD x RSI Study
2 stars

Rolling Z-Score Trend [QuantAlgo] calculates a rolling Z-score using mean and standard deviation over a user-defined lookback window to evaluate statistical price deviations and momentum. Plotted in a separate indicator pane, it displays the rolling Z-score li

Indicator v6 TrendOscillators & momentum
Updated 8 months ago · None stated GitHub repository of Rolling Z-Score Trend [QuantAlgo]

Adaptive Signals V17

by Matthew-Eucaristo
1 stars

A crypto futures signal indicator in a separate pane that scores setups and only flags those passing a validity gate. It has a trend pullback engine using limit-order style entries and a range engine that fades stretched moves back toward the mean. Filters inc

Indicator v6 TrendMean reversion
Updated 3 weeks ago · MIT GitHub repository of Adaptive Signals V17

More indicators

Trade Your Charts With a Regulated Broker

Compare brokers that connect to TradingView, with spreads, minimum deposits and leverage side by side.

Compare brokers