Hello everyone,
I'm back today with a pretty unique indicator for evaluating market trend and conditions. It combines two different oscillators with a moving average, standard deviations and fractal energy to help identify trends and their exhaustion. I use this for day trading and this is mostly a mean reversion tool for me. It allows me to keep my charts clean to focus on levels while still providing me with useful information. The setup of this indicator is really a framework that could be used to swap in other oscillators or trend identifiers as desired. It is important to note that oversold or overbought conditions can continue to exist for a long while. Never enter a trade simply because something is overbought or oversold.
On to the details:
There are 4 sections to this indicator, so I will go from the bottom to the top. The colored band is an indication of the current trend. This information is derived from the Vidya Moving Average. As the fractal energy decreases in the move (ie. FE < 0.382), gray squares are printed on the trend identifier.
The next area is dedicated to the Chande Momentum Oscillator. I have found this to be a pretty reasonable oscillator for day trading/scalping on smaller timeframes. Many other oscillators seem to be constantly OB/OS on smaller timeframes and this is about as good as I could find.
The next area is the Volume Strength Index or Slow VSI. Provides a different take on the action by using volume vs price.
The final area (at the top) is the 'Signal' area. This is triggered when we move back from extended to 'normal' as per the Deviation Scaled Oscillator.
For each of the lines above, an orange triangle is the overbought type signal and the blue triangle is oversold. I've included an image of a 1 minute /ES chart with some arrows demonstrating where the reversal signals are happening. Note, that it is best if the fractal energy 'alert' is showing prior to the reversal signal. It is intended more as a confirmation of a trend change than as an entry signal.
Again, I am using this on lower timeframes as a reference point for my trading. I have left the ability to change the standard inputs for the 'base' indicators I have mentioned above. There is also an option to color the candles when the indicators are in alignment. By posting this here, I am hoping that others might find value in it and/or be able to extend it to help in their trading journey. Let me know if you have any questions.
I'm back today with a pretty unique indicator for evaluating market trend and conditions. It combines two different oscillators with a moving average, standard deviations and fractal energy to help identify trends and their exhaustion. I use this for day trading and this is mostly a mean reversion tool for me. It allows me to keep my charts clean to focus on levels while still providing me with useful information. The setup of this indicator is really a framework that could be used to swap in other oscillators or trend identifiers as desired. It is important to note that oversold or overbought conditions can continue to exist for a long while. Never enter a trade simply because something is overbought or oversold.
On to the details:
There are 4 sections to this indicator, so I will go from the bottom to the top. The colored band is an indication of the current trend. This information is derived from the Vidya Moving Average. As the fractal energy decreases in the move (ie. FE < 0.382), gray squares are printed on the trend identifier.
The next area is dedicated to the Chande Momentum Oscillator. I have found this to be a pretty reasonable oscillator for day trading/scalping on smaller timeframes. Many other oscillators seem to be constantly OB/OS on smaller timeframes and this is about as good as I could find.
The next area is the Volume Strength Index or Slow VSI. Provides a different take on the action by using volume vs price.
The final area (at the top) is the 'Signal' area. This is triggered when we move back from extended to 'normal' as per the Deviation Scaled Oscillator.
For each of the lines above, an orange triangle is the overbought type signal and the blue triangle is oversold. I've included an image of a 1 minute /ES chart with some arrows demonstrating where the reversal signals are happening. Note, that it is best if the fractal energy 'alert' is showing prior to the reversal signal. It is intended more as a confirmation of a trend change than as an entry signal.
Again, I am using this on lower timeframes as a reference point for my trading. I have left the ability to change the standard inputs for the 'base' indicators I have mentioned above. There is also an option to color the candles when the indicators are in alignment. By posting this here, I am hoping that others might find value in it and/or be able to extend it to help in their trading journey. Let me know if you have any questions.
Ruby:
declare lower;
input showLines = yes;
# setup Colors
DefineGlobalColor("bullColor", CreateColor(30, 144, 255));
DefineGlobalColor("bearColor", Color.ORANGE);
DefineGlobalColor("bullCandle", CreateColor(0, 164, 204));
DefineGlobalColor("bearCandle", CreateColor(252, 118, 106));
DefineGlobalColor("bullCloud", CreateColor(51, 152, 177));
DefineGlobalColor("bearCloud", CreateColor(249, 87, 0));
plot Line1 = if showLines then 0.5 else Double.NaN;
Line1.SetDefaultColor(Color.GRAY);
Line1.HideBubble();
plot Line2 = if showLines then 1 else Double.NaN;
Line2.SetDefaultColor(Color.GRAY);
Line2.HideBubble();
plot Line3 = if showLines then 1.5 else Double.NaN;
Line3.SetDefaultColor(Color.GRAY);
Line3.HideBubble();
# slow volume strength index
def emaLength = 6;
def vsiLength = 14;
def VSI_over_bought = 80;
def VSI_over_sold = 20;
def ema = ExpAverage(close, emaLength);
def avgVolUp = WildersAverage(if close > ema then volume else 0, vsiLength);
def avgVolDown = WildersAverage(if close < ema then volume else 0, vsiLength);
def SlowVSI = if avgVolUp + avgVolDown == 0 then 50 else 100 * avgVolUp / (avgVolUp + avgVolDown);
def VSIBull = SlowVSI < VSI_over_sold;
def VSIBear = SlowVSI > VSI_over_bought;
plot VSIDot = if (VSIBear or VSIBull) then Line2 else Double.NaN;
VSIDot.SetPaintingStrategy(PaintingStrategy.TRIANGLES);
VSIDot.SetDefaultColor(Color.BLACK);
VSIDot.DefineColor("LONG", GlobalColor("bullColor"));
VSIDot.DefineColor("SHORT", GlobalColor("bearColor"));
VSIDot.AssignValueColor(if VSIBull then VSIDot.Color("LONG") else VSIDot.Color("SHORT"));
VSIDot.HideBubble();
#plot deviation Scaled oscillation
input Dlength = 40;
input over_bought = 2.0;
input over_sold = -2.0;
def zeros = close - close[2];
def filter = reference EhlersSuperSmootherFilter(price = zeros, "cutoff length" = 0.5 * Dlength);
def rms = Sqrt(Average(Sqr(filter), Dlength));
def scaledFilter = filter / rms;
def DSO = if AbsValue(scaledFilter) < 2 then 0.5 * Log((1 + scaledFilter / 2) / (1 - scaledFilter / 2)) else scaledFilter;
def UpSignal = DSO crosses above over_sold;
def DownSignal = DSO crosses below over_bought;
plot DSOSignal = if (UpSignal or DownSignal) then Line3 else Double.NaN;
DSOSignal.SetPaintingStrategy(PaintingStrategy.TRIANGLES);
DSOSignal.SetDefaultColor(Color.BLACK);
DSOSignal.DefineColor("LONG", GlobalColor("bullColor"));
DSOSignal.DefineColor("SHORT", GlobalColor("bearColor"));
DSOSignal.AssignValueColor(if UpSignal then DSOSignal.Color("LONG") else DSOSignal.Color("SHORT"));
DSOSignal.HideBubble();
# SuperTrend
input AtrMult = 1.5;
input nATR = 10;
input AvgType = AverageType.HULL;
def ATR = ATR("length" = nATR, "average type" = AvgType);
def UP_Band_Basic = HL2 + (AtrMult * ATR);
def LW_Band_Basic = HL2 + (-AtrMult * ATR);
def UP_Band = if ((UP_Band_Basic < UP_Band[1]) or (close[1] > UP_Band[1])) then UP_Band_Basic else UP_Band[1];
def LW_Band = if ((LW_Band_Basic > LW_Band[1]) or (close[1] < LW_Band[1])) then LW_Band_Basic else LW_Band[1];
def ST = if ((ST[1] == UP_Band[1]) and (close < UP_Band)) then UP_Band
else if ((ST[1] == UP_Band[1]) and (close > Up_Band)) then LW_Band
else if ((ST[1] == LW_Band[1]) and (close > LW_Band)) then LW_Band
else if ((ST[1] == LW_Band) and (close < LW_Band)) then UP_Band
else LW_Band;
def SuperTrend = ST;
def bullTrendST = close > ST;# and pvma[1] > pvma[2];
def bearTrendST = close < ST;# and pvma[1] < pvma[2];
def fastLength = 12;
def slowLength = 26;
def MACDLength = 9;
input averageType = AverageType.EXPONENTIAL;
def fastLength2 = fastLength * 2;
def slowLength2 = slowLength * 2;
def MACDLength2 = MACDLength * 2;
def Value2 = MACD(fastLength2, slowLength2, MACDLength2, averageType).Value;
def Avg2 = MACD(fastLength2, slowLength2, MACDLength2, averageType).Avg;
def bullMACD = Value2 > Avg2;
input useMACDFilter = yes;
def bearTrend = if !useMACDFilter then bearTrendST else bearTrendST and !bullMACD;
def bullTrend = if !useMACDFilter then bullTrendST else bullTrendST and bullMACD;
AddCloud(if bearTrend then -0.5 else Double.NaN, 0, GlobalColor("bearCloud"), GlobalColor("bearCloud"));
AddCloud(if bullTrend then -0.5 else Double.NaN, 0, GlobalColor("bullCloud"), GlobalColor("bullCloud"));
AddCloud(if !bullTrend and !bearTrend then -0.5 else Double.NaN, 0, Color.DARK_GRAY, Color.DARK_GRAY);
# chande momentum
def cLength = 20;
def curClose = close;
def prevClose = close[1];
def inc = if curClose > prevClose then curClose - prevClose else 0;
def dec = if prevClose > curClose then prevClose - curClose else 0;
def sumInc = Sum(inc, cLength);
def sumDec = Sum(dec, cLength);
def CMO = if sumInc + sumDec == 0 then 0 else (sumInc - sumDec) / (sumInc + sumDec) * 100;
def CMO_OB = CMO > 50;
def CMO_OS = CMO < -50;
plot CMODot = if showLines and (CMO_OB or CMO_OS) then Line1 else Double.NaN;
CMODot.SetPaintingStrategy(PaintingStrategy.TRIANGLES);
CMODot.SetDefaultColor(Color.BLACK);
CMODot.DefineColor("LONG", GlobalColor("bullColor"));
CMODot.DefineColor("SHORT", GlobalColor("bearColor"));
CMODot.AssignValueColor(if CMO_OS then CMODot.Color("LONG") else CMODot.Color("SHORT"));
CMODot.HideBubble();
input colorCandles = no;
def allBull = !VSIBull and bullTrend and !CMO_OB;
def allBear = !VSIBear and bearTrend and !CMO_OS;
AssignPriceColor(if colorCandles and allBull then GlobalColor("bullCandle") else if colorCandles and allBear then GlobalColor("bearCandle") else Color.CURRENT);
input nFE = 8;#hint nFE: length for Fractal Energy calculation.
input Glength = 13;
input betaDev = 8;
input data = close;
input lowFELevel = 0.382;
def w = (2 * Double.Pi / Glength);
def beta = (1 - Cos(w)) / (Power(1.414, 2.0 / betaDev) - 1 );
def alpha = (-beta + Sqrt(beta * beta + 2 * beta));
def Go = Power(alpha, 4) * open +
4 * (1 – alpha) * Go[1] – 6 * Power( 1 - alpha, 2 ) * Go[2] +
4 * Power( 1 - alpha, 3 ) * Go[3] - Power( 1 - alpha, 4 ) * Go[4];
def Gh = Power(alpha, 4) * high +
4 * (1 – alpha) * Gh[1] – 6 * Power( 1 - alpha, 2 ) * Gh[2] +
4 * Power( 1 - alpha, 3 ) * Gh[3] - Power( 1 - alpha, 4 ) * Gh[4];
def Gl = Power(alpha, 4) * low +
4 * (1 – alpha) * Gl[1] – 6 * Power( 1 - alpha, 2 ) * Gl[2] +
4 * Power( 1 - alpha, 3 ) * Gl[3] - Power( 1 - alpha, 4 ) * Gl[4];
def Gc = Power(alpha, 4) * data +
4 * (1 – alpha) * Gc[1] – 6 * Power( 1 - alpha, 2 ) * Gc[2] +
4 * Power( 1 - alpha, 3 ) * Gc[3] - Power( 1 - alpha, 4 ) * Gc[4];
# Variables:
def o;
def h;
def l;
def c;
# Calculations for fractal energy
o = (Go + Gc[1]) / 2;
h = Max(Gh, Gc[1]);
l = Min(Gl, Gc[1]);
c = (o + h + l + Gc) / 4;
def gamma = Log(Sum((Max(Gh, Gc[1]) - Min(Gl, Gc[1])), nFE) /
(Highest(Gh, nFE) - Lowest(Gl, nFE)))
/ Log(nFE);
def lowFE = gamma < lowFELevel;
plot lowEnergy = if lowFE then -0.25 else Double.NaN;
lowEnergy.SetPaintingStrategy(PaintingStrategy.SQUARES);
lowEnergy.SetDefaultColor(Color.GRAY);
lowEnergy.hideBubble();
input showMACDTrend = no;
AddCloud(if showMACDTrend and !bullMACD then -0.51 else Double.NaN, -1, GlobalColor("bearCloud"), GlobalColor("bearCloud"));
AddCloud(if showMACDTrend and bullMACD then -0.51 else Double.NaN, -1, GlobalColor("bullCloud"), GlobalColor("bullCloud"));
Last edited: