Is there Hurst Exponent in ToS?

K

KKaiser

Member
VIP
Dear Members,

I am trying to locate Hurst Exponent. I came this while reading thinkScript manual where @AlphaInvestor uses it as follow: I use it to gauge whether the price is Random (Chop) HE = 0.5, Trending (HE>0.5), or Mean Reverting (HE<0.5). Please advice where i can get the script and more info about this indicator for day trading/scalping.


Thank you,
KKaiser
 
sniktau

sniktau

New member
Hello,

I am fascinated by the Hurst Exponent and interested in its use in determining if a price is persisting, reverting, or random across timescales. This is a lovely departure from the i.i.d. stochastic processes touched upon in my undergraduate probability and signal processing courses. I am still absorbing the significance and nuance of Mandelbrot's: The (Mis)Behavior of Markets, and scrutinizing the heaps of curious tools, scripts, and scratches I've trawled up from the internet which are in varying degrees of disrepair and decay.

Given that neither of us can find such a function within ToS or just about on the wide web, I have been interested in implementing the following approximation of the Hurst Exponent, which I found in a YouTube Video from Paralax Research (the manual for their Bloomberg Application is here, page 37 onwards is interesting for our purposes). The approximation discussed in their YouTube video is as follows:



  • Where h is the highest high in the time range,
  • l is the lowest low in the time range,
  • t is the time period over which measurements are taken
  • average_*true*_range is the average true price range
  • C is a correction factor... ExtremeHurst has some other part that considers log-periodic oscillations... not going into that
EDIT Correcting an error.

I've tracked down the YouTube video here


Let me know what you think of this approximation. I have been a little bit frozen on this because I also want to check it against calculating the Hurst Exponent with the same data in a different tool, and probability was not my strong point in engineering school.
 
Last edited:
K

KKaiser

Member
VIP
Hi @sniktau After searching whole day I came across Hurst channel code from Trendxplore website. Hopefully @BenTen @markos @horserider can help us with this topic. Thank you for the Paralax Reseach. I am not at all a coder but trying to learn. This site is great place to understand all the fancy and useful tools and suggestions.

Code:
# Hurst_Channels
#
# www.trendxplorer.info
# [email protected]
#
# Build: July 25, 2012
# Rev 1: July 27, 2012: ExtrapolatedMA based on Kirills code
# Rev 2: July 29, 2012: FlowPrice value for better extremes
# Rev 3: Sept 9, 2012: Coloring for ExtrapolatedCMA added
#

#
# --- script begin ----
#

declare upper;

input price = hl2;
input length = 10;
input InnerValue = 1.6;
input OuterValue = 2.6;
input ExtremeValue = 4.2;
input showFlowPrice = NO;
input showPriceBar = YES;
input smooth = 1;

def displacement = (-length / 2) + 1;
def dPrice = price[displacement];

rec CMA = if !IsNaN(dPrice) then Average(dPrice, AbsValue(length)) else CMA[1] + (CMA[1] - CMA[2]);

plot CenteredMA = if !IsNaN(dPrice) then CMA else Double.NaN;
CenteredMA.SetDefaultColor(GetColor(1));
CenteredMA.SetLineWeight(2);

plot ExtrapolatedMA = if !IsNaN(price) and IsNaN(dprice[-1]) then CMA else
Double.NaN;
ExtrapolatedMA.SetDefaultColor(GetColor(0));
ExtrapolatedMA.SetLineWeight(2);
ExtrapolatedMA.SetStyle(Curve.SHORT_DASH);
ExtrapolatedMA.DefineColor("Up", Color.Magenta);
ExtrapolatedMA.DefineColor("Down", Color.Yellow);
ExtrapolatedMA.AssignValueColor(if ExtrapolatedMA >= ExtrapolatedMA[1] then ExtrapolatedMA.color("Up") else ExtrapolatedMA.color("Down"));

def ExtremeBand = CMA * ExtremeValue / 100;;
def OuterBand = CMA * OuterValue / 100;
def InnerBand   = CMA * InnerValue / 100;

