NGVC announced their most recent earnings after markets closed on 5/6/2021 and promptly fell by 20% the next day. I was curious about how the market typically reacts to grocers reporting earnings that are less than the prior seasonally lagged quarter. Using data from Sharadar and obtained via Quandl, the steps to answer this question are:

Step 1: Pull the Tickers dataset conditional on the ticker == NGVC. This dataset has the four-digit SIC code along with other useful information.

Step 2: Filter this dataset based on the SIC Code== 5411 and Table == SF1.

Step 3: Initialize a Python list object, iterate through the tickers that meet the conditions in Step 2, and append each ticker to the list. [Note: these steps are not shown in the posted code. This post starts with Steps 6 and 7 as they are the most complicated.]

Step 4: Pull the Sharadar SF1 data, which contains financial statement variables, via feeding the list in Step 3 into the query and conditioning on the “ARQ” time dimension.

Step 5: Pull the Sharadar daily price data from the SEP table.

Step 6: Merge the earnings and accounting data in Step 4 with the stock price data in Step 5. This step requires consideration of firms reporting earnings on non-trading days (i.e., the earnings announcement date in the SF1 data does not exist in the SEP data since markets were closed on that day). My approach to this was to identify earnings announcement dates that were not connected to trading days, and then to “shift” these dates forward by one or two days and also backward by one or two days to see trading occurred on the shifted dates.

Step 7: Write a function that will take an input for the number of trading days around the earnings announcement to calculate the returns. Note that the day before the earnings announcement is used for the beginning price in the returns calculation. This accounts for firms issuing earnings during or after a given trading day.

The code contains notes about things that I looked into thinking they could have been driven from mistakes. For example, ACI had several years of financial statement data without any stock price data. My conclusion is that these were quarters before filed for their S1 and before trading occurred. A second firm, CBD, is an ADR and was excluded from the data query based on them having no time dimensions == “ARQ.” GO and FWMHQ had earnings filed on non-trading days, also likely due to IPO’s, but these were cases where “shifting” the announcement dates enabled the data to be merged together.

There is a ton of output in the Jupyter Notebook because I heavily used print statements in the loops to try and check for errors. Even though the output is…. voluminous… if you’re just getting started with Python and/or trying to figure out what is going on in the loops and functions I think this will help make things more clear.

The Python code and a Jupyter Notebook are here.