Analytics in Stock Markets Zoomcamp
📚

Analytics in Stock Markets Zoomcamp

Created
Sep 1, 2025 10:05 PM
Tags
AI summary

The content covers a comprehensive analysis of stock market data, focusing on setting a 70-year historical date range for economic analysis, retrieving U.S. Real Potential GDP data from FRED, and calculating Year-over-Year and Quarter-over-Quarter growth rates. It includes detailed Python code examples for data retrieval, growth rate calculations, and visualizations using dual y-axis plots to display GDP values and growth rates effectively.

Assignee
Due
Status
Not started
image

Week 1: Introduction and Data Sources

Setting the Date

GDP

The next stage is to collect data for Real potential GDP

gdppot = pdr.DataReader("GDPPOT", "fred", start=start)
gdppot['gdppot_us_yoy'] = gdppot.GDPPOT/gdppot.GDPPOT.shift(4)-1
gdppot['gdppot_us_qoq'] = gdppot.GDPPOT/gdppot.GDPPOT.shift(1)-1
gdppot.tail(15)

Objective

To retrieve and analyze U.S. Real Potential Gross Domestic Product (GDPPOT) from the Federal Reserve Economic Data (FRED), and calculate:

  • Year-over-Year (YoY) growth
  • Quarter-over-Quarter (QoQ) growth

🧾 Dataset Description

  • GDPPOT: Real Potential GDP
  • Unit: Billions of chained 2012 dollars
  • Frequency: Quarterly
  • Source: U.S. Congressional Budget Office via FRED
  • FRED Series CodeGDPPOT

⚙️ Code Breakdown

python
CopyEdit
from pandas_datareader import data as pdr
from datetime import date

# Get current date and create a 70-year date range
end = date.today()
start = date(year=end.year - 70, month=end.month, day=end.day)

  • end: today’s date
  • start: same day/month but 70 years earlier
  • This range captures long-term economic trends.

📥 Download GDPPOT Data from FRED

python
CopyEdit
gdppot = pdr.DataReader("GDPPOT", "fred", start=start)

  • Retrieves quarterly potential GDP starting from start.
  • Resulting gdppot DataFrame contains:
    • Index: Dates (quarterly)
    • Column: 'GDPPOT'

📊 Calculate Growth Rates

🟢 Year-over-Year (YoY) Growth

python
CopyEdit
gdppot['gdppot_us_yoy'] = gdppot['GDPPOT'] / gdppot['GDPPOT'].shift(4) - 1

  • Compares each quarter with the same quarter of the previous year
  • shift(4): Moves data 4 rows (quarters) backward
  • Output is decimal form (e.g., 0.025 = 2.5%)

🟡 Quarter-over-Quarter (QoQ) Growth

python
CopyEdit
gdppot['gdppot_us_qoq'] = gdppot['GDPPOT'] / gdppot['GDPPOT'].shift(1) - 1

  • Compares current quarter to the previous quarter
  • Useful for short-term economic trend analysis

📋 View Recent Data

python
CopyEdit
gdppot.tail(15)

  • Shows the most recent 15 entries
  • Helps track recent GDP levels and growth performance

GDP Analysis Study Notes - Python Implementation

GDP Visualization Study Notes - Dual Y-Axis Plotting

Table of Contents

  1. Overview and Concept
  2. Required Libraries
  3. Figure Setup
  4. Primary Axis (GDP Values)
  5. Secondary Axis (Growth Rates)
  6. Formatting and Styling
  7. Complete Implementation
  8. Customization Options

Overview and Concept

Purpose

Create a dual y-axis plot to visualize both:

  • GDP absolute values (billions of dollars) - Primary axis
  • GDP growth rates (percentage) - Secondary axis

Why Dual Y-Axis?

Different scales make it impossible to plot both metrics on a single axis effectively:

  • GDP values: Range from ~$8,000B to $25,000B
  • Growth rates: Range from -2% to +8%

Reference Source

Based on: cmdlinetips.com dual y-axis tutorial

