ECI Gaussian Indicator for ThinkorSwim

H

horserider

Well-known member
VIP
Warehouse
Did not find this in a search. Sorry if it already was posted.

It is a compression study is very fast at showing compression. Has some hints of when compression turns into expansion.

Code:
#hint: Expansion Contraction Indicator (ECI): \n ECI Identifies areas of price compression which leads to price expansion. ECI doesn't show the direction of a trend but does indicate when a trend is going to resume (price flagging) or if a change in trend polarity is happening.\n ECI plots the areas where price becomes compressed with colored and clouded bands. The indicator also leaves legacy points in areas of past compression.
# ECI is based on the FE algorithm
# Original plot style by Mobius
# Note: Default Lengths are not optimized. My personal experience has been length ranges between 8 and 13 are generally effective.
# Here's another way to look at Fractal Energy. This study plots it on the chart graph with clouded areas for the current price compression, exhaustion area and leaves colored points as a legacy plot for past areas.
# Good CSA choices with this study are:
# ECI + SuperTrend + Fractal Pivots
# ECI + SuperTrend + RSI in Laguerre Time
# ECI + SuperTrend + Standard Deviation Bands
# ECI + Linear Regression Standard Deviation Bands
# This version Modified to filter price to a normalized distribution

# User Inputs
input EciLength = 14; #hint EciLength: Length for calculations.
input AvgLength = 10; #hint AvgLength: Length for smoothing.
input AvgType = AverageType.Simple; #hint AvgType: Average Type
input MeanValue = HL2; #hint MeanValue: Point of origen.
input DisplayPoints = yes; #hint DisplayPoints: No Points.
input OnExpansion = yes; #hint OnExpansion: Line extensions.

# Variables
script g {
    input data = close;
    def w = (2 * Double.Pi / 8);
    def beta = (1 - Cos(w)) / (Power(1.414, 2.0 / 4) - 1 );
    def alpha = (-beta + Sqrt(beta * beta + 2 * beta));
    def G = Power(alpha, 4) * data +
                 4 * (1 – alpha) * G[1] – 6 * Power( 1 - alpha, 2 ) * G[2] +
                 4 * Power( 1 - alpha, 3 ) * G[3] - Power( 1 - alpha, 4 ) * G[4];
    plot Line = G;
}
def o = g(data = open);
def h = g(data = high);
def l = g(data = low);
def c = g(data = close);
def bar = BarNumber();
def HMax = Highest(Max(h, c[1]), EciLength);
def LMax = Lowest(Min(l, c[1]), EciLength);
def TR = HMax - LMax;
def ECI = Round((Log(Sum(TrueRange(h, c, l), EciLength) / TR) /
         Log(EciLength)) / TickSize(), 0) * TickSize();
def Avg = MovingAverage(AverageType = AvgType, ECI, AvgLength);
def S1 = if ECI crosses above Avg
         then MeanValue
         else S1[1];
def S = ECI > Avg;
def SBars = if ECI > Avg
            then bar
            else Double.NaN;
def StartBar = if ECI crosses above Avg
               then bar
               else StartBar[1];
def LastSBar = if ECI crosses below Avg
               then bar
               else LastSBar[1];
def PP = if ECI crosses above Avg
         then MeanValue
         else PP[1];
def Mean_Limit = if bar != StartBar
                 then bar - StartBar
                 else if bar == StartBar
                      then Double.NaN
                      else Mean_Limit[1];
def SHigh = if ECI crosses above Avg
            then h
            else SHigh[1];
def SHighBar = if S and
                  h == SHigh
               then bar
               else SHighBar[1];
def SHigh_Limit = if bar == StartBar
                  then Double.NaN
                  else if bar > StartBar
                       then bar - SHighBar
                       else SHigh_Limit[1];
def SLow = if ECI crosses above Avg
           then l
           else SLow[1];
def SLowBar = if S and
                  l == SLow
              then bar
              else SLowBar[1];
def SLow_Limit = if bar == StartBar
                 then Double.NaN
                 else if bar > StartBar
                      then bar - SLowBar
                      else SLow_Limit[1];
