The main idea is to let the 20 EMA and 20 SMA form a cloud so the chart gives a cleaner visual read of short-term trend condition, while the 8 EMA helps show whether price is still in control of that cloud or starting to lose it.
How I’m using it:
- Green cloud = 20 EMA is above 20 SMA and the 8 EMA is above both 20s.
This is the strongest bullish condition. - Dark green cloud = 20 EMA is below 20 SMA, but the 8 EMA is still not below both 20s.
This tells me the bearish turn is not fully confirmed yet. - Red cloud = 20 EMA is below 20 SMA and the 8 EMA is below both 20s.
This is the strongest bearish condition. - Dark red cloud = 20 EMA is above 20 SMA, but the 8 EMA is no longer above both 20s.
This tells me bullish structure is weakening and may be rolling over.
- I want the best long setups when the moving averages are stacked well and turning up.
- I want the best short/avoid signals when the structure flips and the 8 loses control of the 20/20 zone.
- The cloud helps show whether momentum is confirmed, weakening, or trying to transition without loading the chart up with a bunch of extra indicators.
- trend direction
- momentum confirmation
- pullback quality
- and possible transition points
What do you guys think? Does this seem useful, or would you change anything about how the cloud logic is set up?
Code:
declare upper;
#===================================================================
# ThinkOrSwim Study: 8 EMA / 20 SMA / 20 EMA / 50 SMA
# 20/20 cloud state with 4 colors
#
# RULES
# - Green = 20 EMA > 20 SMA and 8 EMA > both 20s
# - Dark Red = 20 EMA > 20 SMA but 8 EMA not above both 20s
# - Red = 20 EMA < 20 SMA and 8 EMA < both 20s
# - Dark Green = 20 EMA < 20 SMA but 8 EMA not below both 20s
#===================================================================
input fastEmaLen = 8;
input midSmaLen = 20;
input midEmaLen = 20;
input slowSmaLen = 50;
input showCloud = yes;
input showLabels = yes;
DefineGlobalColor("FastEMA", Color.YELLOW);
DefineGlobalColor("SlowSMA", Color.WHITE);
DefineGlobalColor("BullConfirmed", Color.GREEN);
DefineGlobalColor("BullUnconfirmed", Color.DARK_RED);
DefineGlobalColor("BearConfirmed", Color.RED);
DefineGlobalColor("BearUnconfirmed", Color.DARK_GREEN);
def fastEMA = ExpAverage(close, fastEmaLen);
def midSMA = Average(close, midSmaLen);
def midEMA = ExpAverage(close, midEmaLen);
def slowSMA = Average(close, slowSmaLen);
def bull20 = midEMA > midSMA;
def bear20 = midEMA < midSMA;
def fastAboveBoth = fastEMA > midEMA and fastEMA > midSMA;
def fastBelowBoth = fastEMA < midEMA and fastEMA < midSMA;
def stateGreen = bull20 and fastAboveBoth;
def stateDarkRed = bull20 and !fastAboveBoth;
def stateRed = bear20 and fastBelowBoth;
def stateDarkGreen = bear20 and !fastBelowBoth;
plot pFastEMA = fastEMA;
plot pMidSMA = midSMA;
plot pMidEMA = midEMA;
plot pSlowSMA = slowSMA;
pFastEMA.SetDefaultColor(GlobalColor("FastEMA"));
pFastEMA.SetLineWeight(2);
pMidSMA.AssignValueColor(
if stateGreen then GlobalColor("BullConfirmed")
else if stateDarkRed then GlobalColor("BullUnconfirmed")
else if stateRed then GlobalColor("BearConfirmed")
else if stateDarkGreen then GlobalColor("BearUnconfirmed")
else Color.GRAY
);
pMidSMA.SetLineWeight(2);
pMidEMA.AssignValueColor(
if stateGreen then GlobalColor("BullConfirmed")
else if stateDarkRed then GlobalColor("BullUnconfirmed")
else if stateRed then GlobalColor("BearConfirmed")
else if stateDarkGreen then GlobalColor("BearUnconfirmed")
else Color.GRAY
);
pMidEMA.SetLineWeight(2);
pSlowSMA.SetDefaultColor(GlobalColor("SlowSMA"));
pSlowSMA.SetLineWeight(2);
AddCloud(
if showCloud and stateGreen then midEMA else Double.NaN,
if showCloud and stateGreen then midSMA else Double.NaN,
GlobalColor("BullConfirmed"),
GlobalColor("BullConfirmed")
);
AddCloud(
if showCloud and stateDarkRed then midEMA else Double.NaN,
if showCloud and stateDarkRed then midSMA else Double.NaN,
GlobalColor("BullUnconfirmed"),
GlobalColor("BullUnconfirmed")
);
AddCloud(
if showCloud and stateRed then midEMA else Double.NaN,
if showCloud and stateRed then midSMA else Double.NaN,
GlobalColor("BearConfirmed"),
GlobalColor("BearConfirmed")
);
AddCloud(
if showCloud and stateDarkGreen then midEMA else Double.NaN,
if showCloud and stateDarkGreen then midSMA else Double.NaN,
GlobalColor("BearUnconfirmed"),
GlobalColor("BearUnconfirmed")
);
AddLabel(showLabels,
if stateGreen then "20/20 Bull + 8 Above"
else if stateDarkRed then "20/20 Bull + 8 Not Above"
else if stateRed then "20/20 Bear + 8 Below"
else if stateDarkGreen then "20/20 Bear + 8 Not Below"
else "20/20 Flat",
if stateGreen then Color.GREEN
else if stateDarkRed then Color.DARK_RED
else if stateRed then Color.RED
else if stateDarkGreen then Color.DARK_GREEN
else Color.GRAY
);
Last edited: