Announcement

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

  • Calculating skewness and kurtosis of monthly returns

    Hello all,

    I have a dataset with a firm identifying number (called "PERMNO"), a date variable ("date") for the end of each month in a year (with respect to the firm), as well as a variable "RET" that is the return of the firm at the end of the month. What I would like to be able to do is calculate is skewness as well as kurtosis of the past 3 month returns (so by sorting on "PERMNO", generating a past 3 month skewness/kurtosis variable of the sort RET[_n-3] + RET[_n-2] + RET[_n-1]).

    Does someone know if Stata has some sort of commands to calculate skewness and kurtosis of returns?

    Here is the data that I am working with:

    Code:
    * Example generated by -dataex-. For more info, type help dataex
    clear
    input double PERMNO long date double RET
    10078 13545    .23600973188877106
    10078 13573  -.027559055015444756
    10078 13604   -.06477732956409454
    10078 13634 -.0021645021624863148
    10078 13664    .11930585652589798
    10078 13695    .15406976640224457
    10078 13726    .22753988206386566
    10078 13755    .05608754977583885
    10078 13787  -.029792746528983116
    10078 13818    -.2683578133583069
    10078 13846   .051094889640808105
    10078 13879     .1076388880610466
    10078 13909    .20219436287879944
    10078 13937   -.00651890505105257
    10078 13969   -.12401574850082397
    10078 13999  -.012734082527458668
    10078 14028  -.027314111590385437
    10078 14060    .08424337208271027
    10078 14091    .08776978403329849
    10078 14122   -.16137565672397614
    10078 14152     .2570977807044983
    10078 14182    .16938519477844238
    10078 14213     .2714592218399048
    10078 14244    .15611813962459564
    10078 14273    .30510950088500977
    10078 14301   -.12919463217258453
    10078 14334     .2851637899875641
    10078 14364  -.043478261679410934
    10078 14392 -.0010449320543557405
    10078 14425     .1527196615934372
    10078 14455  -.014519056305289268
    10078 14487     .1712707132101059
    10078 14517    .16981132328510284
    10078 14546    .13776881992816925
    10078 14578    .24985232949256897
    10078 14609    .17107750475406647
    10078 14640   .014527845196425915
    10078 14669    .21241049468517303
    10078 14700  -.016240157186985016
    10078 14728  -.018842754885554314
    10078 14761   -.16655336320400238
    10078 14791    .18678629398345947
    10078 14822    .15945017337799072
    10078 14853    .20391227304935455
    10078 14882   -.08025602996349335
    10078 14914  -.050321198999881744
    10078 14944   -.31397971510887146
    10078 14973    -.2670501172542572
    10078 15006     .0964125543832779
    10078 15034     -.349693238735199
    10078 15064    -.2266666740179062
    10078 15095    .11385823041200638
    10078 15126   -.03796737641096115
    10078 15155   -.04553728550672531
    10078 15187    .03625958412885666
    10078 15218   -.29711484909057617
    10078 15246   -.27772921323776245
    10078 15279    .22732757031917572
    10078 15309    .40295568108558655
    10078 15340   -.13623592257499695
    10078 15371   -.12520325183868408
    10078 15399   -.20910780131816864
    10078 15427    .03642766922712326
    10078 15460   -.07256229221820831
    10078 15491    -.1577017605304718
    10078 15519    -.2728591561317444
    10078 15552    -.2175648957490921
    10078 15582   -.05867347493767738
    10078 15613     -.298103004693985
    10078 15644    .14324326813220978
    10078 15673     .4491725564002991
    10078 15705   -.27522721886634827
    10078 15736  -.006430862471461296
    10078 15764     .1132686585187912
    10078 15795  -.052325598895549774
    10078 15825   .015337408520281315
    10078 15855    .31419938802719116
    10078 15886    .06896556168794632
    10078 15917   -.19139787554740906
    10078 15946   .037234071642160416
    10078 15978   -.15128208696842194
    10078 16009    .19335350394248962
    10078 16037    .07848105579614639
    10078 16070    .04929566755890846
    10078 16100     .1827741414308548
    10078 16128   .004350248258560896
    10078 16161     -.214689239859581
    10078 16191   -.06474819779396057
    10078 16219    .06923076510429382
    10078 16252    .03836926817893982
    10078 16282   -.08775978535413742
    10078 16314   -.02025320567190647
    10078 16344   .043927669525146484
    10078 16373    .11386139690876007
    10078 16405    .23333337903022766
    10078 16436  -.028828885406255722
    10078 16467   -.19109457731246948
    10078 16495  -.032110169529914856
    10078 16526   -.04265398904681206
    10078 16555   -.10396041721105576
    end
    format %td date

  • #2
    You have monthly data and so will find it much easier to work in terms of monthly dates.

    rangestat (SSC) will do the calculations. However, I would call a sample of 3 far too small to get useful results for skewness, and the limitation is even stronger for kurtosis.

    See https://www.stata-journal.com/articl...article=st0204 which surveys the literature known to me at the time, including a known result implying an upper limit of 1.5 for kurtosis for a sample of 3 (using the recipe followed by Stata; other recipes can be found).

    Further references were given in Section 7 of https://journals.sagepub.com/doi/10....6867X211063415 -- of which

    https://projecteuclid.org/journals/a...177729602.full

    should be easily accessible.

    What is not covered in the paper is how often this maximum is attained, and the answer appears to be often. Here are some results for your data example.


    .
    Code:
    . gen mdate = mofd(date)
    
    . format mdate %tm
    .
    . rangestat (skewness) RET (kurtosis) RET, int(mdate -3 -1)  by(PERMNO) 
    
    . list in 1/10
    
         +-------------------------------------------------------------------+
         | PERMNO        date          RET     mdate   RET_skew~s   RET_ku~s |
         |-------------------------------------------------------------------|
      1. |  10078   31jan1997    .23600973    1997m1            .          . |
      2. |  10078   28feb1997   -.02755906    1997m2            .          . |
      3. |  10078   31mar1997   -.06477733    1997m3            0          1 |
      4. |  10078   30apr1997    -.0021645    1997m4    .66634517        1.5 |
      5. |  10078   30may1997    .11930586    1997m5   -.22631561        1.5 |
         |-------------------------------------------------------------------|
      6. |  10078   30jun1997    .15406977    1997m6    .36816565        1.5 |
      7. |  10078   31jul1997    .22753988    1997m7    -.5669329        1.5 |
      8. |  10078   29aug1997    .05608755    1997m8    .40555684        1.5 |
      9. |  10078   30sep1997   -.02979275    1997m9   -.17293064        1.5 |
     10. |  10078   31oct1997   -.26835781   1997m10    .38100752        1.5 |
         +-------------------------------------------------------------------+
    An informal story here is that kurtosis is about comparing values near the mean with values further from the mean and you don't have enough of both kinds in a sample of 3.

    Even though skewness can be calculated for such a sample its absolute value for samples of size 3 cannot exceed the square root of 1/2 or 0.7071 to 4 dp, so its diagnostic value is limited.



    Comment


    • #3
      Thank you Nick for your answer

      Comment


      • #4
        I imagine that the study or studies you are emulating worked with say 3 months of daily returns. There is always an upper limit on skewness and kurtosis for finite samples. but it would not bite so hard with a larger sample.

        Comment


        • #5
          Here is a solutiion based on asrol.
          Code:
          ssc install asrol
          
          gen mofd = mofd(date)
          
          . bys PERMNO : asrol RET, stat(skewness kurtosis) window(mofd -4 -1)
          
          . list in 1/10
          
               +----------------------------------------------------------------+
               | PERMNO        date          RET   mofd   RET_skew~1   RET_ku~1 |
               |----------------------------------------------------------------|
            1. |  10078   31jan1997    .23600973    444            .          . |
            2. |  10078   28feb1997   -.02755906    445            .          . |
            3. |  10078   31mar1997   -.06477733    446            0          1 |
            4. |  10078   30apr1997    -.0021645    447    .66634517        1.5 |
            5. |  10078   30may1997    .11930586    448   -.22631561        1.5 |
               |----------------------------------------------------------------|
            6. |  10078   30jun1997    .15406977    449    .36816565        1.5 |
            7. |  10078   31jul1997    .22753988    450    -.5669329        1.5 |
            8. |  10078   29aug1997    .05608755    451    .40555684        1.5 |
            9. |  10078   30sep1997   -.02979275    452   -.17293064        1.5 |
           10. |  10078   31oct1997   -.26835781    453    .38100752        1.5 |
               +----------------------------------------------------------------+
          More on asrol can be found here https://fintechprofessor.com/2017/10...tics-in-stata/
          Regards
          --------------------------------------------------
          Attaullah Shah, PhD.
          Professor of Finance, Institute of Management Sciences Peshawar, Pakistan
          FinTechProfessor.com
          https://asdocx.com
          Check out my asdoc program, which sends outputs to MS Word.
          For more flexibility, consider using asdocx which can send Stata outputs to MS Word, Excel, LaTeX, or HTML.

          Comment

          Working...
          X