Required Libraries

import matplotlib.pyplot as plt
import matplotlib.ticker as mtick

Library Components

Library
Module
Purpose
matplotlib.pyplot
plt
Core plotting functionality
matplotlib.ticker
mtick
Advanced tick formatting (percentage)

Figure Setup

Basic Figure Creation

fig, ax = plt.subplots(figsize=(20, 6))
plt.grid(True)

Syntax Breakdown

Component
Purpose
Parameters
plt.subplots()
Creates figure and axis objects
figsize=(width, height) in inches
figsize=(20, 6)
Sets plot dimensions
Width=20", Height=6"
plt.grid(True)
Adds grid lines
Boolean parameter

Alternative Syntax

# Method 1: Using plt.subplots()
fig, ax = plt.subplots(figsize=(20, 6))

# Method 2: Using plt.figure()
plt.figure(figsize=(20, 6))
ax = plt.gca()  # Get current axis

Primary Axis (GDP Values)

Fill Between Plot

ax.fill_between(gdppot.index, gdppot.GDPPOT,
                color="red", alpha=0.3,
                label="US Potential GDP")

Parameter Details

Parameter
Type
Purpose
Example Value
gdppot.index
DatetimeIndex
X-axis values (dates)
Quarterly dates
gdppot.GDPPOT
Series
Y-axis values (GDP)
GDP in billions
color
string
Fill color
"red""#FF0000"
alpha
float
Transparency (0-1)
0.3 = 30% opacity
label
string
Legend label
For legend display

Alternative Fill Options

# Fill between zero and values
ax.fill_between(x, y, color="red", alpha=0.3)

# Fill between two series
ax.fill_between(x, y1, y2, color="blue", alpha=0.2)

# Fill above/below a threshold
ax.fill_between(x, y, 20000, where=(y > 20000),
                color="green", alpha=0.4)

Secondary Axis (Growth Rates)

Creating Secondary Y-Axis

ax2 = ax.twinx()

Syntax Explanation

  • ax.twinx(): Creates a new axis sharing the same x-axis
  • ax2: New axis object for right y-axis
  • Both axes share the same x-coordinates but have independent y-scales

Percentage Formatting

ax2.yaxis.set_major_formatter(mtick.PercentFormatter(1.0))

Formatter Options

Parameter
Meaning
Input Format
Display
1.0
Decimal input
0.05
5%
100.0
Percentage input
5.0
5%

Growth Rate Plot

ax2.plot(gdppot.gdppot_us_yoy, color="blue", marker="o",
         label="US Potential GDP Growth, % Y/Y")

Plot Parameters

Parameter
Purpose
Options
Example
color
Line color
Color names, hex codes
"blue""#0000FF"
marker
Point markers
"o""s""^""*"
"o" = circles
label
Legend text
String
For legend display

Marker Options

# Common marker styles
markers = {
    "o": "circle",
    "s": "square",
    "^": "triangle up",
    "v": "triangle down",
    "*": "star",
    "+": "plus",
    "x": "x mark"
}

Formatting and Styling

Axis Labels

ax.set_xlabel("Date", fontsize=14)
ax.set_ylabel("US Potential GDP, $b", color="red", fontsize=14)
ax2.set_ylabel("US Potential GDP Growth, % Y/Y", color="blue", fontsize=14)

Label Parameters

Parameter
Purpose
Example Values
fontsize
Text size
121416'large'
color
Text color
"red""blue""#FF0000"

Font Size Options

# Numeric sizes
fontsize=10  # Small
fontsize=12  # Medium
fontsize=14  # Large
fontsize=16  # Extra large

# Named sizes
fontsize='small'
fontsize='medium'
fontsize='large'
fontsize='x-large'

Legend Handling

Combining Legends from Both Axes

lines, labels = ax.get_legend_handles_labels()
lines2, labels2 = ax2.get_legend_handles_labels()
ax2.legend(lines + lines2, labels + labels2, loc='upper left')

