Help & Knowledge Center
< All Topics
Print

Stress Measurement with Apple Watch and Google Watch

Apple Watch and Google Watch do not natively provide stress values or information. 

To make the devices comparable to Garmin device data, which provides stress information, Fitrockr computes a stress value from the Apple Watch and Google Watch data. The algorithm is described in the following.

Stress Estimation Based on RMSSD and SDNN

In this system, stress is estimated using Heart Rate Variability (HRV) metrics, specifically RMSSD and/or SDNN values. The estimation follows a well-defined inverse relationship where higher HRV values indicate lower stress levels higher HRV values indicate lower stress levels.

RMSSD-Based Stress Calculation

Algorithm: Linear inverse mapping from RMSSD to stress level (1-100 scale).

public int calculateStressLevelFromRmssd(double rmssd) {

if (rmssd <= 10) return 100; // Maximum stress

if (rmssd >= 100) return 1; // Minimum stress

// Linear mapping from RMSSD to stress level (inverse relationship)

return (int) (101 – rmssd);

}

Key Parameters:

Range: Typical RMSSD values from 10-100 ms

Thresholds:

– RMSSD ≤ 10 ms → Stress Level = 100 (Maximum stress)

– RMSSD ≥ 100 ms → Stress Level = 1 (Minimum stress)

Formula: Stress Level = 101 – RMSSD (for values between 10-100)

SDNN-Based Stress Calculation

Algorithm: Linear inverse mapping from SDNN to stress level (1-100 scale).

public int calculateStressLevelFromSdnn(double sdnn) {

if (sdnn <= 20) return 100; // Maximum stress

if (sdnn >= 200) return 1; // Minimum stress

// Linear mapping from SDNN to stress level (inverse relationship)

return (int) (101 – (sdnn – 20) * 99 / 180);

}

Key Parameters:

Range: Typical SDNN values from 20-200 ms

Thresholds:

– SDNN ≤ 20 ms → Stress Level = 100 (Maximum stress)

– SDNN ≥ 200 ms → Stress Level = 1 (Minimum stress)

Formula: Stress Level = 101 – ((SDNN – 20) × 99 / 180) (for values between 20-200)

Combined RMSSD and SDNN Calculation

When both metrics are available, the system uses a weighted approach:

private int calculateCombinedStressLevel(double rmssd, double sdnn) {

int rmssdStress = calculateStressLevelFromRmssd(rmssd);

int sdnnStress = calculateStressLevelFromSdnn(sdnn);

// Weighted average, giving more weight to RMSSD

return (int) (rmssdStress * 0.6 + sdnnStress * 0.4);

}

Weighting Strategy:

RMSSD: 60% weight (considered more sensitive to stress changes)

SDNN: 40% weight

Formula: Combined Stress = (RMSSD_Stress × 0.6) + (SDNN_Stress × 0.4)

Stress Categories

The calculated stress levels (1-100) are mapped to categorical levels:

VERY_LOW: < 20

LOW: 20-39

MODERATE: 40-59

HIGH: 60-79

VERY_HIGH: ≥ 80

Implementation Strategy

The system uses a fallback hierarchy:

First Priority: Combined calculation (when both RMSSD and SDNN are available)

Second Priority: RMSSD-only calculation (when only RMSSD is available)

Third Priority: SDNN-only calculation (when only SDNN is available)

Temporal Resolution

Calculation Interval: 5-minute basis

Data Source: Health log records with Beat-to-Beat Interval (BBI) data

Output: Time-series of stress scores with Unix timestamps

Scientific Rationale

The inverse relationship between HRV metrics and stress is based on physiological principles:

Higher RMSSD/SDNN: Indicates greater parasympathetic (rest-and-digest) activity → Lower stress

Lower RMSSD/SDNN: Indicates reduced heart rate variability → Higher stress/sympathetic dominance

The weighting preference for RMSSD (60%) reflects its higher sensitivity to acute stress changes compared to SDNN, which represents overall variability over longer periods.

Shopping Basket