#!/usr/bin/php
\n";
echo "
HARS - Historical Actuarial Retirement Simulator\n";
echo "";
echo "HARS - Historical Actuarial Retirement Simulator
\n";
echo "\n";
# Financial data.
# Annualized real monthly S&P Comp. data from Shiller: http://www.econ.yale.edu/~shiller/data.htm
$shiller_initial = 1871; # Initial year for the Shiller dataset
$shiller_price = array(
4.44, 4.50, 4.61, 4.74, 4.86, 4.82, 4.73, 4.79, 4.84, 4.59, 4.64, 4.74, # 1871
4.86, 4.88, 5.04, 5.18, 5.18, 5.13, 5.10, 5.04, 4.95, 4.97, 4.95, 5.07,
5.11, 5.15, 5.11, 5.04, 5.05, 4.98, 4.97, 4.97, 4.59, 4.19, 4.04, 4.42,
4.66, 4.80, 4.73, 4.60, 4.48, 4.46, 4.46, 4.47, 4.54, 4.53, 4.57, 4.54,
4.54, 4.53, 4.59, 4.65, 4.47, 4.38, 4.39, 4.41, 4.37, 4.30, 4.37, 4.37,
4.46, 4.52, 4.51, 4.34, 4.18, 4.15, 4.10, 3.93, 3.69, 3.67, 3.60, 3.58,
3.55, 3.34, 3.17, 2.94, 2.94, 2.73, 2.85, 3.05, 3.24, 3.31, 3.26, 3.25,
3.25, 3.18, 3.24, 3.33, 3.34, 3.41, 3.48, 3.45, 3.52, 3.48, 3.47, 3.45,
3.58, 3.71, 3.65, 3.77, 3.94, 3.96, 4.04, 4.07, 4.22, 4.68, 4.93, 4.92,
5.11, 5.20, 5.30, 5.18, 4.77, 4.79, 5.01, 5.19, 5.18, 5.33, 5.61, 5.84,
6.19, 6.17, 6.24, 6.22, 6.50, 6.58, 6.35, 6.20, 6.25, 6.15, 6.19, 6.01,
5.92, 5.79, 5.78, 5.78, 5.71, 5.68, 6.00, 6.18, 6.24, 6.07, 5.81, 5.84,
5.81, 5.68, 5.75, 5.87, 5.77, 5.82, 5.73, 5.47, 5.53, 5.38, 5.46, 5.34,
5.18, 5.32, 5.30, 5.06, 4.65, 4.46, 4.46, 4.74, 4.59, 4.44, 4.35, 4.34,
4.24, 4.37, 4.38, 4.37, 4.32, 4.30, 4.46, 4.71, 4.65, 4.92, 5.24, 5.20,
5.20, 5.30, 5.19, 5.12, 5.02, 5.25, 5.33, 5.37, 5.51, 5.65, 5.79, 5.64,
5.58, 5.54, 5.67, 5.80, 5.90, 5.73, 5.59, 5.45, 5.38, 5.20, 5.30, 5.27,
5.31, 5.28, 5.08, 5.10, 5.17, 5.01, 5.14, 5.25, 5.38, 5.35, 5.24, 5.14,
5.24, 5.30, 5.19, 5.18, 5.32, 5.41, 5.30, 5.37, 5.50, 5.40, 5.35, 5.32,
5.38, 5.32, 5.28, 5.39, 5.62, 5.58, 5.54, 5.41, 5.32, 5.08, 4.71, 4.60,
4.84, 4.90, 4.81, 4.97, 4.95, 4.85, 4.77, 4.93, 5.33, 5.33, 5.25, 5.41,
5.51, 5.52, 5.58, 5.57, 5.57, 5.54, 5.54, 5.62, 5.48, 5.59, 5.57, 5.51,
5.61, 5.51, 5.31, 5.31, 4.84, 4.61, 4.18, 4.08, 4.37, 4.50, 4.57, 4.41,
4.32, 4.38, 4.51, 4.57, 4.40, 4.34, 4.25, 4.41, 4.48, 4.34, 4.34, 4.30,
4.25, 4.19, 4.19, 4.37, 4.61, 4.70, 4.72, 4.79, 4.82, 4.75, 4.59, 4.32,
4.27, 4.45, 4.38, 4.42, 4.40, 4.32, 4.04, 3.81, 4.01, 4.10, 4.38, 4.22,
4.22, 4.18, 4.19, 4.06, 4.08, 4.27, 4.46, 4.75, 4.98, 4.82, 4.65, 4.75,
4.88, 4.87, 4.65, 4.57, 4.87, 5.06, 5.08, 5.27, 5.26, 5.15, 5.32, 5.65,
6.08, 6.31, 6.40, 6.48, 6.21, 6.07, 6.28, 6.44, 6.37, 6.34, 6.46, 6.02,
6.10, 6.21, 6.26, 6.34, 6.04, 5.86, 5.86, 5.94, 5.80, 6.01, 6.48, 6.87,
7.07, 7.25, 7.51, 8.14, 7.73, 8.50, 7.93, 8.04, 8.00, 7.91, 8.08, 7.95,
8.12, 8.19, 8.20, 8.48, 8.46, 8.41, 8.60, 8.83, 8.85, 8.57, 8.24, 8.05,
8.46, 8.41, 8.08, 7.75, 7.60, 7.18, 6.85, 6.63, 6.47, 6.26, 6.28, 6.57,
6.68, 6.50, 6.48, 6.64, 6.50, 6.51, 6.78, 7.01, 7.32, 7.75, 8.17, 8.25,
8.43, 8.80, 9.05, 8.94, 8.50, 8.60, 8.87, 9.20, 9.23, 9.36, 9.31, 9.54,
9.87, 9.80, 9.56, 9.43, 9.18, 9.30, 9.06, 9.73, 10.03, 9.73, 9.93, 9.84,
9.56, 9.26, 8.35, 8.39, 8.10, 7.84, 8.14, 7.53, 7.45, 6.64, 6.25, 6.57,
6.85, 6.60, 6.87, 7.24, 7.63, 7.64, 7.92, 8.26, 8.17, 8.27, 8.83, 9.03,
9.06, 8.80, 8.92, 9.32, 9.63, 9.80, 9.94, 10.18, 10.19, 10.23, 10.18, 10.30,
10.08, 9.72, 9.96, 9.72, 9.56, 9.10, 8.64, 8.85, 8.91, 9.32, 9.31, 9.05,
9.27, 9.43, 9.32, 9.28, 9.48, 9.67, 9.63, 9.17, 8.67, 8.72, 9.07, 9.11,
9.12, 9.04, 9.30, 9.59, 9.58, 9.58, 9.59, 9.81, 9.86, 9.84, 9.73, 9.38,
9.30, 8.97, 8.80, 8.79, 8.55, 8.12, 8.23, 8.45, 8.53, 8.26, 8.05, 8.04,
8.37, 8.48, 8.32, 8.12, 8.17, 8.13, 7.68, 7.68, 7.68, 7.68, 7.68, 7.35,
7.48, 7.38, 7.57, 8.14, 7.95, 8.04, 8.01, 8.35, 8.66, 9.14, 9.46, 9.48,
9.33, 9.20, 9.17, 9.07, 9.27, 9.36, 9.23, 9.30, 9.68, 9.98, 10.21, 9.80,
9.57, 9.03, 9.31, 9.17, 8.86, 9.04, 8.79, 8.53, 8.12, 7.68, 7.04, 6.80,
7.21, 7.43, 7.28, 7.21, 7.44, 7.45, 7.51, 7.58, 7.54, 7.86, 8.06, 7.90,
7.85, 7.88, 8.12, 8.39, 8.97, 9.21, 9.51, 8.87, 9.01, 9.47, 9.19, 8.92,
8.83, 8.10, 8.67, 8.60, 8.06, 7.92, 7.91, 7.60, 7.87, 7.88, 7.48, 6.81,
7.11, 7.06, 6.88, 6.91, 7.12, 6.55, 6.53, 6.45, 6.61, 6.70, 7.06, 7.31,
7.30, 7.46, 7.74, 8.21, 8.53, 8.45, 8.51, 8.83, 9.06, 9.26, 8.80, 8.78,
8.90, 9.28, 9.43, 9.10, 8.67, 8.34, 8.06, 8.10, 8.15, 8.03, 8.27, 8.55,
8.83, 8.87, 8.70, 8.50, 8.47, 8.63, 9.03, 9.34, 9.25, 9.13, 9.64, 10.16,
10.58, 10.67, 10.39, 10.28, 10.61, 10.80, 11.10, 11.25, 11.51, 11.89, 12.26, 12.46,
12.65, 12.67, 11.81, 11.48, 11.56, 12.11, 12.62, 13.12, 13.32, 13.02, 13.19, 13.49,
13.40, 13.66, 13.87, 14.21, 14.70, 14.89, 15.22, 16.03, 16.94, 16.68, 17.06, 17.46,
17.53, 17.32, 18.25, 19.40, 20.00, 19.02, 19.16, 19.78, 21.17, 21.60, 23.06, 23.15,
24.86, 24.99, 25.43, 25.28, 25.66, 26.15, 28.48, 30.10, 31.30, 27.99, 20.58, 21.40,
21.71, 23.07, 23.94, 25.46, 23.94, 21.52, 21.06, 20.79, 20.78, 17.92, 16.62, 15.51,
15.98, 17.20, 17.53, 15.86, 14.33, 13.87, 14.33, 13.90, 11.83, 10.25, 10.39, 8.44,
8.30, 8.23, 8.26, 6.28, 5.51, 4.77, 5.01, 7.53, 8.26, 7.12, 7.05, 6.82,
7.09, 6.25, 6.23, 6.89, 8.87, 10.39, 11.23, 10.67, 10.58, 9.55, 9.78, 9.97,
10.54, 11.32, 10.74, 10.92, 9.81, 9.94, 9.47, 9.10, 8.88, 8.95, 9.20, 9.26,
9.26, 8.98, 8.41, 9.04, 9.75, 10.12, 10.65, 11.37, 11.61, 11.92, 13.04, 13.04,
13.76, 14.55, 14.86, 14.88, 14.09, 14.69, 15.56, 15.87, 16.05, 16.89, 17.36, 17.06,
17.59, 18.11, 18.09, 17.01, 16.25, 15.64, 16.57, 16.74, 14.37, 12.28, 11.20, 11.02,
11.31, 11.04, 10.31, 9.89, 9.98, 10.21, 12.24, 12.31, 11.75, 13.06, 13.07, 12.69,
12.50, 12.40, 12.39, 10.83, 11.23, 11.43, 11.71, 11.54, 12.77, 12.90, 12.67, 12.37,
12.30, 12.22, 12.15, 12.27, 10.58, 9.67, 9.99, 10.20, 10.63, 10.73, 10.98, 10.53,
10.55, 9.89, 9.95, 9.64, 9.43, 9.76, 10.26, 10.21, 10.24, 9.83, 9.37, 8.76,
8.93, 8.65, 8.18, 7.84, 7.93, 8.33, 8.64, 8.59, 8.68, 9.32, 9.47, 9.52,
10.09, 10.69, 11.07, 11.44, 11.89, 12.10, 12.35, 11.74, 11.99, 11.88, 11.33, 11.48,
11.85, 11.77, 12.10, 11.89, 12.10, 12.67, 13.00, 12.81, 12.60, 12.91, 12.82, 13.10,
13.49, 13.94, 13.93, 14.28, 14.82, 15.09, 14.78, 14.83, 15.84, 16.50, 17.04, 17.33,
18.02, 18.07, 17.53, 18.66, 18.70, 18.58, 18.05, 17.70, 15.09, 14.75, 14.69, 15.13,
15.21, 15.80, 15.16, 14.60, 14.34, 14.84, 15.77, 15.46, 15.06, 15.45, 15.27, 15.03,
14.83, 14.10, 14.30, 15.40, 16.15, 16.82, 16.42, 15.94, 15.76, 16.19, 15.29, 15.19,
15.36, 14.77, 14.91, 14.89, 14.78, 13.97, 14.76, 15.29, 15.49, 15.89, 16.11, 16.54,
16.88, 17.21, 17.35, 17.84, 18.44, 18.74, 17.38, 18.43, 19.08, 19.87, 19.83, 19.75,
21.21, 22.00, 21.63, 21.92, 21.93, 21.55, 21.93, 22.89, 23.48, 23.36, 22.71, 23.41,
24.19, 23.75, 23.81, 23.74, 23.73, 24.38, 25.08, 25.18, 24.78, 24.26, 25.03, 26.04,
26.18, 25.86, 25.99, 24.71, 24.84, 23.95, 24.29, 24.39, 23.27, 23.97, 24.50, 24.83,
25.46, 26.02, 26.57, 27.63, 28.73, 28.96, 30.13, 30.73, 31.45, 32.18, 33.44, 34.97,
35.60, 36.79, 36.50, 37.76, 37.60, 39.78, 42.69, 42.43, 44.34, 42.11, 44.95, 45.37,
44.15, 44.43, 47.49, 48.05, 46.54, 46.27, 48.78, 48.49, 46.84, 46.24, 45.76, 46.44,
45.43, 43.47, 44.03, 45.05, 46.78, 47.55, 48.51, 45.84, 43.98, 41.24, 40.35, 40.33,
41.12, 41.26, 42.11, 42.34, 43.70, 44.75, 45.98, 47.70, 48.96, 50.95, 52.50, 53.49,
55.62, 54.77, 56.16, 57.10, 57.96, 57.46, 59.74, 59.40, 57.05, 57.00, 57.23, 59.06,
58.03, 55.78, 55.02, 55.73, 55.22, 57.26, 55.84, 56.51, 54.81, 53.73, 55.47, 56.80,
59.72, 62.17, 64.12, 65.83, 66.50, 65.62, 65.44, 67.79, 67.26, 68.00, 71.08, 71.74,
69.07, 70.22, 70.29, 68.05, 62.99, 55.63, 56.97, 58.52, 58.00, 56.17, 60.04, 62.64,
65.06, 65.92, 65.67, 68.76, 70.14, 70.11, 69.07, 70.98, 72.85, 73.03, 72.62, 74.17,
76.45, 77.39, 78.80, 79.94, 80.72, 80.24, 83.22, 82.00, 83.41, 84.85, 85.44, 83.96,
86.12, 86.75, 86.83, 87.97, 89.28, 85.04, 84.91, 86.49, 89.38, 91.39, 92.15, 91.73,
93.32, 92.69, 88.88, 91.60, 86.78, 86.06, 85.84, 80.65, 77.81, 77.13, 80.99, 81.33,
84.45, 87.36, 89.42, 90.96, 92.59, 91.43, 93.01, 94.49, 95.81, 95.66, 92.66, 95.30,
95.04, 90.75, 89.09, 95.67, 97.87, 100.50, 100.30, 98.11, 101.30, 103.80, 105.40, 106.50,
102.00, 101.50, 99.30, 101.30, 104.60, 99.14, 94.71, 94.18, 94.51, 95.52, 96.21, 91.11,
90.31, 87.16, 88.65, 85.95, 76.06, 75.59, 75.72, 77.92, 82.58, 84.37, 84.28, 90.05,
93.49, 97.11, 99.60, 103.00, 101.60, 99.72, 99.00, 97.24, 99.40, 97.29, 92.78, 99.17,
103.30, 105.20, 107.70, 108.80, 107.70, 108.00, 107.20, 111.00, 109.40, 109.60, 115.10, 117.50,
118.40, 114.20, 112.40, 110.30, 107.20, 104.80, 105.80, 103.80, 105.60, 109.80, 102.00, 94.78,
96.11, 93.45, 97.44, 92.46, 89.67, 89.79, 79.31, 76.03, 68.12, 69.44, 71.74, 67.07,
72.56, 80.10, 83.78, 84.72, 90.10, 92.40, 92.49, 85.71, 84.67, 88.57, 90.07, 88.70,
96.86, 100.60, 101.10, 101.90, 101.20, 101.80, 104.20, 103.30, 105.50, 101.90, 101.20, 104.70,
103.80, 101.00, 100.60, 99.05, 98.76, 99.29, 100.20, 97.75, 96.23, 93.74, 94.28, 93.82,
90.25, 88.98, 88.82, 92.71, 97.41, 97.66, 97.19, 103.90, 103.90, 100.60, 94.71, 96.11,
99.71, 98.23, 100.10, 102.10, 99.73, 101.70, 102.70, 107.40, 108.60, 104.50, 103.70, 107.80,
110.90, 115.30, 104.70, 103.00, 107.70, 114.60, 119.80, 123.50, 126.50, 130.20, 135.70, 133.50,
133.00, 128.40, 133.20, 134.40, 131.70, 132.30, 129.10, 129.60, 118.30, 119.80, 122.90, 123.80,
117.30, 114.50, 110.80, 116.30, 116.40, 109.70, 109.40, 109.70, 122.40, 132.70, 138.10, 139.40,
144.30, 146.80, 151.90, 157.70, 164.10, 166.40, 167.00, 162.40, 167.20, 167.70, 165.20, 164.40,
166.40, 157.30, 157.40, 157.60, 156.60, 153.10, 151.10, 164.40, 166.10, 164.80, 166.30, 164.50,
171.60, 180.90, 179.40, 180.60, 184.90, 188.90, 192.50, 188.30, 184.10, 186.20, 197.50, 207.30,
208.20, 219.40, 232.30, 238.00, 238.50, 245.30, 240.20, 245.00, 238.30, 237.40, 245.10, 248.60,
264.50, 280.90, 292.50, 289.30, 289.10, 301.40, 310.10, 329.40, 318.70, 280.20, 245.00, 241.00,
250.50, 258.10, 265.70, 262.60, 256.10, 270.70, 269.10, 263.70, 268.00, 277.40, 271.00, 276.50,
285.40, 294.00, 292.70, 302.30, 313.90, 323.70, 331.90, 346.60, 347.30, 347.40, 340.20, 348.60,
339.97, 330.45, 338.46, 338.18, 350.25, 360.39, 360.03, 330.75, 315.41, 307.12, 315.29, 328.75,
325.49, 362.26, 372.28, 379.68, 377.99, 378.29, 380.23, 389.40, 387.20, 386.88, 385.92, 388.51,
416.08, 412.56, 407.36, 407.41, 414.81, 408.27, 415.05, 417.93, 418.48, 412.50, 422.84, 435.64,
435.23, 441.70, 450.16, 443.08, 445.25, 448.06, 447.29, 454.13, 459.24, 463.90, 462.89, 465.95,
472.99, 471.58, 463.81, 447.23, 450.90, 454.83, 451.40, 464.24, 466.96, 463.81, 461.01, 455.19,
465.25, 481.92, 493.15, 507.91, 523.81, 539.35, 557.37, 559.11, 578.77, 582.92, 595.53, 614.57,
614.42, 649.54, 647.07, 647.17, 661.23, 668.50, 644.07, 662.68, 674.88, 701.46, 735.67, 743.25,
766.22, 798.39, 792.16, 763.93, 833.09, 876.29, 925.29, 927.24, 937.02, 951.16, 938.92, 962.37,
963.36, 1023.74, 1076.83, 1112.20, 1108.42, 1108.39, 1156.58, 1074.62, 1020.64, 1032.47, 1144.43, 1190.05,
1248.77, 1246.58, 1281.66, 1334.76, 1332.07, 1322.55, 1380.99, 1327.49, 1318.17, 1300.01, 1391.00, 1428.68,
1425.59, 1388.87, 1442.21, 1461.36, 1418.48, 1461.96, 1473.00, 1485.46, 1468.05, 1390.14, 1378.04, 1330.93,
1335.63, 1305.75, 1185.85, 1189.84, 1270.37, 1238.71, 1204.45, 1178.50, 1044.64, 1076.59, 1129.68, 1144.93,
1140.21, 1100.67, 1153.79, 1111.93, 1079.25, 1014.02, 903.59, 912.55, 867.81, 854.63, 909.93, 899.18,
895.84, 837.03, 846.63, 890.03, 935.96, 988.00, 992.54, 989.53, 1019.44, 1038.73, 1049.90, 1080.64,
1132.52, 1143.36, 1123.98, 1133.36, 1102.78, 1132.76, 1105.85, 1088.94, 1117.66, 1117.21, 1168.94, 1199.21,
1181.41, 1199.63, 1194.90, 1164.43, 1178.28, 1202.25, 1222.24, 1224.27, 1225.92, 1191.96, 1237.37, 1262.07,
1278.73, 1276.65, 1293.74, 1302.17, 1290.01, 1253.17, 1260.24, 1287.15, 1317.74, 1363.38, 1388.64, 1416.42,
1424.16, 1444.80, 1406.95, 1463.64, 1511.14, 1514.19, 1520.71, 1454.62, 1497.12, 1539.66, 1463.39, 1479.22,
1378.76, 1354.87, 1316.94, 1370.47, 1403.22, 1341.25, 1257.33, 1281.47, 1216.95, 968.8, 883.04, 877.56, # 2008
);
$shiller_dividend = array(
0.26, 0.26, 0.26, 0.26, 0.26, 0.26, 0.26, 0.26, 0.26, 0.26, 0.26, 0.26, # 1871
0.26, 0.27, 0.27, 0.27, 0.28, 0.28, 0.28, 0.29, 0.29, 0.29, 0.30, 0.30,
0.30, 0.31, 0.31, 0.31, 0.31, 0.32, 0.32, 0.32, 0.32, 0.33, 0.33, 0.33,
0.33, 0.33, 0.33, 0.33, 0.33, 0.33, 0.33, 0.33, 0.33, 0.33, 0.33, 0.33,
0.33, 0.33, 0.32, 0.32, 0.32, 0.32, 0.31, 0.31, 0.31, 0.31, 0.30, 0.30,
0.30, 0.30, 0.30, 0.30, 0.30, 0.30, 0.30, 0.30, 0.30, 0.30, 0.30, 0.30,
0.29, 0.28, 0.27, 0.26, 0.25, 0.25, 0.24, 0.23, 0.22, 0.21, 0.20, 0.19,
0.19, 0.19, 0.19, 0.19, 0.19, 0.19, 0.18, 0.18, 0.18, 0.18, 0.18, 0.18,
0.18, 0.18, 0.19, 0.19, 0.19, 0.19, 0.19, 0.19, 0.20, 0.20, 0.20, 0.20,
0.21, 0.21, 0.22, 0.22, 0.23, 0.23, 0.24, 0.24, 0.25, 0.25, 0.26, 0.26,
0.27, 0.27, 0.28, 0.28, 0.29, 0.29, 0.30, 0.30, 0.31, 0.31, 0.32, 0.32,
0.32, 0.32, 0.32, 0.32, 0.32, 0.32, 0.32, 0.32, 0.32, 0.32, 0.32, 0.32,
0.32, 0.32, 0.32, 0.32, 0.32, 0.33, 0.33, 0.33, 0.33, 0.33, 0.33, 0.33,
0.33, 0.33, 0.33, 0.32, 0.32, 0.32, 0.32, 0.32, 0.32, 0.31, 0.31, 0.31,
0.30, 0.30, 0.29, 0.29, 0.28, 0.28, 0.27, 0.26, 0.26, 0.25, 0.25, 0.24,
0.24, 0.24, 0.24, 0.23, 0.23, 0.23, 0.23, 0.23, 0.23, 0.22, 0.22, 0.22,
0.22, 0.23, 0.23, 0.23, 0.23, 0.24, 0.24, 0.24, 0.24, 0.25, 0.25, 0.25,
0.25, 0.25, 0.25, 0.24, 0.24, 0.24, 0.24, 0.24, 0.24, 0.23, 0.23, 0.23,
0.23, 0.23, 0.23, 0.23, 0.23, 0.23, 0.22, 0.22, 0.22, 0.22, 0.22, 0.22,
0.22, 0.22, 0.22, 0.22, 0.22, 0.22, 0.22, 0.22, 0.22, 0.22, 0.22, 0.22,
0.22, 0.22, 0.22, 0.22, 0.22, 0.22, 0.22, 0.22, 0.22, 0.22, 0.22, 0.22,
0.22, 0.22, 0.23, 0.23, 0.23, 0.23, 0.23, 0.23, 0.24, 0.24, 0.24, 0.24,
0.24, 0.24, 0.24, 0.24, 0.24, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25,
0.25, 0.24, 0.24, 0.24, 0.23, 0.23, 0.23, 0.22, 0.22, 0.22, 0.21, 0.21,
0.21, 0.21, 0.21, 0.20, 0.20, 0.20, 0.20, 0.20, 0.20, 0.19, 0.19, 0.19,
0.19, 0.19, 0.19, 0.19, 0.19, 0.19, 0.18, 0.18, 0.18, 0.18, 0.18, 0.18,
0.18, 0.18, 0.18, 0.18, 0.18, 0.18, 0.18, 0.18, 0.18, 0.18, 0.18, 0.18,
0.18, 0.18, 0.19, 0.19, 0.19, 0.19, 0.19, 0.19, 0.20, 0.20, 0.20, 0.20,
0.20, 0.20, 0.20, 0.20, 0.20, 0.21, 0.21, 0.21, 0.21, 0.21, 0.21, 0.21,
0.22, 0.23, 0.23, 0.24, 0.25, 0.26, 0.26, 0.27, 0.28, 0.29, 0.29, 0.30,
0.30, 0.30, 0.31, 0.31, 0.31, 0.31, 0.31, 0.31, 0.32, 0.32, 0.32, 0.32,
0.32, 0.32, 0.32, 0.32, 0.32, 0.33, 0.33, 0.33, 0.33, 0.33, 0.33, 0.33,
0.33, 0.33, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.35, 0.35, 0.35, 0.35,
0.35, 0.34, 0.34, 0.34, 0.33, 0.33, 0.33, 0.32, 0.32, 0.32, 0.31, 0.31,
0.31, 0.31, 0.32, 0.32, 0.32, 0.32, 0.32, 0.32, 0.33, 0.33, 0.33, 0.33,
0.34, 0.34, 0.35, 0.35, 0.36, 0.37, 0.37, 0.38, 0.38, 0.39, 0.39, 0.40,
0.40, 0.41, 0.41, 0.41, 0.42, 0.42, 0.42, 0.43, 0.43, 0.43, 0.44, 0.44,
0.44, 0.43, 0.43, 0.43, 0.42, 0.42, 0.42, 0.41, 0.41, 0.41, 0.40, 0.40,
0.40, 0.41, 0.41, 0.41, 0.42, 0.42, 0.42, 0.43, 0.43, 0.43, 0.44, 0.44,
0.44, 0.45, 0.45, 0.45, 0.45, 0.46, 0.46, 0.46, 0.46, 0.47, 0.47, 0.47,
0.47, 0.47, 0.47, 0.47, 0.47, 0.47, 0.47, 0.47, 0.47, 0.47, 0.47, 0.47,
0.47, 0.47, 0.47, 0.47, 0.47, 0.48, 0.48, 0.48, 0.48, 0.48, 0.48, 0.48,
0.48, 0.48, 0.48, 0.48, 0.48, 0.48, 0.48, 0.48, 0.48, 0.48, 0.48, 0.48,
0.48, 0.47, 0.47, 0.46, 0.46, 0.45, 0.45, 0.44, 0.44, 0.43, 0.43, 0.42,
0.42, 0.42, 0.42, 0.42, 0.42, 0.43, 0.43, 0.43, 0.43, 0.43, 0.43, 0.43,
0.44, 0.45, 0.46, 0.47, 0.48, 0.50, 0.51, 0.52, 0.53, 0.54, 0.55, 0.56,
0.57, 0.58, 0.59, 0.60, 0.61, 0.63, 0.64, 0.65, 0.66, 0.67, 0.68, 0.69,
0.68, 0.67, 0.66, 0.65, 0.64, 0.63, 0.62, 0.61, 0.60, 0.59, 0.58, 0.57,
0.57, 0.56, 0.56, 0.56, 0.55, 0.55, 0.55, 0.54, 0.54, 0.54, 0.53, 0.53,
0.53, 0.53, 0.53, 0.52, 0.52, 0.52, 0.52, 0.52, 0.52, 0.51, 0.51, 0.51,
0.51, 0.50, 0.50, 0.49, 0.49, 0.49, 0.48, 0.48, 0.47, 0.47, 0.46, 0.46,
0.46, 0.47, 0.47, 0.48, 0.48, 0.49, 0.49, 0.49, 0.50, 0.50, 0.51, 0.51,
0.51, 0.51, 0.52, 0.52, 0.52, 0.52, 0.52, 0.52, 0.53, 0.53, 0.53, 0.53,
0.53, 0.53, 0.54, 0.54, 0.54, 0.54, 0.54, 0.54, 0.55, 0.55, 0.55, 0.55,
0.55, 0.56, 0.56, 0.57, 0.57, 0.58, 0.58, 0.58, 0.59, 0.59, 0.60, 0.60,
0.61, 0.62, 0.62, 0.63, 0.64, 0.65, 0.65, 0.66, 0.67, 0.68, 0.68, 0.69,
0.70, 0.70, 0.71, 0.72, 0.72, 0.73, 0.74, 0.74, 0.75, 0.76, 0.76, 0.77,
0.78, 0.78, 0.79, 0.80, 0.80, 0.81, 0.82, 0.82, 0.83, 0.84, 0.84, 0.85,
0.86, 0.87, 0.88, 0.89, 0.90, 0.91, 0.92, 0.93, 0.94, 0.95, 0.96, 0.97,
0.97, 0.97, 0.97, 0.97, 0.97, 0.98, 0.98, 0.98, 0.98, 0.98, 0.98, 0.98,
0.97, 0.95, 0.94, 0.93, 0.91, 0.90, 0.89, 0.87, 0.86, 0.85, 0.83, 0.82,
0.79, 0.77, 0.74, 0.71, 0.69, 0.66, 0.63, 0.61, 0.58, 0.55, 0.53, 0.50,
0.50, 0.49, 0.49, 0.48, 0.48, 0.47, 0.47, 0.46, 0.46, 0.45, 0.45, 0.44,
0.44, 0.44, 0.44, 0.44, 0.44, 0.45, 0.45, 0.45, 0.45, 0.45, 0.45, 0.45,
0.45, 0.45, 0.45, 0.45, 0.44, 0.44, 0.44, 0.44, 0.44, 0.45, 0.46, 0.47,
0.48, 0.49, 0.50, 0.52, 0.53, 0.55, 0.57, 0.59, 0.61, 0.65, 0.68, 0.72,
0.73, 0.74, 0.75, 0.78, 0.81, 0.84, 0.82, 0.79, 0.77, 0.78, 0.79, 0.80,
0.79, 0.79, 0.78, 0.77, 0.75, 0.74, 0.71, 0.69, 0.66, 0.61, 0.56, 0.51,
0.51, 0.52, 0.52, 0.52, 0.53, 0.53, 0.54, 0.55, 0.56, 0.58, 0.60, 0.62,
0.62, 0.63, 0.63, 0.64, 0.64, 0.65, 0.66, 0.66, 0.67, 0.67, 0.67, 0.67,
0.67, 0.68, 0.68, 0.68, 0.69, 0.69, 0.69, 0.70, 0.70, 0.70, 0.71, 0.71,
0.70, 0.70, 0.69, 0.68, 0.67, 0.66, 0.65, 0.63, 0.62, 0.61, 0.60, 0.59,
0.59, 0.59, 0.59, 0.59, 0.59, 0.59, 0.59, 0.60, 0.60, 0.60, 0.61, 0.61,
0.61, 0.62, 0.62, 0.62, 0.63, 0.63, 0.63, 0.64, 0.64, 0.64, 0.64, 0.64,
0.64, 0.65, 0.65, 0.65, 0.65, 0.65, 0.65, 0.66, 0.66, 0.66, 0.66, 0.66,
0.67, 0.67, 0.68, 0.68, 0.68, 0.68, 0.68, 0.69, 0.69, 0.70, 0.70, 0.71,
0.71, 0.72, 0.72, 0.73, 0.75, 0.76, 0.77, 0.78, 0.79, 0.81, 0.82, 0.84,
0.84, 0.85, 0.85, 0.85, 0.85, 0.85, 0.86, 0.86, 0.87, 0.89, 0.91, 0.93,
0.95, 0.96, 0.98, 0.99, 1.01, 1.02, 1.03, 1.03, 1.04, 1.07, 1.11, 1.14,
1.15, 1.16, 1.17, 1.18, 1.19, 1.20, 1.24, 1.29, 1.33, 1.38, 1.42, 1.47,
1.49, 1.50, 1.52, 1.53, 1.55, 1.56, 1.55, 1.53, 1.52, 1.48, 1.45, 1.41,
1.41, 1.42, 1.42, 1.43, 1.44, 1.45, 1.45, 1.45, 1.45, 1.44, 1.42, 1.41,
1.41, 1.41, 1.41, 1.41, 1.42, 1.42, 1.42, 1.42, 1.42, 1.43, 1.44, 1.45,
1.46, 1.46, 1.47, 1.46, 1.46, 1.45, 1.46, 1.46, 1.47, 1.49, 1.52, 1.54,
1.55, 1.55, 1.56, 1.56, 1.57, 1.57, 1.59, 1.60, 1.62, 1.63, 1.63, 1.64,
1.67, 1.70, 1.73, 1.75, 1.78, 1.80, 1.81, 1.83, 1.84, 1.81, 1.77, 1.74,
1.74, 1.73, 1.73, 1.73, 1.73, 1.73, 1.74, 1.75, 1.76, 1.77, 1.78, 1.79,
1.78, 1.78, 1.77, 1.76, 1.74, 1.73, 1.73, 1.73, 1.73, 1.74, 1.74, 1.75,
1.76, 1.76, 1.77, 1.78, 1.78, 1.79, 1.80, 1.80, 1.81, 1.82, 1.82, 1.83,
1.87, 1.90, 1.94, 1.94, 1.95, 1.95, 1.95, 1.95, 1.95, 1.95, 1.95, 1.95,
1.95, 1.94, 1.94, 1.94, 1.94, 1.94, 1.95, 1.95, 1.96, 1.98, 2.00, 2.02,
2.03, 2.03, 2.04, 2.05, 2.05, 2.06, 2.07, 2.07, 2.08, 2.10, 2.11, 2.13,
2.14, 2.14, 2.15, 2.17, 2.18, 2.20, 2.20, 2.21, 2.21, 2.23, 2.26, 2.28,
2.30, 2.31, 2.33, 2.35, 2.36, 2.38, 2.40, 2.42, 2.44, 2.46, 2.48, 2.50,
2.52, 2.53, 2.55, 2.57, 2.59, 2.61, 2.63, 2.64, 2.66, 2.68, 2.70, 2.72,
2.74, 2.76, 2.78, 2.80, 2.81, 2.83, 2.85, 2.87, 2.89, 2.88, 2.88, 2.87,
2.88, 2.89, 2.90, 2.90, 2.90, 2.90, 2.91, 2.91, 2.92, 2.92, 2.92, 2.92,
2.93, 2.94, 2.95, 2.96, 2.98, 2.99, 3.00, 3.02, 3.03, 3.04, 3.06, 3.07,
3.08, 3.09, 3.10, 3.11, 3.12, 3.13, 3.14, 3.14, 3.15, 3.15, 3.16, 3.16,
3.16, 3.17, 3.17, 3.17, 3.18, 3.18, 3.18, 3.19, 3.19, 3.17, 3.16, 3.14,
3.13, 3.12, 3.11, 3.11, 3.10, 3.10, 3.10, 3.09, 3.09, 3.08, 3.08, 3.07,
3.07, 3.07, 3.07, 3.07, 3.07, 3.07, 3.07, 3.08, 3.08, 3.10, 3.13, 3.15,
3.16, 3.16, 3.17, 3.19, 3.20, 3.22, 3.24, 3.25, 3.27, 3.31, 3.34, 3.38,
3.40, 3.42, 3.44, 3.46, 3.48, 3.50, 3.53, 3.56, 3.59, 3.59, 3.60, 3.60,
3.62, 3.65, 3.67, 3.68, 3.70, 3.71, 3.71, 3.71, 3.71, 3.70, 3.69, 3.68,
3.68, 3.69, 3.69, 3.71, 3.74, 3.76, 3.79, 3.82, 3.85, 3.92, 3.98, 4.05,
4.10, 4.14, 4.19, 4.25, 4.30, 4.36, 4.41, 4.45, 4.50, 4.56, 4.61, 4.67,
4.71, 4.76, 4.80, 4.84, 4.87, 4.91, 4.95, 4.98, 5.02, 5.04, 5.05, 5.07,
5.11, 5.16, 5.20, 5.25, 5.29, 5.34, 5.40, 5.45, 5.51, 5.56, 5.60, 5.65,
5.70, 5.75, 5.80, 5.85, 5.89, 5.94, 5.98, 6.03, 6.07, 6.10, 6.13, 6.16,
6.20, 6.24, 6.28, 6.32, 6.35, 6.39, 6.43, 6.48, 6.52, 6.56, 6.59, 6.63,
6.66, 6.69, 6.72, 6.75, 6.78, 6.81, 6.82, 6.84, 6.85, 6.86, 6.86, 6.87,
6.88, 6.90, 6.91, 6.92, 6.93, 6.94, 6.96, 6.98, 7.00, 7.03, 7.06, 7.09,
7.12, 7.15, 7.18, 7.22, 7.27, 7.31, 7.33, 7.36, 7.38, 7.43, 7.48, 7.53,
7.57, 7.62, 7.66, 7.69, 7.71, 7.74, 7.77, 7.81, 7.84, 7.86, 7.88, 7.90,
7.94, 7.98, 8.02, 8.05, 8.07, 8.10, 8.14, 8.19, 8.23, 8.25, 8.26, 8.28,
8.30, 8.32, 8.34, 8.40, 8.46, 8.52, 8.57, 8.61, 8.66, 8.71, 8.76, 8.81,
8.86, 8.90, 8.95, 9.04, 9.14, 9.23, 9.31, 9.38, 9.46, 9.55, 9.64, 9.73,
9.81, 9.90, 9.98, 10.09, 10.19, 10.30, 10.42, 10.55, 10.67, 10.80, 10.92, 11.05,
11.14, 11.23, 11.32, 11.44, 11.55, 11.67, 11.73, 11.78, 11.84, 11.93, 12.01, 12.10,
12.11, 12.11, 12.12, 12.13, 12.14, 12.15, 12.19, 12.24, 12.28, 12.25, 12.23, 12.20,
12.24, 12.28, 12.32, 12.32, 12.32, 12.32, 12.34, 12.37, 12.39, 12.39, 12.38, 12.38,
12.41, 12.45, 12.48, 12.49, 12.51, 12.52, 12.52, 12.52, 12.52, 12.54, 12.56, 12.58,
12.62, 12.67, 12.71, 12.75, 12.80, 12.84, 12.87, 12.90, 12.93, 13.01, 13.10, 13.18,
13.18, 13.18, 13.18, 13.24, 13.31, 13.37, 13.44, 13.51, 13.58, 13.65, 13.72, 13.79,
13.89, 14.00, 14.10, 14.16, 14.21, 14.27, 14.40, 14.53, 14.66, 14.74, 14.82, 14.90,
14.95, 15.01, 15.06, 15.09, 15.13, 15.16, 15.22, 15.27, 15.33, 15.39, 15.44, 15.50,
15.55, 15.60, 15.65, 15.75, 15.85, 15.95, 16.02, 16.08, 16.15, 16.17, 16.18, 16.20,
16.28, 16.37, 16.45, 16.37, 16.29, 16.21, 16.29, 16.38, 16.46, 16.47, 16.47, 16.48,
16.57, 16.67, 16.76, 16.74, 16.72, 16.70, 16.58, 16.46, 16.34, 16.32, 16.29, 16.27,
16.17, 16.07, 15.97, 15.88, 15.78, 15.69, 15.71, 15.72, 15.74, 15.74, 15.74, 15.74,
15.74, 15.73, 15.73, 15.83, 15.93, 16.03, 15.95, 15.87, 15.79, 15.88, 15.98, 16.07,
16.12, 16.17, 16.22, 16.20, 16.19, 16.17, 16.31, 16.45, 16.59, 16.86, 17.12, 17.39,
17.60, 17.81, 18.02, 18.21, 18.41, 18.60, 18.79, 18.97, 19.16, 19.25, 19.35, 19.44,
19.70, 19.97, 20.23, 20.46, 20.70, 20.93, 21.11, 21.30, 21.48, 21.73, 21.97, 22.22,
22.41, 22.60, 22.79, 23.01, 23.22, 23.44, 23.66, 23.88, 24.10, 24.36, 24.62, 24.88,
25.08, 25.29, 25.49, 25.72, 25.94, 26.17, 26.44, 26.70, 26.97, 27.22, 27.48, 27.73,
27.92, 28.11, 28.3, 28.44, 28.57, 28.71, 28.76, 28.80, 28.85, 28.70, 28.54, 28.39, # 2008
);
$shiller_cpi = array(
12.46, 12.84, 13.03, 12.56, 12.27, 12.08, 12.08, 11.89, 12.18, 12.37, 12.37, 12.65, # 1871
12.65, 12.65, 12.84, 13.13, 13.13, 13.03, 12.84, 12.94, 13.03, 12.75, 13.13, 12.94,
12.94, 13.23, 13.23, 13.23, 12.94, 12.56, 12.56, 12.56, 12.56, 12.27, 11.89, 12.18,
12.37, 12.37, 12.37, 12.18, 12.08, 11.80, 11.89, 11.80, 11.80, 11.61, 11.51, 11.51,
11.51, 11.51, 11.51, 11.61, 11.32, 11.13, 11.13, 11.23, 11.13, 11.13, 11.04, 10.94,
10.85, 10.85, 10.85, 10.75, 10.37, 10.09, 10.09, 10.18, 10.28, 10.47, 10.56, 10.75,
10.94, 10.66, 10.18, 10.47, 10.66, 10.09, 10.18, 9.80, 9.70, 9.70, 9.51, 9.51,
9.23, 9.13, 8.94, 8.85, 8.56, 8.37, 8.47, 8.56, 8.56, 8.47, 8.37, 8.18,
8.28, 8.37, 8.28, 8.18, 8.18, 8.09, 8.18, 8.18, 8.47, 8.94, 9.42, 9.70,
9.99, 9.99, 10.09, 9.70, 9.42, 9.23, 9.23, 9.23, 9.32, 9.32, 9.42, 9.51,
9.42, 9.51, 9.51, 9.61, 9.51, 9.51, 9.61, 9.80, 10.18, 10.28, 10.18, 10.18,
10.18, 10.28, 10.28, 10.37, 10.47, 10.56, 10.47, 10.56, 10.28, 10.18, 10.09, 9.99,
9.99, 10.09, 9.99, 9.90, 9.80, 9.51, 9.32, 9.32, 9.23, 9.23, 9.13, 9.23,
9.23, 9.23, 9.23, 9.04, 8.85, 8.85, 8.75, 8.75, 8.66, 8.56, 8.37, 8.28,
8.28, 8.37, 8.18, 8.28, 8.09, 7.90, 7.99, 7.99, 7.90, 7.90, 7.99, 8.18,
7.99, 7.99, 7.90, 7.80, 7.61, 7.52, 7.61, 7.71, 7.71, 7.71, 7.71, 7.80,
7.99, 8.09, 8.09, 8.09, 8.09, 7.99, 7.90, 7.99, 7.90, 7.99, 8.09, 8.28,
8.37, 8.28, 8.28, 8.18, 8.09, 7.99, 8.09, 8.09, 8.09, 8.18, 8.28, 8.28,
7.99, 7.90, 7.80, 7.80, 7.61, 7.61, 7.61, 7.61, 7.71, 7.71, 7.71, 7.80,
7.61, 7.61, 7.61, 7.61, 7.71, 7.71, 7.71, 7.99, 8.09, 8.09, 7.90, 7.90,
7.80, 7.90, 7.99, 8.09, 7.99, 7.80, 7.71, 7.71, 7.61, 7.61, 7.52, 7.52,
7.33, 7.33, 7.14, 7.04, 7.04, 7.04, 7.23, 7.33, 7.33, 7.33, 7.52, 7.61,
7.90, 7.99, 7.80, 7.71, 7.61, 7.42, 7.23, 6.95, 7.23, 7.33, 7.14, 7.04,
6.85, 6.76, 6.57, 6.57, 6.57, 6.57, 6.57, 6.76, 6.85, 6.66, 6.66, 6.57,
6.57, 6.57, 6.57, 6.85, 6.95, 7.04, 6.95, 6.85, 6.85, 6.85, 6.85, 6.76,
6.66, 6.57, 6.57, 6.47, 6.37, 6.28, 6.28, 6.28, 6.28, 6.47, 6.66, 6.66,
6.47, 6.47, 6.47, 6.37, 6.28, 6.28, 6.28, 6.57, 6.76, 6.66, 6.66, 6.66,
6.66, 6.76, 6.76, 6.76, 7.23, 6.76, 6.66, 6.66, 6.66, 6.66, 6.66, 6.76,
6.76, 6.95, 6.95, 7.04, 7.04, 7.14, 7.23, 7.33, 7.61, 7.71, 7.80, 7.90,
7.90, 7.99, 7.99, 7.99, 7.80, 7.71, 7.80, 7.71, 7.80, 7.71, 7.71, 7.61,
7.71, 7.61, 7.61, 7.52, 7.52, 7.52, 7.61, 7.71, 7.80, 7.80, 7.90, 7.99,
7.90, 7.90, 7.90, 7.99, 8.09, 8.18, 8.18, 8.09, 8.18, 8.75, 8.47, 8.56,
8.66, 8.66, 8.37, 8.37, 8.18, 8.18, 8.18, 8.18, 8.28, 8.18, 8.09, 8.09,
8.28, 8.47, 8.37, 8.28, 8.09, 8.09, 8.09, 8.18, 8.28, 8.28, 8.47, 8.47,
8.47, 8.47, 8.37, 8.37, 8.28, 8.28, 8.28, 8.37, 8.28, 8.28, 8.37, 8.47,
8.47, 8.47, 8.47, 8.47, 8.56, 8.56, 8.28, 8.47, 8.56, 8.75, 8.85, 8.94,
8.85, 9.04, 8.94, 8.94, 9.13, 9.23, 9.23, 9.23, 9.23, 9.32, 8.94, 8.75,
8.66, 8.56, 8.56, 8.66, 8.66, 8.66, 8.75, 8.75, 8.75, 8.85, 8.94, 9.04,
8.94, 9.04, 9.04, 9.23, 9.32, 9.42, 9.42, 9.51, 9.61, 9.80, 9.90, 9.99,
9.90, 9.90, 10.09, 10.18, 9.99, 9.90, 9.90, 9.80, 9.70, 9.42, 9.23, 9.23,
9.23, 8.94, 9.04, 8.75, 8.75, 8.75, 8.85, 9.13, 9.23, 9.23, 9.13, 9.04,
9.13, 9.23, 9.42, 9.70, 9.70, 9.61, 9.61, 9.70, 9.80, 9.80, 9.80, 9.70,
9.80, 9.80, 9.80, 9.80, 9.70, 9.80, 9.90, 9.90, 10.00, 10.00, 10.10, 10.00,
10.00, 9.90, 9.90, 9.80, 9.90, 9.90, 10.00, 10.20, 10.20, 10.10, 10.20, 10.10,
10.10, 10.00, 9.90, 10.00, 10.10, 10.10, 10.10, 10.10, 10.10, 10.20, 10.30, 10.30,
10.40, 10.40, 10.50, 10.60, 10.70, 10.80, 10.80, 10.90, 11.10, 11.30, 11.50, 11.60,
11.70, 12.00, 12.00, 12.60, 12.80, 13.00, 12.80, 13.00, 13.30, 13.50, 13.50, 13.70,
14.00, 14.10, 14.00, 14.20, 14.50, 14.70, 15.10, 15.40, 15.70, 16.00, 16.30, 16.50,
16.50, 16.20, 16.40, 16.70, 16.90, 16.90, 17.40, 17.70, 17.80, 18.10, 18.50, 18.90,
19.30, 19.50, 19.70, 20.30, 20.60, 20.90, 20.80, 20.30, 20.00, 19.90, 19.80, 19.40,
19.00, 18.40, 18.30, 18.10, 17.70, 17.60, 17.70, 17.70, 17.50, 17.50, 17.40, 17.30,
16.90, 16.90, 16.70, 16.70, 16.70, 16.70, 16.80, 16.60, 16.60, 16.70, 16.80, 16.90,
16.80, 16.80, 16.80, 16.90, 16.90, 17.00, 17.20, 17.10, 17.20, 17.30, 17.30, 17.30,
17.30, 17.20, 17.10, 17.00, 17.00, 17.00, 17.10, 17.00, 17.10, 17.20, 17.20, 17.30,
17.30, 17.20, 17.30, 17.20, 17.30, 17.50, 17.70, 17.70, 17.70, 17.70, 18.00, 17.90,
17.90, 17.90, 17.80, 17.90, 17.80, 17.70, 17.50, 17.40, 17.50, 17.60, 17.70, 17.70,
17.50, 17.40, 17.30, 17.30, 17.40, 17.60, 17.30, 17.20, 17.30, 17.40, 17.30, 17.30,
17.30, 17.10, 17.10, 17.10, 17.20, 17.10, 17.10, 17.10, 17.30, 17.20, 17.20, 17.10,
17.10, 17.10, 17.00, 16.90, 17.00, 17.10, 17.30, 17.30, 17.30, 17.30, 17.30, 17.20,
17.10, 17.00, 16.90, 17.00, 16.90, 16.80, 16.60, 16.50, 16.60, 16.50, 16.40, 16.10,
15.90, 15.70, 15.60, 15.50, 15.30, 15.10, 15.10, 15.10, 15.00, 14.90, 14.70, 14.60,
14.30, 14.10, 14.00, 13.90, 13.70, 13.60, 13.60, 13.50, 13.40, 13.30, 13.20, 13.10,
12.90, 12.70, 12.60, 12.60, 12.60, 12.70, 13.10, 13.20, 13.20, 13.20, 13.20, 13.20,
13.20, 13.30, 13.30, 13.30, 13.30, 13.40, 13.40, 13.40, 13.60, 13.50, 13.50, 13.40,
13.60, 13.70, 13.70, 13.80, 13.80, 13.70, 13.70, 13.70, 13.70, 13.70, 13.80, 13.80,
13.80, 13.80, 13.70, 13.70, 13.70, 13.80, 13.90, 14.00, 14.00, 14.00, 14.00, 14.00,
14.10, 14.10, 14.20, 14.30, 14.40, 14.40, 14.50, 14.50, 14.60, 14.60, 14.50, 14.40,
14.20, 14.10, 14.10, 14.20, 14.10, 14.10, 14.10, 14.10, 14.10, 14.00, 14.00, 14.00,
14.00, 13.90, 13.90, 13.80, 13.80, 13.80, 13.80, 13.80, 14.10, 14.00, 14.00, 14.00,
13.90, 14.00, 14.00, 14.00, 14.00, 14.10, 14.00, 14.00, 14.00, 14.00, 14.00, 14.10,
14.10, 14.10, 14.20, 14.30, 14.40, 14.70, 14.70, 14.90, 15.10, 15.30, 15.40, 15.50,
15.70, 15.80, 16.00, 16.10, 16.30, 16.30, 16.40, 16.50, 16.50, 16.70, 16.80, 16.90,
16.90, 16.90, 17.20, 17.40, 17.50, 17.50, 17.40, 17.30, 17.40, 17.40, 17.40, 17.40,
17.40, 17.40, 17.40, 17.50, 17.50, 17.60, 17.70, 17.70, 17.70, 17.70, 17.70, 17.80,
17.80, 17.80, 17.80, 17.80, 17.90, 18.10, 18.10, 18.10, 18.10, 18.10, 18.10, 18.20,
18.20, 18.10, 18.30, 18.40, 18.50, 18.70, 19.80, 20.20, 20.40, 20.80, 21.30, 21.50,
21.50, 21.50, 21.90, 21.90, 21.90, 22.00, 22.20, 22.50, 23.00, 23.00, 23.10, 23.40,
23.70, 23.50, 23.40, 23.80, 23.90, 24.10, 24.40, 24.50, 24.50, 24.40, 24.20, 24.10,
24.00, 23.80, 23.80, 23.90, 23.80, 23.90, 23.70, 23.80, 23.90, 23.70, 23.80, 23.60,
23.50, 23.50, 23.60, 23.60, 23.70, 23.80, 24.10, 24.30, 24.40, 24.60, 24.70, 25.00,
25.40, 25.70, 25.80, 25.80, 25.90, 25.90, 25.90, 25.90, 26.10, 26.20, 26.40, 26.50,
26.50, 26.30, 26.30, 26.40, 26.40, 26.50, 26.70, 26.70, 26.70, 26.70, 26.70, 26.70,
26.60, 26.50, 26.60, 26.60, 26.70, 26.80, 26.80, 26.90, 26.90, 27.00, 26.90, 26.90,
26.90, 26.90, 26.90, 26.80, 26.90, 26.90, 26.90, 26.90, 26.80, 26.80, 26.80, 26.70,
26.70, 26.70, 26.70, 26.70, 26.70, 26.70, 26.80, 26.80, 26.90, 26.90, 26.90, 26.80,
26.80, 26.80, 26.80, 26.90, 27.00, 27.20, 27.40, 27.30, 27.40, 27.50, 27.50, 27.60,
27.60, 27.70, 27.80, 27.90, 28.00, 28.10, 28.30, 28.30, 28.30, 28.30, 28.40, 28.40,
28.60, 28.60, 28.80, 28.90, 28.90, 28.90, 29.00, 28.90, 28.90, 28.90, 29.00, 28.90,
29.00, 28.90, 28.90, 29.00, 29.00, 29.10, 29.20, 29.20, 29.30, 29.40, 29.40, 29.40,
29.30, 29.40, 29.40, 29.50, 29.50, 29.60, 29.60, 29.60, 29.60, 29.80, 29.80, 29.80,
29.80, 29.80, 29.80, 29.80, 29.80, 29.80, 30.00, 29.90, 30.00, 30.00, 30.00, 30.00,
30.00, 30.10, 30.10, 30.20, 30.20, 30.20, 30.30, 30.30, 30.40, 30.40, 30.40, 30.40,
30.40, 30.40, 30.50, 30.50, 30.50, 30.60, 30.70, 30.70, 30.70, 30.80, 30.80, 30.90,
30.90, 30.90, 30.90, 30.90, 30.90, 31.00, 31.10, 31.00, 31.10, 31.10, 31.20, 31.20,
31.20, 31.20, 31.30, 31.40, 31.40, 31.60, 31.60, 31.60, 31.60, 31.70, 31.70, 31.80,
31.80, 32.00, 32.10, 32.30, 32.30, 32.40, 32.50, 32.70, 32.70, 32.90, 32.90, 32.90,
32.90, 32.90, 33.00, 33.10, 33.20, 33.30, 33.40, 33.50, 33.60, 33.70, 33.80, 33.90,
34.10, 34.20, 34.30, 34.40, 34.50, 34.70, 34.90, 35.00, 35.10, 35.30, 35.40, 35.50,
35.60, 35.80, 36.10, 36.30, 36.40, 36.60, 36.80, 37.00, 37.10, 37.30, 37.50, 37.70,
37.80, 38.00, 38.20, 38.50, 38.60, 38.80, 39.00, 39.00, 39.20, 39.40, 39.60, 39.80,
39.80, 39.90, 40.00, 40.10, 40.30, 40.60, 40.70, 40.80, 40.80, 40.90, 40.90, 41.10,
41.10, 41.30, 41.40, 41.50, 41.60, 41.70, 41.90, 42.00, 42.10, 42.30, 42.40, 42.50,
42.60, 42.90, 43.30, 43.60, 43.90, 44.20, 44.30, 45.10, 45.20, 45.60, 45.90, 46.20,
46.60, 47.20, 47.80, 48.00, 48.60, 49.00, 49.40, 50.00, 50.60, 51.10, 51.50, 51.90,
52.10, 52.50, 52.70, 52.90, 53.20, 53.60, 54.20, 54.30, 54.60, 54.90, 55.30, 55.50,
55.60, 55.80, 55.90, 56.10, 56.50, 56.80, 57.10, 57.40, 57.60, 57.90, 58.00, 58.20,
58.50, 59.10, 59.50, 60.00, 60.30, 60.70, 61.00, 61.20, 61.40, 61.60, 61.90, 62.10,
62.50, 62.90, 63.40, 63.90, 64.50, 65.20, 65.70, 66.00, 66.50, 67.10, 67.40, 67.70,
68.30, 69.10, 69.80, 70.60, 71.50, 72.30, 73.10, 73.80, 74.60, 75.20, 75.90, 76.70,
77.80, 78.90, 80.10, 81.00, 81.80, 82.70, 82.70, 83.30, 84.00, 84.80, 85.50, 86.30,
87.00, 87.90, 88.50, 89.10, 89.80, 90.60, 91.60, 92.30, 93.20, 93.40, 93.70, 94.00,
94.30, 94.60, 94.50, 94.90, 95.80, 97.00, 97.50, 97.70, 97.90, 98.20, 98.00, 97.60,
97.80, 97.90, 97.90, 98.60, 99.20, 99.50, 99.90, 100.20, 100.70, 101.00, 101.20, 101.30,
101.90, 102.40, 102.60, 103.10, 103.40, 103.70, 104.10, 104.50, 105.00, 105.30, 105.30, 105.30,
105.50, 106.00, 106.40, 106.90, 107.30, 107.60, 107.80, 108.00, 108.30, 108.70, 109.00, 109.30,
109.60, 109.30, 108.80, 108.60, 108.90, 109.50, 109.50, 109.70, 110.20, 110.30, 110.40, 110.50,
111.20, 111.60, 112.10, 112.70, 113.10, 113.50, 113.80, 114.40, 115.00, 115.30, 115.40, 115.40,
115.70, 116.00, 116.50, 117.10, 117.50, 118.00, 118.50, 119.00, 119.80, 120.20, 120.30, 120.50,
121.10, 121.60, 122.30, 123.10, 123.80, 124.10, 124.40, 124.60, 125.00, 125.60, 125.90, 126.10,
127.40, 128.00, 128.70, 128.90, 129.20, 129.90, 130.40, 131.60, 132.70, 133.50, 133.80, 133.80,
134.60, 134.80, 135.00, 135.20, 135.60, 136.00, 136.20, 136.60, 137.20, 137.40, 137.80, 137.90,
138.10, 138.60, 139.30, 139.50, 139.70, 140.20, 140.50, 140.90, 141.30, 141.80, 142.00, 141.90,
142.60, 143.10, 143.60, 144.00, 144.20, 144.40, 144.40, 144.80, 145.10, 145.70, 145.80, 145.80,
146.20, 146.70, 147.20, 147.40, 147.50, 148.00, 148.40, 149.00, 149.40, 149.50, 149.70, 149.70,
150.30, 150.90, 151.40, 151.90, 152.20, 152.50, 152.50, 152.90, 153.20, 153.70, 153.60, 153.50,
154.40, 154.90, 155.70, 156.30, 156.60, 156.70, 157.00, 157.30, 157.80, 158.30, 158.60, 158.60,
159.10, 159.60, 160.00, 160.20, 160.10, 160.30, 160.50, 160.80, 161.20, 161.60, 161.50, 161.30,
161.60, 161.90, 162.20, 162.50, 162.80, 163.00, 163.20, 163.40, 163.60, 164.00, 164.00, 163.90,
164.30, 164.50, 165.00, 166.20, 166.20, 166.20, 166.70, 167.10, 167.90, 168.20, 168.30, 168.30,
168.80, 169.80, 171.20, 171.30, 171.50, 172.40, 172.80, 172.80, 173.70, 174.00, 174.10, 174.00,
175.10, 175.80, 176.20, 176.90, 177.70, 178.00, 177.50, 177.50, 178.30, 177.70, 177.40, 176.70,
177.10, 177.80, 178.80, 179.80, 179.80, 179.90, 180.10, 180.70, 181.00, 181.30, 181.30, 180.90,
181.70, 183.10, 184.20, 183.80, 183.50, 183.70, 183.90, 184.60, 185.20, 185.00, 184.50, 184.30,
185.20, 186.20, 187.40, 188.00, 189.10, 189.70, 189.40, 189.50, 189.90, 190.90, 191.00, 190.30,
190.70, 191.80, 193.30, 194.60, 194.40, 194.50, 195.40, 196.40, 198.80, 199.20, 197.60, 196.80,
198.30, 198.70, 199.80, 201.50, 202.50, 202.90, 203.50, 203.90, 202.90, 201.80, 201.50, 201.80,
202.42, 203.5, 205.35, 206.69, 207.95, 208.35, 208.3, 207.92, 208.49, 208.94, 210.18, 210.04,
211.08, 211.69, 213.53, 214.82, 216.63, 218.82, 219.96, 219.09, 218.78, 216.57, 212.43, 210.23, # 2008
);
(count($shiller_price) == count($shiller_dividend)) or die("Mismatched table lengths.");
(count($shiller_price) == count($shiller_cpi)) or die("Mismatched table lengths.");
# Actuarial data.
# Male and female probability of dying during a given year of age.
# National Vital Statistics Reports: United States Life Tables, 2004
#
# (Source: http://www.cdc.gov/nchs/products/pubs/pubd/lftbls/life/1966.htm )
$male = array( 0.007475, 0.000508, 0.000326, 0.000250, 0.000208, 0.000191, 0.000182, 0.000171, 0.000152, 0.000125, # 0-9
0.000105, 0.000111, 0.000162, 0.000274, 0.000431, 0.000608, 0.000777, 0.000935, 0.001064, 0.001166,
0.001266, 0.001360, 0.001419, 0.001435, 0.001419, 0.001390, 0.001365, 0.001344, 0.001336, 0.001341,
0.001352, 0.001371, 0.001408, 0.001469, 0.001553, 0.001653, 0.001770, 0.001911, 0.002075, 0.002254,
0.002438, 0.002632, 0.002853, 0.003113, 0.003412, 0.003735, 0.004071, 0.004428, 0.004806, 0.005206,
0.005648, 0.006121, 0.006594, 0.007045, 0.007488, 0.007946, 0.008459, 0.009064, 0.009810, 0.010706,
0.011763, 0.012934, 0.014159, 0.015362, 0.016558, 0.017847, 0.019331, 0.020992, 0.022858, 0.024921,
0.027065, 0.029363, 0.032031, 0.035178, 0.038734, 0.042414, 0.046171, 0.050325, 0.055085, 0.060498,
0.066557, 0.072986, 0.079682, 0.086593, 0.094013, 0.102498, 0.111640, 0.121472, 0.132023, 0.143319,
0.155383, 0.168232, 0.181880, 0.196334, 0.211592, 0.227645, 0.244476, 0.262057, 0.280351, 0.299312,
0.32, 0.34, 0.36, 0.38, 0.40, 0.42, 0.44, 0.46, 0.48, 0.50, # 100-109 extrapolated
1.0 # 110 terminal
);
$female = array( 0.006091, 0.000457, 0.000267, 0.000197, 0.000168, 0.000151, 0.000138, 0.000129, 0.000120, 0.000112, # 0-9
0.000107, 0.000113, 0.000135, 0.000178, 0.000237, 0.000306, 0.000371, 0.000421, 0.000446, 0.000453,
0.000456, 0.000464, 0.000471, 0.000481, 0.000492, 0.000506, 0.000522, 0.000541, 0.000565, 0.000593,
0.000627, 0.000667, 0.000712, 0.000764, 0.000825, 0.000892, 0.000971, 0.001071, 0.001190, 0.001321,
0.001453, 0.001586, 0.001727, 0.001883, 0.002055, 0.002243, 0.002439, 0.002633, 0.002819, 0.003005,
0.003204, 0.003432, 0.003695, 0.004000, 0.004346, 0.004725, 0.005137, 0.005594, 0.006110, 0.006697,
0.007389, 0.008167, 0.008977, 0.009776, 0.010581, 0.011466, 0.012498, 0.013661, 0.014966, 0.016407,
0.017945, 0.019617, 0.021503, 0.023635, 0.025987, 0.028358, 0.030849, 0.033818, 0.037481, 0.041792,
0.046463, 0.051306, 0.056613, 0.062608, 0.069533, 0.076645, 0.084411, 0.092876, 0.102085, 0.112081,
0.122907, 0.134602, 0.147201, 0.160735, 0.175225, 0.190689, 0.207132, 0.224550, 0.242924, 0.262224,
0.28, 0.30, 0.32, 0.34, 0.36, 0.38, 0.40, 0.42, 0.44, 0.46, # 100-109 extrapolated
1.0 # 110 terminal
);
# End of data.
if (isset($_GET['total'])) {
# Run the simulator.
# Get simulation parameters.
$total = $_GET['total'] + 0;
$equity_steps = 10; # Simulate different bond/stock ratios $total/$equity_steps appart
$limit = $_GET['limit'] + 0;
$savings = $_GET['savings'] + 0;
$income = $_GET['income'] + 0;
$ret_equity = $_GET['ret_equity'] + 0;
$ret_bonds = $_GET['ret_bonds'] + 0;
# The next parameter has to do with a sudden unexpected economic shock occuring when the simulation first starts.
# This is most useful if the stock market is highly valued and a correction is anticipated, or if the historical stock market data understates the future.
# It can be also used to build some conservative estimations into the simulation.
$pe_adjust = 1; # Assume an immediate one time adjustment in P/E from the denominator to the numerator eg. 11.5/14.0; set to 1 for no adjust.
$sim_start_year = intval($_GET['sim_start_year']);
(($sim_start_year >= $shiller_initial + 1) && ($sim_start_year <= $shiller_initial + count($shiller_price) / 12 - 2)) or die("Invalid simulation start year.");
# Minus 2 rather than minus 1 so we have at least two samples and can compute the standard deviation of returns later on.
$seq = (($_GET['seq'] == 'seq') ? 'seq' : 'rnd');
$deplete = $_GET['deplete'];
preg_match('/^(ef|bf|rb)$/', $deplete) or die("Invalid depletion mode.");
$num_experiments = $_GET['num_experiments'] + 0;
($num_experiments == 1000) || ($num_experiments == 3000) or die("Invalid number of experiments.");
$age1 = intval($_GET['age1']); # Set to -1 to never die.
(($age1 >= -1) && ($age1 <= 110)) or die("Invalid first person age.");
$sex1 = (($_GET['sex1'] == 'male') ? 'male' : 'female');
$age2 = intval($_GET['age2']); # Set to -1 if effectively already dead.
(($age2 >= -1) && ($age2 <= 110)) or die("Invalid second person age.");
$sex2 = (($_GET['sex2'] == 'male') ? 'male' : 'female');
$years = 110; # Maximum years to run. Stops early if both parties die.
$years_to_retire = intval($_GET['years_to_retire']);
($years_to_retire >= 0) or die("Invalid years until retirement.");
$go_to_bonds = $_GET['go_to_bonds'] + 0;
($go_to_bonds == -1) || (($go_to_bonds >= 0) && ($go_to_bonds <= 100)) or die("Invalid go to bonds percentage");
$income_dead_fraction = $_GET['income_dead_fraction'] / 100;
($income_dead_fraction >= 0) or die("Invalid income dead proportion.");
$diversification = $_GET['diversification'] / 100;
(($diversification >= 0) && ($diversification <= 1)) or die("Invalid diversification.");
$correlation = $_GET['correlation'] / 100;
(($correlation >= -1) && ($correlation <= 1)) or die("Invalid correlation.");
$diversify_sds = $_GET['diversify_sds'] + 0;
($diversify_sds >= 0) or die("Invalid diversification standard deviation scaling factor.");
# Output input parameters.
echo "\n";
echo "
\n";
printf("initial assets %4dk max assets %4dk return on equity %3.1f%% return on bonds %3.1f%%\n", $total / 1000, $limit / 1000, $ret_equity, $ret_bonds);
echo "
\n";
printf("years until retire %2d annual savings until retire %3dk annual living expenses once retire %3dk\n", $years_to_retire, $savings / 1000, $income / 1000);
echo "
\n";
printf("equity diversification %d%% correlation %d%% standard deviation scaling factor %3.1f\n", $diversification * 100, $correlation * 100, $diversify_sds);
echo "
\n";
printf("go to bonds %5.1f%% income dead fraction %3d%% age %d/%d gender %s/%s\n", $go_to_bonds, $income_dead_fraction * 100, $age1, $age2, $sex1, $sex2);
echo "
\n";
printf("simulation order mode '%3s' asset depletion mode '%2s'\n", $seq, $deplete);
echo "
\n";
printf("simulation start year %d end year %d experiments per result %d\n", $sim_start_year, $shiller_initial + count($shiller_price) / 12 - 1, $num_experiments);
# Construct array of equity values to use
$equity_fraction = array();
for ($i = 0; $i <= $equity_steps; $i++) {
array_push($equity_fraction, $i / $equity_steps);
}
if (($age1 != -1) && ($deplete == 'rb')) {
array_push($equity_fraction, 'age-in-bonds');
}
$diversify_factor = (1 - $correlation) * $diversification;
$death1 = (($sex1 == 'male') ? $male : $female);
$death2 = (($sex2 == 'male') ? $male : $female);
# Compute shiller annual returns.
$shiller_real_price = array();
$shiller_real_dividend = array();
for ($i = 0; $i <= count($shiller_price) -1 ; $i++) {
array_push($shiller_real_price, $shiller_price[$i] * $shiller_cpi[count($shiller_cpi) - 1] / $shiller_cpi[$i]);
array_push($shiller_real_dividend, $shiller_dividend[$i] * $shiller_cpi[count($shiller_cpi) - 1] / $shiller_cpi[$i]);
}
$index = 1;
$shiller = array();
$cpi_level = array();
for ($i = 1; $i <= count($shiller_real_price) - 1; $i++) {
$index = $index / $shiller_real_price[$i - 1] * ($shiller_real_price[$i] + $shiller_real_dividend[$i] / 12);
if ($i % 12 == 11) { # Just simulate every 12 monthly value for speed.
array_push($shiller, $index);
array_push($cpi_level, $shiller_cpi[$i]);
}
}
# The terminal value of the index differs from the terminal value computed using a spreadsheet by 0.5%.
# This represents 0.0003% per iteration. This difference is assumed to be due to rounding differences.
# The difference in successive index values, which is what we care about, is far less.
# Compute Shiller returns
$shiller_offset = $sim_start_year - ($shiller_initial + 1);
for ($i = 0; $i < (count($shiller) - ($shiller_offset + 1)); $i++) {
$returns[$i] = ($shiller[$shiller_offset + $i + 1] - $shiller[$shiller_offset + $i]) / $shiller[$shiller_offset + $i];
}
# Compute diversify to have a scaled standard deviation
$diversify = array();
for ($i = 0; $i <= count($returns) - 1; $i++) {
$diversify[$i] = $returns[$i] * $diversify_sds;
}
# Normalize diversify to have a geometric mean of $ret_equity and a correspondingly scaled standard deviation
$samp_prod = 1;
for ($i = 0; $i <= count($diversify) - 1; $i++) {
$samp_prod *= 1 + $diversify[$i];
}
$samp_geomean = pow($samp_prod, 1 / count($diversify)) - 1;
$adjust = (1 + $ret_equity / 100) / (1 + $samp_geomean);
for ($i = 0; $i <= count($diversify) - 1; $i++) {
$diversify[$i] = (1 + $diversify[$i]) * $adjust - 1;
}
# XXX 2009-09 - Don't understand following 5 lines - comment them out. Had been increasing volatility and bringing down success probabilities.
# Compute returns to have a scaled standard deviation
#$returns_sds = (1 - $diversification) + $diversify_sds * $diversification;
#for ($i = 0; $i <= count($returns) - 1; $i++) {
# $returns[$i] = $returns[$i] * $returns_sds;
#}
# Normalize returns to have a geometric mean of $ret_equity and a correspondingly scaled standard deviation
$samp_prod = 1;
for ($i = 0; $i <= count($returns) - 1; $i++) {
$samp_prod *= 1 + $returns[$i];
}
$samp_geomean = pow($samp_prod, 1 / count($returns)) - 1;
$adjust = (1 + $ret_equity / 100) / (1 + $samp_geomean);
for ($i = 0; $i <= count($returns) - 1; $i++) {
$returns[$i] = (1 + $returns[$i]) * $adjust - 1;
}
# Report statistics
$samp_prod = 1;
for ($i = 0; $i <= count($returns) - 1; $i++) {
$samp_prod *= 1 + $returns[$i];
}
$samp_geomean = pow($samp_prod, 1 / count($returns)) - 1;
$samp_tot = 0;
for ($i = 0; $i <= count($returns) - 1; $i++) {
$samp_tot += $returns[$i];
}
$samp_mean = $samp_tot / count($returns);
$samp_ss = 0;
for ($i = 0; $i <= count($returns) - 1; $i++) {
$samp_ss += pow($returns[$i] - $samp_mean, 2);
}
$samp_sd = pow(1 / (count($returns) - 1) * $samp_ss, 0.5);
echo "
\n";
echo "\n";
printf("equity return = geometric mean %4.2f%% arithmetic mean %4.2f%% +/- %4.2f%%\n", $samp_geomean * 100, $samp_mean * 100, $samp_sd * 100);
$samp_prod = 1;
for ($i = 0; $i <= count($diversify) - 1; $i++) {
$samp_prod *= 1 + $diversify[$i];
}
$samp_geomean = pow($samp_prod, 1 / count($diversify)) - 1;
$samp_tot = 0;
for ($i = 0; $i <= count($diversify) - 1; $i++) {
$samp_tot += $diversify[$i];
}
$samp_mean = $samp_tot / count($diversify);
$samp_ss = 0;
for ($i = 0; $i <= count($diversify) - 1; $i++) {
$samp_ss += pow($diversify[$i] - $samp_mean, 2);
}
$samp_sd = pow(1 / (count($diversify) - 1) * $samp_ss, 0.5);
echo "
\n";
printf("diversify return = geometric mean %4.2f%% arithmetic mean %4.2f%% +/- %4.2f%%\n", $samp_geomean * 100, $samp_mean * 100, $samp_sd * 100);
# Compute percentile life expectancies in order to be able to implement go to bonds strategy
if ($go_to_bonds != -1) {
if (($age1 != -1) && ($age2 != -1)) {
$death_prob = array();
# $death_prob[$y][$e] is the probability both members of a couple are dead at the end of year $e if they were both alive at the start of year $y
assert(count($death1) == count($death2));
for ($y = 0; min($age1, $age2) + $y <= count($death1) - 1; $y++) {
$alive1 = 1;
$alive2 = 1;
$death_prob[$y] = array();
for ($e = $y; min($age1, $age2) + $e <= count($death1) - 1; $e++) {
$alive1 *= ($age1 + $e >= count($death1)) ? 0 : 1 - $death1[$age1 + $e];
$alive2 *= ($age2 + $e >= count($death2)) ? 0 : 1 - $death2[$age2 + $e];
$death_prob[$y][$e] = (1 - $alive1) * (1 - $alive2);
}
}
$life_epectancy_both = array();
# $life_expectancy_both[$y] is the $go_to_bonds percentile life expectancy for a couple given they were both alive at the start of year $y
# Value should be rounded up
for ($y = 0; $y <= count($death_prob) - 1; $y++) {
$le = 0;
for ($e = count($death1) - 1 - min($age1, $age2); $e >= $y; $e--) {
if ($death_prob[$y][$e] <= $go_to_bonds / 100) {
$le = $e - $y + 1;
break;
}
}
$life_expectancy_both[$y] = $le + 1;
}
echo "
\n";
printf("%5.1fth percentile additional life expectancy=%d\n", $go_to_bonds, $life_expectancy_both[0]);
}
if ($age1 != -1) {
$death_prob = array();
# $death_prob[$y][$e] is the probability the first person is dead at the end of year $e if they were alive at the start of year $y
for ($y = 0; $age1 + $y <= count($death1) - 1; $y++) {
$alive1 = 1;
$death_prob[$y] = array();
for ($e = $y; $age1 + $e <= count($death1) - 1; $e++) {
$alive1 *= 1 - $death1[$age1 + $e];
$death_prob[$y][$e] = 1 - $alive1;
}
}
$life_epectancy_1 = array();
# $life_expectancy_1[$y] is the $go_to_bonds percentile life expectancy for the first person given they were alive at the start of year $y
# Value should be rounded up
for ($y = 0; $y <= count($death_prob) - 1; $y++) {
$le = 0;
for ($e = count($death1) - 1 - $age1; $e >= $y; $e--) {
if ($death_prob[$y][$e] <= $go_to_bonds / 100) {
$le = $e - $y + 1;
break;
}
}
$life_expectancy_1[$y] = $le + 1;
}
if ($age2 == -1) {
echo "
\n";
printf("%5.1fth percentile additional life expectancy=%d\n", $go_to_bonds, $life_expectancy_1[0]);
}
}
if ($age2 != -1) {
$death_prob = array();
# $death_prob[$y][$e] is the probability the second person is dead at the end of year $e if they were alive at the start of year $y
for ($y = 0; $age2 + $y <= count($death2) - 1; $y++) {
$alive2 = 1;
$death_prob[$y] = array();
for ($e = $y; $age2 + $e <= count($death2) - 1; $e++) {
$alive2 *= 1 - $death2[$age2 + $e];
$death_prob[$y][$e] = 1 - $alive2;
}
}
$life_epectancy_2 = array();
# $life_expectancy_2[$y] is the $go_to_bonds percentile life expectancy for the second person given they were alive at the start of year $y
# Value should be rounded up
for ($y = 0; $y <= count($death_prob) - 1; $y++) {
$le = 0;
for ($e = count($death2) - 1 - $age2; $e >= $y; $e--) {
if ($death_prob[$y][$e] <= $go_to_bonds / 100) {
$le = $e - $y + 1;
break;
}
}
$life_expectancy_2[$y] = $le + 1;
}
}
}
echo "\n";
echo "
\n";
echo "
\n";
echo "
| \n";
echo " |
|---|
| Equity | Bonds | Success probability \n";
echo " | Mean gifted assets | Mean assets at final death \n";
srand(0);
# Simulate portfolios
foreach ($equity_fraction as $ef) {
if (is_string($ef) && ($ef == 'age-in-bonds')) {
$equity = (1 - min(100, ($age2 == -1) ? $age1 : ($age1 + $age2) / 2) / 100) * $total;
} else {
$equity = $ef * $total;
}
$cash = $total - $equity;
$p_array = array();
$fail = 0;
$tot = 0;
$charitable_tot = 0;
$experiments = $num_experiments;
for ($experiment = 0; $experiment < $experiments; $experiment++) {
$e = $equity * $pe_adjust;
$c = $cash;
$in = $income;
$charitable = 0;
$dead1 = 0;
$dead2 = ($age2 == -1);
$index1 = rand(0, count($returns) - 1);
$index2 = rand(0, count($diversify) - 1);
$gone_to_bonds = 0;
for ($y = 0; ($y < $years) && !($dead1 && $dead2); $y++) {
if ($seq == 'seq') {
$e *= (1 - $diversify_factor) * (1 + $returns[$index1]) + $diversify_factor * (1 + $diversify[$index2]);
$index1 = ($index1 + 1) % count($returns);
$index2 = ($index2 + 1) % count($diversify);
} else {
$e *= (1 - $diversify_factor) * (1 + $returns[rand(0, count($returns) - 1)]) + $diversify_factor * (1 + $diversify[rand(0, count($diversify) - 1)]);
}
$c *= 1 + $ret_bonds / 100;
$p = $e + $c;
if ($y >= $years_to_retire) {
if ($dead1 || ($dead2 && ($age2 != -1))) {
$p -= $in * $income_dead_fraction;
} else {
$p -= $in;
}
} else {
$p += $savings;
}
if (($limit > 0) && ($p > $limit)) {
$charitable += $p - $limit;
$p = $limit;
}
if (($go_to_bonds != -1) && ! $gone_to_bonds) {
if ($dead1) {
$le = $life_expectancy_2[$y];
if ($age1 != -1) {
$le *= $income_dead_fraction;
}
} elseif ($dead2) {
$le = $life_expectancy_1[$y];
if ($age2 != -1) {
$le *= $income_dead_fraction;
}
} else {
$le = $life_expectancy_both[$y];
}
$gone_to_bonds = ($p >= $le * $in);
}
if ($gone_to_bonds) {
$c = $p;
} elseif (is_string($ef) && ($ef == 'age-in-bonds')) {
$c = min(100, ($age2 == -1) ? $age1 : ($age1 + $age2) / 2) / 100 * $p;
} elseif ($deplete == 'rb') {
$c = (1 - $ef) * $p;
} else {
if ($y < $years_to_retire) {
# use savings contribution to try and maintain bond fraction up to entire contribution amount
$c = min(max($c, (1 - $ef) * $p), $c + $savings);
}
if ($deplete == 'bf') {
if ($y >= $years_to_retire) {
if ($dead1 || ($dead2 && ($age2 != -1))) {
$c -= $in * $income_dead_fraction;
} else {
$c -= $in;
}
}
} else {
# ($deplete == 'ef');
$c = $c; # leave alone
}
}
if ($c < 0) {
$c = 0;
}
$e = $p - $c;
if ($e < 0) {
$c = $p;
$e = 0;
}
if (($age1 != -1) && !$dead1) {
$dead1 = (rand(0, 9999) / 10000 < $death1[$age1 + $y]);
}
if (!$dead2) {
$dead2 = (rand(0, 9999) / 10000 < $death2[$age2 + $y]);
}
}
array_push($p_array, $p);
if ($p < 0) {
$fail++;
}
$tot += $p;
$charitable_tot += $charitable;
}
# Compute and report stats
# sort($p_array);
# $pctl_0 = $p_array[0];
# $pctl_10 = $p_array[intval((count($p_array) + 1) / 10)];
# $pctl_25 = $p_array[intval((count($p_array) + 1) / 4)];
# $pctl_50 = $p_array[intval((count($p_array) + 1) / 2)];
$mean = $tot / $experiments;
$charitable_mean = $charitable_tot / $experiments;
# if ($pctl_0 < 0) {
# $pctl_0_display = "-$" . round(- $pctl_0 / 1000) . "k";
# } else {
# $pctl_0_display = "$" . round($pctl_0 / 1000) . "k";
# }
if ($mean < 0) {
$mean_display = "-$" . round(- $mean / 1000) . "k";
} else {
$mean_display = "$" . round($mean / 1000) . "k";
}
if (is_string($ef) && ($ef == 'age-in-bonds')) {
echo " |
| average age in bonds\n";
} else {
printf(" |
| %d%% | %d%%\n", round($ef * 100), round((1 - $ef) * 100));
}
printf(" | %d%% | $%dk | %s\n",
round(($experiments - $fail) / $experiments * 100), round($charitable_mean / 1000), $mean_display);
}
echo " |
\n";
echo "
\n";
} else {
# Display simulator input page.
echo "\n";
echo "This retirement simulator simulates an initial set of assets
with a savings accumulation phase followed by an income
withdrawal retirement phase. The results associated with
holding different ratios of stocks/bonds are reported.\n";
echo "
\n";
echo "The reported results show the probability of dying without
running out of money (success). For a couple the death of one
partner reduces the amount of income required to support the
other partner, but simulation continues until both partners
are dead.\n";
echo "
\n";
echo "To use this tool effectively, you should perform multiple runs
of the simulator changing the input parameters in order to
assess the sensitivity of your results to small changes in the
inputs.\n";
echo "
\n";
echo "Equity returns are based on the historical returns reported by
Shiller, but with the mean return adjusted to match a
specified simulation parameter. This is because it seems
unlikely that the return values of the past will be repeated,
but they are still informative in setting the volatility of
future returns.\n";
echo "
\n";
echo "Bond returns are assumed to be a fixed amount per year after
adjusting for inflation, and as such most closely model
TIPS.\n";
echo "
\n";
echo "An actuarial model of longevity is employed, in which the
probability of death each year is taken from the U.S. Life
Tables. Separate tables are used for men and women.\n";
echo "
\n";
echo "All input values and reported values are adjusted for
inflation.\n";
echo "
\n";
echo "
\n";
}
echo "\n";
echo "\n";
?>