GlucoseIQ
API Reference@glucoseiq/core

Variability & Risk Metrics

Glucose variability and risk indices.

calculateADRR

Import: @glucoseiq/core/metrics

calculateADRR(readings: GlucoseReading[]): number

Calculates the Average Daily Risk Range (ADRR).

Returns: ADRR value, or NaN if no valid readings

See: https://doi.org/10.2337/dc06-1085

ParameterDescription
readingsArray of GlucoseReading objects with timestamps

calculateActivePercent

Import: @glucoseiq/core/metrics

calculateActivePercent(readings: GlucoseReading[], options?: ActivePercentOptions): ActivePercentResult

Calculates a timestamp-slot coverage estimate for CGM readings.

Returns: Slot-coverage result, or a result with NaN if the timestamp span is insufficient

Throws: If expectedIntervalMinutes is invalid or creates an unsafe slot count

Remarks: This estimates data coverage; it does not prove sensor wear or clinical suitability.

See: https://doi.org/10.2337/dc17-1600

ParameterDescription
readingsArray of GlucoseReading objects with timestamps
optionsExpected interval configuration

calculateCONGA

Import: @glucoseiq/core/metrics

calculateCONGA(readings: GlucoseReading[], options?: CONGAOptions): number

Calculates CONGA (Continuous Overall Net Glycemic Action).

Returns: CONGA value in mg/dL, or NaN if insufficient matched pairs

See: https://doi.org/10.1089/dia.2005.7.253

ParameterDescription
readingsArray of GlucoseReading objects with timestamps
optionsTime lag (hours) and tolerance configuration

calculateGRADE

Import: @glucoseiq/core/metrics

calculateGRADE(readings: number[], hypoThreshold: number = 70, hyperThreshold: number = 140, unit: GlucoseUnit = MG_DL): GRADEResult

Calculates the GRADE score and its partitioned components.

Returns: GRADE result with overall score and percentage breakdown, or NaN fields if no valid data

See: https://doi.org/10.1111/j.1464-5491.2007.02119.x

ParameterDescription
readingsArray of glucose values (mg/dL by default)
hypoThresholdUpper bound for hypoglycemia (default: 70 mg/dL, always mg/dL)
hyperThresholdLower bound for hyperglycemia (default: 140 mg/dL, always mg/dL)
unitUnit of readings (default 'mg/dL'); 'mmol/L' is converted to mg/dL first

calculateGRI

Import: @glucoseiq/core/metrics

calculateGRI(input: GRIInput): GRIResult

Calculates the Glycemia Risk Index (GRI) from TIR zone percentages.

Returns: GRI result with composite score and risk zone

See: https://doi.org/10.1177/19322968221085273

ParameterDescription
inputPercentages for each out-of-range zone

calculateGVIPGS

Import: @glucoseiq/core/metrics

calculateGVIPGS(readings: GlucoseReading[], options?: GVIPGSOptions): GVIPGSResult

Calculates GVI and PGS from glucose readings (Nightscout algorithm).

Returns: GVI, PGS, the mean glucose, and PTIR; NaN when there are no valid steps

ParameterDescription
readingsGlucose readings with ISO 8601 timestamps
optionsTarget range and maximum gap

calculateIGC

Import: @glucoseiq/core/metrics

calculateIGC(readings: number[], options?: IGCOptions): IGCResult

Calculates Rodbard's hypo/hyper indices and IGC.

Returns: Hypo index, hyper index, and their sum (IGC); NaN fields if no valid readings

See: https://doi.org/10.1089/dia.2008.0132

ParameterDescription
readingsGlucose values (mg/dL by default)
optionsUnit, target limits, exponents, and scale factors

calculateJIndex

Import: @glucoseiq/core/metrics

calculateJIndex(readings: number[], unit: GlucoseUnit = MG_DL): number

Calculates the J-Index for a glucose trace.

The J-Index captures both central tendency and variability in a single score. Higher values indicate worse glycemic control.

Returns: J-Index value, or NaN if fewer than 2 valid readings

See: https://doi.org/10.1055/s-2007-979906

