/* Computation of Averaged Indexed Monthly Earning
based on Social Security Handbook
						for United States -
Based on discussions with N. Maestas
and Social Security Handbook.
* Version 2. Dec 2007, Add comments by Yuhui
---------------------------------------------------- */


/// 3. Calculation of AIME


cap program drop SsAIME
program define SsAIME, sortpreserve
	version 9
	syntax varlist [if] [in], gen(name) earn(string) fyr(integer) yr(integer)
	marksample touse

	/*
	"name": the variable to generate (AIME)
	"earn": beginning name of earnings history, should be in the format of "earn"YYYY
	"fyr" : A scalar of beginning year of earnings history
	"cyr" : A scalar of the year of calculating AIME
	*/

	/// 0.  Confirm existence of variables from "fyr" to "yr", and also two acciliary datasets exist
	foreach t of numlist `fyr'/`yr' {
		  cap confirm var `earn'`t'
		  if _rc {
		  	dis "Missing earning history for year `t'"
		  	exit(333)
		  }
	}
	foreach f in cnatwage earnlimit{
		cap confirm file `f'.dta
			if _rc{
					dis "Please put file `f'.dta under the working directory"
					exit (555)
			}
	}

	tokenize `varlist'
	#delimit;
	tempvar rq rbyr rclyr;

	///1. Assign Data to Variables -------------------

	qui gen `rq'       = `1'  if `touse';
	qui gen `rbyr'     = `2'  if `touse';
	qui gen `rclyr'    = `3'  if `touse';

	/*  by YUHUI
			 `rq': total quarters of covered earnings
			 `rbyr': year of birth
			 `rclyr': claim year
	*/

	/// 2.A Important Indicators ----------------------
	tempvar ry60 endyr;
	qui gen `ry60' = `rbyr' + 60 if `touse';
	qui gen `endyr' = min(`rclyr',`yr') if `touse';

	/// 2.B Earning History ---------------------------
	capture drop y60;
	gen y60 = `ry60' if `touse';
	sort y60;
	capture drop _merge;
	qui merge y60 using "cnatwage.dta", nokeep;
	drop _merge y60;

	/* by YUHUI
		cnatwage.dta includes wage threshold from yr1960-2060
		"w" is the threshold in a certain year
		"wYYYY" is the wide format of threshold in a certain year, constant across rows
	*/

	/// 2.C. Allowed Earnings --------------------------
	tempvar ecap;
	gen yr = `yr' if `touse';
	sort yr;
	capture drop _merge;
	qui merge yr using "earnlimit.dta", nokeep;
	drop _merge yr cap;

	/// 2.D. Indexation --------------------------------
	tempvar yrn;
	qui gen `yrn' = `ry60'-`fyr'+1 if `touse';

foreach t of numlist `fyr'/`yr' {;
    tempvar rw`t';
    qui gen `rw`t'' = `earn'`t' if `touse';
    qui replace `rw`t'' = min(`rw`t'',c`t')*w/w`t' if `touse'&`ry60'>=`t'& `rclyr'>= `t';
    qui replace `rw`t'' = min(`rw`t'',c`t') if `touse'&`ry60'<`t' & `rclyr' >= `t';
    qui replace `rw`t'' = 0 if `rclyr'< `t'  ;
  };

	/* by YUHUI
	  the "
	  if not older than age 60, taxable earnings will be inflated to the year at which one reaches 60
	  if older than 60, then no inflation is made
	  if year later than claiming year, then earning is zero
	  the year of claiming might include some earnings
	*/

  drop w1* c1* w2* c2* `yrn' w;
  /// 2.E. Computation Years --------------------------
  tempvar rcpyr endyr2;
  qui gen `endyr2' = `endyr'-`fyr'+1 if `touse';
  qui gen `rcpyr' = min(35,`endyr2')  if `touse';

  global w "";
  forvalues i = `fyr'/`yr'{;
			global w $w `rw`i'' ;
	};


  /// 2.F. Computation AIME   --------------------------
  cap drop aime_r;
  mata: caime("$w","`rcpyr'","`endyr2'");
	capture drop `gen';

///	list aime in 1;
	qui gen `gen' = aime_r/12 if `touse';
	drop aime_r ;
  macro drop w;

///	list `gen' in 1;
	mata: mata clear;
	#delimit cr
end


version 9
 mata:
 void caime(earnings, rcpyr, endyr2)
 {
    mW = st_data(.,tokens(earnings))
    vC = st_data(.,rcpyr)
    vE = st_data(.,endyr2)
    N = rows(mW)
    mA = J(N,1,0)
    for (i=1;i<=N;i++){
			endyr = vE[i]
			cyr = vC[i]
			mwi = sort(mW[i,1::endyr]',-1)

			mA[i] =	sum(mwi[1::cyr])/35

    }
    idx = st_addvar("double","aime_r")
    st_store(range(1,N,1),"aime_r",mA);
 }

 end