# Internal Script Reference
script LinePlot {
    input LineLimit = 0;
    input OnExpansion = yes;
    input data = close;
    input bar = 0;
    def ThisBar = HighestAll(bar);
    def cLine = if bar == ThisBar
                then data
                else Double.NaN;
    def cond1 = CompoundValue(1, if IsNaN(data)
                                 then cond1[1]
                                 else data, data);
    plot P = if ThisBar - LineLimit <= bar
             then HighestAll(cLine)
             else Double.NaN;
    plot ExpLine = if OnExpansion and
                     IsNaN(data[-1])
                   then cond1
                   else Double.NaN;
}
# Plots
plot SD_Pivot = LinePlot(data = PP, LineLimit = Mean_Limit, OnExpansion = OnExpansion, bar = StartBar).P;
plot SD_Pivot_X = LinePlot(data = PP, LineLimit = StartBar).ExpLine;
     SD_Pivot.SetDefaultColor(Color.CYAN);
     SD_Pivot_X.SetDefaultColor(Color.CYAN);
plot SD_R1 = LinePlot(data = SHigh, LineLimit = SHigh_Limit, OnExpansion = OnExpansion, bar = SHighBar).P;
plot SD_R1_X = LinePlot(data = SHigh, LineLimit = SHigh_Limit).ExpLine;
     SD_R1.SetDefaultColor(Color.Light_GREEN);
     SD_R1_X.SetDefaultColor(Color.Light_GREEN);
plot SD_S1 = LinePlot(data = SLow, LineLimit = SLow_Limit, OnExpansion = OnExpansion, bar = SLowBar).P;
plot SD_S1_X = LinePlot(data = SLow, LineLimit = SLow_Limit).ExpLine;
     SD_S1.SetDefaultColor(Color.Light_RED);
     SD_S1_X.SetDefaultColor(Color.Light_RED);
plot SPlot = if S
             then S1 #l - (2 * TickSize())
             else Double.NaN;
     SPlot.SetHiding(!DisplayPoints);
     SPlot.SetPaintingStrategy(PaintingStrategy.POINTS);
     SPlot.SetLineWeight(1);
     SPlot.SetDefaultColor(Color.Yellow);
addCloud(SD_pivot, SD_R1, CreateColor(50,150,75), CreateColor(50,150,70));
addCloud(SD_S1, SD_pivot, CreateColor(175,0,50), CreateColor(175,0,50));
addCloud(SD_pivot_X, SD_R1_X, CreateColor(50,150,75), CreateColor(50,150,70));
addCloud(SD_S1_X, SD_pivot_X, CreateColor(175,0,50), CreateColor(175,0,50));
# Audible Alerts
Alert(ECI crosses below Avg, "Exit", Alert.BAR, Sound.Bell);
AddLabel(1, "Energy Level = " + ECI, color.white);
# End Code Modified ECI
 
Last edited by a moderator:
T

tomsk

Well-known member
VIP
Warehouse
Given some of the recent discussion on consolidation and Mobius ECI study, for those folks that might be interested to scan the universe of stocks for such setups, I have converted Mobius ECI study into a scan. Two scan conditions are created - one for the bullish case and another for the bearish case. I have also removed extraneous variables not required for the scan.

Tested this on a scan of the S&P 500 (Daily aggregation) with the following results
Bullish scan - 138 hits, e.g. AMZN
Bearish scan - 20 hits e.go. PSX

Please remember that the scanner only expects one plot so comment out the scan plot statement you do not wish.
Here then is the scan code

Code:
# ECI Scan
# tomsk
# 11.25.2019

# Given some of the recent discussion on consolidation and Mobius ECI study, 
# for those folks that might be interested to scan the universe of stocks for 
# such setups, I have converted Mobius ECI study into a scan. Two scan conditions 
# are created - one for the bullish case and another for the bearish case. I 
# have also removed variables not required for the scan.

# Expansion Contraction Indication
# Flags: Uses Fractal enregy to locate price compression or flag areas
# Mobius
# 3.18.2017

# User Inputs
input EciLength = 5; #hint EciLength: Length for calculations.
input AvgType = AverageType.Simple; #hint AvgType: Average Type
input MeanValue = HL2; #hint MeanValue: Point of origen.
input betaDev = 4;

script G {
    input p = close;
    input n = 2;
    input b = 1.05;
    def w;
    def beta;
    def alpha;
    def G;
    w = (2 * Double.Pi / n);
    beta = (1 - Cos(w)) / (Power(1.414, 2.0 / b) - 1 );
    alpha = (-beta + Sqrt(beta * beta + 2 * beta));
    G = Power(alpha, 4) * p + 
                 4 * (1 – alpha) * G[1] – 6 * Power( 1 - alpha, 2 ) * G[2] + 
                 4 * Power( 1 - alpha, 3 ) * G[3] - Power( 1 - alpha, 4 ) * G[4];
    plot data = G;
}
# Variables:
def bar = barNumber();
def o = g(open, ECIlength, betaDev);
def h = g(high, ECIlength, betaDev);
def l = g(low, ECIlength, betaDev);
def c = g(close, ECIlength, betaDev);
def ECI = Log(Sum(Max(h, c[1]) - Min(l, c[1]), ECIlength) / 
           (Highest(h, ECIlength) - Lowest(l, ECIlength))) / 
            Log(ECIlength);
