Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lookahead bias in AnnouncementReturn #158

Closed
chenandrewy opened this issue Sep 18, 2024 · 3 comments
Closed

Lookahead bias in AnnouncementReturn #158

chenandrewy opened this issue Sep 18, 2024 · 3 comments
Labels
bug Something isn't working

Comments

@chenandrewy
Copy link
Collaborator

Many thanks to Ming Zheng of University of Gothenburg for catching this bug. He writes:

I am writing regarding a potential error in your code for calculating returns from sorting on firm-level announcement returns. While the code for the signal is right, it does use information in the following month (if the announcement date is at the month end). As a result, doing monthly portfolio sorts based on this signal will lead to very high returns. (we have searched over your GitHub page and we can only find a do file: "ZZ2_AnnouncementReturn.do", so not sure that is the right one you use to generate the announcement return factor)

We have this doubt because our recent paper "Analysts Are Good At Ranking Stocks" has compared our analyst-based strategy with all factors in your factor zoo. The long-short portfolio by sorting on announcement returns gives a super high return and Sharpe ratio that we cannot beat, and it is probably the best-performing factor in the zoo. So we just have some doubt in it. Thanks!

There is indeed a nontrivial lookahead bias in ZZ2_AnnouncementReturn.do, unfortunately. The error is in these lines:
image

Line 49 means that we use data 2 days after the announcement date. Tom finds

If I replace line 55 with
gcollapse (sum) AnnouncementReturn (firstnm) AnnTime (min) mintime = time_d (max) maxtime = time_d, by(permno time_ann_d)
and then
br if mofd(maxtime) > mofd(mintime)
I get 120k out of 950k obs that cross the month
FWIW, I think the fix is (probably) to increase time_avail_m by one month in line 56 if maxtime > mintime (or just use gen time_avail_m = mofd(maxtime) in line 56 directly).

Given that this is a clear and lookahead bias that occurs for about 10% of observations I think we should patch this soon and create a new data release.

@chenandrewy chenandrewy added the bug Something isn't working label Sep 18, 2024
@chenandrewy
Copy link
Collaborator Author

Tom fixed the bug here: f5cf185
I added copious comments here: 2299edb

@chenandrewy
Copy link
Collaborator Author

I ran ZZ2_AnnouncementReturn.do , added it to the existing 2024.08 release signals data, and ran the portfolios code.

The patch had, in my view, surprisingly small effects. I mean, the revisions in the post-pub returns are non-negligible, about 20 bps per month. But post-pub this guy still has 85 bps per month returns. I did not check the value-weighted or other implementations.

2024.10 version:

signalname before insamp between postpub last5years 2023
AnnouncementReturn 1.05 1.15 1.29 0.85 0.39 0.65
AssetGrowth 0.20 1.50 -0.42 0.74 1.11 -0.45

2024.08 version:

signalname before insamp between postpub last5years 2023
AnnouncementReturn 0.80 1.20 1.41 1.03 0.58 0.86
AssetGrowth 0.20 1.50 -0.42 0.74 1.11 -0.45

Will post the data on the website when Tom is available, should be early October.

@chenandrewy
Copy link
Collaborator Author

Data is posted and the website (https://www.openassetpricing.com/data/) is updated. Some more details on the patch are here: https://drive.google.com/drive/folders/1SSoHGbwgyhRwUCzLE0YWvUlS0DjLCd4k.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

1 participant