Champion Stats Hub - Score Calculations & Metric Dependencies¶
Document Purpose: Single source of truth for how raw metrics are transformed into calculated scores.
Overview¶
The Champion Stats Hub uses 200 raw metrics to calculate 15 advanced health scores. This document maps every calculation, showing which metrics feed into which scores and the exact formulas used.
Input Metrics (Raw Data)¶
Vitals (7 metrics)¶
| Metric | Unit | Source | Used In |
|---|---|---|---|
restingHeartRate |
bpm | Wearable/Manual | Biological Age, Cardio Fitness, Readiness, Stress Resilience, Athletic Potential, Overtraining Risk |
hrv |
ms (RMSSD) | Wearable | Biological Age, Cardio Fitness, Readiness, Recovery Potential, Stress Resilience, Injury Risk, Overtraining Risk |
maxHeartRate |
bpm | Calculated (220-age) | Strain Score |
bloodPressureSystolic |
mmHg | Manual/Device | Cardio Fitness |
bloodPressureDiastolic |
mmHg | Manual/Device | (Reserved) |
spo2 |
% | Wearable | Cardio Fitness |
respiratoryRate |
breaths/min | Wearable | (Reserved) |
Body Composition (6 metrics)¶
| Metric | Unit | Source | Used In |
|---|---|---|---|
age |
years | Profile | All scores (baseline calculations) |
gender |
male/female | Profile | Cardio Fitness, Metabolic Health, Athletic Potential |
heightCm |
cm | Profile | Metabolic Health (BMI) |
weightKg |
kg | Scale/Manual | Metabolic Health, Fuel Efficiency |
bodyFatPercent |
% | Scale/Scan | Biological Age, Metabolic Health |
muscleMassKg |
kg | Scale | (Reserved) |
Sleep (5 metrics)¶
| Metric | Unit | Source | Used In |
|---|---|---|---|
sleepDurationHours |
hours | Wearable | Readiness, Sleep Performance, Injury Risk |
sleepQuality |
0-100 | Wearable/AI | Biological Age, Readiness, Recovery Potential, Sleep Performance, Stress Resilience, Overtraining Risk |
sleepEfficiency |
% | Wearable | Recovery Potential, Sleep Performance |
deepSleepPercent |
% | Wearable | Recovery Potential, Sleep Performance |
remSleepPercent |
% | Wearable | Sleep Performance |
Activity (4 metrics)¶
| Metric | Unit | Source | Used In |
|---|---|---|---|
dailySteps |
count | Wearable | Strain Score |
weeklyExerciseMinutes |
minutes | Tracked | Biological Age, Stress Resilience, Longevity, Athletic Potential, Injury Risk, Overtraining Risk |
vo2MaxEstimate |
ml/kg/min | Wearable/Test | Cardio Fitness, Athletic Potential |
activeCaloriesDaily |
kcal | Wearable | Athletic Potential, Fuel Efficiency |
Recovery (1 metric)¶
| Metric | Unit | Source | Used In |
|---|---|---|---|
perceivedRecovery |
0-100 | Manual/Survey | Readiness, Stress Resilience, Injury Risk, Overtraining Risk |
Nutrition (4 metrics)¶
| Metric | Unit | Source | Used In |
|---|---|---|---|
hydrationPercent |
0-100 | Manual/Estimate | Fuel Efficiency |
proteinGrams |
g | Food Log | Metabolic Health, Fuel Efficiency |
caloriesConsumed |
kcal | Food Log | Metabolic Health, Fuel Efficiency |
caloriesGoal |
kcal | Plan | Metabolic Health, Fuel Efficiency |
Strain/Workout (3 metrics)¶
| Metric | Unit | Source | Used In |
|---|---|---|---|
todayWorkoutMinutes |
minutes | Tracked | Strain Score |
todayHRZoneMinutes |
object | Wearable | Strain Score |
recentWorkouts |
array | History | Fitness Score |
Calculated Scores (15 Outputs)¶
1. Biological Age¶
Scale: Years (lower = better) Purpose: Estimates how old your body "acts" compared to chronological age
Input Metrics:¶
age(baseline)hrvrestingHeartRatesleepQualityweeklyExerciseMinutesbodyFatPercentgender
Formula:¶
biologicalAge = age + hrvDelta + rhrAdjustment + sleepAdjustment + exerciseAdjustment + bodyFatAdjustment
Where:
- expectedHrvForAge = 75 - (age × 0.6)
- hrvDelta = (expectedHrvForAge - hrv) / 5
- rhrAdjustment = max(0, (restingHeartRate - 55) / 10)
- sleepAdjustment = (100 - sleepQuality) / 20
- exerciseAdjustment = clamp(-3, 3, (150 - weeklyExerciseMinutes) / 50)
- bodyFatAdjustment = |bodyFatPercent - optimalBF| / 5
- optimalBF: male=15%, female=22%
Result: clamped to [18, age+15]
Example:¶
Input: age=35, hrv=50, rhr=60, sleepQuality=75, exercise=200min, bodyFat=18%, male
- expectedHrv = 75 - (35 × 0.6) = 54
- hrvDelta = (54 - 50) / 5 = 0.8
- rhrAdjustment = max(0, (60-55)/10) = 0.5
- sleepAdjustment = (100-75) / 20 = 1.25
- exerciseAdjustment = (150-200) / 50 = -1.0
- bodyFatAdjustment = |18-15| / 5 = 0.6
biologicalAge = 35 + 0.8 + 0.5 + 1.25 - 1.0 + 0.6 = 37.15 → 37 years
2. Biological Age Delta¶
Scale: Years (positive = younger than actual age) Purpose: Quick indicator of aging rate
Formula:¶
biologicalAgeDelta = chronologicalAge - biologicalAge
3. Metabolic Health¶
Scale: 0-100 (higher = better) Purpose: Overall metabolic function assessment
Input Metrics:¶
weightKgheightCmbodyFatPercentcaloriesConsumedcaloriesGoalproteinGramsgender
Formula:¶
metabolicHealth = bmiScore + bodyFatScore + calorieScore + proteinScore
Where:
BMI Score (0-30):
- BMI = weightKg / (heightCm/100)²
- 18.5-24.9 → 30 pts
- 17-18.5 → 20 pts
- 25-29.9 → 15 pts
- else → 5 pts
Body Fat Score (0-30):
- Optimal range: male [10-20%], female [18-28%]
- In range → 30 pts
- Below range → 20 pts
- Above range → 30 - ((bf - upper) × 2), min 5
Calorie Score (0-20):
- Ratio = consumed / goal
- 0.85-1.1 → 20 pts
- else → 10 pts
Protein Score (0-20):
- proteinPerKg = protein / weight
- 1.6-2.5 g/kg → 20 pts
- 1.2+ g/kg → 15 pts
- else → 5 pts
4. Cardiovascular Fitness¶
Scale: 0-100 (higher = better) Purpose: Heart and lung health assessment
Input Metrics:¶
restingHeartRatehrvvo2MaxEstimatebloodPressureSystolicagegender
Formula:¶
cardiovascularFitness = rhrScore + hrvScore + vo2Score + bpScore
Where:
RHR Score (0-30):
- ≤50 bpm → 30 pts
- ≤60 bpm → 25 pts
- ≤70 bpm → 18 pts
- ≤80 bpm → 10 pts
- >80 bpm → 5 pts
HRV Score (0-30):
- expectedHrv = 75 - (age × 0.5)
- hrvRatio = hrv / expectedHrv
- ≥1.2 → 30 pts
- ≥1.0 → 25 pts
- ≥0.8 → 18 pts
- ≥0.6 → 10 pts
- <0.6 → 5 pts
VO2max Score (0-25):
- excellent = male ? 50 : 42
- ≥excellent → 25 pts
- ≥excellent-8 → 20 pts
- ≥excellent-15 → 15 pts
- else → 8 pts
BP Score (0-15):
- <120 → 15 pts
- <130 → 12 pts
- <140 → 8 pts
- ≥140 → 3 pts
5. Readiness Score¶
Scale: 0-100 (higher = better) Purpose: Today's training readiness (like WHOOP Recovery / Oura Readiness)
Input Metrics:¶
hrvsleepQualitysleepDurationHoursperceivedRecoveryrestingHeartRateage
Formula:¶
readinessScore = (hrvReadiness × 0.4) + (sleepReadiness × 0.3) + (recoveryReadiness × 0.2) + (rhrReadiness × 0.1)
Where:
- baselineHrv = 75 - (age × 0.5)
- hrvReadiness = min(100, (hrv / baselineHrv) × 100)
- sleepDurationScore = min(100, (sleepDurationHours / 8) × 100)
- sleepReadiness = (sleepQuality × 0.6) + (sleepDurationScore × 0.4)
- recoveryReadiness = perceivedRecovery
- rhrDeviation = restingHeartRate - 55
- rhrReadiness = max(0, 100 - (rhrDeviation × 3))
Result: clamped to [0, 100]
6. Recovery Potential¶
Scale: 0-100 (higher = better) Purpose: Baseline ability to recover (NOT today's state)
Input Metrics:¶
hrvsleepEfficiencydeepSleepPercentsleepQualityage
Formula:¶
recoveryPotential = (hrvCapacity × 0.4) + (efficiencyScore × 0.3) + (deepSleepScore × 0.2) + (sleepQuality × 0.1)
Where:
- baselineHrv = 80 - (age × 0.5)
- hrvCapacity = min(100, (hrv / baselineHrv) × 100)
- efficiencyScore = sleepEfficiency (default 85)
- deepSleepScore = min(100, deepSleepPercent × 5) (default 70)
Result: clamped to [0, 100]
7. Sleep Performance¶
Scale: 0-100 (higher = better) Purpose: Comprehensive sleep quality assessment
Input Metrics:¶
sleepDurationHourssleepQualitysleepEfficiencydeepSleepPercentremSleepPercent
Formula:¶
sleepPerformance = durationScore + qualityScore + efficiencyScore + architectureScore
Where:
Duration Score (0-25):
- 7-9 hrs → 25 pts
- 6-7 hrs → 18 pts
- 9-10 hrs → 20 pts
- else → 10 pts
Quality Score (0-25):
- sleepQuality × 0.25
Efficiency Score (0-25):
- (sleepEfficiency / 100) × 25
Architecture Score (0-25):
- combined = deepSleepPercent + remSleepPercent
- 40-55% → 25 pts
- ≥30% → 18 pts
- else → 10 pts
8. Stress Resilience¶
Scale: 0-100 (higher = better) Purpose: Ability to handle and recover from stress
Input Metrics:¶
hrvrestingHeartRatesleepQualityperceivedRecoveryageweeklyExerciseMinutes
Formula:¶
stressResilience = (hrvResilience × 0.45) + (rhrResilience × 0.25) + (perceivedRecovery × 0.15) + exerciseBonus + sleepBonus
Where:
- baselineHrv = 70 - (age × 0.4)
- hrvResilience = min(100, (hrv / baselineHrv) × 100)
- rhrResilience = max(0, 100 - ((restingHeartRate - 50) × 2))
- exerciseBonus = min(15, weeklyExerciseMinutes / 20)
- sleepBonus = sleepQuality × 0.15
Result: clamped to [0, 100]
9. Longevity Score¶
Scale: 0-100 (higher = better) Purpose: Long-term health trajectory prediction
Input Metrics:¶
- All metrics from: Cardio Fitness, Metabolic Health, Sleep Performance, Stress Resilience
weeklyExerciseMinutesage
Formula:¶
longevityScore = (cardioFitness × 0.3) + (metabolicHealth × 0.2) + (sleepPerformance × 0.2) + (stressResilience × 0.15) + (activityScore × 0.15) + ageBonus
Where:
- activityScore = min(100, (weeklyExerciseMinutes / 300) × 100)
- bioAge = calculateBiologicalAge(...)
- ageDelta = age - bioAge
- ageBonus = clamp(-10, 10, ageDelta × 2)
Result: clamped to [0, 100]
10. Athletic Potential¶
Scale: 0-100 (higher = better) Purpose: Current fitness level and performance capacity
Input Metrics:¶
vo2MaxEstimaterestingHeartRatehrvweeklyExerciseMinutesactiveCaloriesDailygender
Formula:¶
athleticPotential = vo2Score + heartEfficiency + trainingScore + energyScore
Where:
VO2 Score (0-30):
- excellent = male ? 55 : 47
- min(30, (vo2Max / excellent) × 30)
Heart Efficiency (0-30):
- min(30, ((70 - rhr) / 25) × 15 + (hrv / 60) × 15)
Training Score (0-20):
- min(20, (weeklyExerciseMinutes / 250) × 20)
Energy Score (0-20):
- min(20, (activeCaloriesDaily / 600) × 20)
11. Injury Risk Index¶
Scale: 0-100 (LOWER = better) Purpose: Predicts injury vulnerability
Input Metrics:¶
perceivedRecoverysleepQualitysleepDurationHoursweeklyExerciseMinuteshrvage
Formula:¶
injuryRiskIndex = (recoveryRisk × 0.35) + (sleepRisk × 0.25) + (hrvRisk × 0.25) + (overtrainingRisk × 0.15)
Where:
- recoveryRisk = 100 - perceivedRecovery
- sleepRisk = sleepDurationHours < 7 ? (7 - sleepDurationHours) × 15 : 0
- baselineHrv = 60 - (age × 0.3)
- hrvRisk = hrv < baselineHrv ? ((baselineHrv - hrv) / baselineHrv) × 30 : 0
- overtrainingRisk = weeklyExerciseMinutes > 600 ? min(25, (weeklyExerciseMinutes - 600) / 20) : 0
Result: clamped to [0, 100]
12. Overtraining Risk¶
Scale: 0-100 (LOWER = better) Purpose: Detects overtraining syndrome signs
Input Metrics:¶
hrvrestingHeartRatesleepQualityperceivedRecoveryweeklyExerciseMinutesage
Formula:¶
overtrainingRisk = (hrvSuppression × 0.35) + (rhrElevation × 0.2) + (sleepIssue × 0.2) + (volumeRisk × 0.1) + (recoveryIssue × 0.15)
Where:
- baselineHrv = 65 - (age × 0.4)
- hrvSuppression = max(0, ((baselineHrv - hrv) / baselineHrv) × 40)
- rhrElevation = max(0, (restingHeartRate - 55) × 1.5)
- sleepIssue = max(0, 70 - sleepQuality)
- volumeRisk = weeklyExerciseMinutes > 400 ? min(20, (weeklyExerciseMinutes - 400) / 30) : 0
- recoveryIssue = max(0, 60 - perceivedRecovery)
Result: clamped to [0, 100]
13. Fuel Efficiency¶
Scale: 0-100 (higher = better) Purpose: How well nutrition supports activity
Input Metrics:¶
caloriesConsumedcaloriesGoalproteinGramsweightKghydrationPercentactiveCaloriesDaily
Formula:¶
fuelEfficiency = calorieScore + proteinScore + hydrationScore + balanceScore
Where:
Calorie Score (0-30):
- ratio = caloriesConsumed / caloriesGoal
- 0.9-1.1 → 30 pts
- 0.8-1.2 → 20 pts
- else → 10 pts
Protein Score (0-30):
- proteinPerKg = proteinGrams / weightKg
- 1.6-2.5 g/kg → 30 pts
- ≥1.2 g/kg → 20 pts
- else → 10 pts
Hydration Score (0-20):
- hydrationPercent × 0.2
Balance Score (0-20):
- netCalories = caloriesConsumed - activeCaloriesDaily
- 1500-2500 → 20 pts
- else → 10 pts
14. Strain Score¶
Scale: 0-21 (logarithmic, WHOOP-style) Purpose: Daily cardiovascular load
Input Metrics:¶
todayWorkoutMinutestodayHRZoneMinutes(zone1-5)dailySteps
Formula:¶
strainScore = 21 × (1 - e^(-rawStrain/200))
Where:
Zone Multipliers:
- zone1 (50-60% HR): 0.5
- zone2 (60-70% HR): 1.0
- zone3 (70-80% HR): 2.0
- zone4 (80-90% HR): 4.0
- zone5 (90-100% HR): 8.0
rawStrain = Σ(zoneMinutes × zoneMultiplier)
If no zone data:
- rawStrain = todayWorkoutMinutes × 1.5
Steps contribution:
- stepsStrain = min(30, (dailySteps / 10000) × 30)
- rawStrain += stepsStrain × 0.3
Result: 0-21 (rounded to 1 decimal)
Example:¶
Input: 30min zone3, 15min zone4, 10min zone5, 8000 steps
- rawStrain = (30 × 2.0) + (15 × 4.0) + (10 × 8.0) = 60 + 60 + 80 = 200
- stepsStrain = min(30, (8000/10000) × 30) = 24
- rawStrain += 24 × 0.3 = 207.2
- strainScore = 21 × (1 - e^(-207.2/200)) = 21 × 0.645 = 13.5
15. Fitness Score¶
Scale: 0-∞ (typically 0-150, CTL-style) Purpose: Cumulative fitness level with decay
Input Metrics:¶
recentWorkouts[](date, duration, averageHRPercent, strainPoints)weeklyExerciseMinutes(fallback)
Formula:¶
fitnessScore = Σ(TSS × decayFactor) / timeConstant
Where:
- timeConstant = 42 days
- For each workout:
- daysAgo = today - workoutDate
- if daysAgo > 90: skip (negligible)
- durationHours = durationMinutes / 60
- intensityFactor = averageHRPercent / 100
- TSS = strainPoints || (durationHours × intensityFactor² × 100)
- decayFactor = e^(-daysAgo / 42)
- fitnessScore += TSS × decayFactor
Fallback (no workout history):
- fitnessScore = min(60, weeklyExerciseMinutes / 3)
Example:¶
Workout 3 days ago: 60min at 75% intensity
- TSS = (60/60) × 0.75² × 100 = 56.25
- decayFactor = e^(-3/42) = 0.931
- contribution = 56.25 × 0.931 = 52.4
Workout 10 days ago: 45min at 80% intensity
- TSS = (45/60) × 0.80² × 100 = 48
- decayFactor = e^(-10/42) = 0.788
- contribution = 48 × 0.788 = 37.8
fitnessScore = (52.4 + 37.8) / 42 = 2.1 (low, only 2 workouts)
Dependency Graph¶
Raw Metrics → Calculated Scores
restingHeartRate ──┬─→ Biological Age
├─→ Cardiovascular Fitness
├─→ Readiness Score
├─→ Stress Resilience
├─→ Athletic Potential
└─→ Overtraining Risk
hrv ───────────────┬─→ Biological Age
├─→ Cardiovascular Fitness
├─→ Readiness Score
├─→ Recovery Potential
├─→ Stress Resilience
├─→ Injury Risk Index
└─→ Overtraining Risk
sleepQuality ──────┬─→ Biological Age
├─→ Readiness Score
├─→ Recovery Potential
├─→ Sleep Performance
├─→ Stress Resilience
└─→ Overtraining Risk
sleepDurationHours ┬─→ Readiness Score
├─→ Sleep Performance
└─→ Injury Risk Index
weeklyExerciseMinutes ┬─→ Biological Age
├─→ Stress Resilience
├─→ Longevity Score
├─→ Athletic Potential
├─→ Injury Risk Index
└─→ Overtraining Risk
perceivedRecovery ─┬─→ Readiness Score
├─→ Stress Resilience
├─→ Injury Risk Index
└─→ Overtraining Risk
Composite Dependencies:
Longevity Score ←── Cardiovascular Fitness
←── Metabolic Health
←── Sleep Performance
←── Stress Resilience
←── Biological Age
Score Interpretation¶
Positive Scores (higher = better)¶
| Score | Label | Description |
|---|---|---|
| ≥85 | Excellent | Top-tier performance |
| 70-84 | Good | Above average |
| 55-69 | Average | Room for improvement |
| 40-54 | Fair | Needs attention |
| <40 | Poor | Requires intervention |
Risk Scores (lower = better)¶
| Score | Label | Description |
|---|---|---|
| ≤20 | Low Risk | Excellent - minimal concern |
| 21-40 | Moderate | Good - stay vigilant |
| 41-60 | Elevated | Caution - take preventive action |
| 61-80 | High | Warning - immediate attention needed |
| >80 | Critical | Critical - rest and recover |
Biological Age Interpretation¶
| Delta | Label | Emoji | Description |
|---|---|---|---|
| ≥5 younger | X years younger | 🏆 | Exceptional - aging slower |
| 2-4 younger | X years younger | ✨ | Great - healthy aging |
| -1 to +1 | On track | 👍 | Matches chronological age |
| 2-4 older | X years older | ⚠️ | Lifestyle adjustments needed |
| ≥5 older | X years older | 🚨 | Focus on sleep, exercise, stress |
References¶
- WHOOP: Strain score methodology, recovery concepts
- Oura Ring: Readiness score, sleep architecture
- Kubios: HRV analysis, biological age
- TrainingPeaks: CTL/ATL fitness tracking (TSS)
- Strava: Fitness score with decay
- Research: Peer-reviewed studies on HRV, sleep, recovery
Generated: 2026-02-04 Source: champion-stats-hub/src/lib/advancedHealthScores.ts