plot UpperExtremeBand = if !IsNaN(price) then CMA + ExtremeBand else Double.Nan;
plot LowerExtremeBand = if !IsNaN(price) then CMA - ExtremeBand else Double.Nan;
plot UpperOuterBand = if !IsNaN(price) then CMA + OuterBand else Double.Nan;
plot LowerOuterBand = if !IsNaN(price) then CMA - OuterBand else Double.Nan;
plot UpperInnerBand = if !IsNaN(price) then CMA + InnerBand else Double.Nan;
plot LowerInnerBand   = if !IsNaN(price) then CMA - InnerBand else Double.Nan;

UpperExtremeBand.SetDefaultColor(GetColor(4));
UpperExtremeBand.SetLineWeight(2);
LowerExtremeBand.SetDefaultColor(GetColor(4));
LowerExtremeBand.SetLineWeight(2);
UpperExtremeBand.hide();
LowerExtremeBand.hide();

UpperOuterBand.SetDefaultColor(GetColor(5));
UpperOuterBand.SetLineWeight(2);
LowerOuterBand.SetDefaultColor(GetColor(6));
LowerOuterBand.SetLineWeight(2);

UpperInnerBand.SetDefaultColor(GetColor(5));
UpperInnerBand.SetLineWeight(1);
UpperInnerBand.SetStyle(Curve.SHORT_DASH);
LowerInnerBand.SetDefaultColor(GetColor(6));
LowerInnerBand.SetLineWeight(1);
LowerInnerBand.SetStyle(Curve.SHORT_DASH);

# Turn AddClouds off by putting a #-sign at the first position of the lines
AddCloud(UpperOuterBand, UpperInnerBand, color.red);
AddCloud(LowerInnerBand, LowerOuterBand, color.green);

#Rev 2:
#def FlowValue = if close > close[1] then high else if close < close[1] then low else (high + low)/2;
def FlowValue =
if high >= high[1] and low <= low[1]
then
if close >= close[1] #or high >= high[2]
then high
else low
else
if high > high[1]
then high
else
if low < low[1]
then low
else
if close > close[1]
then high
else
if close < close[1]
then low
                    else (high + low) / 2;

plot FlowPrice = if showFlowPrice then Average(FlowValue, smooth) else double.nan;
FlowPrice.SetDefaultColor(GetColor(9));
FlowPrice.SetLineWeight(2);

hidePricePlot(!showPriceBar);

#
# --- script end ----
#
 
horserider

horserider

Well-known member
VIP
Looked at these long ago. If I remember correctly the inputs need to be specific for the stock you are charting. Maybe that was a different band indicator. Just too long ago to remember correctly. Anyway I dropped it due to that problem.
 
sniktau

sniktau

New member
Thank you, @KKaiser, this is another interesting tidbit but just like I've observed from looking at other tools scattered about, there's clear deficiencies or missing dependencies that make them hard to use, as @horserider mentioned. Now, with that in mind, I'd like to pore over the code you posted and see what else is associated with it.

... the inputs need to be specific for the stock you are charting

What do you mean by this, Horserider? How did do you tune the inputs? How do you know if they're set sane or insane?
 
T

tradebyday

Active member
As a word of caution to those looking at Hurst bands, the indicator repaints many candles back as it uses forward price action to adjust where "center" is. @sniktau what horserider is saying is that you will need to adjust the settings for each time frame and each asset you trade. For example: I use hurst bands on a 1min chart for MES with length 400 and deviations set at .5, 1.0, and 1.5 respectively. I start scaling in shorts when price enters the upper highlighted zone, start scaling in longs when it enters lower highlighted zone, with the expectation of scalping profits the other way back towards center channel. BUT if I switch to a different time frame, these settings will not work. If I go with still a 1min time frame but on SPY instead, those settings most likely are far from optimal. This is a usable tool, but important to understand its limitations.
 
sniktau

sniktau

New member
Thanks for the reply @tradebyday, I will apply your defaults to this interesting plugin and see what it does with that instrument and timescale to calibrate my sense of what it "should" look like, but I still am without a means to systematively calibrate the Hurst bands study for other times scales or instruments. How did you figure it out the first time?

I am also a bit disinclined from using this tool because I want to do analysis at multiple timescales and present it in the "thermo" style window. Hurst at one timescale? Good, but not especially insightful.
 
T

tradebyday

