Announcement

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

  • Expanding window through existing mata code

    Dear Statalist,

    I have some working code, but I would like to alter is so the result is an expanding window in time. The result at a given time would only depend on the observations from previous time.

    My current code generates three random variables, s1, s2, s3 (we can think of them as monthly stock returns) over 100 months.

    The code finds the mean and inverse of the covariance matrix of the three vectors, and multiplies them together with a matrix including all three stocks to generate one vector.

    The resulting vector, M, depends only on the first have of the data, which is set by "pre" less than or equal to 50. M at time 51 through 100 depend on the means and covariances from time = 1 to 50. I would like to change this result so that the data used expands. At time = 51, M depends on the means and covariances from time<51, then at time =52, M depends on the means and covariances from time < 52 and so on. The M at time = 100 would depend on the means and covariances in time 1 to 99.

    I'd really appreciate any guidance. I'm not sure how to proceed.


    Code:
    set obs 100
    
    gen time = _n
    
    gen s1 = rnormal(1, 4)
    gen s2 = rnormal(1, 4)
    gen s3 = rnormal(1, 4)
    
    order s*
    
    gen pre=0
    replace pre =1 if time<=50
    
    
    mata
    
    Xpre =st_data(.,(1,2,3),"pre")
    X=st_data(.,(1,2,3))
    
    //    real colvector SDFo    
    M=(mean(Xpre)*invsym(variance(Xpre))*X')'
    
    st_addvar("double","M")
    st_store(.,"M", M)
    end

  • #2
    I am not a mata expert by any means but in the absence of a better response, I offer the solution below (providing I've understood your aim):

    Code:
    clear all
    set obs 100
    
    gen time = _n
    
    gen s1 = rnormal(1, 4)
    gen s2 = rnormal(1, 4)
    gen s3 = rnormal(1, 4)
    
    order s*
    
    gen pre=0
    replace pre =1 if time<=50
    
    
    mata
    
    Xpre =st_data(.,(1,2,3),"pre")
    X=st_data(.,(1,2,3))
    
    //    real colvector SDFo    
    M=(mean(Xpre)*invsym(variance(Xpre))*X')'
    oldM = (mean(Xpre)*invsym(variance(Xpre))*X')'
    
    // Loop over the vector
    for(i=rows(Xpre)+1; i<=rows(M); i++){ //starting at 51 through to 100
        j = i - 1 //since M at 51 depends on obs from 1 to 50 etc.
        val = (mean(X[1..j,.])*invsym(variance(X[1..j,.]))*X')' // calculate for 1 to 50 etc.
        M[i] = val[i] //replace M at position 51 etc.
    }
    
    
    st_addvar("double","M")
    st_store(.,"M", M)
    
    st_addvar("double","oldM")
    st_store(.,"oldM", oldM)
    
    end
    
    // Values change from position 52 
    assert M == oldM if pre //same in 1 to 50
    assert M == oldM in 51 //and in 51 (since 51 depends on 1 to 50 in either case) 
    assert M == oldM if _n > 51 //changed in next 49 obs
    Caveats:
    Beyond what you see above, I haven't checked that this is correct.
    There may be a better solution that doesn't involve looping over observations.
    I suspect there's a much neater way to do this using -rangestat- (from SSC) by supplying it with your own mata function. See the excellent help file for examples.


    Hope this helps.

    Comment

    Working...
    X