def Avg = MovingAverage(AverageType = AvgType, ECI, ECILength);
def S1 = if ECI crosses above Avg 
         then MeanValue
         else S1[1];
def S = ECI > Avg;
def SBars = if ECI > Avg
            then bar
            else Double.NaN;
def StartBar = if ECI crosses above Avg 
               then bar
               else StartBar[1];
def LastSBar = if ECI crosses below Avg
               then bar
               else LastSBar[1];
def PP = if ECI crosses above Avg
         then MeanValue
         else PP[1];
def Mean_Limit = if bar != StartBar
                 then bar - StartBar
                 else if bar == StartBar
                      then Double.NaN
                      else Mean_Limit[1];
def SHigh = if ECI crosses above Avg
            then h
            else SHigh[1];
def SHighBar = if S and
                  h == SHigh
               then bar
               else SHighBar[1];
def SHigh_Limit = if bar == StartBar
                  then Double.NaN
                  else if bar > StartBar
                       then bar - SHighBar
                       else SHigh_Limit[1];
def SLow = if ECI crosses above Avg
           then l
           else SLow[1];
def SLowBar = if S and
                  l == SLow
              then bar
              else SLowBar[1];
def SLow_Limit = if bar == StartBar
                 then Double.NaN
                 else if bar > StartBar
                      then bar - SLowBar
                      else SLow_Limit[1];

# Comment out (#) the ONE not needed
plot BullScan = close crosses above SHigh;
#plot BearScan = close crosses below SLow;
# ECI Scan
 
M

mmm777

New member
VIP
Marketplace
thanks. it is very good indicator , but scanner is just for uptrend, can you make one for downtrend.
 
C

chillc15

New member
@mmm777

Per @tomsk you have to comment out which one you don't want.

# Comment out (#) the ONE not needed
plot BullScan = close crosses above SHigh;
#plot BearScan = close crosses below SLow;
# ECI Scan

# Comment out (#) the ONE not needed
#plot BullScan = close crosses above SHigh;
plot BearScan = close crosses below SLow;
# ECI Scan
 
Last edited by a moderator:
H

HighBredCloud

Active member
@chillc15 so for the rest of the none coders on this site...how is that suppose to look like? I know it easy for most of you...but where exactly do you comment out? What part?
 
BenTen

BenTen

Administrative
Staff
VIP
Warehouse
@HighBredCloud The code posted by @chillc15 already commented out the stuff for you.

Take a look at the first portion:

Code:
# Comment out (#) the ONE not needed
plot BullScan = close crosses above SHigh;
#plot BearScan = close crosses below SLow;
# ECI Scan
Notice how in front of plot BullScan there isn't a # sign? That means you're looking for bullish signals. Now, if you want to scan for bearish signals, then add # back to the BullScan and remove the # from plot BearScan.
 
H

HighBredCloud

Active member
@BenTen OK...so it looks like just the bottom of the code needs to be changed with the # mark in order to see which scan you want...

I had no idea where to insert the portion @chillc15 did...Thank You!
 
T

tomsk

Well-known member
VIP
Warehouse
Just to be sure that EVERYONE understands how to interpret this, at the end of the scan there is a section of code like so:

# Comment out (#) the ONE not needed
plot BullScan = close crosses above SHigh;
#plot BearScan = close crosses below SLow;

