Announcement

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

  • #16
    Yes, you can discard them if you wish. You can leave them in if you want, because they don't interfere with anything in 10(2), but they are not needed and can be removed.

    Comment


    • #17
      Thanks indeed!

      Well, do we need to introduce any changes in other code where bmr of march month and mcap of june month is to be used for grouping (partitioning). In that case also, we want that rt portfolio should be weighted using prior june month mcap values instead of lag values of mcap for each month. I reproduce code here for a cross-check please.

      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 bmr, into(mcap_bmr_work)
      frame change mcap_bmr_work
      collapse (count) n_mcap = mcap n_bmr = bmr (firstnm) mcap bmr, by(stock_id fyear)
      assert n_mcap <= 1 & n_bmr <= 1 // VERIFY UNIQUE VALUE OF MCAP AND BMR
      replace fyear = fyear + 1 // CHANGE THE FYEAR TO WHICH THEY WILL APPLY
      frame change default
      rename (mcap bmr) orig=
      frlink m:1 stock_id fyear, frame(mcap_bmr_work)
      frget mcap bmr, from(mcap_bmr_work)
      frame drop mcap_bmr_work
      drop mcap_bmr_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 bmr
      capture program drop one_year_three_groups
      program define one_year_three_groups
          if _N > = 3 {
              _pctile bmr, percentiles(30 70)
              gen cut = `r(r1)' in 1
              replace cut = `r(r2)' in 2
              xtile march_bmr_group = bmr, cutpoints(cut)
          }
          else {
              gen march_bmr_group = .
          }
          exit
      end
      frame put stock_id fyear bmr if representative & !missing(bmr), 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_bmr_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_bmr_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_bmr_group)
      runby one_weighted_return, by(mdate june_mcap_group march_bmr_group)
      
      collapse (first) vw_mean_rt, by(mdate june_mcap_group march_bmr_group)
      drop if missing(vw_mean_rt)
      keep mdate june_mcap_group march_bmr_group vw_mean_rt
      
      isid june_mcap_group march_bmr_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_bmr_group, sort: egen temp = mean(vw_mean_rt)
      by mdate (march_bmr_group): gen HML = 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_bmr_group 1 "L" 2 "M" 3 "H"
      label values june_mcap_group june_mcap_group
      label values march_bmr_group march_bmr_group
      decode june_mcap_group, gen (mcap_group)
      decode march_bmr_group, gen(bmr_group)
      drop june_mcap_group march_bmr_group
      egen groups = concat(mcap_group bmr_group)
      keep mdate groups SMB HML vw_mean_rt
      rename vw_mean_rt =_
      reshape wide vw_mean_rt_, i(mdate) j(groups) string
      
      gen HML_new = (vw_mean_rt_SH + vw_mean_rt_BH)/2 - (vw_mean_rt_SL + vw_mean_rt_BL)/2
      drop HML
      rename HML_new HML

      Comment


      • #18
        Yes, to use lagged (one month) mcap for the weighted return, make the changes shown in bold face:

        Code:
        capture program drop one_weighted_return
        program define one_weighted_return
            if !missing(june_mcap_group, march_bmr_group) {
                egen numerator = total(lagged_mcap*rt)
                egen denominator = total(lagged_mcap)
                gen vw_mean_rt = numerator/denominator
            }
            exit
        end
        drop if missing(june_mcap_group, march_bmr_group)
        xtset stock_id mdate
        gen lagged_mcap = L1.mcap
        runby one_weighted_return, by(mdate june_mcap_group march_bmr_group)

        Comment


        • #19
          No, you got wrong. I mean #2 scheme of weighting as explained in #10 and #13 of thread.

          Comment


          • #20
            Then the code in #17 needs no revisions. It already does that.

            Comment


            • #21
              I mention it again because like in #14, in #17 also mcap groups will be based on the June immediately preceding the start of a July-June fiscal year. While bmr groups will be based on March preceding the start of a July-June fiscal year. Just want to confirm if no revisions are needed for #17.

              Comment


              • #22
                The beginning part of the code in #17 assumes that the only values of mcap and bmr in the starting data come from June and March, respecively. It does not verify that assumption, but it does verify that only one month out of each fiscal year has a non-missing value for each of those, and uses that unique value for partitioning the data into the groups. We can make it more robust by adding the following bold-faced changes to the code:

                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 bmr, into(mcap_bmr_work)
                frame change mcap_bmr_work
                assert moy == 3 if !missing(bmr)
                assert moy == 6 if !missing(mcap)
                collapse (count) n_mcap = mcap n_bmr = bmr (firstnm) mcap bmr, by(stock_id fyear)
                assert n_mcap <= 1 & n_bmr <= 1 // VERIFY UNIQUE VALUE OF MCAP AND BMR
                replace fyear = fyear + 1 // CHANGE THE FYEAR TO WHICH THEY WILL APPLY
                frame change default
                rename (mcap bmr) orig=
                frlink m:1 stock_id fyear, frame(mcap_bmr_work)
                frget mcap bmr, from(mcap_bmr_work)
                frame drop mcap_bmr_work
                drop mcap_bmr_work
                egen byte representative = tag(stock_id fyear)
                Now the code will break if it is fed non-March values of bmr or non-June values of mcap.

                But I also recall that over the many iterations we have gone through, sometimes the data set contains monthly values of mcap in every month. This code (revised or otherwise) will not work with such data, nor with data that has more than one value of bmr per fiscal year. So if you are going to be using data sets that contain multiple values of mcap or bmr within a fiscal year, then it needs a different set of changes:

                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 bmr, into(mcap_bmr_work)
                frame change mcap_bmr_work
                replace mcap = . if moy != 6
                replace bmr = . if moy != 3
                collapse (count) n_mcap = mcap n_bmr = bmr (firstnm) mcap bmr, by(stock_id fyear)
                assert n_mcap <= 1 & n_bmr <= 1 // VERIFY UNIQUE VALUE OF MCAP AND BMR
                replace fyear = fyear + 1 // CHANGE THE FYEAR TO WHICH THEY WILL APPLY
                frame change default
                rename (mcap bmr) orig=
                frlink m:1 stock_id fyear, frame(mcap_bmr_work)
                frget mcap bmr, from(mcap_bmr_work)
                frame drop mcap_bmr_work
                drop mcap_bmr_work
                egen byte representative = tag(stock_id fyear)

                Comment


                • #23
                  When i run code in #22, following error is encountered for this line of code:
                  Code:
                  assert moy == 3 if !missing(bmr)
                  Error:
                  moy not found
                  r(111);

                  Comment


                  • #24
                    Change
                    Code:
                    frame put stock_id fyear mcap bmr, into(mcap_bmr_work)
                    to
                    Code:
                    frame put stock_id fyear mcap bmr moy, into(mcap_bmr_work)

                    Comment


                    • #25
                      Well, thanks, it works now. But one clarification, modifying the code #17 by #22(1) and #24 generates similar results to the basic code #17.
                      Last edited by Sartaj Hussain; 10 Jan 2022, 11:11.

                      Comment


                      • #26
                        Well, that's right. You said you wanted to be sure that the code used the mcap from the preceding June and the bmr from the preceding March. The code in #17 would do that, or not, depending on the particular data that was fed to it. The modifications in #22(1) and #24 do not modify what the code in #17 does: it just puts in a verification that the preceding June mcap and preceding March bmr are, indeed the ones being used. In other words, the modifications served only to assure that the data being provided were in accord with expectations. In effect, it just checked that the data the code is running on are consistent with the assumptions needed for the code in #17 to be correct.

                        Comment


                        • #27
                          Thats is fine. Thanks!

                          Comment

                          Working...
                          X