Here's confirmation that even with missing time periods and some missing values for exret, you can match results from the loop by adjusting the interval that rangestat uses. The following does what you requested, that is a recursive interval that excludes the current observation. The interval of the rangestat call that counts the number of non-missing values for exret is also adjusted to use the previous 12 periods.
Code:
* Example generated by -dataex-. To install: ssc install dataex
clear
input long(obs permno) float(time exret inflation)
1 1470874 1 .9122462 .51331943
2 1470874 2 .5948181 .3065938
3 1470874 3 .25645664 .4921637
4 1470874 4 .930954 .3914094
5 1470874 5 .9577237 .8338873
6 1470874 6 .5671181 .8355323
7 1470874 7 .2708475 .26582384
8 1470874 8 .34942105 .672545
9 1470874 9 .4345023 .5868091
10 1470874 10 .8107689 .23440893
11 1470874 11 .5516335 .29357833
12 1470874 12 .6561857 .9301422
13 1470874 13 .7671857 .04822804
14 1470874 14 .4452506 .09964211
15 1470874 15 .51762706 .8284212
16 1470874 16 .2166194 .13313739
17 1470874 17 .19157566 .3796502
18 1470874 18 .9459305 .7317557
19 1470874 19 .7275512 .0852162
20 1470874 20 .927551 .6083384
21 1470874 21 .4164995 .4719198
22 1470874 29 . .4488523
23 1470874 30 .4370895 .1835875
24 6879153 1 .6476775 .3955551
25 6879153 2 .4472069 .02203239
end
* loop, based on Mohammad's single case
gen b = .
gen n = .
local nobs = _N
qui forvalues i = 1/`nobs' {
count if !mi(exret) & permno == permno[`i'] ///
& inrange(time, time[`i']-12, time[`i']-1)
if r(N) >= 8 {
gen double ww = exp(-(time[`i'] - time) * log(2)/60) ///
if permno == permno[`i'] & time < time[`i']
regress exret inflation [aweight=ww] ///
if permno == permno[`i'] & time <time[`i']
drop ww
replace n = e(N) in `i'
replace b = _b[inflation] in `i'
}
}
* --------------- redo using rangestat ----------------------------------------
* precompute number of non-missing observations in the past 12 periods
rangestat (count) exret, interval(time -12 -1) by(permno)
* define a Mata function for Weighted Least Squares, original OLS Mata code derived from
* http://blog.stata.com/2016/01/12/programming-an-estimation-command-in-stata-an-ols-command-using-mata/
* and adapted using the information on
* https://www.mathworks.com/help/curvefit/least-squares-fitting.html?requestedDomain=www.mathworks.com
mata:
mata clear
real rowvector mywls(real matrix Xall)
{
real colvector y, b, w, wy, t
real matrix X, XpX, XpXi, wX
real scalar n, k, tau
y = Xall[.,1] // dependent var is first
X = Xall[.,2::cols(Xall)-1] // independent variables
t = Xall[.,cols(Xall)] // time variable
n = rows(X) // the number of observations
X = X,J(n,1,1) // add a constant
k = cols(X) // number of independent variables
if (n > k) { // need more than k obs to estimate model and standard errors
tau = t[rows(t)]
w = exp(-(tau :- t) * log(2)/60)
wX = w :* X
wy = w :* y
XpX = quadcross(X, wX)
XpXi = invsym(XpX)
if (diag0cnt(XpXi) == 0) {
b = XpXi * quadcross(X, wy)
}
}
return(rows(X), b')
}
end
gen high = cond(exret_count >= 8, time-1, 0)
rangestat (mywls) exret inflation time, interval(time . high) by(permno) casewise
gen reg_n = mywls1
gen reg_b = mywls2
assert n == reg_n
assert b == reg_b

Comment