Active member
No problem @sniktau . Ya a trader on twitter had some settings he shared, so that's how I got something close to his. The longer length is needed to keep the repaint from being too drastic, but the deviations of the bands will need major modifications between each ticker symbol and each timeframe. The hurst bands I have settings for are a tad extreme and therefore do not yield reversal trades every day, which I prefer since I trade multiple strategies in a given day based on what is presented to me. But at the end of the day, it is more of a scalpers tool, rather than a trend trading tool
 
sniktau

sniktau

New member
@tradebyday I would like to investigate KKaiser's Hurst find some more because it never occurred to me there was a way to map that measure to bounds on a price. I haven't looked at the script too closely yet but I've tried a few input parameters against a few stocks but I don't know good cal from bad cal.

What is the handle for that Twitter trader? Do they give out unique calibration parameters for the Hurst channels when they discuss a stock?
 
K

KKaiser

Member
VIP
Hi @sniktau I found Mobius version of Hurst Exponent.

# Hurst Exponent
# Mobius
# V03.10.2015

# To estimate the Hurst exponent a Root time series is rescaled into shorter ranges. The ranges are mean centered and the Hurst exponent is derived from the exponent of this power law.

# The commented out plots are to check the Average rescaled segments for continuity.

#hint: Hurst Exponent responds best to large data fields.

declare lower;

input n = 252; #hint n: Length for the Hurst Exponent calculations.

def bar = barNumber();
def Lbar = HighestAll(if !isNaN(close[-1]) then bar else double.nan);
def coef1 = Floor(n / 2);
def coef2 = Floor(n / 4);
def coef3 = Floor(n / 8);
def coef4 = Floor(n / 16);

addLabel(1, "Bars On Chart = " + bar + " coef n = " + n + " coef 1 = " + coef1 + " coef2 = " + coef2 + " coef3 = " + coef3 + " coef4 = " + coef4, color.white);

def c = close;
def LD = LinDev(c, n);
def Root = (highest(LD, n) - lowest(LD, n)) / StDev(LD, n);

# =====================================================

def baseSet = if bar >= Lbar - n
then (fold a = 0 to n
with r
while bar < Lbar
do r + Root) / n
else baseSet[1];

#plot data = if baseSet then baseSet else double.nan;

# =====================================================

def Set1 = if bar >= Lbar - n
then (fold i = 0 to coef1
with s
while bar < Lbar - n + coef1
do s + Root) / coef1
else Set1[1];

#plot data1 = if Set1 then Set1 else double.nan;

def Set2 = if bar >= Lbar - n + coef1
then (fold i2 = 0 to coef1
with s2
while bar <= Lbar
do s2 + Root) / coef1
else Set2[1];

#plot data2 = if Set2 then Set2 else double.nan;

# ============================================================

def Set3 = if bar >= Lbar - n
then (fold i3 = 0 to coef2
with s3
while bar < Lbar - n + coef2
do s3 + Root) / coef2
else Set3[1];

#plot data3 = if Set3 then Set3 else double.nan;

def Set4 = if bar >= Lbar - n + coef2
then (fold i4 = 0 to coef2
with s4
while bar < Lbar - n + (coef2 * 2)
do s4 + Root) / coef2
else Set4[1];

#plot data4 = if Set4 then Set4 else double.nan;

def Set5 = if bar >= Lbar - n + (coef2 * 2)
then (fold i5 = 0 to coef2
with s5
while bar < Lbar - n + (coef2 * 3)
do s5 + Root) / coef2
else Set5[1];

#plot data5 = if Set5 then Set5 else double.nan;

def Set6 = if bar >= Lbar - n + (coef2 * 3)
then (fold i6 = 0 to coef2
with s6
while bar < Lbar
do s6 + Root) / coef2
else Set6[1];

#plot Data6 = if Set6 then Set6 else double.nan;

#===========================================================

def Set7 = if bar >= Lbar - n
then (fold i7 = 0 to coef3
with s7
while barNumber() < Lbar - n + coef3
do s7 + Root) / coef3
else Set7[1];

#plot Data7 = if Set7 then Set7 else double.nan;

def Set8 = if bar >= Lbar - n + coef3
then (fold i8 = 0 to coef3
with s8
while bar < Lbar - n + (coef3 * 2)
do s8 + Root) / coef3
else Set8[1];

