/* Social Security Benefit Function for United States - Based on Social Security Handbook 2004 ---------------------------------------------------- */ program define SsBenefit, syntax varlist [if], gen(namelist) marksample touse tokenize `varlist' #delimit; tempvar raime saime rq sq ry_earn sy_earn; tempvar rclyr sclyr rbyr sbyr rmar rl sl yr; tempvar rdthyr sdthyr; ///1. Assign Data to Variables ------------------- qui gen `raime' = `1' if `touse'; qui gen `rq' = `2' if `touse'; qui gen `ry_earn' = `3' if `touse'; qui gen `rclyr' = `4' if `touse'; qui gen `rbyr' = `5' if `touse'; qui gen `rl' = `6' if `touse'; qui gen `rdthyr' = `7' if `touse'; qui gen `saime' = `8' if `touse'; qui gen `sq' = `9' if `touse'; qui gen `sy_earn' = `10' if `touse'; qui gen `sclyr' = `11' if `touse'; qui gen `sbyr' = `12' if `touse'; qui gen `sl' = `13' if `touse'; qui gen `sdthyr' = `14' if `touse'; qui gen `rmar' = `15' if `touse'; qui gen `yr' = `16' if `touse'; /// 2.A Important Indicators ---------------------- tempvar ry60 sy60 ry62 sy62 rynra synra ry70 sy70 rage sage; qui gen `ry60' = `rbyr' + 60 if `touse'; qui gen `ry62' = `rbyr' + 62 if `touse'; qui gen `ry70' = `rbyr' + 70 if `touse'; qui egen `rynra' = nra(`rbyr') if `touse'; qui replace `rynra' = `rbyr' + `rynra' if `touse'; qui gen `sy60' = `sbyr' + 60 if `touse'; qui gen `sy62' = `sbyr' + 62 if `touse'; qui gen `sy70' = `sbyr' + 70 if `touse'; qui egen `synra' = nra(`sbyr') if `touse'; qui replace `synra' = `sbyr' + `synra' if `touse'; qui gen `rage' = `yr' - `rbyr' if `touse'; qui gen `sage' = `yr' - `sbyr' if `touse'; /// Determine Eligibility based on age and quarters or coverage tempvar rmin smin re se; qui gen `rmin' = 40 if `touse'; qui replace `rmin' = 40 - (1929-`rbyr') if `rbyr'<1929&`touse'; qui gen `smin' = 40 if `touse'; qui replace `smin' = 40 - (1929-`sbyr') if `sbyr'<1929&`touse'; qui gen `re' = (`rage'>=62)&(`rq'>=`rmin') if `touse'&`sl'==1; qui replace `re' = (`rage'>=60)&(`rq'>=`rmin') if `touse'&`sl'==0; qui gen `se' = (`sage'>=62)&(`sq'>=`smin') if `touse'&`rl'==1; qui replace `se' = (`sage'>=60)&(`sq'>=`smin') if `touse'&`rl'==0; /// Get PIA based on AIME, quarters (for minimum PIA) and birth year tempvar rpia spia; SsPIA `raime' `rq' `rbyr' `rl' `rdthyr' if `touse', gen(`rpia'); SsPIA `saime' `sq' `sbyr' `sl' `sdthyr' if `touse', gen(`spia'); /// Get DRC or ARF based on birth year and claiming date tempname arf; tempvar rdrc sdrc rr sr; scalar `arf' = 0.0678; qui egen `rdrc' = drc(`rbyr') if `touse'; qui egen `sdrc' = drc(`sbyr') if `touse'; qui replace `rdrc' = exp(`arf'*max(min(`rclyr'-`rynra',0),62-`rynra')) if `rclyr'<=`rynra'&`touse'; qui replace `rdrc' = exp(`rdrc'*min(`rclyr'-`rynra',`ry70'-`rynra')) if `rclyr'>`rynra'&`touse'; qui replace `sdrc' = exp(`arf'*max(min(`sclyr'-`synra',0),62-`synra')) if `sclyr'<=`synra'&`touse'; qui replace `sdrc' = exp(`sdrc'*min(`sclyr'-`synra',`sy70'-`synra')) if `sclyr'>`synra'&`touse'; qui gen `rr' = `rclyr'<=`yr' if `touse'; qui gen `sr' = `sclyr'<=`yr' if `touse'; qui replace `rdrc' = 0 if (`rl'==0|`rr'==0|`re'==0)&`touse'; qui replace `sdrc' = 0 if (`sl'==0|`sr'==0|`se'==0)&`touse'; /// Calculate Admissible Benefits on own account tempvar rben_g sben_g; qui gen `rben_g' = `rdrc'*`rpia' if `touse'; qui gen `sben_g' = `sdrc'*`spia' if `touse'; /// Calculate Benefit admissible as spouse tempvar rben_s sben_s; tempname sp_factor; scalar `sp_factor' = 0.5; qui gen `rben_s' = max(`sp_factor'*`rdrc'*`spia' - `rben_g',0) if `touse'; qui replace `rben_s' = 0 if `sr'==0&`touse'; qui gen `sben_s' = max(`sp_factor'*`sdrc'*`rpia' - `sben_g',0) if `touse'; qui replace `sben_s' = 0 if `rr'==0&`touse'; /// If not married, no spousal benefits qui replace `rben_s' = 0 if `rmar'==0&`touse'; qui replace `sben_s' = 0 if `rmar'==0&`touse'; /// Survivor Benefits tempvar rben_v sben_v; qui gen `rben_v' = 0; qui gen `sben_v' = 0; qui replace `rben_v' = max(`rdrc'*`spia' - `rben_g',0) if `sl'==0&`touse'; qui replace `sben_v' = max(`sdrc'*`rpia' - `sben_g',0) if `rl'==0&`touse'; /// If married, no survival benefits qui replace `rben_v' = 0 if `rmar'==1 &`touse'; qui replace `sben_v' = 0 if `rmar'==1 &`touse'; /// Calculate Total Benefit for Purpose of Earnings Test tempvar rben_all sben_all; qui gen `rben_all' = `rben_g' + `rben_s' + `rben_v' if `touse'; qui gen `sben_all' = `sben_g' + `sben_s' + `sben_v' if `touse'; /// sum `re' `rpia' `rdrc' `rben_g' `rben_all' `se' `spia' `sdrc' `sben_g' `sben_all'; /// Get Earnings Disregard tempvar rea_cap sea_cap; qui egen `rea_cap' = eadisreg(`yr' `rage') if `touse'; qui egen `sea_cap' = eadisreg(`yr' `sage') if `touse'; /// Appl Tax Rates to Earnings Over Cap tempname ea_era ea_nra; scalar `ea_era' = 1/2; scalar `ea_nra' = 1/3; tempvar rea_tax sea_tax; qui gen `rea_tax' = `ea_era'*max(`ry_earn'-`rea_cap',0) if `touse'&`yr'<`rynra'; qui replace `rea_tax' = `ea_nra'*max(`ry_earn'-`rea_cap',0) if `touse'&`yr'>=`rynra'; qui replace `rea_tax' = 0 if `touse'&`rea_tax'==.; qui gen `sea_tax' = `ea_era'*max(`sy_earn'-`sea_cap',0) if `touse'&`yr'<`synra'; qui replace `sea_tax' = `ea_nra'*max(`sy_earn'-`sea_cap',0) if `touse'&`yr'>=`synra'; qui replace `sea_tax' = 0 if `touse'&`sea_tax'==.; qui replace `rea_tax' = max(min(`rea_tax'/`rben_all',1),0) if `touse'&`rben_all'!=0; qui replace `sea_tax' = max(min(`sea_tax'/`sben_all',1),0) if `touse'&`sben_all'!=0; // Proportional Reduction of All benefits qui replace `rben_g' = `rben_g'*(1-`rea_tax') if `rea_tax'!=.&`touse'; qui replace `rben_s' = `rben_s'*(1-`rea_tax') if `rea_tax'!=.&`touse'; qui replace `rben_v' = `rben_v'*(1-`rea_tax') if `rea_tax'!=.&`touse'; // Proportional Reduction of All benefits qui replace `sben_g' = `sben_g'*(1-`sea_tax') if `sea_tax'!=.&`touse'; qui replace `sben_s' = `sben_s'*(1-`sea_tax') if `sea_tax'!=.&`touse'; qui replace `sben_v' = `sben_v'*(1-`sea_tax') if `sea_tax'!=.&`touse'; /// Sep 14, 2008 - adjust to 2004 dollars ; tempvar cola_r60 cola_s60 cola_04 ; qui egen `cola_r60' = cola(`ry60'); qui egen `cola_s60' = cola(`sy60'); qui egen `cola_04' = cola(2004); foreach x in rben_g rben_s rben_v {; qui replace ``x'' = ``x''* (`cola_04'/`cola_r60') if `touse' & !missing(``x''); }; foreach x in sben_g sben_s sben_v {; qui replace ``x'' = ``x''* (`cola_04'/`cola_s60') if `touse' & !missing(``x''); }; tokenize `gen'; qui gen `1' = `rben_g' if `touse'; qui gen `2' = `rben_s' if `touse'; qui gen `3' = `rben_v' if `touse'; qui gen `4' = `sben_g' if `touse'; qui gen `5' = `sben_s' if `touse'; qui gen `6' = `sben_v' if `touse'; end;