“Earnings season” is the time when most companies report their quarterly and annual earnings. It can be quite intense and move the market or at least individual stocks, in case they beat or miss the expected earnings numbers. So as an investor you sure want to know when the companies you care about report their earnings.

But when is this “season” actually? Okay, let’s find out…

1. Read filing index

So let’s assume you have downloaded the filing index files for the full last year from the SEC. (See here how to do it.) And saved these files for Q3, Q4, Q1 and Q2 like this:

  • master_2016_Q3.idx
  • master_2016_Q4.idx
  • master_2017_Q1.idx
  • master_2017_Q2.idx

Now we use this little bit of Javascript to read these filing index files into an array of objects:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
let fs = require('fs');
let filings = [];
const readFilingIndex = (filename) =>
fs.readFileSync(filename,'utf8')
.split("\n") //lines
.slice(11) //remove 11 header lines
.slice(0, -1) //remove last line (empty)
.map((filing) => { //convert filing index into array of objects:
let fields = filing.split('|');
//CIK|Company Name|Form Type|Date Filed|Filename
return {
CIK: fields[0],
CompanyName: fields[1],
FormType: fields[2],
DateFiled: fields[3],
Filename: fields[4]
};
});
filings = filings.concat(readFilingIndex('./master_2016_Q3.idx'));
filings = filings.concat(readFilingIndex('./master_2016_Q4.idx'));
filings = filings.concat(readFilingIndex('./master_2017_Q1.idx'));
filings = filings.concat(readFilingIndex('./master_2017_Q2.idx'));

2. Filter quarterly and annual reports

Based on our definition of earnings season we are only interested in quarterly and annual reports. So we can use this neat one-liner to filter only these filing types:

1
2
//filter quarterly and annual reports:
filings = filings.filter(filing => filing.FormType === "10-Q" || filing.FormType === "10-K");

This nicely shows the beauty of functional programming and how concise things can be with arrow-functions.

3. Calculate weekly and monthly distributions and display results

Now that we have focused on all quarterly and annual reports for one full year we can calculate the weekly and monthly distribution (frequency) of these filing types.

To handle the conversion of dates I use the powerful moment.js library.

ascii-histogram comes in handy is an easy but useful way to display the data as a histogram:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
let moment = require('moment');
let hist = require('ascii-histogram');
let weeklyDistribution = {};
let monthlyDistribution = {};
filings.forEach((filing) => {
let filingDate = moment(filing.DateFiled, "YYYY-MM-DD");
let week = filingDate.format("w");
let month = filingDate.format("M");
weeklyDistribution[week] = weeklyDistribution[week] || 0;
monthlyDistribution[month] = monthlyDistribution[month] || 0;
weeklyDistribution[week]++;
monthlyDistribution[month]++;
});
console.log(hist(weeklyDistribution));
console.log(hist(monthlyDistribution));

4. Results and interpretation

Here are the results:

Weekly distribution:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
1 | ## | 63
2 | #### | 140
3 | ### | 114
4 | ### | 116
5 | ###### | 219
6 | ############# | 472
7 | ################# | 605
8 | ######################### | 889
9 | ############################# | 1065
10 | ################ | 583
11 | ##################### | 765
12 | ################# | 626
13 | ################################ | 1162
14 | #### | 149
15 | ####### | 267
16 | ######### | 340
17 | ############### | 561
18 | ############################################ | 1589
19 | ############################################################ | 2173
20 | ########################### | 971
21 | ########## | 350
22 | ### | 102
23 | ###### | 201
24 | ##### | 176
25 | ### | 102
26 | #### | 148
27 | | 17
28 | ## | 69
29 | ##### | 167
30 | #### | 158
31 | ################### | 701
32 | ################################################## | 1796
33 | ###################################################### | 1948
34 | ########################## | 952
35 | ######### | 312
36 | ##### | 171
37 | ##### | 175
38 | #### | 160
39 | ### | 98
40 | #### | 146
41 | ### | 92
42 | #### | 147
43 | #### | 149
44 | ################# | 610
45 | ############################################ | 1598
46 | ################################################### | 1834
47 | ##################################### | 1333
48 | ######### | 322
49 | ### | 114
50 | ###### | 200
51 | ###### | 219
52 | #### | 129
53 | # | 51

Monthly distribution:

1
2
3
4
5
6
7
8
9
10
11
12
1 | ###### | 486
2 | ############################### | 2659
3 | ########################################### | 3674
4 | ############### | 1317
5 | ############################################################ | 5125
6 | ######## | 687
7 | ############# | 1112
8 | ############################################################ | 5111
9 | ######## | 647
10 | ############# | 1120
11 | ########################################################### | 5033
12 | ######## | 645

Interpretation:

Very roughly one can say the earnings season is in the second month of each quarter (February, May, August and November). The weekly distribution also shows that “the season” starts slowly in the first week, then peaks in the 2nd and 3rd week and slows down in the 4th week of the month.

So why is it like that? Well, the companies are required to post their quarterly reports between 40 and 45 days after the end of the quarter. More detailed explanations can be found here.

If we look closely, we can also see that in the first quarter of the year the distribution looks a little bit different. The “earnings season” in Q1 starts later and extends longer into the quarter. This is because most companies finish their fiscal year in Q4 and are therefore reporting their annual report in Q1, which has slightly different rules than the quarterly reports (annual reports are due 60 to 90 days after the end of the year). This can be seen better when we filter only for annual reports:

Only annual reports:

1
2
3
4
5
6
7
8
9
10
11
12
1 | ## | 133
2 | ################################ | 1802
3 | ############################################################ | 3340
4 | ######### | 520
5 | ### | 186
6 | #### | 239
7 | ### | 143
8 | #### | 198
9 | #### | 233
10 | ## | 138
11 | ### | 194
12 | #### | 216

Interestingly there are quite a number of annual reports also filed during the rest of the year.