Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • #31
    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


    • #32
      Dear Rober,

      Thanks a lot for your help. :-)

      Comment


      • #33
        Dear Robert,

        Assume that in the previous code that you wrote for me with mata, I want to regress Y only on a constant without any independent variable. How can I change the code to run such a rolling regression? I checked several ways (for example, putting an independent variable equal to 0), but I couldn't fix it. Could you plz help me? :-) ( Robert Picard )

        Thanks,
        Mohammad
        Last edited by Mohammad Khodadadi; 31 Jul 2017, 12:36.

        Comment


        • #34
          This is the same code as in #31, altered to regress exret on a constant.

          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 one = 1
          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 one [aweight=ww] ///
                      if permno == permno[`i'] & time <time[`i'], nocons
                  drop ww
                  replace n = e(N) in `i'
                  replace b = _b[one] 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
              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 one time, interval(time . high) by(permno) casewise
          
          gen reg_n = mywls1
          gen reg_b = mywls2
          assert n == reg_n
          assert b == reg_b

          Comment


          • #35
            Thanks a lot, Robert. :-)

            Comment

            Working...
            X