ParameterDescription
readingsArray of glucose values (mg/dL by default)
unitUnit of readings (default 'mg/dL'); 'mmol/L' is converted to mg/dL first

calculateMODD

Import: @glucoseiq/core/metrics

calculateMODD(readings: GlucoseReading[], options?: MODDOptions): number

Calculates Mean of Daily Differences (MODD).

Returns: MODD value in mg/dL, or NaN if insufficient matched pairs

See: https://doi.org/10.2337/diacare.3.1.58

ParameterDescription
readingsArray of GlucoseReading objects with timestamps
optionsOptional tolerance configuration

clinicalMAGE

Import: @glucoseiq/core

clinicalMAGE(readings: number[], options: MAGEOptions = {}): number

Calculates Mean Amplitude of Glycemic Excursions (MAGE). Implements Service FJ et al. (1970) methodology.

Returns: MAGE value, or NaN if insufficient data or no valid excursions

See:

import { clinicalMAGE } from '@glucoseiq/core'

const readings: number[] = Array.from(
  { length: 100 },
  (_, index) => (index % 2 === 0 ? 90 : 160)
)
const mage = clinicalMAGE(readings)

Remarks: - Minimum 24 data points recommended (1 day of hourly readings)

  • Best suited for continuous glucose monitoring (CGM) data
  • Not recommended for sparse or irregular measurements
  • Uses dual moving averages, three-point excursion definition, and prevents double-counting.
ParameterDescription
readingsArray of glucose values (mg/dL or mmol/L)
optionsConfiguration options for MAGE calculation

glucoseCoefficientOfVariation

Import: @glucoseiq/core

glucoseCoefficientOfVariation(readings: number[]): number

Calculates the coefficient of variation (CV) for glucose values. CV = (SD / mean) × 100. Used to assess glycemic variability.

Returns: Coefficient of variation as a percentage, or NaN if <2 values or mean is 0

See: ADA 2019: Glycemic Targets

import { glucoseCoefficientOfVariation } from '@glucoseiq/core'

const valuesMgDl: number[] = [100, 120, 140]
const coefficientOfVariation = glucoseCoefficientOfVariation(valuesMgDl)

Remarks: - If readings contains <2 values or mean is 0, returns NaN.

  • Handles NaN/Infinity values by propagating them in the result.
ParameterDescription
readingsArray of glucose values (numbers)

glucoseGVP

Import: @glucoseiq/core/metrics

glucoseGVP(readings: GlucoseReading[]): number

Glycemic Variability Percentage (GVP): the percentage by which the length of the glucose trace exceeds the length of a flat line over the same time.

GVP = (L / L0 − 1) × 100, where L = Σ √(Δt² + Δglucose²) and L0 = Σ Δt (Δt in minutes, Δglucose in mg/dL).

Returns: GVP as a percentage, or NaN if < 2 readings or no time span

See: https://doi.org/10.1089/dia.2017.0187

ParameterDescription
readingsGlucose readings with ISO 8601 timestamps

glucoseHBGI

Import: @glucoseiq/core/metrics

glucoseHBGI(readings: number[], unit: GlucoseUnit = MG_DL): number

Calculates the High Blood Glucose Index (HBGI).

Quantifies the risk and extent of hyperglycemia from a glucose trace. Higher values indicate greater hyperglycemia risk.

Risk categories (Kovatchev 2006):

  • < 4.5: low risk
  • 4.5 - 9.0: moderate risk
  • > 9.0: high risk

Returns: HBGI value, or NaN if no valid readings

See: https://doi.org/10.2337/dc06-1085

ParameterDescription
readingsArray of glucose values (mg/dL by default)
unitUnit of readings (default 'mg/dL'); 'mmol/L' is converted to mg/dL first

glucoseLBGI

Import: @glucoseiq/core/metrics

glucoseLBGI(readings: number[], unit: GlucoseUnit = MG_DL): number

Calculates the Low Blood Glucose Index (LBGI).

Quantifies the risk and extent of hypoglycemia from a glucose trace. Higher values indicate greater hypoglycemia risk.