Step-by-Step Process

  1. Extract from primary axisax.get_legend_handles_labels()
  2. Extract from secondary axisax2.get_legend_handles_labels()
  3. Combine bothlines + lines2, labels + labels2
  4. Create unified legendax2.legend(...)

Legend Locations

Parameter
Position
'upper left'
Top left corner
'upper right'
Top right corner
'lower left'
Bottom left corner
'lower right'
Bottom right corner
'center'
Center of plot
'best'
Automatic best position

Complete Implementation

Full Code Template

import matplotlib.pyplot as plt
import matplotlib.ticker as mtick

# Create figure and primary axis
fig, ax = plt.subplots(figsize=(20, 6))
plt.grid(True)

# Plot GDP values on primary axis (left y-axis)
ax.fill_between(gdppot.index, gdppot.GDPPOT,
                color="red", alpha=0.3,
                label="US Potential GDP")

# Create secondary axis (right y-axis)
ax2 = ax.twinx()

# Format secondary axis for percentages
ax2.yaxis.set_major_formatter(mtick.PercentFormatter(1.0))

# Plot growth rates on secondary axis
ax2.plot(gdppot.gdppot_us_yoy, color="blue", marker="o",
         label="US Potential GDP Growth, % Y/Y")

# Set axis labels
ax.set_xlabel("Date", fontsize=14)
ax.set_ylabel("US Potential GDP, $b", color="red", fontsize=14)
ax2.set_ylabel("US Potential GDP Growth, % Y/Y", color="blue", fontsize=14)

# Combine legends from both axes
lines, labels = ax.get_legend_handles_labels()
lines2, labels2 = ax2.get_legend_handles_labels()
ax2.legend(lines + lines2, labels + labels2, loc='upper left')

# Display the plot
plt.show()

Customization Options

Color Schemes

# Professional color scheme
primary_color = "#2E86AB"    # Blue
secondary_color = "#A23B72"  # Purple
fill_alpha = 0.2

# Economic data color scheme
gdp_color = "#1f77b4"        # Blue
growth_color = "#ff7f0e"     # Orange

Enhanced Styling

# Add title
plt.title("US Potential GDP and Growth Rate Analysis",
          fontsize=16, fontweight='bold', pad=20)

# Customize grid
plt.grid(True, alpha=0.3, linestyle='--')

# Set axis limits
ax.set_ylim(0, gdppot.GDPPOT.max() * 1.1)
ax2.set_ylim(-0.05, gdppot.gdppot_us_yoy.max() * 1.2)

Advanced Formatting

# Rotate x-axis labels
plt.xticks(rotation=45)

# Add annotations
ax2.annotate('Financial Crisis',
             xy=('2008-01-01', -0.02),
             xytext=('2010-01-01', 0.04),
             arrowprops=dict(arrowstyle='->'))

# Tight layout
plt.tight_layout()

Save Options

# Save as high-quality image
plt.savefig('gdp_analysis.png', dpi=300, bbox_inches='tight')
plt.savefig('gdp_analysis.pdf', bbox_inches='tight')

Troubleshooting Common Issues

Issue 1: Legend Not Showing

# Ensure both plots have labels
ax.fill_between(..., label="GDP Values")
ax2.plot(..., label="Growth Rate")

Issue 2: Percentage Not Displaying

# Check formatter parameter
ax2.yaxis.set_major_formatter(mtick.PercentFormatter(1.0))  # For decimal input
# OR
ax2.yaxis.set_major_formatter(mtick.PercentFormatter(100.0))  # For percentage input

Issue 3: Overlapping Text

# Use tight_layout
plt.tight_layout()
# OR adjust figure size
fig, ax = plt.subplots(figsize=(22, 8))

Practice Exercises

  1. Color Variations: Change colors and transparency levels
  2. Different Markers: Experiment with various marker styles
  3. Multiple Series: Add QoQ growth rate to the secondary axis
  4. Time Filtering: Plot only the last 20 years of data
  5. Annotations: Add markers for recession periods
  6. Style Themes: Apply different matplotlib style sheets