#plot Data8 = if Set8 then Set8 else double.nan;

def Set9 =if bar >= Lbar - n + (coef3 * 2)
then (fold i9 = 0 to coef3
with s9
while bar < Lbar - n + (coef3 * 3)
do s9 + Root) / coef3
else Set9[1];

#plot Data9 = if Set9 then Set9 else double.nan;

def Set10 = if bar >= Lbar - n + (coef3 * 3)
then (fold i10 = 0 to coef3
with s10
while bar < Lbar - n + (coef3 * 4)
do s10 + Root) / coef3
else Set10[1];

#plot Data10 = if Set10 then Set10 else double.nan;

def Set11 = if bar >= Lbar - n + (coef3 * 4)
then (fold i11 = 0 to coef3
with s11
while bar < Lbar - n + (coef3 * 5)
do s11 + Root) / coef3
else Set11[1];

#plot Data11 = if Set11 then Set11 else double.nan;

def Set12 = if bar >= Lbar - n + (coef3 * 5)
then (fold i12 = 0 to coef3
with s12
while bar < Lbar - n + (coef3 * 6)
do s12 + Root) / coef3
else Set12[1];

#plot Data12 = if Set12 then Set12 else double.nan;

def Set13 = if bar >= Lbar - n + (coef3 * 6)
then (fold i13 = 0 to coef3
with s13
while bar < Lbar - n + (coef3 * 7)
do s13 + Root) / coef3
else Set13[1];

#plot Data13 = if Set13 then Set13 else double.nan;

def Set14 = if bar >= Lbar - n + (coef3 * 7)
then (fold i14 = 0 to coef3
with s14
while bar < Lbar
do s14 + Root) / coef3
else Set14[1];

#plot Data14 = if Set14 then Set14 else double.nan;

#================================================================

def Set15 = if bar >= Lbar - n
then (fold i15 = 0 to coef4
with s15
while bar < Lbar - n + coef4
do s15 + Root) / coef4
else Set15[1];

#plot Data15 = if Set15 then Set15 else double.nan;

def Set16 = if bar >= Lbar - n + coef4
then (fold i16 = 0 to coef4
with s16
while bar < Lbar - n + (coef4 * 2)
do s16 + Root) / coef4
else Set16[1];

#plot Data16 = if Set16 then Set16 else double.nan;

def Set17 = if bar >= Lbar - n + (coef4 * 2)
then (fold i17 = 0 to coef4
with s17
while bar < Lbar - n + (coef4 * 3)
do s17 + Root) / coef4
else Set17[1];

#plot Data17 = if Set17 then Set17 else double.nan;

def Set18 = if bar >= Lbar - n + (coef4 * 3)
then (fold i18 = 0 to coef4
with s18
while bar < Lbar - n + (coef4 * 4)
do s18 + Root) / coef4
else Set18[1];

#plot Data18 = if Set18 then Set18 else double.nan;

def Set19 = if bar >= Lbar - n + (coef4 * 4)
then (fold i19 = 0 to coef4
with s19
while bar < Lbar - n + (coef4 * 5)
do s19 + Root) / coef4
else Set19[1];

#plot Data19 = if Set19 then Set19 else double.nan;

def Set20 = if bar >= Lbar - n + (coef4 * 5)
then (fold i20 = 0 to coef4
with s20
while bar < Lbar - n + (coef4 * 6)
do s20 + Root) / coef4
else Set20[1];

#plot Data20 = if Set20 then Set20 else double.nan;

def Set21 = if bar >= Lbar - n + (coef4 * 6)
then (fold i21 = 0 to coef4
with s21
while bar < Lbar - n + (coef4 * 7)
do s21 + Root) / coef4
else Set21[1];

#plot Data21 = if Set21 then Set21 else double.nan;

def Set22 = if bar >= Lbar - n + (coef4 * 7)
then (fold i22 = 0 to coef4
with s22
while bar < Lbar - n + (coef4 * 8)
do s22 + Root) / coef4
else Set22[1];

#plot Data22 = if Set22 then Set22 else double.nan;

