Spaces:
Running
Running
import json | |
from pathlib import Path | |
from typing import List, Dict, Any | |
from datetime import datetime | |
# Path to the processed meetings data | |
DATA_DIR = Path(__file__).parents[2] / "data" | |
MEETINGS_FILE = DATA_DIR / "fed_processed_meetings.json" | |
def _load_meetings_data() -> List[Dict[str, Any]]: | |
"""Load processed meetings data from JSON file""" | |
try: | |
if MEETINGS_FILE.exists(): | |
with open(MEETINGS_FILE, 'r', encoding='utf-8') as f: | |
data = json.load(f) | |
return sorted(data, key=lambda x: x.get('date', ''), reverse=True) | |
else: | |
return [] | |
except Exception as e: | |
return [] | |
def search_meetings(query: str, limit: int = 3) -> Dict[str, Any]: | |
""" | |
Search across all FOMC meeting data for relevant information. | |
Args: | |
query (str): Search term or phrase to look for in meetings | |
limit (int): Maximum number of meetings to return (default: 3) | |
Returns: | |
Dict containing: | |
- success (bool): Whether the search succeeded | |
- query (str): The original search query | |
- results (List[Dict]): List of matching meetings | |
- count (int): Number of results returned | |
- total_matches (int): Total number of meetings that matched | |
""" | |
meetings_data = _load_meetings_data() | |
if not meetings_data: | |
return { | |
"success": False, | |
"error": "No meetings data available", | |
"results": [], | |
"count": 0 | |
} | |
query_lower = query.lower() | |
scored_meetings = [] | |
for meeting in meetings_data: | |
score = 0 | |
matched_fields = [] | |
search_fields = { | |
'date': 2, | |
'title': 1, | |
'action': 3, | |
'rate': 3, | |
'magnitude': 2, | |
'forward_guidance': 2, | |
'economic_outlook': 1, | |
'market_impact': 1, | |
'key_economic_factors': 1 | |
} | |
for field, weight in search_fields.items(): | |
field_value = meeting.get(field, '') | |
if isinstance(field_value, list): | |
field_value = ' '.join(field_value) | |
if field_value and query_lower in str(field_value).lower(): | |
score += weight | |
matched_fields.append(field) | |
if score > 0: | |
scored_meetings.append({ | |
'meeting': meeting, | |
'score': score, | |
'matched_fields': matched_fields | |
}) | |
scored_meetings.sort(key=lambda x: x['score'], reverse=True) | |
top_results = scored_meetings[:limit] | |
return { | |
"success": True, | |
"query": query, | |
"results": [result['meeting'] for result in top_results], | |
"match_details": [{'score': r['score'], 'matched_fields': r['matched_fields']} for r in top_results], | |
"count": len(top_results), | |
"total_matches": len(scored_meetings) | |
} | |
def get_rate_decision(date: str) -> Dict[str, Any]: | |
""" | |
Get details about a specific FOMC meeting's rate decision. | |
Args: | |
date (str): Meeting date in YYYY-MM-DD format (e.g., "2025-06-18") | |
Returns: | |
Dict containing: | |
- success (bool): Whether the meeting was found | |
- meeting (Dict): Complete meeting data if found | |
- exact_match (bool): True if exact date match, False if closest match | |
- requested_date (str): The date that was requested | |
""" | |
meetings_data = _load_meetings_data() | |
if not meetings_data: | |
return { | |
"success": False, | |
"error": "No meetings data available" | |
} | |
target_meeting = None | |
for meeting in meetings_data: | |
if meeting.get('date') == date: | |
target_meeting = meeting | |
break | |
if not target_meeting and date: | |
try: | |
target_date = datetime.strptime(date, '%Y-%m-%d') | |
closest_meeting = None | |
min_diff = float('inf') | |
for meeting in meetings_data: | |
try: | |
meeting_date = datetime.strptime(meeting.get('date', ''), '%Y-%m-%d') | |
diff = abs((meeting_date - target_date).days) | |
if diff < min_diff and diff <= 30: | |
min_diff = diff | |
closest_meeting = meeting | |
except ValueError: | |
continue | |
target_meeting = closest_meeting | |
except ValueError: | |
pass | |
if target_meeting: | |
return { | |
"success": True, | |
"requested_date": date, | |
"meeting": target_meeting, | |
"exact_match": target_meeting.get('date') == date | |
} | |
else: | |
return { | |
"success": False, | |
"error": f"No meeting found for date {date}", | |
"requested_date": date | |
} | |
def compare_meetings(date1: str, date2: str) -> Dict[str, Any]: | |
""" | |
Compare two FOMC meetings side by side to analyze differences and similarities. | |
Args: | |
date1 (str): First meeting date in YYYY-MM-DD format | |
date2 (str): Second meeting date in YYYY-MM-DD format | |
Returns: | |
Dict containing: | |
- success (bool): Whether both meetings were found | |
- meeting1/meeting2 (Dict): Data for each meeting | |
- differences (Dict): Fields that differ between meetings | |
- similarities (Dict): Fields that are the same | |
- factor_analysis (Dict): Analysis of key economic factors | |
""" | |
meeting1_result = get_rate_decision(date1) | |
meeting2_result = get_rate_decision(date2) | |
if not meeting1_result["success"]: | |
return { | |
"success": False, | |
"error": f"Could not find meeting for {date1}: {meeting1_result.get('error')}" | |
} | |
if not meeting2_result["success"]: | |
return { | |
"success": False, | |
"error": f"Could not find meeting for {date2}: {meeting2_result.get('error')}" | |
} | |
meeting1 = meeting1_result["meeting"] | |
meeting2 = meeting2_result["meeting"] | |
# Compare key fields | |
comparison = { | |
"success": True, | |
"meeting1": { | |
"date": meeting1.get('date'), | |
"title": meeting1.get('title'), | |
"data": meeting1 | |
}, | |
"meeting2": { | |
"date": meeting2.get('date'), | |
"title": meeting2.get('title'), | |
"data": meeting2 | |
}, | |
"differences": {}, | |
"similarities": {} | |
} | |
# Compare specific fields | |
compare_fields = ['action', 'rate', 'magnitude', 'forward_guidance', 'economic_outlook', 'market_impact'] | |
for field in compare_fields: | |
val1 = meeting1.get(field, '') | |
val2 = meeting2.get(field, '') | |
if val1 != val2: | |
comparison["differences"][field] = { | |
"meeting1_value": val1, | |
"meeting2_value": val2 | |
} | |
else: | |
comparison["similarities"][field] = val1 | |
# Compare key economic factors | |
factors1 = set(meeting1.get('key_economic_factors', [])) | |
factors2 = set(meeting2.get('key_economic_factors', [])) | |
comparison["factor_analysis"] = { | |
"common_factors": list(factors1.intersection(factors2)), | |
"unique_to_meeting1": list(factors1 - factors2), | |
"unique_to_meeting2": list(factors2 - factors1) | |
} | |
return comparison | |
def get_latest_meeting() -> Dict[str, Any]: | |
""" | |
Get the most recent FOMC meeting data. | |
Returns: | |
Dict containing: | |
- success (bool): Whether data was retrieved successfully | |
- meeting (Dict): The most recent meeting data | |
- total_meetings (int): Total number of meetings in database | |
""" | |
meetings_data = _load_meetings_data() | |
if not meetings_data: | |
return { | |
"success": False, | |
"error": "No meetings data available" | |
} | |
# Data is already sorted by date (newest first) | |
latest_meeting = meetings_data[0] | |
return { | |
"success": True, | |
"meeting": latest_meeting, | |
"total_meetings": len(meetings_data) | |
} |