# ==========================================================
# PORTFOLIO TMO HEALTH ENGINE V1
# Editable 8-Symbol Self-Made Fund Dashboard
# ANTWERKS ==========================================================
declare upper;
# =========================
# INPUTS
# =========================
input symbol1 = "NVDA";
input symbol2 = "META";
input symbol3 = "MSFT";
input symbol4 = "AAPL";
input symbol5 = "GOOGL";
input symbol6 = "AMZN";
input symbol7 = "TSLA";
input symbol8 = "QQQ";
input use1 = yes;
input use2 = yes;
input use3 = yes;
input use4 = yes;
input use5 = yes;
input use6 = yes;
input use7 = yes;
input use8 = yes;
input analysisAgg = AggregationPeriod.DAY;
input fastEMA = 9;
input slowEMA = 21;
input TMO_length = 14;
input TMO_calcLength = 5;
input TMO_smoothLength = 3;
input showLabels = yes;
input showMemberLabels = yes;
# =========================
# MEMBER SCORE SCRIPT
# +2 Strong Bull
# +1 Bull
# 0 Neutral
# -1 Bear
# -2 Strong Bear
# =========================
script MemberScore {
input price = close;
input fastEMA = 9;
input slowEMA = 21;
input TMO_length = 14;
input TMO_calcLength = 5;
input TMO_smoothLength = 3;
def emaFast = ExpAverage(price, fastEMA);
def emaSlow = ExpAverage(price, slowEMA);
def tmoRaw = ExpAverage(price - price[1], TMO_length);
def tmoCalc = ExpAverage(tmoRaw, TMO_calcLength);
def tmo = ExpAverage(tmoCalc, TMO_smoothLength);
def bullTrend = emaFast > emaSlow;
def bearTrend = emaFast < emaSlow;
def tmoRising = tmo > tmo[1];
def tmoFalling = tmo < tmo[1];
plot score =
if bullTrend and tmoRising and tmo > 0 then 2
else if bullTrend or tmoRising then 1
else if bearTrend and tmoFalling and tmo < 0 then -2
else if bearTrend or tmoFalling then -1
else 0;
}
# =========================
# PRICE DATA
# =========================
def c1 = close(symbol = symbol1, period = analysisAgg);
def c2 = close(symbol = symbol2, period = analysisAgg);
def c3 = close(symbol = symbol3, period = analysisAgg);
def c4 = close(symbol = symbol4, period = analysisAgg);
def c5 = close(symbol = symbol5, period = analysisAgg);
def c6 = close(symbol = symbol6, period = analysisAgg);
def c7 = close(symbol = symbol7, period = analysisAgg);
def c8 = close(symbol = symbol8, period = analysisAgg);
# =========================
# SCORES
# =========================
def s1 = if use1 then MemberScore(c1, fastEMA, slowEMA, TMO_length, TMO_calcLength, TMO_smoothLength) else 0;
def s2 = if use2 then MemberScore(c2, fastEMA, slowEMA, TMO_length, TMO_calcLength, TMO_smoothLength) else 0;
def s3 = if use3 then MemberScore(c3, fastEMA, slowEMA, TMO_length, TMO_calcLength, TMO_smoothLength) else 0;
def s4 = if use4 then MemberScore(c4, fastEMA, slowEMA, TMO_length, TMO_calcLength, TMO_smoothLength) else 0;
def s5 = if use5 then MemberScore(c5, fastEMA, slowEMA, TMO_length, TMO_calcLength, TMO_smoothLength) else 0;
def s6 = if use6 then MemberScore(c6, fastEMA, slowEMA, TMO_length, TMO_calcLength, TMO_smoothLength) else 0;
def s7 = if use7 then MemberScore(c7, fastEMA, slowEMA, TMO_length, TMO_calcLength, TMO_smoothLength) else 0;
def s8 = if use8 then MemberScore(c8, fastEMA, slowEMA, TMO_length, TMO_calcLength, TMO_smoothLength) else 0;
def activeCount =
(if use1 then 1 else 0) +
(if use2 then 1 else 0) +
(if use3 then 1 else 0) +
(if use4 then 1 else 0) +
(if use5 then 1 else 0) +
(if use6 then 1 else 0) +
(if use7 then 1 else 0) +
(if use8 then 1 else 0);
def bullCount =
(if s1 > 0 then 1 else 0) +
(if s2 > 0 then 1 else 0) +
(if s3 > 0 then 1 else 0) +
(if s4 > 0 then 1 else 0) +
(if s5 > 0 then 1 else 0) +
(if s6 > 0 then 1 else 0) +
(if s7 > 0 then 1 else 0) +
(if s8 > 0 then 1 else 0);
def bearCount =
(if s1 < 0 then 1 else 0) +
(if s2 < 0 then 1 else 0) +
(if s3 < 0 then 1 else 0) +
(if s4 < 0 then 1 else 0) +
(if s5 < 0 then 1 else 0) +
(if s6 < 0 then 1 else 0) +
(if s7 < 0 then 1 else 0) +
(if s8 < 0 then 1 else 0);
def neutralCount = activeCount - bullCount - bearCount;
def totalScore = s1 + s2 + s3 + s4 + s5 + s6 + s7 + s8;
def maxScore = activeCount * 2;
def minScore = -activeCount * 2;
# =========================
# PORTFOLIO STATUS
# =========================
def strongBull = totalScore >= maxScore * 0.65;
def bullish = totalScore >= maxScore * 0.25 and !strongBull;
def neutral = totalScore < maxScore * 0.25 and totalScore > minScore * 0.25;
def strongBear = totalScore <= minScore * 0.65;
def bearish = totalScore <= minScore * 0.25 and !strongBear;
# =========================
# MASTER LABELS
# =========================
AddLabel(showLabels,
"PORTFOLIO TMO HEALTH",
Color.WHITE
);
AddLabel(showLabels,
"BULLISH MEMBERS: " + bullCount + "/" + activeCount,
if bullCount >= activeCount * 0.75 then Color.GREEN
else if bullCount >= activeCount * 0.50 then Color.CYAN
else if bullCount <= activeCount * 0.25 then Color.RED
else Color.YELLOW
);
AddLabel(showLabels,
"BEARISH MEMBERS: " + bearCount + "/" + activeCount,
if bearCount >= activeCount * 0.75 then Color.RED
else if bearCount >= activeCount * 0.50 then Color.PINK
else Color.GRAY
);
AddLabel(showLabels,
"PORT SCORE: " + totalScore + " / " + maxScore,
if strongBull then Color.GREEN
else if bullish then Color.CYAN
else if strongBear then Color.RED
else if bearish then Color.PINK
else Color.GRAY
);
AddLabel(showLabels,
if strongBull then "STATUS: STRONG RISK-ON"
else if bullish then "STATUS: BULLISH / HOLD"
else if neutral then "STATUS: MIXED / WATCH"
else if bearish then "STATUS: DEFENSIVE"
else "STATUS: RISK-OFF",
if strongBull then Color.GREEN
else if bullish then Color.CYAN
else if neutral then Color.GRAY
else if bearish then Color.PINK
else Color.RED
);
AddLabel(showLabels,
if bullCount >= activeCount * 0.75 then "ACTION: HOLD / ADD ONLY ON PULLBACKS"
else if bullCount >= activeCount * 0.50 then "ACTION: HOLD CORE / SELECTIVE ADDS"
else if bullCount >= activeCount * 0.35 then "ACTION: CAUTION / HEDGE PARTIAL"
else "ACTION: DEFENSIVE / REDUCE RISK",
if bullCount >= activeCount * 0.75 then Color.GREEN
else if bullCount >= activeCount * 0.50 then Color.CYAN
else if bullCount >= activeCount * 0.35 then Color.YELLOW
else Color.RED
);
# =========================
# MEMBER LABELS
# =========================
AddLabel(showMemberLabels and use1,
symbol1 + ": " + s1,
if s1 == 2 then Color.GREEN else if s1 == 1 then Color.CYAN else if s1 == -1 then Color.PINK else if s1 == -2 then Color.RED else Color.GRAY
);
AddLabel(showMemberLabels and use2,
symbol2 + ": " + s2,
if s2 == 2 then Color.GREEN else if s2 == 1 then Color.CYAN else if s2 == -1 then Color.PINK else if s2 == -2 then Color.RED else Color.GRAY
);
AddLabel(showMemberLabels and use3,
symbol3 + ": " + s3,
if s3 == 2 then Color.GREEN else if s3 == 1 then Color.CYAN else if s3 == -1 then Color.PINK else if s3 == -2 then Color.RED else Color.GRAY
);
AddLabel(showMemberLabels and use4,
symbol4 + ": " + s4,
if s4 == 2 then Color.GREEN else if s4 == 1 then Color.CYAN else if s4 == -1 then Color.PINK else if s4 == -2 then Color.RED else Color.GRAY
);
AddLabel(showMemberLabels and use5,
symbol5 + ": " + s5,
if s5 == 2 then Color.GREEN else if s5 == 1 then Color.CYAN else if s5 == -1 then Color.PINK else if s5 == -2 then Color.RED else Color.GRAY
);
AddLabel(showMemberLabels and use6,
symbol6 + ": " + s6,
if s6 == 2 then Color.GREEN else if s6 == 1 then Color.CYAN else if s6 == -1 then Color.PINK else if s6 == -2 then Color.RED else Color.GRAY
);
AddLabel(showMemberLabels and use7,
symbol7 + ": " + s7,
if s7 == 2 then Color.GREEN else if s7 == 1 then Color.CYAN else if s7 == -1 then Color.PINK else if s7 == -2 then Color.RED else Color.GRAY
);
AddLabel(showMemberLabels and use8,
symbol8 + ": " + s8,
if s8 == 2 then Color.GREEN else if s8 == 1 then Color.CYAN else if s8 == -1 then Color.PINK else if s8 == -2 then Color.RED else Color.GRAY
);
# =========================
# OPTIONAL BACKGROUND
# =========================
AssignBackgroundColor(
if strongBull then CreateColor(0, 35, 0)
else if bullish then CreateColor(0, 25, 35)
else if strongBear then CreateColor(45, 0, 0)
else if bearish then CreateColor(35, 0, 20)
else Color.CURRENT
);