""" 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}"