alphaforge-quant-system / metrics_guide.py
Premchan369's picture
Upload metrics_guide.py
b666cca verified
"""AlphaForge Metrics Guide - Deep explanations of every metric and how to trade with them.
This module teaches you WHAT each number means, WHY it matters, and HOW to act on it.
Think of this as your quant trading playbook.
"""
METRICS_GUIDE = {
"sharpe_ratio": {
"name": "Sharpe Ratio",
"formula": "(Portfolio Return - Risk-Free Rate) / Portfolio Volatility",
"what_it_means": """
The Sharpe Ratio tells you how much EXTRA return you get per unit of risk taken.
It's the #1 metric every hedge fund looks at first.
- Sharpe = 0.5 β†’ You're getting some reward for risk, but barely worth it
- Sharpe = 1.0 β†’ Good. You're getting $1 of return for every $1 of risk
- Sharpe = 1.5 β†’ Very good. Professional-grade
- Sharpe = 2.0+ β†’ Excellent. Top-quartile hedge fund territory
- Sharpe = 3.0+ β†’ Legendary. Renaissance Technologies territory
""",
"how_it_influences": """
ACTIONABLE RULES:
- If Sharpe < 0.5: STOP. Your strategy is broken. Reduce position sizes by 50% or stop trading.
- If Sharpe 0.5-1.0: CAUTION. You're making money but taking too much risk. Tighten stops, reduce leverage.
- If Sharpe 1.0-1.5: SOLID. This is your baseline. Keep doing what you're doing.
- If Sharpe 1.5-2.0: GREAT. Consider INCREASING position sizes by 20-30%.
- If Sharpe > 2.0: EXCEPTIONAL. This is when you go ALL IN. Max out your allocation.
TWO SIGMA BENCHMARK: Their flagship fund runs ~1.8 Sharpe
CITADEL BENCHMARK: Their equity fund runs ~2.1 Sharpe
YOUR GOAL: Consistently above 1.2 Sharpe
""",
"real_example": """
Example: Your strategy returned 15% with 12% volatility. Risk-free rate is 4%.
Sharpe = (15% - 4%) / 12% = 0.92
Verdict: Decent, but not amazing. You're getting $0.92 per $1 of risk.
To improve: Either increase return (better signals) or reduce volatility (hedging).
""",
"tier": "CRITICAL",
"weight": 0.25
},
"sortino_ratio": {
"name": "Sortino Ratio",
"formula": "(Portfolio Return - Risk-Free Rate) / Downside Volatility",
"what_it_means": """
Sortino is like Sharpe, but it ONLY counts bad volatility (losses).
Sharpe punishes you for ALL volatility β€” even the good kind (big upward jumps).
Sortino is smarter: it only cares about downside risk.
- Sortino < 1.0 β†’ Your losses are too frequent or too large
- Sortino 1.0-1.5 β†’ Acceptable. You handle downside okay
- Sortino 1.5-2.5 β†’ Strong. You make money while controlling losses
- Sortino 2.5+ β†’ Elite. You're a loss-cutting machine
""",
"how_it_influences": """
ACTIONABLE RULES:
- If Sortino < Sharpe: GOOD. Means your upside volatility is helping you.
- If Sortino β‰ˆ Sharpe: NEUTRAL. Your upside and downside are balanced.
- If Sortino > Sharpe by 0.5+: EXCELLENT. You have asymmetric upside β€” the holy grail.
- If Sortino drops below 0.8: RAISE STOPS IMMEDIATELY. Your downside is out of control.
PRO TIP: Always compare Sortino to Sharpe. The GAP between them tells you
if your strategy has positive skew (good) or negative skew (dangerous).
""",
"real_example": """
Example: Return = 12%, Downside volatility = 5%, Total volatility = 15%
Sharpe = (12-4)/15 = 0.53
Sortino = (12-4)/5 = 1.6
Verdict: Sharpe looks mediocre, but Sortino is strong! This means most of your
volatility is UPWARD (good jumps). Strategy has positive skew. KEEP TRADING.
""",
"tier": "CRITICAL",
"weight": 0.20
},
"information_coefficient": {
"name": "Information Coefficient (IC)",
"formula": "Rank correlation between predicted returns and actual returns",
"what_it_means": """
IC measures: "How good are my predictions ACTUALLY?"
It's the correlation between what your model PREDICTED and what REALLY happened.
- IC = 0.00 β†’ Your model is random. Coin-flip level.
- IC = 0.02 β†’ Barely useful. Weak but tradable at scale.
- IC = 0.05 β†’ Decent. This is where most quant strategies live.
- IC = 0.10 β†’ Strong. You're genuinely predicting better than chance.
- IC = 0.15+ β†’ Exceptional. Top-tier signal quality.
KEY INSIGHT: IC compounds. If you have 0.05 IC daily, that's MASSIVE over a year.
""",
"how_it_influences": """
ACTIONABLE RULES:
- If IC < 0.02: YOUR SIGNAL IS DEAD. Stop trading it. Retrain the model.
- If IC 0.02-0.05: WORKABLE. Trade smaller sizes. This is your bread-and-butter range.
- If IC 0.05-0.08: STRONG. Increase allocation to this signal. Scale up positions.
- If IC 0.08-0.12: EXCELLENT. This is your golden goose. Maximize exposure.
- If IC turns NEGATIVE: SIGNAL DECAY. Your model is now WRONG. FLIP THE SIGNAL or stop.
IC IR (IC / std(IC)):
- IC IR < 0.5: Unstable signal. Too noisy.
- IC IR 0.5-1.0: Decent stability.
- IC IR > 1.0: Rock solid. You can build a career on this.
""",
"real_example": """
Example: You predicted AAPL would return +2%, MSFT +1%, TSLA -1%.
Actual returns: AAPL +3%, MSFT 0%, TSLA -2%.
Your ranking was: AAPL > MSFT > TSLA
Actual ranking was: AAPL > MSFT > TSLA
IC = 1.0 (perfect!)
But if actual was: TSLA +5%, AAPL +1%, MSFT -1%
Then your ranking was wrong. IC would be negative.
This is why IC is rank-based β€” it cares about ORDER, not exact values.
""",
"tier": "CRITICAL",
"weight": 0.20
},
"max_drawdown": {
"name": "Maximum Drawdown",
"formula": "(Peak Value - Trough Value) / Peak Value",
"what_it_means": """
Max Drawdown is: "What's the worst losing streak I've ever had?"
It's the biggest drop from your highest point to your lowest point.
- Max DD < 5% β†’ You're a conservative saint
- Max DD 5-10% β†’ Conservative. Sleep-well-at-night level
- Max DD 10-20% β†’ Moderate. Normal for active strategies
- Max DD 20-30% β†’ Aggressive. You'll have sleepless nights
- Max DD 30-50% β†’ Dangerous. Most people panic-sell here
- Max DD > 50% β†’ You will blow up. Guaranteed.
""",
"how_it_influences": """
ACTIONABLE RULES:
- If Max DD exceeds your personal pain threshold: REDUCE RISK by 50%.
- If Max DD > 25%: Add hedges (buy puts, short index, reduce beta).
- If Max DD < 10% for 6 months: You can INCREASE leverage by 25%.
- If drawdown lasts > 3 months: Something is structurally broken. Review strategy.
THE PSYCHOLOGY RULE:
Most traders can handle 10% drawdown.
At 20%, they start questioning the strategy.
At 30%, they panic and sell the bottom.
At 40%, they quit trading forever.
Set your max pain level BEFORE you trade. AlphaForge suggests 15% as default.
""",
"real_example": """
Example: You started with $1M. Grew to $1.3M (peak). Then dropped to $1.1M (trough).
Max DD = ($1.3M - $1.1M) / $1.3M = 15.4%
This means at your worst moment, you were down $200K from your best moment.
Can you handle seeing $200K evaporate? If not, trade smaller.
RECOVERY MATH: After a 15.4% drawdown, you need +18.2% to get back to peak.
After a 50% drawdown, you need +100% just to break even. This is why drawdown KILLS.
""",
"tier": "CRITICAL",
"weight": 0.15
},
"calmar_ratio": {
"name": "Calmar Ratio",
"formula": "Annualized Return / |Max Drawdown|",
"what_it_means": """
Calmar answers: "How much return do I get relative to my worst nightmare?"
It compares your yearly gain to your maximum drawdown.
- Calmar < 1.0 β†’ Your drawdown is BIGGER than your annual return. Dangerous.
- Calmar 1.0-2.0 β†’ Decent. You're getting paid for the risk.
- Calmar 2.0-3.0 β†’ Strong. Good risk/reward balance.
- Calmar 3.0+ β†’ Excellent. Your returns dwarf your worst losses.
Calmar is MORE important than Sharpe for long-term survival.
""",
"how_it_influences": """
ACTIONABLE RULES:
- If Calmar < 1.0: EMERGENCY. Your strategy will eventually blow up. Cut size by 75%.
- If Calmar 1.0-1.5: CAUTION. You're surviving but not thriving. Add diversification.
- If Calmar 1.5-2.5: SOLID. This is sustainable long-term.
- If Calmar > 3.0: EXCEPTIONAL. You've found a gem. Scale up carefully.
THE SURVIVAL RULE: No strategy with Calmar < 1.0 survives 5 years. Period.
""",
"real_example": """
Example: Annual return = 20%, Max drawdown = 15%
Calmar = 20 / 15 = 1.33
Verdict: Okay but not great. You're making 20% but had a 15% nightmare.
Better: Annual return = 15%, Max drawdown = 5%
Calmar = 15 / 5 = 3.0
Verdict: MUCH better! Lower return but tiny drawdown. You'll compound wealth
steadily without panic-selling. THIS is the path to GOAT status.
""",
"tier": "HIGH",
"weight": 0.10
},
"win_rate": {
"name": "Win Rate",
"formula": "Number of winning days / Total trading days",
"what_it_means": """
Win Rate is: "How often am I right?"
But here's the SECRET: Win rate ALONE is meaningless.
A 30% win rate can be profitable (if wins are 3x bigger than losses).
A 70% win rate can be unprofitable (if losses are 3x bigger than wins).
What matters is: Win Rate Γ— Average Win / (1 - Win Rate) Γ— Average Loss
This is your EXPECTANCY. If it's > 0, you're profitable.
""",
"how_it_influences": """
ACTIONABLE RULES:
- If Win Rate < 40% but profitable: You have positive skew. Your wins are HUGE.
β†’ Keep going but prepare for long losing streaks mentally.
- If Win Rate > 60% but barely profitable: You have negative skew.
β†’ DANGER. One big loss wipes out 10 small wins. Tighten stops.
- If Win Rate 45-55% with good profits: BALANCED. The sweet spot.
- If Win Rate drops 10% from historical average: SIGNAL DECAY. Retrain.
THE MENTAL GAME:
A 50% win rate means you'll have 5 losses in a row ~3% of the time.
You'll have 10 losses in a row ~0.1% of the time (but it WILL happen).
Prepare mentally. This is why position sizing > prediction accuracy.
""",
"real_example": """
Example A: 40% win rate. Average win = $300, average loss = $100
Expectancy = (0.4 Γ— $300) - (0.6 Γ— $100) = $120 - $60 = +$60 per trade
Verdict: PROFITABLE despite low win rate!
Example B: 65% win rate. Average win = $100, average loss = $250
Expectancy = (0.65 Γ— $100) - (0.35 Γ— $250) = $65 - $87.50 = -$22.50 per trade
Verdict: LOSING despite high win rate! This is a classic trap.
""",
"tier": "MEDIUM",
"weight": 0.05
},
"profit_factor": {
"name": "Profit Factor",
"formula": "Gross Profits / Gross Losses",
"what_it_means": """
Profit Factor is: "For every $1 I lose, how much do I make?"
- PF < 1.0 β†’ You're losing money. Period.
- PF = 1.0 β†’ You're breaking even before costs. Losing money after costs.
- PF 1.0-1.5 β†’ Marginal. Profitable but fragile.
- PF 1.5-2.0 β†’ Good. Solid edge.
- PF 2.0-3.0 β†’ Strong. Professional grade.
- PF 3.0+ β†’ Exceptional. Don't tell anyone your secret.
""",
"how_it_influences": """
ACTIONABLE RULES:
- If PF < 1.0: STOP IMMEDIATELY. You have no edge.
- If PF 1.0-1.3: BARELY ALIVE. One bad streak kills you. Reduce size 50%.
- If PF 1.3-1.8: HEALTHY. This is sustainable.
- If PF > 2.0: ROBUST. You can survive multiple bad streaks.
THE COMPOUNDING RULE:
PF of 1.5 with 50% win rate = steady wealth builder
PF of 1.2 with 60% win rate = fragile, will eventually break
Higher PF > Higher Win Rate (for survival).
""",
"real_example": """
Example: Over 100 trades, your winners totaled $50,000. Your losers totaled $30,000.
Profit Factor = $50,000 / $30,000 = 1.67
Verdict: For every $1 you lost, you made $1.67. Solid.
After transaction costs (say $5,000), net PF = $45K/$35K = 1.29
Transaction costs dropped your PF from 1.67 to 1.29! This is why
keeping costs low is CRITICAL. Use low-cost brokers, trade less.
""",
"tier": "HIGH",
"weight": 0.05
},
"alpha": {
"name": "Alpha (Jensen's Alpha)",
"formula": "Portfolio Return - (Risk-Free Rate + Beta Γ— (Market Return - Risk-Free Rate))",
"what_it_means": """
Alpha is: "How much EXTRA return did I generate ABOVE what the market explains?"
If Beta = 1 and market goes up 10%, you "should" make 10%.
If you made 15%, your Alpha = 5%. That's YOUR skill.
- Alpha < 0% β†’ You're underperforming a simple index fund. Just buy SPY.
- Alpha 0-2% β†’ Matching the market. No edge.
- Alpha 2-5% β†’ Good. You're adding value.
- Alpha 5-10% β†’ Strong. Significant edge.
- Alpha 10%+ β†’ Elite. You're in the top 1% of managers.
""",
"how_it_influences": """
ACTIONABLE RULES:
- If Alpha < 0% for 6+ months: JUST BUY THE INDEX. You're wasting time and money.
- If Alpha 0-3%: You're a "closet indexer." Either commit to active or go passive.
- If Alpha 3-7%: SOLID EDGE. Keep refining but don't over-optimize.
- If Alpha > 7%: EXCEPTIONAL. Document your process. This edge won't last forever.
THE HUMBLING TRUTH:
80% of active managers have NEGATIVE alpha after fees.
S&P 500 has returned ~10%/year for decades.
If you can't beat that, just buy SPY and enjoy life.
""",
"real_example": """
Example: You returned 18%. Market (SPY) returned 12%. Your Beta = 1.2. Risk-free = 4%.
Expected return = 4% + 1.2 Γ— (12% - 4%) = 4% + 9.6% = 13.6%
Alpha = 18% - 13.6% = 4.4%
Verdict: You beat what the market explains by 4.4%. That's YOUR skill.
But if you paid 2% in fees, net alpha = 2.4%. Still good, but fees HALVED it.
This is why hedge funds charge 2% + 20% β€” they claim to generate alpha.
Most don't. You can beat them with discipline.
""",
"tier": "HIGH",
"weight": 0.05
},
"beta": {
"name": "Beta",
"formula": "Covariance(Portfolio, Market) / Variance(Market)",
"what_it_means": """
Beta measures: "How much do I move when the market moves?"
- Beta = 0.0 β†’ You're market-neutral. Market crashes, you don't care.
- Beta = 0.5 β†’ You're conservative. Market up 10%, you up 5%.
- Beta = 1.0 β†’ You move exactly with the market (like SPY).
- Beta = 1.5 β†’ You're aggressive. Market up 10%, you up 15%. Market down 10%, you down 15%.
- Beta = -0.5 β†’ You move opposite to market. Market crashes, you gain.
Beta is NOT good or bad. It's a CHOICE based on your goals.
""",
"how_it_influences": """
ACTIONABLE RULES:
- If you want MARKET EXPOSURE (bullish): Target Beta 0.8-1.2
- If you want LOW RISK (wealth preservation): Target Beta 0.3-0.6
- If you want MARKET NEUTRAL (hedge fund style): Target Beta 0.0 Β± 0.1
- If you want INVERSE (betting on crash): Target Beta -0.5 to -1.0
DYNAMIC BETA MANAGEMENT:
- In bull markets (regime = 'bull'): Increase beta to 1.2-1.5 to capture upside
- In bear markets (regime = 'bear'): Reduce beta to 0.3-0.5 to protect capital
- In high volatility: Reduce beta to 0.0-0.3. Survive first, profit second.
THE BETA TRAP:
Most amateur traders have Beta > 1.5 without knowing it.
They think they're skilled, but they're just LEVERAGED to the market.
When the market crashes, they get destroyed.
""",
"real_example": """
Example: Market (SPY) drops 20% in a month.
- If your Beta = 0.3: You drop ~6%. Annoying but survivable.
- If your Beta = 1.5: You drop ~30%. Devastating.
- If your Beta = -0.2: You GAIN ~4%. You're the smart one.
This is why Beta management is MORE important than stock picking.
Being in the right "market exposure" at the right time beats being right about Apple.
""",
"tier": "HIGH",
"weight": 0.05
},
"information_ratio": {
"name": "Information Ratio",
"formula": "(Portfolio Return - Benchmark Return) / Tracking Error",
"what_it_means": """
Information Ratio measures: "How much excess return do I get per unit of ACTIVE risk?"
It's like Sharpe, but compares you to a BENCHMARK instead of risk-free rate.
- IR < 0.0 β†’ You're losing to the benchmark. Just buy the index.
- IR 0.0-0.3 β†’ Barely adding value. Probably not worth the effort.
- IR 0.3-0.5 β†’ Decent. You're adding some value.
- IR 0.5-1.0 β†’ Good. Meaningful active management skill.
- IR 1.0+ β†’ Excellent. Top-tier active manager.
THE GOLDEN RULE: IR > 0.5 means active management is WORTH the fees/time.
""",
"how_it_influences": """
ACTIONABLE RULES:
- If IR < 0: STOP ACTIVE TRADING. Buy SPY and save yourself the stress.
- If IR 0-0.3: You're "expensive index fund." Reduce active bets, increase passive.
- If IR 0.3-0.7: SOLID ACTIVE MANAGEMENT. Keep your current strategy.
- If IR > 0.7: EXCEPTIONAL. You have genuine skill. Consider managing money for others.
TRACKING ERROR:
Low tracking error + positive IR = "closet indexer with slight edge"
High tracking error + positive IR = "concentrated bets paying off"
High tracking error + negative IR = "you're gambling, not investing"
""",
"real_example": """
Example: You returned 14%. SPY returned 10%. Tracking error = 8%.
IR = (14% - 10%) / 8% = 0.5
Verdict: You're making 4% extra but with 8% of "different" risk.
IR = 0.5 means it's worth it, but barely.
Better scenario: You returned 16%. SPY returned 10%. Tracking error = 5%.
IR = (16% - 10%) / 5% = 1.2
Verdict: MUCH better! More excess return with LESS tracking error.
This is the definition of skill. IR > 1.0 is top 5% of all managers.
""",
"tier": "MEDIUM",
"weight": 0.05
},
"turnover": {
"name": "Portfolio Turnover",
"formula": "Sum of absolute weight changes / 2",
"what_it_means": """
Turnover measures: "How much of my portfolio did I trade?"
100% turnover = You sold everything and bought new stuff.
- Turnover < 20%/year β†’ Very low. Buy-and-hold style.
- Turnover 20-50%/year β†’ Low. Long-term focused.
- Turnover 50-100%/year β†’ Moderate. Typical for active strategies.
- Turnover 100-200%/year β†’ High. Trading frequently.
- Turnover > 300%/year β†’ Very high. Day-trading territory.
HIGH TURNOVER = HIGH COSTS. Every trade costs money.
""",
"how_it_influences": """
ACTIONABLE RULES:
- If turnover > 150% but Sharpe < 1.0: You're trading too much. Reduce rebalancing frequency.
- If turnover < 30% but Sharpe > 1.5: Perfect. Low cost, high return.
- If transaction costs > 20% of gross profits: Your strategy is paying your broker, not you.
THE COST RULE:
At 3bps (0.03%) per trade + 150% annual turnover:
Total cost = 150% Γ— 0.03% Γ— 2 (buy + sell) = 0.09% per year
At 10bps + 300% turnover:
Total cost = 300% Γ— 0.10% Γ— 2 = 0.60% per year
This doesn't sound like much, but on $1M, that's $6,000/year in friction.
Over 20 years at 10% return, that's $40,000+ in lost compounding.
""",
"real_example": """
Example: Your strategy rebalances weekly. Each rebalance has 40% turnover.
Annual turnover = 40% Γ— 52 weeks = 2,080%
At 3bps cost: Annual friction = 2,080% Γ— 0.03% Γ— 2 = 1.25%
If your gross alpha is 3%, your NET alpha is 3% - 1.25% = 1.75%
You lost 42% of your edge to transaction costs!
SOLUTION: Rebalance monthly instead of weekly.
Annual turnover = 40% Γ— 12 = 480%
Annual friction = 480% Γ— 0.03% Γ— 2 = 0.29%
Net alpha = 3% - 0.29% = 2.71%
You DOUBLED your net alpha just by trading less! This is why patience pays.
""",
"tier": "MEDIUM",
"weight": 0.05
}
}
def get_metric_explanation(metric_key: str) -> dict:
"""Get full explanation for a metric"""
return METRICS_GUIDE.get(metric_key, {})
def print_all_metrics():
"""Print the complete metrics guide"""
print("=" * 80)
print("ALPHAFORGE METRICS GUIDE - YOUR PATH TO GOAT STATUS")
print("=" * 80)
print()
for key, info in METRICS_GUIDE.items():
print(f"\n{'='*80}")
print(f"πŸ“Š {info['name'].upper()} [{info['tier']} | Weight: {info['weight']*100:.0f}%]")
print(f"{'='*80}")
print(f"\nπŸ“ FORMULA:\n{info['formula']}")
print(f"\nπŸ’‘ WHAT IT MEANS:\n{info['what_it_means']}")
print(f"\n🎯 HOW IT INFLUENCES YOUR TRADING:\n{info['how_it_influences']}")
print(f"\nπŸ“– REAL EXAMPLE:\n{info['real_example']}")
print()
def get_goat_score(metrics: dict) -> dict:
"""
Calculate a composite GOAT score based on all metrics.
This tells you how close you are to elite quant status.
"""
score = 0
max_score = 0
breakdown = {}
weights = {
'sharpe_ratio': 0.25,
'sortino_ratio': 0.20,
'information_coefficient': 0.20,
'max_drawdown': 0.15,
'calmar_ratio': 0.10,
'win_rate': 0.05,
'profit_factor': 0.05,
'alpha': 0.05,
'beta': 0.05,
'information_ratio': 0.05,
'turnover': 0.05
}
# Sharpe scoring
sharpe = metrics.get('sharpe_ratio', 0)
sharpe_score = min(sharpe / 2.0, 1.0) * 100
score += sharpe_score * weights['sharpe_ratio']
max_score += 100 * weights['sharpe_ratio']
breakdown['sharpe'] = {'value': sharpe, 'score': sharpe_score, 'max': 100}
# Sortino scoring
sortino = metrics.get('sortino_ratio', 0)
sortino_score = min(sortino / 2.5, 1.0) * 100
score += sortino_score * weights['sortino_ratio']
max_score += 100 * weights['sortino_ratio']
breakdown['sortino'] = {'value': sortino, 'score': sortino_score, 'max': 100}
# IC scoring
ic = metrics.get('ic_mean', metrics.get('mean_ic', 0))
ic_score = min(ic / 0.10, 1.0) * 100
score += ic_score * weights['information_coefficient']
max_score += 100 * weights['information_coefficient']
breakdown['ic'] = {'value': ic, 'score': ic_score, 'max': 100}
# Max DD scoring (inverted - lower is better)
mdd = abs(metrics.get('max_drawdown', 0))
mdd_score = max(0, (1 - mdd / 0.30)) * 100
score += mdd_score * weights['max_drawdown']
max_score += 100 * weights['max_drawdown']
breakdown['max_drawdown'] = {'value': mdd, 'score': mdd_score, 'max': 100}
# Calmar scoring
calmar = metrics.get('calmar_ratio', 0)
calmar_score = min(calmar / 3.0, 1.0) * 100
score += calmar_score * weights['calmar_ratio']
max_score += 100 * weights['calmar_ratio']
breakdown['calmar'] = {'value': calmar, 'score': calmar_score, 'max': 100}
total_score = (score / max_score * 100) if max_score > 0 else 0
# Determine tier
if total_score >= 85:
tier = "LEGENDARY GOAT"
emoji = "🐐"
elif total_score >= 70:
tier = "ELITE QUANT"
emoji = "⭐"
elif total_score >= 55:
tier = "SOLID PRO"
emoji = "πŸ’ͺ"
elif total_score >= 40:
tier = "DEVELOPING"
emoji = "πŸ“ˆ"
else:
tier = "NEEDS WORK"
emoji = "πŸ”§"
return {
'total_score': total_score,
'tier': tier,
'emoji': emoji,
'breakdown': breakdown
}
if __name__ == '__main__':
print_all_metrics()