Announcement

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

  • 5x5 Yearly Portfolios

    Recently we used the below code. It is written to do yearly mcap sort on median break-point and idiovol sort on 33.33 and 66.67 break-points. I need necessary modifications to it so that it does now first sort to create quintiles of size and then second sort to create quintiles of idiovol. After this, it should generate data set that contains one observation for each month and each of the (up to ) 25 groups in each month and gives the weighted and unweighted means of rt. Other parameters to this code are alright. However, the part that creates six portfolios and then SMB and HML is to discarded.

    Code:
    gen moy = month(dofm(mdate))
    gen year = year(dofm(mdate))
    //  CREATE A "FISCAL YEAR" RUNNING FROM JULY THROUGH SUBSEQUENT JUNE
    gen fyear = cond(moy > 6, year, year-1)
    frame put stock_id fyear mcap idiovol, into(mcap_idiovol_work)
    frame change mcap_idiovol_work
    collapse (count) n_mcap = mcap n_idiovol = idiovol (firstnm) mcap idiovol, by(stock_id fyear)
    assert n_mcap <= 1 & n_idiovol <= 1 // VERIFY UNIQUE VALUE OF MCAP AND idiovol
    replace fyear = fyear + 1 // CHANGE THE FYEAR TO WHICH THEY WILL APPLY
    frame change default
    rename (mcap idiovol) orig=
    frlink m:1 stock_id fyear, frame(mcap_idiovol_work)
    frget mcap idiovol, from(mcap_idiovol_work)
    frame drop mcap_idiovol_work
    drop mcap_idiovol_work
    egen byte representative = tag(stock_id fyear)
    
    //  MEDIAN SPLIT BASED ON JUNE VALUE OF mcap
    capture program drop one_year_median_split
    program define one_year_median_split
        xtile june_mcap_group = mcap, nq(2)
        exit
    end
    frame put stock_id fyear mcap if representative & !missing(mcap), into(median_split) // ***
    frame change median_split
    runby one_year_median_split, by(fyear)
    frame change default
    frlink m:1 stock_id fyear, frame(median_split stock_id fyear) // ***
    frget june_mcap_group, from(median_split)
    frame drop median_split
    drop median_split
    
    //  NOW SPLIT AT 30TH AND 70TH PERCENTILES OF idiovol
    capture program drop one_year_three_groups
    program define one_year_three_groups
        if _N > = 3 {
            _pctile idiovol, percentiles(33.33 66.67)
            gen cut = `r(r1)' in 1
            replace cut = `r(r2)' in 2
            xtile march_idiovol_group = idiovol, cutpoints(cut)
        }
        else {
            gen march_idiovol_group = .
        }
        exit
    end
    frame put stock_id fyear idiovol if representative & !missing(idiovol), into(three_groups) // ***
    frame change three_groups
    runby one_year_three_groups, by(fyear) verbose
    frame change default
    frlink m:1 stock_id fyear, frame(three_groups stock_id fyear) // ***
    frget march_idiovol_group, from(three_groups)
    frame drop three_groups
    drop three_groups
    
    capture program drop one_weighted_return
    program define one_weighted_return
        if !missing(june_mcap_group, march_idiovol_group) {
            egen numerator = total(mcap*rt)
            egen denominator = total(mcap)
            gen vw_mean_rt = numerator/denominator
        }
        exit
    end
    drop if missing(june_mcap_group, march_idiovol_group)
    runby one_weighted_return, by(mdate june_mcap_group march_idiovol_group)
    
    collapse (first) vw_mean_rt, by(mdate june_mcap_group march_idiovol_group)
    drop if missing(vw_mean_rt)
    keep mdate june_mcap_group march_idiovol_group vw_mean_rt
    
    isid june_mcap_group march_idiovol_group mdate, sort
    by mdate june_mcap_group, sort: egen temp = mean(vw_mean_rt)
    by mdate (june_mcap_group), sort: gen SMB = temp[1] - temp[_N]
    drop temp
    
    by mdate march_idiovol_group, sort: egen temp = mean(vw_mean_rt)
    by mdate (march_idiovol_group): gen LMH = temp[1] - temp[_N]
    drop temp
    
    //  AND IF YOU WANT TO REDUCE TO ONE OBSERVATION PER MONTH
    label define june_mcap_group 1 "S" 2 "B"
    label define march_idiovol_group 1 "L" 2 "M" 3 "H"
    label values june_mcap_group june_mcap_group
    label values march_idiovol_group march_idiovol_group
    decode june_mcap_group, gen (mcap_group)
    decode march_idiovol_group, gen(idiovol_group)
    drop june_mcap_group march_idiovol_group
    egen groups = concat(mcap_group idiovol_group)
    keep mdate groups SMB LMH vw_mean_rt
    rename vw_mean_rt =_
    reshape wide vw_mean_rt_, i(mdate) j(groups) string
    
    gen HML = (vw_mean_rt_SH + vw_mean_rt_BH)/2 - (vw_mean_rt_SL + vw_mean_rt_BL)/2
    Last edited by Sartaj Hussain; 30 Dec 2021, 13:07.

  • #2
    It is unclear whether you want to generate 5 quintiles of mcap and, irrespective of the mcap quintile, also calculate 5 quintiles of idiovol on all of the observations in the year, or if you want five quintiles of idiovol to be created within each mcap quintile. Either approach leads to an (up to) 5x5 classification, but in one the quintiles of idiovol are the same in all quintiles of mcap, whereas in the second approach the quintiles of idiovol differ among the mcap quintiles.

    Also, does "size" mean mcap?

    Comment


    • #3
      The second sort is basically independently of first sort. And not within each mcap quintile. Therefore, the intersection of two independent sorts should lead to 25 portfolios or groups. Please treat size as mcap
      Last edited by Sartaj Hussain; 30 Dec 2021, 13:48.

      Comment


      • #4
        So this can be condensed and simplified to:
        Code:
        gen moy = month(dofm(mdate))
        gen year = year(dofm(mdate))
        //  CREATE A "FISCAL YEAR" RUNNING FROM JULY THROUGH SUBSEQUENT JUNE
        gen fyear = cond(moy > 6, year, year-1)
        frame put stock_id fyear mcap idiovol if moy == 6, into(mcap_idiovol_work)
        frame change mcap_idiovol_work
        collapse (count) n_mcap = mcap n_idiovol = idiovol (firstnm) mcap idiovol, by(stock_id fyear)
        assert n_mcap <= 1 & n_idiovol <= 1 // VERIFY UNIQUE VALUE OF MCAP AND idiovol
        replace fyear = fyear + 1 // CHANGE THE FYEAR TO WHICH THEY WILL APPLY
        frame change default
        rename (mcap idiovol) orig=
        frlink m:1 stock_id fyear, frame(mcap_idiovol_work)
        frget mcap idiovol, from(mcap_idiovol_work)
        frame drop mcap_idiovol_work
        drop mcap_idiovol_work
        egen byte representative = tag(stock_id fyear)
        tab representative
        
        //  QUINTILES BASED ON JUNE VALUE OF mcap AND idiovol
        capture program drop double_quintiles
        program define double_quintiles
            xtile mcap_group = mcap, nq(5)
            xtile idiovol_group = idiovol, nq(5)
            exit
        end
        
        frame put stock_id fyear mcap idiovol if representative, into(representatives)
        frame change representatives
        runby double_quintiles, by(fyear) verbose
        frame change default
        frlink m:1 stock_id fyear, frame(representatives stock_id fyear) // ***
        frget mcap_group idiovol_group, from(representatives)
        frame drop representatives
        drop representatives representative
        
        capture program drop one_weighted_return
        program define one_weighted_return
            if !missing(mcap_group, idiovol_group) {
                egen numerator = total(mcap*rt)
                egen denominator = total(mcap)
                gen vw_mean_rt = numerator/denominator
                egen unwtd_mean_rt = mean(rt)
            }
            exit
        end
        drop if missing(mcap_group, idiovol_group)
        runby one_weighted_return, by(mdate mcap_group idiovol_group)
        
        collapse (first) vw_mean_rt unwtd_mean_rt, by(mdate mcap_group idiovol_group)
        drop if missing(vw_mean_rt)
        keep mdate mcap_group idiovol_group *_mean_rt

        Comment


        • #5
          I run the code #4 on data file. However, one error is noticed. I paste the error report below:

          runby double_quintiles, by(fyear) verbose
          no observations

          --------------------------------------
          Number of by-groups = 2
          by-groups with errors = 1
          by-groups with no data = 0
          Observations processed = 1,036
          Observations saved = 518
          --------------------------------------

          Moreover, I need the observations in wide format by mdate.

          Comment


          • #6
            Please provide example data that exhibits the problem.

            I do have one hypothesis about what may be the source of the problem. The code uses a July-June fiscal year, and for the purposes of partitioning the data into the quantiles, it relies on the mcap and idiovol from the June immediately preceding the fiscal year. In the very first fiscal year in the data, there will be no such preceding June, and so the attempt to form quintiles will fail. If that is what's causing the problem, I can work around that in the code. But I need to see what you are actually experiencing to be sure that a) this is actually happening, and b) there isn't also something else going wrong.
            Last edited by Clyde Schechter; 30 Dec 2021, 21:07.

            Comment


            • #7
              Here is the example data.

              Code:
              * Example generated by -dataex-. For more info, type help dataex
              clear
              input int stock_id str56 stock float(date mdate rt mcap idiovol)
              1 "3M India Ltd."                   15127 497           .  428.19  .10065009
              1 "3M India Ltd."                   15157 498  -.14469875  366.23          .
              1 "3M India Ltd."                   15188 499  -.00645957  363.86  .06956539
              1 "3M India Ltd."                   15219 500   -.1764706  299.65    .088255
              1 "3M India Ltd."                   15249 501  .015037594  304.16  .07604478
              1 "3M India Ltd."                   15280 502   .08518519  330.07  .08619624
              1 "3M India Ltd."                   15310 503   -.0887372  300.78  .06342645
              1 "3M India Ltd."                   15341 504  -.02640445  292.84  .11689825
              1 "3M India Ltd."                   15372 505   .04250813  305.28  .14444776
              1 "3M India Ltd."                   15400 506   .14926204  350.85  .12306575
              1 "3M India Ltd."                   15431 507  .008990168     354  .07602096
              1 "3M India Ltd."                   15461 508  -.10039774  318.46  .09038305
              1 "3M India Ltd."                   15492 509  .008666365  321.22   .0916427
              2 "A B B India Ltd."                15127 497           . 1034.63  .06530816
              2 "A B B India Ltd."                15157 498  .008807095 1043.74  .05433929
              2 "A B B India Ltd."                15188 499   -.0930556  946.62  .05364652
              2 "A B B India Ltd."                15219 500  -.13563773  818.22  .11843422
              2 "A B B India Ltd."                15249 501 -.030118924  793.58    .046893
              2 "A B B India Ltd."                15280 502   .06915453  848.46  .10159888
              2 "A B B India Ltd."                15310 503 -.004149426  864.59   .0457102
              2 "A B B India Ltd."                15341 504    .0906863  942.99  .05675213
              2 "A B B India Ltd."                15372 505     .154382 1088.57  .13100874
              2 "A B B India Ltd."                15400 506   .03387194 1125.45   .1140816
              2 "A B B India Ltd."                15431 507  .002824284 1128.62  .09106217
              2 "A B B India Ltd."                15461 508  -.07641757 1042.38  .06690538
              2 "A B B India Ltd."                15492 509    .0927018 1139.01  .09048145
              3 "A C C Ltd."                      15127 497           . 2328.01   .0797946
              3 "A C C Ltd."                      15157 498   .01906163 2372.39  .09540155
              3 "A C C Ltd."                      15188 499  -.07949643 2183.79  .05714733
              3 "A C C Ltd."                      15219 500 -.026963634 2124.91  .13976797
              3 "A C C Ltd."                      15249 501  .069879495 2273.39   .1118523
              3 "A C C Ltd."                      15280 502   .28115615 2912.57   .1072322
              3 "A C C Ltd."                      15310 503  -.11045995 2591.13  .07732503
              3 "A C C Ltd."                      15341 504   .05401842 2731.58  .11700913
              3 "A C C Ltd."                      15372 505     .021875  2791.8  .11240999
              3 "A C C Ltd."                      15400 506  -.05840981 2628.73  .07147745
              3 "A C C Ltd."                      15431 507  -.02143555 2573.11  .04187184
              3 "A C C Ltd."                      15461 508  .003982782 2583.53  .07652828
              3 "A C C Ltd."                      15492 509   .05057847 2714.39   .0494189
              4 "A D C India Communications Ltd." 15127 497           .   58.65  .22523586
              4 "A D C India Communications Ltd." 15157 498  -.28196076   42.11  .13027842
              4 "A D C India Communications Ltd." 15188 499    .2113599   51.01  .18007316
              4 "A D C India Communications Ltd." 15219 500  -.29711455   35.86  .22130314
              4 "A D C India Communications Ltd." 15249 501 -.031430367   34.73  .12866698
              4 "A D C India Communications Ltd." 15280 502   .22052982   42.39  .14436947
              4 "A D C India Communications Ltd." 15310 503  -.05588716   40.02   .1278039
              4 "A D C India Communications Ltd." 15341 504  -.01724138   39.33  .09830305
              4 "A D C India Communications Ltd." 15372 505  -.03567255   37.93  .14645375
              4 "A D C India Communications Ltd." 15400 506 -.003638513   37.79  .08370786
              4 "A D C India Communications Ltd." 15431 507    .1905052   44.99  .23667724
              4 "A D C India Communications Ltd." 15461 508  -.10838452   40.11  .16488414
              4 "A D C India Communications Ltd." 15492 509 -.028096296   38.98   .0899244
              5 "A G C Networks Ltd."             15127 497           .  116.66  .10551737
              5 "A G C Networks Ltd."             15157 498  -.10980967  103.85  .15191686
              5 "A G C Networks Ltd."             15188 499 -.064418815   97.16  .10186497
              5 "A G C Networks Ltd."             15219 500   -.3108702   66.98  .13506944
              5 "A G C Networks Ltd."             15249 501   .14795916   76.87  .12192778
              5 "A G C Networks Ltd."             15280 502   .13518517   87.26  .06552172
              5 "A G C Networks Ltd."             15310 503    .1663948  101.78   .1620788
              5 "A G C Networks Ltd."             15341 504    .6041958  163.28   .1820102
              5 "A G C Networks Ltd."             15372 505   .15082827  187.91   .2737067
              5 "A G C Networks Ltd."             15400 506   .28606057  241.65  .13774931
              5 "A G C Networks Ltd."             15431 507   .08152694  261.36  .14321175
              5 "A G C Networks Ltd."             15461 508  -.10675384  233.46  .14417796
              5 "A G C Networks Ltd."             15492 509 -.000609793  233.32 .072601065
              6 "Aarti Industries Ltd."           15127 497           .   35.74          .
              6 "Aarti Industries Ltd."           15157 498  -.13281247   31.03          .
              6 "Aarti Industries Ltd."           15188 499    .2072072   37.48          .
              6 "Aarti Industries Ltd."           15219 500  .007462679   37.71          .
              6 "Aarti Industries Ltd."           15249 501   .09629629   41.14          .
              6 "Aarti Industries Ltd."           15280 502  -.00675675   41.03          .
              6 "Aarti Industries Ltd."           15310 503  -.04761908   38.93          .
              6 "Aarti Industries Ltd."           15341 504   .04285719   40.68          .
              6 "Aarti Industries Ltd."           15372 505    .1712329   49.75 .069698885
              6 "Aarti Industries Ltd."           15400 506  .017543843   50.66  .09248569
              6 "Aarti Industries Ltd."           15431 507    .2298851   62.37  .13722476
              6 "Aarti Industries Ltd."           15461 508   .11214953   69.17  .14189382
              6 "Aarti Industries Ltd."           15492 509   .15546213   80.09  .07460695
              7 "Aban Offshore Ltd."              15127 497           .   20.44  .12911019
              7 "Aban Offshore Ltd."              15157 498    .4193548   29.01  .19600622
              7 "Aban Offshore Ltd."              15188 499    -.004329   28.88  .09510764
              7 "Aban Offshore Ltd."              15219 500  -.23804344   22.01   .0899549
              7 "Aban Offshore Ltd."              15249 501   .06419398   23.42          .
              7 "Aban Offshore Ltd."              15280 502  .036193028   24.27   .1055649
              7 "Aban Offshore Ltd."              15310 503 -.029754207   23.55          .
              7 "Aban Offshore Ltd."              15341 504  -.04000003    22.6          .
              7 "Aban Offshore Ltd."              15372 505   .11111114   25.12  .24280624
              7 "Aban Offshore Ltd."              15400 506      .75375   44.05          .
              7 "Aban Offshore Ltd."              15431 507 -.036350626   42.44  .17515473
              7 "Aban Offshore Ltd."              15461 508   .16863903   58.28  .21415813
              7 "Aban Offshore Ltd."              15492 509    .3487341   78.61  .16154057
              8 "Abbott India Ltd."               15127 497           .  479.92 .036127977
              8 "Abbott India Ltd."               15157 498  -.09181438  435.86  .07008448
              8 "Abbott India Ltd."               15188 499   .03865462  452.71  .07183885
              8 "Abbott India Ltd."               15219 500  -.12685636  395.28  .08310906
              8 "Abbott India Ltd."               15249 501   .00573768  397.55  .04329815
              8 "Abbott India Ltd."               15280 502   .05175229  418.12  .07003711
              8 "Abbott India Ltd."               15310 503   -.0803952  384.51 .031918976
              8 "Abbott India Ltd."               15341 504   .03897198  399.49  .05026837
              8 "Abbott India Ltd."               15372 505    .2489862  498.96  .11764716
              end
              format %td date
              format %tm mdate

              Comment


              • #8
                The code uses a July-June fiscal year, and for the purposes of partitioning the data into the quantiles, it relies on the mcap and idiovol from the June immediately preceding the fiscal year. In the very first fiscal year in the data, there will be no such preceding June, and so the attempt to form quintiles will fail.
                To this, i want to say that for a given fiscal year say 2001-02 in present case, it should use same year June numbers and not preceding fiscal year numbers for partitioning. The general idea is portfolios are to be made with December t-1 month values for the year t. Here we use a different convention to define year and that is period from July to June. Given that, June value of mcap and idiovol are duly provided in the data set.

                Comment


                • #9
                  My theory is correct. If you remove the line that says -replace fyear = fyear + 1 // CHANGE THE FYEAR TO WHICH THEY WILL APPLY- from the code, that now causes the portfolios to be partitioned based on the current fiscal year's June values, and that eliminates the error you were getting before. And if I understand #8 correctly, you are telling me that the current fiscal year's June values are what you wanted in the first place.

                  Comment


                  • #10
                    Yes. That is how it should work using current fiscal years june values. The fundamental thing is partitioning is to be done once a year. But below listed things need explanation:

                    1. If the portfolios (groups for mcap weighted return) are to be weighted each month from July onwards using month(t-1) mcap values, then what is to be given in code?

                    2. Instead of 1 above, if we want portfolios to be weighted each month using current fiscal year june month mcap values, then what change we have to bring in code?

                    Finally, I need the observations in wide format by mdate. Hope things are pretty clear.

                    Comment


                    • #11
                      For my query in #10(1) and also to get observations in wide format by mdate, I have incorporated changes in the code. I reproduce new code below. Kindly verify if it is rightly modified.

                      But one thing needs specific attention here and that is: Does the yearly sorts (partitions) happen using begin year(t-1) June month values of mcap and idiovol, i.e June 2001 values in present case? It should not be year(t) June value (i.e. June 2002). Remember there is data from June 2001 to June 2002 (13 months). I am asking this because i replaced idiovol values for all other months than June (t-1, or June 2001) with missing value. Then ran the code but there are no generations rather blank sheet. So, there is a reason to suspect. But i think there must some more change to be brought in the code and that is what i can't. I request you for the same.

                      Moreover, the part of the query #10(2) is still not resolved. Please suggest for that also.

                      Code:
                      gen moy = month(dofm(mdate))
                      gen year = year(dofm(mdate))
                      //  CREATE A "FISCAL YEAR" RUNNING FROM JULY THROUGH SUBSEQUENT JUNE
                      gen fyear = cond(moy > 6, year, year-1)
                      frame put stock_id fyear mcap idiovol if moy == 6, into(mcap_idiovol_work)
                      frame change mcap_idiovol_work
                      collapse (count) n_mcap = mcap n_idiovol = idiovol (firstnm) mcap idiovol, by(stock_id fyear)
                      assert n_mcap <= 1 & n_idiovol <= 1 // VERIFY UNIQUE VALUE OF MCAP AND idiovol
                      //replace fyear = fyear + 1 // CHANGE THE FYEAR TO WHICH THEY WILL APPLY
                      frame change default
                      rename (mcap idiovol) orig=
                      frlink m:1 stock_id fyear, frame(mcap_idiovol_work)
                      frget mcap idiovol, from(mcap_idiovol_work)
                      frame drop mcap_idiovol_work
                      drop mcap_idiovol_work
                      egen byte representative = tag(stock_id fyear)
                      tab representative
                      
                      //  QUINTILES BASED ON JUNE VALUE OF mcap AND idiovol
                      capture program drop double_quintiles
                      program define double_quintiles
                          xtile mcap_group = mcap, nq(5)
                          xtile idiovol_group = idiovol, nq(5)
                          exit
                      end
                      
                      frame put stock_id fyear mcap idiovol if representative, into(representatives)
                      frame change representatives
                      runby double_quintiles, by(fyear) verbose
                      frame change default
                      frlink m:1 stock_id fyear, frame(representatives stock_id fyear) // ***
                      frget mcap_group idiovol_group, from(representatives)
                      frame drop representatives
                      drop representatives representative
                      
                      capture program drop one_weighted_return
                      program define one_weighted_return
                          if !missing(mcap_group, idiovol_group) {
                              egen numerator = total(lagged_mcap*rt)
                              egen denominator = total(lagged_mcap)
                              gen vw_mean_rt = numerator/denominator
                              egen unwtd_mean_rt = mean(rt)
                          }
                          exit
                      end
                      
                      xtset stock_id mdate
                      gen lagged_mcap = L1.mcap
                      drop if missing(mcap_group, idiovol_group)
                      runby one_weighted_return, by(mdate mcap_group idiovol_group)
                      
                      collapse (first) vw_mean_rt unwtd_mean_rt, by(mdate mcap_group idiovol_group)
                      drop if missing(vw_mean_rt)
                      keep mdate mcap_group idiovol_group *_mean_rt
                      
                      gen str32 group = "q" + string(mcap_group) +"_idiovol_q" +string(idiovol_group) + "_"
                      drop *_group
                      
                      reshape wide vw_mean_@rt unwtd_mean_@rt, i(mdate) j(group) string
                      Last edited by Sartaj Hussain; 31 Dec 2021, 05:17.

                      Comment


                      • #12
                        I think we need to be a little more clear about what is wanted, as I don't think I understand it now.

                        1. Consider the fiscal year that goes from July 2002 through June 2003. Should the quintiles be based on mcap and idiovol in June 2002, or in June 2003?

                        2. For 10(#1), do I understand correctly that, for example, for the April 2003 weighted return, the weight should be the mcap from March 2003?

                        3. For 10(#2), do I understand correctly that, for example, for the April 2003 weighted return, the weight should be the mcap from June 2003?

                        That said, your additions to the code starting with -gen str32 group = "q" + ... - do correctly convert the data to the wide layout you want.

                        Comment


                        • #13
                          I clarify as below:

                          1. June 2002.
                          2. Correct.
                          3. No, it should be March 2003.

                          The difference between #1 and #2 is that #1 involves weighting repeatedly every month with lagged mcap values. For example, For July 2002 month return - June 2002 month mcap values, for August 2002 month - July 2002 month mcap values, for Sep 2002 month - August 2002 month mcap values and so on till June 2003 month until process is over.

                          However, in case of #2, weighting of each month return will only use June 2002 month mcap values. No previous lag values of mcap as in case of #1. So in this case For July 2002 month return - June 2002 month mcap values, for August 2002 month - June 2002 month mcap values, for Sep 2002 month - June 2002 month mcap values and so on till June 2003 month until process is over.

                          Hope i made it amply clear!

                          Comment


                          • #14
                            I have made some modifications to what you showed so that the quintiles will be based on the June immediately preceding the start of a July-June fiscal year as per your response in #13. There were also some errors in the way you implemented weighting the return by lagged mcap. With the example data, they would still produce correct results, but they could fail in the real data under some other conditions not instantiated in the example data.

                            Because the code now looks to the June immediately preceding the start of the fiscal year for reference mcap and idiovol to make quintiles, there may be no available data for the very first fiscal year in which they appear. I have modified the code so that this will not produce error messages.

                            Code:
                            gen moy = month(dofm(mdate))
                            gen year = year(dofm(mdate))
                            //  CREATE A "FISCAL YEAR" RUNNING FROM JULY THROUGH SUBSEQUENT JUNE
                            gen fyear = cond(moy > 6, year, year-1)
                            frame put stock_id fyear mcap idiovol if moy == 6, into(mcap_idiovol_work)
                            frame change mcap_idiovol_work
                            collapse (count) n_mcap = mcap n_idiovol = idiovol (firstnm) mcap idiovol, by(stock_id fyear)
                            assert n_mcap <= 1 & n_idiovol <= 1 // VERIFY UNIQUE VALUE OF MCAP AND idiovol
                            replace fyear = fyear + 1 // CHANGE THE FYEAR TO WHICH THEY WILL APPLY
                            rename (mcap idiovol) prior_june_=
                            frame change default
                            
                            frlink m:1 stock_id fyear, frame(mcap_idiovol_work)
                            frget prior_june_*, from(mcap_idiovol_work)
                            frame drop mcap_idiovol_work
                            drop mcap_idiovol_work
                            egen byte representative = tag(stock_id fyear)
                            tab representative
                            
                            //  QUINTILES BASED ON PREVIOUS FY JUNE VALUE OF mcap AND idiovol
                            capture program drop double_quintiles
                            program define double_quintiles
                                capture assert missing(prior_june_mcap)
                                if `c(rc)' {
                                    xtile mcap_group = prior_june_mcap, nq(5)
                                }
                                capture assert missing(prior_june_idiovol)
                                if `c(rc)' {
                                    xtile idiovol_group = prior_june_idiovol, nq(5)
                                }
                                exit
                            end
                            
                            frame put stock_id fyear prior_june_mcap prior_june_idiovol if representative, into(representatives)
                            frame change representatives
                            runby double_quintiles, by(fyear) verbose
                            frame change default
                            frlink m:1 stock_id fyear, frame(representatives stock_id fyear) // ***
                            frget mcap_group idiovol_group, from(representatives)
                            frame drop representatives
                            drop representatives representative
                            
                            capture program drop one_weighted_return
                            program define one_weighted_return
                                    egen numerator = total(lagged_mcap*rt)
                                    egen denominator = total(lagged_mcap)
                                    gen vw_mean_rt = numerator/denominator
                                    egen unwtd_mean_rt = mean(rt)
                                exit
                            end
                            
                            xtset stock_id mdate
                            gen lagged_mcap = L1.mcap
                            drop if missing(mcap_group, idiovol_group)
                            runby one_weighted_return, by(mdate mcap_group idiovol_group)
                            
                            collapse (first) vw_mean_rt unwtd_mean_rt, by(mdate mcap_group idiovol_group)
                            drop if missing(vw_mean_rt)
                            keep mdate mcap_group idiovol_group *_mean_rt
                            
                            gen str32 group = "q" + string(mcap_group) +"_idiovol_q" +string(idiovol_group) + "_"
                            drop *_group
                            
                            reshape wide vw_mean_@rt unwtd_mean_@rt, i(mdate) j(group) string
                            For #10(2.) you can use the same code, except you have to change program one_weighted_return to:
                            Code:
                            capture program drop one_weighted_return
                            program define one_weighted_return
                                    egen numerator = total(prior_june_mcap*rt)
                                    egen denominator = total(prior_june_mcap)
                                    gen vw_mean_rt = numerator/denominator
                                    egen unwtd_mean_rt = mean(rt)
                                exit
                            end
                            I think this will wrap it up. Happy New Year.


                            Comment


                            • #15
                              For #10(2), these lines will also be discarded?

                              Code:
                               xtset stock_id mdate gen lagged_mcap = L1.mcap

                              Comment

                              Working...
                              X