Unlocking the Potential of the Chicago Fed National Activity Index
Written on
Chapter 1: Introduction to the CFNAI
The Chicago Fed National Activity Index (CFNAI) is a remarkable yet underappreciated tool for predicting economic downturns. In this guide, we will learn how to implement it using Python.
Cordell Tanny boasts over 24 years of experience in the financial industry, with a focus on quantitative finance. He has previously served as a quantitative analyst and portfolio manager at a prominent Canadian financial institution, managing a $2 billion multi-asset retail investment program. Currently, he is the President and co-founder of Trend Prophets, a company specializing in quantitative finance and AI solutions. Additionally, he is the Managing Director of DigitalHub Insights, an educational platform aimed at integrating AI into investment management. Cordell earned his B.Sc. in Biology from McGill University, is a CFA Charterholder, a certified Financial Risk Manager, and holds the Financial Data Professional designation. For more information, visit trendprophets.com.
This article is part of a series that shares valuable tools and strategies employed by professional investment strategists. The Python code will be provided at the conclusion.
The Summary:
- The CFNAI is a highly effective indicator for forecasting recessions.
- By analyzing three key series, we can gain insights into the economic landscape.
Why is This Important?
- Portfolio managers and economists continuously seek innovative ways to identify economic turbulence. Since its introduction in 2001, the CFNAI has shown promise, demonstrating a strong predictive capability.
- By plotting the CFNAI, its three-month moving average (CFNAI-MA3), and its diffusion index (CFNAIDIFF), we can establish effective guidelines:
- A CFNAI-MA3 below -0.7 indicates significantly heightened recession risk.
- A CFNAI-MA3 of -1.5 typically signals a recession.
- A rebound above 0.2 suggests we may be emerging from a recession.
- Sustained growth above 1 might indicate economic overheating.
- A diffusion index below -0.35 is a warning sign.
The Broader Perspective
While the CFNAI isn't widely followed by many professionals, its monthly updates can be a valuable addition to your recession monitoring toolkit. While no single indicator can definitively predict a recession, the CFNAI, along with other key metrics, forms a robust analytical framework.
Now, let’s delve into the programming aspects. First, we will set up functions to retrieve historical recession data and incorporate them into our graphs.
Chapter 2: Coding the CFNAI
In the first video, "Plotting Multiple Stock Market Indicators on One Graph - Five Minute Python Scripts," we explore how to visualize multiple economic indicators on a single graph, enhancing our understanding of market trends.
To begin, we need to code functions for retrieving and plotting the CFNAI and its moving average. Below is the code that accomplishes this task:
import pandas as pd
import numpy as np
import pandas_datareader as pdr
import matplotlib.pyplot as plt
import seaborn as sns
from datetime import datetime
import calendar
import pandas_datareader.data as web
sns.set_theme()
def fetch_recession_periods(start_date, end_date):
"""
Retrieves the start and end dates of US recessions from FRED.
"""
usrec = web.DataReader("USREC", "fred", start_date, end_date)
recessions = {}
recession_num = 0
start = None
for i in range(len(usrec)):
if usrec.iloc[i, 0] == 1:
if start is None:
start = usrec.index[i]
start = datetime(start.year, start.month, calendar.monthrange(start.year, start.month)[1])
end = usrec.index[i]
end = datetime(end.year, end.month, calendar.monthrange(end.year, end.month)[1])
elif start is not None:
recession_num += 1
recessions[recession_num] = {'start': start.strftime('%Y-%m-%d'), 'end': end.strftime('%Y-%m-%d')}
start = None
if start is not None:
recession_num += 1
recessions[recession_num] = {'start': start.strftime('%Y-%m-%d'), 'end': end.strftime('%Y-%m-%d')}
return recessions
def add_recession_bands(ax, recessions, start_date, end_date):
"""
Adds shaded areas for recession periods on a plot.
"""
plot_start_date = pd.to_datetime(start_date)
plot_end_date = pd.to_datetime(end_date)
for rec_num, rec_dates in recessions.items():
rec_start_date = pd.to_datetime(rec_dates['start'])
rec_end_date = pd.to_datetime(rec_dates['end'])
if (rec_start_date <= plot_end_date) and (rec_end_date >= plot_start_date):
ax.axvspan(rec_start_date, rec_end_date, color="red", alpha=0.2)
In the next section, we will focus on plotting the CFNAI and its moving average.
Chapter 3: Analyzing the CFNAI
The second video, "Top Technical Analysis (TA) libraries in Python," reviews various Python libraries that can assist in technical analysis and data visualization, crucial for our tasks.
Continuing with our Python implementation, we will now define a function to fetch and visualize the CFNAI and its moving average:
def chicago_natl_activity_index(start_date, end_date, plot=False, save_fig=False):
"""
Fetches CFNAI data from FRED and optionally plots it.
"""
fred_ids = {
'Chicago Fed NAI': 'CFNAI',
'Chicago Fed NAI 3-Month MA': 'CFNAIMA3',
}
df_data = pdr.get_data_fred(list(fred_ids.values()), start=start_date, end=end_date)
if plot:
fig, ax = plt.subplots(figsize=(12, 6))
sns.lineplot(data=df_data, dashes=False, ax=ax, palette="viridis")
ax.set_title('Chicago Fed National Activity Index (CFNAI)')
ax.set_xlabel('Date')
ax.set_ylabel('Index Value')
ax.legend(frameon=False)
ax.axhline(y=-0.7, color='red', alpha=0.5)
ax.axhline(y=-1.5, color='red', alpha=0.3)
ax.axhline(y=0.2, color='green', alpha=0.3)
ax.axhline(y=1, color='red', alpha=0.3)
recessions = fetch_recession_periods('1960-01-01', end_date)
add_recession_bands(ax, recessions, start_date, end_date)
ax.set_ylim(-3, 3)
if save_fig:
plt.savefig(f'{end_date}_cf_nai.png', bbox_inches='tight', transparent=False)
plt.show()
else:
return df_data
start_date = '1970-01-01'
end_date = '2024-04-19'
chicago_natl_activity_index(start_date, end_date, plot=True, save_fig=False)
Figure 1: CFNAI and CFNAI-MA3. Source: FRED.
In this graph, we have included horizontal lines to indicate key levels. It is evident that nearly every time the MA3 dips below -0.7, a recession follows shortly after.
Chapter 4: The CFNAI Diffusion Index
Next, we will implement the CFNAI Diffusion Index, complete with recession bands and a threshold line at -0.35.
def cfnai_diffusion(start_date, end_date, plot=False, save_fig=False):
"""
Fetches CFNAIDIFF data from FRED and optionally plots it.
"""
fred_ids = {'Chicago Fed NAI Diffusion Index': 'CFNAIDIFF'}
df_data = pdr.get_data_fred(list(fred_ids.values()), start=start_date, end=end_date)
if plot:
fig, ax = plt.subplots(figsize=(12, 6))
sns.lineplot(data=df_data, dashes=False, ax=ax, palette=["blue"])
ax.set_title('Chicago Fed National Activity Diffusion Index (CFNAIDIFF)')
ax.set_xlabel('Date')
ax.set_ylabel('Index Value')
ax.axhline(y=-0.35, color='red', alpha=0.3)
ax.axhline(y=0, color='black', alpha=0.3)
recessions = fetch_recession_periods('1960-01-01', end_date)
add_recession_bands(ax, recessions, start_date, end_date)
if save_fig:
plt.savefig(f'{end_date}_cf_nai_diff.png', bbox_inches='tight', transparent=False)
plt.show()
else:
return df_data
cfnai_diffusion(start_date, end_date, plot=True, save_fig=False)
Figure 2: The CFNAI Diffusion Index. Source: FRED.
The CFNAI Diffusion Index is also effective for identifying recession timing, particularly when it falls below -0.35.
For additional insights, feel free to explore related resources.
Note: I enjoy sharing the wealth of knowledge I've gained throughout my career as a quant. Not every piece of content needs to be a complex deep learning model; sometimes, it’s the small, practical insights that can significantly enhance your investment strategy. If you appreciate this free code, consider subscribing to the Digital Hub newsletter at dh-insights.com. For a deeper dive into my work, check out Trend Prophets!
Cheers.