Risk categories (Kovatchev 2006):

  • < 1.1: low risk
  • 1.1 - 2.5: moderate risk
  • > 2.5: high risk

Returns: LBGI value, or NaN if no valid readings

See: https://doi.org/10.2337/dc06-1085

ParameterDescription
readingsArray of glucose values (mg/dL by default)
unitUnit of readings (default 'mg/dL'); 'mmol/L' is converted to mg/dL first

glucoseMAG

Import: @glucoseiq/core/metrics

glucoseMAG(readings: GlucoseReading[]): number

Mean Absolute Glucose change rate (MAG): total absolute glucose change divided by total elapsed time, in mg/dL per hour.

Returns: MAG in mg/dL per hour, or NaN if < 2 readings or no time span

See: https://doi.org/10.1186/cc9002

ParameterDescription
readingsGlucose readings with ISO 8601 timestamps

glucoseMAGE

Import: @glucoseiq/core

glucoseMAGE(readings: number[], options?: MAGEOptions): number

Calculates Mean Amplitude of Glycemic Excursions (MAGE) for glucose values. Implements Service FJ et al. (1970) methodology.

Returns: MAGE value, or NaN if insufficient data or no valid excursions

See:

import { glucoseMAGE } from '@glucoseiq/core'

const valuesMgDl: number[] = Array.from(
  { length: 100 },
  (_, index) => (index % 2 === 0 ? 90 : 160)
)
const mage = glucoseMAGE(valuesMgDl, { direction: 'ascending' })

Remarks: - Minimum 24 data points recommended (1 day of hourly readings)

  • Best suited for continuous glucose monitoring (CGM) data
  • Not recommended for sparse or irregular measurements
  • Uses dual moving averages, three-point excursion definition, and prevents double-counting.
ParameterDescription
readingsArray of glucose values (mg/dL or mmol/L)
optionsOptional configuration for MAGE calculation

glucoseMValue

Import: @glucoseiq/core/metrics

glucoseMValue(readings: number[], options?: MValueOptions): number

Calculates the Schlichtkrull M-value for a glucose series.

Returns: The M-value, or NaN if there are no valid (finite, > 0) readings

See: https://pubmed.ncbi.nlm.nih.gov/14163158/

ParameterDescription
readingsGlucose values (mg/dL by default)
optionsUnit, reference index, and whether to add the W correction

glucosePercentiles

Import: @glucoseiq/core

glucosePercentiles(readings: number[], percentiles: number[]): Record<number, number>

Calculates specified percentiles from an array of glucose values using the nearest-rank method.

Returns: Object mapping percentile to value, or {} if input is empty

Throws: If readings or percentiles is not an array (INVALID_OPTION)

See:

import { glucosePercentiles } from '@glucoseiq/core'

const valuesMgDl: number[] = [100, 120, 140, 160, 180]
const requestedPercentiles: number[] = [10, 50, 90]
const percentiles = glucosePercentiles(valuesMgDl, requestedPercentiles)

Remarks: - Returns the value at the nearest-rank for each percentile.

  • If readings is empty, returns an empty object.
  • Percentiles outside [0, 100] are ignored.
ParameterDescription
readingsArray of glucose values (numbers)
percentilesArray of percentiles to calculate (e.g., [10, 25, 50, 75, 90])

glucoseStandardDeviation

Import: @glucoseiq/core

glucoseStandardDeviation(readings: number[]): number

Calculates the unbiased sample standard deviation (SD) of glucose values. Uses n-1 in the denominator (sample SD), as recommended in research guidelines.

Returns: Standard deviation, or NaN if fewer than 2 values

See:

import { glucoseStandardDeviation } from '@glucoseiq/core'

const valuesMgDl: number[] = [100, 120, 140]
const standardDeviation = glucoseStandardDeviation(valuesMgDl)

Remarks: - If readings contains <2 values, returns NaN (not enough data for SD).

  • Handles NaN/Infinity values by propagating them in the result.
ParameterDescription
readingsArray of glucose values (numbers)

On this page