TradingAgents/tradingagents/dataflows/fred.py

397 lines
13 KiB
Python

"""
FRED API Data Retrieval Functions.
This module provides high-level functions for retrieving economic data from FRED:
- Interest rates (Federal Funds Rate)
- Treasury rates (2Y, 5Y, 10Y, 30Y yields)
- Money supply (M1, M2)
- GDP (nominal and real)
- Inflation (CPI, PCE)
- Unemployment rate
- Generic series retrieval
All functions return pandas DataFrames on success or error strings on failure.
Functions automatically handle caching, retry logic, and error recovery.
Usage:
from tradingagents.dataflows.fred import get_interest_rates, get_treasury_rates
# Get federal funds rate
data = get_interest_rates()
# Get 10-year treasury yield with date range
data = get_treasury_rates(maturity='10Y', start_date='2024-01-01', end_date='2024-12-31')
Requirements:
- fredapi package: pip install fredapi
- FRED_API_KEY environment variable must be set
"""
import pandas as pd
from typing import Union, Optional
from .fred_common import (
_make_fred_request,
FredRateLimitError,
FredInvalidSeriesError,
)
# ============================================================================
# FRED Series ID Mappings
# ============================================================================
FRED_SERIES = {
# Interest Rates
'FEDFUNDS': 'FEDFUNDS', # Federal Funds Effective Rate
'EFFR': 'FEDFUNDS', # Alias for Federal Funds Rate
# Treasury Rates
'DGS2': 'DGS2', # 2-Year Treasury Constant Maturity Rate
'DGS5': 'DGS5', # 5-Year Treasury Constant Maturity Rate
'DGS10': 'DGS10', # 10-Year Treasury Constant Maturity Rate
'DGS30': 'DGS30', # 30-Year Treasury Constant Maturity Rate
# Money Supply
'M1SL': 'M1SL', # M1 Money Stock
'M2SL': 'M2SL', # M2 Money Stock
# GDP
'GDP': 'GDP', # Gross Domestic Product (nominal)
'GDPC1': 'GDPC1', # Real Gross Domestic Product
# Inflation
'CPIAUCSL': 'CPIAUCSL', # Consumer Price Index for All Urban Consumers
'PCEPI': 'PCEPI', # Personal Consumption Expenditures Price Index
# Unemployment
'UNRATE': 'UNRATE', # Unemployment Rate
}
# Treasury maturity mappings
TREASURY_MATURITIES = {
'2Y': 'DGS2',
'5Y': 'DGS5',
'10Y': 'DGS10',
'30Y': 'DGS30',
}
# Money supply measure mappings
MONEY_SUPPLY_MEASURES = {
'M1': 'M1SL',
'M2': 'M2SL',
}
# GDP frequency mappings
GDP_FREQUENCIES = {
'quarterly': 'GDP',
'real': 'GDPC1',
'nominal': 'GDP',
'annual': 'GDPA',
}
# Inflation measure mappings
INFLATION_MEASURES = {
'CPI': 'CPIAUCSL',
'CORE': 'CPILFESL',
'PCE': 'PCEPI',
}
# ============================================================================
# Data Retrieval Functions
# ============================================================================
def get_interest_rates(
series_id: str = 'FEDFUNDS',
start_date: Optional[str] = None,
end_date: Optional[str] = None,
use_cache: bool = True
) -> Union[pd.DataFrame, str]:
"""
Retrieve interest rate data from FRED.
Args:
series_id: FRED series ID (default: 'FEDFUNDS' for Federal Funds Rate)
start_date: Start date in YYYY-MM-DD format (optional)
end_date: End date in YYYY-MM-DD format (optional)
use_cache: Whether to use caching (default: True)
Returns:
pd.DataFrame with 'date' and 'value' columns on success
str with error message on failure
Examples:
>>> data = get_interest_rates() # Get federal funds rate
>>> data = get_interest_rates(start_date='2024-01-01', end_date='2024-12-31')
"""
try:
# Make API request
data = _make_fred_request(series_id, start_date=start_date, end_date=end_date)
return data
except FredRateLimitError as e:
return f"Error: FRED API rate limit exceeded. Please try again later. Details: {e}"
except FredInvalidSeriesError as e:
return f"Error: Invalid FRED series ID '{series_id}'. Details: {e}"
except ValueError as e:
return f"Error: Invalid input parameters. Details: {e}"
except Exception as e:
return f"Error retrieving interest rate data: {e}"
def get_treasury_rates(
maturity: str = '10Y',
start_date: Optional[str] = None,
end_date: Optional[str] = None,
use_cache: bool = True
) -> Union[pd.DataFrame, str]:
"""
Retrieve Treasury yield data from FRED.
Args:
maturity: Treasury maturity ('2Y', '5Y', '10Y', or '30Y', default: '10Y')
start_date: Start date in YYYY-MM-DD format (optional)
end_date: End date in YYYY-MM-DD format (optional)
Returns:
pd.DataFrame with 'date' and 'value' columns on success
str with error message on failure
Examples:
>>> data = get_treasury_rates() # Get 10-year yield
>>> data = get_treasury_rates(maturity='2Y', start_date='2024-01-01')
"""
try:
# Map maturity to series ID
series_id = TREASURY_MATURITIES.get(maturity)
if not series_id:
return f"Error: Invalid maturity '{maturity}'. Valid options: {list(TREASURY_MATURITIES.keys())}"
# Make API request (caching handled internally)
data = _make_fred_request(series_id, start_date=start_date, end_date=end_date)
return data
except FredRateLimitError as e:
return f"Error: FRED API rate limit exceeded. Please try again later. Details: {e}"
except FredInvalidSeriesError as e:
return f"Error: Invalid FRED series. Details: {e}"
except ValueError as e:
return f"Error: Invalid input parameters. Details: {e}"
except Exception as e:
return f"Error retrieving treasury rate data: {e}"
def get_money_supply(
measure: str = 'M2',
start_date: Optional[str] = None,
end_date: Optional[str] = None,
use_cache: bool = True
) -> Union[pd.DataFrame, str]:
"""
Retrieve money supply data from FRED.
Args:
measure: Money supply measure ('M1' or 'M2', default: 'M2')
start_date: Start date in YYYY-MM-DD format (optional)
end_date: End date in YYYY-MM-DD format (optional)
Returns:
pd.DataFrame with 'date' and 'value' columns (values in billions) on success
str with error message on failure
Examples:
>>> data = get_money_supply() # Get M2 money supply
>>> data = get_money_supply(measure='M1', start_date='2024-01-01')
"""
try:
# Map measure to series ID
series_id = MONEY_SUPPLY_MEASURES.get(measure)
if not series_id:
return f"Error: Invalid measure '{measure}'. Valid options: {list(MONEY_SUPPLY_MEASURES.keys())}"
# Make API request (caching handled internally)
data = _make_fred_request(series_id, start_date=start_date, end_date=end_date)
return data
except FredRateLimitError as e:
return f"Error: FRED API rate limit exceeded. Please try again later. Details: {e}"
except FredInvalidSeriesError as e:
return f"Error: Invalid FRED series. Details: {e}"
except ValueError as e:
return f"Error: Invalid input parameters. Details: {e}"
except Exception as e:
return f"Error retrieving money supply data: {e}"
def get_gdp(
frequency: str = 'quarterly',
start_date: Optional[str] = None,
end_date: Optional[str] = None,
use_cache: bool = True
) -> Union[pd.DataFrame, str]:
"""
Retrieve GDP data from FRED.
Args:
frequency: GDP type ('quarterly', 'nominal', 'real', or 'annual', default: 'quarterly')
start_date: Start date in YYYY-MM-DD format (optional)
end_date: End date in YYYY-MM-DD format (optional)
Returns:
pd.DataFrame with 'date' and 'value' columns (values in billions) on success
str with error message on failure
Examples:
>>> data = get_gdp() # Get quarterly nominal GDP
>>> data = get_gdp(frequency='real', start_date='2024-01-01')
"""
try:
# Map frequency to series ID
series_id = GDP_FREQUENCIES.get(frequency)
if not series_id:
return f"Error: Invalid frequency '{frequency}'. Valid options: {list(GDP_FREQUENCIES.keys())}"
# Make API request (caching handled internally)
data = _make_fred_request(series_id, start_date=start_date, end_date=end_date)
return data
except FredRateLimitError as e:
return f"Error: FRED API rate limit exceeded. Please try again later. Details: {e}"
except FredInvalidSeriesError as e:
return f"Error: Invalid FRED series. Details: {e}"
except ValueError as e:
return f"Error: Invalid input parameters. Details: {e}"
except Exception as e:
return f"Error retrieving GDP data: {e}"
def get_inflation(
measure: str = 'CPI',
start_date: Optional[str] = None,
end_date: Optional[str] = None,
use_cache: bool = True
) -> Union[pd.DataFrame, str]:
"""
Retrieve inflation data from FRED.
Args:
measure: Inflation measure ('CPI', 'CORE', or 'PCE', default: 'CPI')
start_date: Start date in YYYY-MM-DD format (optional)
end_date: End date in YYYY-MM-DD format (optional)
Returns:
pd.DataFrame with 'date' and 'value' columns (index values) on success
str with error message on failure
Examples:
>>> data = get_inflation() # Get CPI data
>>> data = get_inflation(measure='PCE', start_date='2024-01-01')
"""
try:
# Map measure to series ID
series_id = INFLATION_MEASURES.get(measure)
if not series_id:
return f"Error: Invalid measure '{measure}'. Valid options: {list(INFLATION_MEASURES.keys())}"
# Make API request (caching handled internally)
data = _make_fred_request(series_id, start_date=start_date, end_date=end_date)
return data
except FredRateLimitError as e:
return f"Error: FRED API rate limit exceeded. Please try again later. Details: {e}"
except FredInvalidSeriesError as e:
return f"Error: Invalid FRED series. Details: {e}"
except ValueError as e:
return f"Error: Invalid input parameters. Details: {e}"
except Exception as e:
return f"Error retrieving inflation data: {e}"
def get_unemployment(
series_id: str = 'UNRATE',
start_date: Optional[str] = None,
end_date: Optional[str] = None,
use_cache: bool = True
) -> Union[pd.DataFrame, str]:
"""
Retrieve unemployment rate data from FRED.
Args:
series_id: FRED series ID (default: 'UNRATE' for U.S. unemployment rate)
start_date: Start date in YYYY-MM-DD format (optional)
end_date: End date in YYYY-MM-DD format (optional)
Returns:
pd.DataFrame with 'date' and 'value' columns (percentage) on success
str with error message on failure
Examples:
>>> data = get_unemployment() # Get U.S. unemployment rate
>>> data = get_unemployment(start_date='2024-01-01', end_date='2024-12-31')
"""
try:
# Make API request
data = _make_fred_request(series_id, start_date=start_date, end_date=end_date)
return data
except FredRateLimitError as e:
return f"Error: FRED API rate limit exceeded. Please try again later. Details: {e}"
except FredInvalidSeriesError as e:
return f"Error: Invalid FRED series ID '{series_id}'. Details: {e}"
except ValueError as e:
return f"Error: Invalid input parameters. Details: {e}"
except Exception as e:
return f"Error retrieving unemployment data: {e}"
def get_fred_series(
series_id: str,
start_date: Optional[str] = None,
end_date: Optional[str] = None,
use_cache: bool = True
) -> Union[pd.DataFrame, str]:
"""
Retrieve any FRED series data by series ID.
This is a generic function that can retrieve any FRED series.
Use specific functions (get_interest_rates, get_treasury_rates, etc.)
for better validation and error messages.
Args:
series_id: FRED series ID (e.g., 'FEDFUNDS', 'DGS10', 'UNRATE')
start_date: Start date in YYYY-MM-DD format (optional)
end_date: End date in YYYY-MM-DD format (optional)
Returns:
pd.DataFrame with 'date' and 'value' columns on success
str with error message on failure
Examples:
>>> data = get_fred_series('FEDFUNDS') # Get federal funds rate
>>> data = get_fred_series('DGS10', start_date='2024-01-01')
"""
try:
# Validate series_id
if not series_id or not isinstance(series_id, str):
return "Error: series_id must be a non-empty string"
# Make API request (caching handled internally)
data = _make_fred_request(series_id, start_date=start_date, end_date=end_date)
return data
except FredRateLimitError as e:
return f"Error: FRED API rate limit exceeded. Please try again later. Details: {e}"
except FredInvalidSeriesError as e:
return f"Error: Invalid FRED series ID '{series_id}'. Details: {e}"
except ValueError as e:
return f"Error: Invalid input parameters. Details: {e}"
except Exception as e:
return f"Error retrieving FRED series data: {e}"