def Set23 = if bar >= Lbar - n + (coef4 * 8)
then (fold i23 = 0 to coef4
with s23
while bar < Lbar - n + (coef4 * 9)
do s23 + Root) / coef4
else Set23[1];

#plot Data23 = if Set23 then Set23 else double.nan;

def Set24 = if bar >= Lbar - n + (coef4 * 9)
then (fold i24 = 0 to coef4
with s24
while bar < Lbar - n + (coef4 * 10)
do s24 + Root) / coef4
else Set24[1];

#plot Data24 = if Set24 then Set24 else double.nan;

def Set25 = if bar >= Lbar - n + (coef4 * 10)
then (fold i25 = 0 to coef4
with s25
while bar < Lbar - n + (coef4 * 11)
do s25 + Root) / coef4
else Set25[1];

#plot Data25 = if Set25 then Set25 else double.nan;

def Set26 = if bar >= Lbar - n + (coef4 * 11)
then (fold i26 = 0 to coef4
with s26
while bar < Lbar - n + (coef4 * 12)
do s26 + Root) / coef4
else Set26[1];

#plot Data26 = if Set26 then Set26 else double.nan;

def Set27 = if bar >= Lbar - n + (coef4 * 12)
then (fold i27 = 0 to coef4
with s27
while bar < Lbar - n + (coef4 * 13)
do s27 + Root) / coef4
else Set27[1];

#plot Data27 = if Set27 then Set27 else double.nan;

def Set28 = if bar >= Lbar - n + (coef4 * 13)
then (fold i28 = 0 to coef4
with s28
while bar < Lbar - n + (coef4 * 14)
do s28 + Root) / coef4
else Set28[1];

#plot Data28 = if Set28 then Set28 else double.nan;

def Set29 = if bar >= Lbar - n + (coef4 * 14)
then (fold i29 = 0 to coef4
with s29
while bar < Lbar - n + (coef4 * 15)
do s29 + Root) / coef4
else Set29[1];

#plot Data29 = if Set29 then Set29 else double.nan;

def Set30 = if bar >= Lbar - n + (coef4 * 15)
then (fold i30 = 0 to coef4
with s30
while bar < Lbar
do s30 + Root) / coef4
else Set30[1];

#plot Data30 = if Set30 then Set30 else double.nan;

def M = (BaseSet + Set1 + Set2 + Set3 + Set4 + Set5 + Set6 + Set7 + Set8 + Set9 + Set10 + Set11 + Set12 + Set13 + Set14 + Set15 + Set16 + Set17 + Set18 + Set19 + Set20 + Set21 + Set22 + Set23 + Set24 + Set25 + Set26 + Set27 + Set28 + Set29 + Set30) / 31;

def Hurst = if bar >= Lbar - n
then (fold b = 0 to n
with z
while bar < Lbar
do z + M) / n
else double.nan;

Plot HurstE = If Hurst == 0 then double.nan else Hurst;

#HurstE.SetDefaultColor(Color.Cyan);

plot zero = if isNaN(c) then double.nan else 0;
zero.SetDefaultColor(Color.Yellow);

plot one = if isNaN(c) then double.nan else 1;
one.SetDefaultColor(Color.Yellow);

plot LM = if isNaN(c) then double.nan else .45;
LM.SetDefaultColor(Color.Gray);

plot HM = if isNaN(c) then double.nan else .55;
HM.SetDefaultColor(Color.Gray);

AddCloud(LM , HM, color.white, color.white);

AddCloud(HM, one, Color.Light_Green, Color.Light_Green);

AddCloud(zero, LM, Color.Light_Red, Color.Light_Red);

# End Code Hurst Exponent

AddChartBubble(!isNaN(c[1]) and isNaN(c), .5, "Brownian", color.white, yes);

AddChartBubble(!isNaN(c[1]) and isNaN(c), 0, "Mean Reverting", color.white, yes);

AddChartBubble(!isNaN(c[1]) and isNaN(c), 1, "Trending", color.white, no);

# End Code Hurst Exponent
 
wtf_dude

wtf_dude

Active member
I'm trying to make the value of the Hurst exponent an upper label, but for SOME stupid reason all I get is an N/A or a 0 instead of the plot value? Ideas?
 

Similar threads

Top