ECI Gaussian Indicator for ThinkorSwim

horserider

Well-known member
VIP
2019-11-25-TOS-CHARTS.png

ECI is based on the FE algorithm
Original plot style by Mobius

Expansion Contraction Indicator (ECI): 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. ECI plots the areas where price becomes compressed with colored and clouded bands. The indicator also leaves legacy points in areas of past compression.

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:
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
 
Can anyone help me out. How do you use this indicator? What do you do when you see past plotted lines. Should that act as support resistance? When it's compressing does that mean its getting ready to make a big move? Any input would be greatly appreciated

https://tos.mx/2Lyqnt



https://onedrive.live.com/redir?resid=2FF733D1BA1E1E79%21404&authkey=%21ABOXXFyQg1iUqFk&page=View&wd=target%2803.%20Technical%20Analysis%2FVolatility.one%7Ceb171eac-37e6-47df-a1d0-7142a9089dcf%2FECI%20%28Expansion%20Contraction%20Indicator%5C%29%7C14b44954-d864-4c17-815b-8baa798a3e46%2F%29

 
Last edited:
@Miket The notes in that indicator made it very clear what it does.

> Expansion Contraction Indicator (ECI):
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.

I don't think it shows support or resistance. Basically just where price consolidate and that suggests the stock will be making a move one way or the other soon.

 
Last edited:
I see a green box and red box form above & below the yellow dots. Sometimes its there sometimes not. What does it mean?

 
Last edited:
Miket, The green and red boxes are just visuals. Mobius calls them hot air but included them for the visually impaired. There are many variations of the script floating around, Read the notes and comments where you found the study in the Onenote. They do not show support or resistance as BenTen noted. They also have nothing to do with direction. That is why Mobius mentioned other studies to go along with the ECI. I don't use them but was around for their creation and hacking by others.

I could have made it shorter if I had just included this directly from the script: ECI plots the areas where price becomes compressed with colored and clouded bands.

 
Last edited:
thanks. it is very good indicator , but scanner is just for uptrend, can you make one for downtrend.
 
@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:
@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?
 
@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.
 
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
 
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?
 
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.
 
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
 
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
Question, making sure I understand this, can you have the bull scan and a bear scan in the same code or do you have to have two different quote boards one for the bull scan and another one for the bear? thanks
 
Not sure where the misunderstanding is. The quoted comment you included in the above post refers to a scan. A scan only accepts a single plot statement so that was the reason I mentioned it.
 
Question, making sure I understand this, can you have the bull scan and a bear scan in the same code or do you have to have two different quote boards one for the bull scan and another one for the bear? thanks
@Trading51 As @tomsk said, you can only have one plot in a scan.
Thus, if you want a bullish scan, you put a Hashtag, Pound Sign, Comment (all the same thing >>> #) in front of the line of code that you do not want, which is the "plot bear scan" code.

Commenting out a line or 2 of code saves you from deleting it and then searching for the original to get that code back. :)(y)

Anywhere, at the beginning of any line of code, in any study, scan, marketwatch column or whatever, a person can put this little symbol # in front of any line of code and it will render that line of code unreadable by the computer. (Sorry for yelling)

If a person wants a bull scan and a bear scan, save one as Yogi Bull and the other as Yogi Bear, or whatever one wishes. and call up which ever scan you wish and it should perform as expected.

If all else fails, read the Tutorials Here and on TOS. Thanks!
 
Last edited:
Mobius mention a few indicators that can be used with this, Super trend fractal Pivots, super trend Deviation bands, and Linear regression deviation bands are these posted somewhere?
 

Join useThinkScript to post your question to a community of 21,000+ developers and traders.

Similar threads

Not the exact question you're looking for?

Start a new thread and receive assistance from our community.

87k+ Posts
249 Online
Create Post

Similar threads

Similar threads

The Market Trading Game Changer

Join 2,500+ subscribers inside the useThinkScript VIP Membership Club
  • Exclusive indicators
  • Proven strategies & setups
  • Private Discord community
  • ‘Buy The Dip’ signal alerts
  • Exclusive members-only content
  • Add-ons and resources
  • 1 full year of unlimited support

Frequently Asked Questions

What is useThinkScript?

useThinkScript is the #1 community of stock market investors using indicators and other tools to power their trading strategies. Traders of all skill levels use our forums to learn about scripting and indicators, help each other, and discover new ways to gain an edge in the markets.

How do I get started?

We get it. Our forum can be intimidating, if not overwhelming. With thousands of topics, tens of thousands of posts, our community has created an incredibly deep knowledge base for stock traders. No one can ever exhaust every resource provided on our site.

If you are new, or just looking for guidance, here are some helpful links to get you started.

What are the benefits of VIP Membership?
VIP members get exclusive access to these proven and tested premium indicators: Buy the Dip, Advanced Market Moves 2.0, Take Profit, and Volatility Trading Range. In addition, VIP members get access to over 50 VIP-only custom indicators, add-ons, and strategies, private VIP-only forums, private Discord channel to discuss trades and strategies in real-time, customer support, trade alerts, and much more. Learn all about VIP membership here.
How can I access the premium indicators?
To access the premium indicators, which are plug and play ready, sign up for VIP membership here.
Back
Top