Highlights of PERS assets, liabilities and other important funding metrics over the last 2 decades.
Unfunded Liability
The funded ratio is calculated by dividing the value of plan assets by liabilities. When “Actuarial Value” is selected the actuarially smoothed assets are used. When “Market Value” is selected the market value of those assets are used. The difference between plan assets and liabilities is the unfunded accrued liability (UAL). Again, when “Actuarial Value” is selected the actuarially smoothed assets are used. When “Market Value” is selected the market value of those assets are used.
This chart also shows the difference between plan assets and liabilities–looking at the difference between those assets and liabilities (UAL).When “Actuarial Value” is selected the actuarially smoothed assets are used. When “Market Value” is selected the market value of those assets are used.
Investment Performance below projections has added $1.1 billion to unfunded liabilities.
Updates to Actuarial Methods & Assumptions revealed $837 million in additional unfunded liabilities not previously accounted for due to experience not meeting expectations.
Debt Financed Benefits Increases have added a net $508 million in unfunded liabilities.
Negative Amortization stemming from fixed state contributes has resulted in interest on PERS DBRP debt exceeding the actual debt payments (negative amortization) , adding $331 million in unfunded liabilities.
Other unclassified changes to PERS DCRP over the years have added a net $180 million in unfunded liabilities.
Unclassified Liability Gain/Loss changes have added a net $39 million in unfunded liabilities.
Deviations from Demographic Assumptions updated demographic assumptions exposed $39 million in previously unrecognized unfunded liabilities.
Gains from Expected Pay Increases Not Given reduced unfunded liabilities by $240 million.
Net Change, from 2000 to 2021, unfunded liabilities increased by $2.8 billion
Unpaid Interest
Amortization Payments
Assets & Returns
Investment Returns
The chart below compares assumed returns with market, actuarial, and geometric rolling returns. The table provides the geomtetric average return for the last 5, 10, and 15 years.
Asset Allocation
Fixed Income: U.S. government securities, corporate bonds, mortgage-backed securities, asset backed securities, derivative instruments, etc.
Public Equities: Publicly reported and traded stocks.
Private Equity: Investments in funds managed by private firms such as Blackrock, StateStreet and The Vanguard Group..
Other Alternatives: Hedge funds, real estate, and other limited partnerships.
Probability of Hitting Assumed Rate of Return
The boxes below represent the probability that PERS will hit a given assumed rate of return based on 10,000 simulations of various capital market assumptions, in addition to plan assumptions and historical data.
// Random number generatorfunctionsfc32(a, b, c, d) {let rng =function() { a >>>=0; b >>>=0; c >>>=0; d >>>=0;var t = (a + b) |0; a = b ^ (b >>>9); b = (c + (c <<3)) |0; c = (c <<21) | (c >>>11); d = (d +1) |0; t = (t + d) |0; c = (c + t) |0;return (t >>>0) /4294967296; };for (let i =0; i <10; i++) {rng(); }return rng;}
radius =3;fillOpacity =0.5;strokeOpacity =75;circleStrokeWidth =0.7;returnInput = object.return/100;height =750;addSharedThings =function(svg) {// capital market boxes svg.append("g").attr("fill","#fff")// .attr("stroke", "#ccc").selectAll("rect").data(y2.domain()).join("rect").attr("x",0).attr("y", d =>y2(d)).attr("width",x(1) -x(0)).attr("height", y2.bandwidth).style("margin",10);// capital market labels svg.append("g").attr("fill","#444").selectAll("text").data(y2.domain()).join("text").attr("x",0).attr("y", d =>y2(d) +40).text(d => d).style("font-family","'Open Sans', sans-serif").style("font-size","30px");// x axis svg.append("g").call(xAxis);}addPlanMeans =function(svg) { svg.append("g").attr("stroke","#222").selectAll("line").data(planAverages).join("line").attr("x1", d =>x(returnInput)).attr("x2", d =>x(returnInput)).attr("y1", margin.top+10).attr("y2", height - margin.bottom).attr("stroke-width",2)}addPlanText =function(svg) { svg.append('text').attr('text-anchor','middle').attr('background-color','white').attr("x", d =>x(returnInput)).attr("y", margin.top).text(d => d3.format(".2%")(returnInput)).style("font-size","30px").style("font-weight",700)}data2Temp =FileAttachment("./data/pers/simulation_data.csv").csv()aq.addFunction('random2',sfc32(1,2,3,4))
data2 = aq.from(data2Temp).derive({"Data": d =>+d["Data"],random: d =>+op.random2() }).sample(10000).objects();data2PA = aq.from(data2Temp).derive({"Data": d =>+d["Data"],random: d =>+op.random2() }).objects();planAverages = aq.from(data2PA).derive({"Data": d =>+d["Data"] *100 }).groupby("Plan Name").rollup({"mean": d => op.mean(+d["Mean Return"])}).objects();x = d3.scaleLinear().domain([-0.1,0.15]).range([margin.left, width - margin.right-100])y2 = d3.scaleBand().domain( [...planAverages].sort((a, b) => a.mean- b.mean).map(d => d["Plan Name"]) )// .domain(data.map(d => d.region)).rangeRound([margin.top, height - margin.bottom]).padding(0.02)xAxis = g => g.attr("transform",`translate(0,${height - margin.bottom})`).call(d3.axisBottom(x).ticks(10).tickSize(10).tickFormat((d) => d3.format(`.0%`)(d))).style("fill","rgb(129, 129, 129, 0. 85)").call(g => g.selectAll(".tick text").style("font-size","25px").style("font-weight",400).attr("fill","rgb(129, 129, 129)")).call(g => g.select(".domain").remove()).attr('font-family',"'Open Sans', sans-serif")margin = ({ top:30,right:10,bottom:30,left:20 })