Skip to content

Earned value and earned schedule

Freeze the time-phased planned value curve as a Performance Measurement Baseline (PMB), commit it to version control, and evaluate each reporting period against it.

import pmcontrols as pm

periods = list(range(11))
pv = [i * 10_000 for i in periods]      # linear $100k over 10 periods

pm.plan(periods, pv).save("pmb.json")   # freeze once; commit to git

r = pm.evm("pmb.json", ev=30_000, ac=35_000, at=4)
print(r.summary())

r.stats carries the full indicator set.

Indicator Meaning
cv, sv cost and schedule variance (EV - AC, EV - PV)
cpi, spi cost and schedule performance index (EV/AC, EV/PV)
eac_cpi estimate at completion, BAC / CPI
eac_typical AC + (BAC - EV), remaining work at planned efficiency
eac_cpi_spi the CPI by SPI blended forecast
etc, vac estimate to complete, variance at completion
tcpi_bac to-complete performance index against BAC

The earned-schedule block

Plain SPI = EV/PV is known to drift back to 1.0 as a late project finishes: at completion EV = PV = BAC, so SPI = 1.0 even on a project that delivered months late. Lipke's earned schedule (Lipke, 2003) fixes this by working in the time dimension:

  • ES is the time at which the plan had earned what you have now earned, found by linear interpolation on the cumulative PV curve.
  • SV(t) = ES - AT and SPI(t) = ES / AT give a schedule index that keeps reporting slippage all the way to the finish.
  • IEAC(t) = PD / SPI(t) forecasts the total project duration.
r.stats["es"]        # earned schedule, in PMB time units
r.stats["spi_t"]     # ES / AT
r.stats["ieac_t"]    # forecast completion duration

The PMB

pm.plan(periods, pv) returns a PMB that validates the planned-value curve is non-decreasing and ends at BAC. It round-trips through JSON (save/load, to_json/from_json), so the baseline is a committed, auditable artifact rather than a cell in a spreadsheet. pm.evm accepts either a PMB object or a path to a saved one.

EV above BAC, or negative EV/AC, raises a ValueError. The definitions follow PMBOK / EIA-748 practice for the cost indicators and Lipke (2003) for earned schedule.