Notice that there are some lines that are commented out with (#) - Those would be ignored by the scanner, only for human consumption
In the above example only the bullish scan is enabled.

In order to turn this into a bearish scan, just switch the commented lines like so

# Comment out (#) the ONE not needed
#plot BullScan = close crosses above SHigh;
plot BearScan = close crosses below SLow;

Compare those differences - it really is that simple.
Just REMEMBER that there can only be one active plot defined or the scanner would complain

OK Folks?

@BenTen If there is not already a tutorial that covers scan specifics, perhaps you can add this commentary there for any future folks who may require a little bit more assistance
 
D

diazlaz

Active member
VIP
Warehouse
Hi everyone, if the ECI is trend is quite interesting, amazing works well with lower and higher time frames. any ideas if a MTF version of this would yield any value? thoughts?
 
T

tomsk

Well-known member
VIP
Warehouse
Most folks use MTF studies to determine trend, momentum, breadth, sentiment across different time frames to determine if they have an edge to undertake trading decisions. The ECI is a bit different. The concept of the ECI is very simple - identifies areas of price compression which in turn leads to price expansion. It doesn't show the direction of a trend but indicates when a trend is going to resume or if there is a change in polarity of the trend.
 
J007RMC

J007RMC

Active member
VIP
Warehouse
Given some of the recent discussion on consolidation and Mobius ECI study, for those folks that might be interested to scan the universe of stocks for such setups, I have converted Mobius ECI study into a scan. Two scan conditions are created - one for the bullish case and another for the bearish case. I have also removed extraneous variables not required for the scan.

Tested this on a scan of the S&P 500 (Daily aggregation) with the following results
Bullish scan - 138 hits, e.g. AMZN
Bearish scan - 20 hits e.go. PSX

Please remember that the scanner only expects one plot so comment out the scan plot statement you do not wish.
Here then is the scan code

Code:
# ECI Scan
# tomsk
# 11.25.2019

# Given some of the recent discussion on consolidation and Mobius ECI study,
# for those folks that might be interested to scan the universe of stocks for
# such setups, I have converted Mobius ECI study into a scan. Two scan conditions
# are created - one for the bullish case and another for the bearish case. I
# have also removed variables not required for the scan.

# Expansion Contraction Indication
# Flags: Uses Fractal enregy to locate price compression or flag areas
# Mobius
# 3.18.2017

# User Inputs
input EciLength = 5; #hint EciLength: Length for calculations.
input AvgType = AverageType.Simple; #hint AvgType: Average Type
input MeanValue = HL2; #hint MeanValue: Point of origen.
input betaDev = 4;

script G {
    input p = close;
    input n = 2;
    input b = 1.05;
    def w;
    def beta;
    def alpha;
    def G;
    w = (2 * Double.Pi / n);
    beta = (1 - Cos(w)) / (Power(1.414, 2.0 / b) - 1 );
    alpha = (-beta + Sqrt(beta * beta + 2 * beta));
    G = Power(alpha, 4) * p +
                 4 * (1 – alpha) * G[1] – 6 * Power( 1 - alpha, 2 ) * G[2] +
                 4 * Power( 1 - alpha, 3 ) * G[3] - Power( 1 - alpha, 4 ) * G[4];
    plot data = G;
}
# Variables:
def bar = barNumber();
def o = g(open, ECIlength, betaDev);
def h = g(high, ECIlength, betaDev);
def l = g(low, ECIlength, betaDev);
def c = g(close, ECIlength, betaDev);
def ECI = Log(Sum(Max(h, c[1]) - Min(l, c[1]), ECIlength) /
           (Highest(h, ECIlength) - Lowest(l, ECIlength))) /
            Log(ECIlength);
def Avg = MovingAverage(AverageType = AvgType, ECI, ECILength);
def S1 = if ECI crosses above Avg
         then MeanValue
         else S1[1];
def S = ECI > Avg;
def SBars = if ECI > Avg
            then bar
            else Double.NaN;
def StartBar = if ECI crosses above Avg
               then bar
               else StartBar[1];
def LastSBar = if ECI crosses below Avg
               then bar
               else LastSBar[1];
def PP = if ECI crosses above Avg
         then MeanValue
         else PP[1];
def Mean_Limit = if bar != StartBar
                 then bar - StartBar
                 else if bar == StartBar
                      then Double.NaN
                      else Mean_Limit[1];
def SHigh = if ECI crosses above Avg
            then h
            else SHigh[1];
def SHighBar = if S and
                  h == SHigh
               then bar
               else SHighBar[1];
def SHigh_Limit = if bar == StartBar
                  then Double.NaN
                  else if bar > StartBar
                       then bar - SHighBar
                       else SHigh_Limit[1];
def SLow = if ECI crosses above Avg
           then l
           else SLow[1];
def SLowBar = if S and
                  l == SLow
              then bar
              else SLowBar[1];
def SLow_Limit = if bar == StartBar
                 then Double.NaN
                 else if bar > StartBar
                      then bar - SLowBar
                      else SLow_Limit[1];

# Comment out (#) the ONE not needed
plot BullScan = close crosses above SHigh;
#plot BearScan = close crosses below SLow;
# ECI Scan,,,

I ran this but added a few scan parameters that returned 6 stocks FRI. needless to say all very bullish.
ECI Bull Scan/ set daily
min $20.00
% change plus min 2% max 10%
avg vol 30 simple up to 1 mil
 

Top