localコマンドで嵌まった点
ここで1点気をつけなければならないのが、localコマンドではif文が使えないということ。
たとえば、手順(3)において、イベント日前後5日のデータを取り出すには、データセットを、前後5日分にkeepした上で、
local return_m5 = var_return in 1 local return_m4 = var_return in 2 local return_m3 = var_return in 3 local return_m2 = var_return in 4 local return_m1 = var_return in 5 local return_ 0 = var_return in 6 ...
としなければいけません*1。ここでvar_returnは、その日(or 月)の収益率です。イメージとしては、1行目がイベント5日前、2行目がイベント4日前、、、6行目がイベント日の収益率です。
ただし、たとえば前後100日分をとるときや前後60ヶ月分をとるときなどは、すべての期間の収益率が存在しないときがあります。たとえば上の例で言えば、イベント前4日からの収益率しかないとすると、イベント日の収益率が5行目に来てしまします。
データがフルに存在しないとき
こういったときにイベント日からの距離を表す変数を作り、ifで条件付けができれば楽なのですが、不可能です。
解決の方法はいくつか存在します。ひとつの方法をここでは紹介します。使うのは、_N(_n)とset obsとsortです。
たとえば、上の例では、11(== 5 + 1 + 5)行ある場合は、問題ないのですが、それより少ないときに問題になります。ですので、
>|stata|local n_of_row = _N|
とすることで、現在シートに何行あるかを変数に詰め、その後に
if `n_of_row' != 11{ set obs 11 sort date } else{ }
といった感じで、条件分けをすればよいです。11行無いときの処理は、無理やり11行に行数を増やした上で並び替えています。この場合にはイベント日前の株価データが足らないと仮定しています。
dateを日付を表す変数だとすれば、新しく作成された行は欠損値となります。sortすると、欠損値が上にくるために、上の例では1行目に欠損値だけの行がくることになり、6行目に見事イベント日のデータが来るわけです。
ただし、11行無かったとしてもイベント前のデータは5日分存在するケースもあります。そのときに上の処理をすると、イベント日が6行目に来なくなります。
そのため、上の処理をするために、6行目がイベント日であるかをチェックする必要があります。
そのときは、
local row_no_in_1 = イベント日の何日前かを表す変数 in 6 if `row_no_in_1' == -5{ set obs 11 }
という条件式で6行目にイベント日が来ているかどうかをチェックする必要があります。これと上の処理を組み合わせれば、イベント日前後のデータが存在しないケースに関しては対処できるかと思われます。
まぁこういった例外処理にほとんど時間を費やしたわけでして。。あと、こういった例外処理が入り乱れているためにソースが公開できないのです。
おさらいですが、_Nはシートの行数を表すもので_nは特定の行が何行目かを返すものです。
他にいろいろな方法がありますが*2、まぁ一例として参考にしてください。
ながくなったので、matched企業の見つけ方は省略!大雑把に言うと、各企業のassetとイベント企業のassetの差の絶対値を取って、sortして一番上にある企業の企業コードを使って、上の同じ作業をすればok。
絶対値を取るのはabs()です。