On this page:
- Trading Days per Year in US Markets
- Trading Days per Year in Other Markets
- Calculating Number of Trading Days from Historical Data
- Avoid These Common Mistakes
- Number of Trading Days per Year in SQL
- Average Trading Days per Year in SQL
- Trading Day Counts by Year in SQL
- Number of Trading Days per Year in Python
Trading Days per Year in US Markets
How many trading days per year are there in the US stock and option markets?
The short answer is 252.
To be precise, the average number of trading days per year from 1990 to 2020 has been 251.90. But we usually want to use an integer, so 252 is best.
1990 253 1991 252 1992 254 1993 253 1994 252 1995 252 1996 254 1997 251 1998 252 1999 252 2000 252 2001 248 (closed 4 days extra due to 9/11) 2002 252 2003 252 2004 252 2005 252 2006 251 2007 251 2008 253 2009 252 2010 252 2011 252 2012 250 (closed 2 days extra due to Hurricane Sandy) 2013 252 2014 252 2015 252 2016 252 2017 251 2018 251 2019 252 2020 253
Trading Days per Year in Other Markets
The number of trading days can be quite different in other markets and other countries.
The US has the advantage that most holidays, except major ones like July 4 or Christmas, fall on the same day of week (usually Monday) every year. This makes the number of trading days more stable across years.
Some countries don’t do this and, as a result, the number of trading days can fluctuate a bit more.
Calculating Number of Trading Days from Historical Data
You can easily calculate the number of trading days per year for your market, using daily historical data of some security or index which you are sure to have been trading every trading day in the period you want to use as reference.
A local broad market stock index is the best candidate, as that is certainly calculated every day the exchange is open. In the US, that would be an index like S&P500 or DJIA, or the VIX if you are interested in options. Another advantage of these indices is that their daily historical data is widely available (from the exchange or index provider directly or, for example, from Yahoo Finance).
Once you have the data, you only need to count the number of days for your period (number of rows with daily data) and divide the sum by the number of years it covers.
Avoid These Common Mistakes
1) Make sure your data is complete without gaps.
2) Make sure there are no duplicates. These may result from a technical error on the data provider’s end (writing a day’s data twice), or there can be various notes in some rows. In other words, clean the data before use.
3) Make sure the first and last year you include in your calculation have data from the very start of the year (typically the first trading day is 2 or 3 or 4 of January) to the very end (end of December). Don’t use the last year you have, which is most likely incomplete and would distort the result downwards.
4) Count the number of days using a function like
COUNT in Excel. Do not subtract the first date from the last date, as that would defeat the purpose of the calculation – your number would include all calendar days, not just trading days.
5) When counting the number of years (to divide the number of days by it), do not just subtract the last year from the first year. For example, if you are using years 2016, 2017, 2018, 2019, 2020, you have 5 years. 2020 minus 2016 is 4. The correct formula is last year minus first year plus 1, or in our case 2020 – 2016 + 1 = 5 years. It is obvious with small number of years, but when you have 38 years, this error is easy to overlook.
If you know Pivot Tables, use them. They make this task easier than plain Excel, and less prone to errors.
Number of Trading Days per Year in SQL
It is even better to have historical data stored in a database, which makes cleaning data and avoiding duplicates easier, and calculate average number of trading days per year directly in SQL.
Average Trading Days per Year in SQL
SELECT COUNT(td) / (YEAR(MAX(td)) - YEAR(MIN(td)) + 1) FROM ind_d WHERE symbol = '$VIX' AND td < '2021-01-01' ;
The above query follows the logic explained earlier: count rows and divide by number of years, using the formula last year minus first year plus 1. The result in this case (using VIX index data 1990-2020) is 251.9032.
Alternatively, you can calculate the number of years using
DISTINCT; this query gives the same result as the previous one:
SELECT COUNT(td) / COUNT(DISTINCT YEAR(td)) FROM ind_d WHERE symbol = '$VIX' AND td < '2021-01-01' ;
td < '2021-01-01' condition is to exclude year 2021, if your database includes some data for 2021. Including an incomplete year at the end (or beginning) of data would bias the average downwards (error #3 in the above error list). In this case, I am sure the data starts on 2 January 1990, so I don’t need to include a similar condition for the first year (you may need to if your first year is incomplete).
Trading Day Counts by Year in SQL
To generate an overview of number of trading days in each year, like the table on the top of this page, you can use
GROUP BY to group the dates by year:
SELECT YEAR(td) AS yyyy, COUNT(td) AS trading_days FROM ind_d WHERE symbol = '$VIX' AND td < '2021-01-01' GROUP BY yyyy ORDER BY yyyy ASC;
You can also calculate the average number of trading days for the entire period by selecting
trading_days from the above select. This query will give the same result as before, 251.9032:
SELECT AVG(trading_days) FROM ( SELECT YEAR(td) AS yyyy, COUNT(td) AS trading_days FROM ind_d WHERE symbol = '$VIX' AND td < '2021-01-01' GROUP BY yyyy ORDER BY yyyy ASC ) AS years;
Note that in different database systems, some functions may have different names or not be available at all; these examples use MySQL/MariaDB.
If your database system doesn’t support these functions, you can export the data and use a programming language like Python to do the calculations.
Number of Trading Days per Year in Python
For example, in Python pandas you can generate a series of trading day counts by year (
dpy) and calculate the average like this:
# hp is pandas DataFrame with historical prices # where one row = one trading day # column 'td' contains dates; it is used to asign rows to individual years # column 'c' contains daily closing prices # It must be checked for incomplete years (not implemented here), # duplicate days and non-trading day rows (closing price isna) if hp['td'].value_counts().max() > 1: raise Exception("Duplicate td") if hp['c'].isna().any(): raise Exception("There are days with missing closing price") # Get years into column 'y' hp['td'] = pd.to_datetime(hp['td']) hp['y'] = hp['td'].dt.year # dpy is pandas Series with index = year and values = trading day counts dpy = hp['y'].value_counts().sort_index() # Alternatively: #dpy_alt = hp['c'].groupby(hp['td'].dt.year).count() # This is the average number of trading days per year dpy.mean()