
Economic Calendar Fetcher
- 959 installs
- 2.5k repo stars
- Updated July 26, 2026
- tradermonty/claude-trading-skills
Economic Calendar Fetcher is a Claude trading skill that pulls upcoming economic events, interest-rate decisions, and market-moving releases from the Financial Modeling Prep economic_calendar API for finance agents.
About
Economic Calendar Fetcher is a finance integration skill from tradermonty/claude-trading-skills documenting the Financial Modeling Prep Economic Calendar API. It exposes the https://financialmodelingprep.com/api/v3/economic_calendar endpoint for upcoming and historical economic data releases, central bank decisions, and other market-moving scheduled events. API access requires a valid FMP apikey query parameter obtained from financialmodelingprep.com registration. Developers reach for Economic Calendar Fetcher when building trading agents, market dashboards, or alert workflows that must stay ahead of scheduled macro releases and rate decisions. The skill focuses on API authentication, endpoint usage, and event data retrieval rather than discretionary trade strategy.
- Fetches scheduled economic calendar events including central bank decisions and data releases
- Supports custom date ranges with ISO 8601 format (maximum 90-day window)
- Requires only an FMP API key as a query parameter
- Designed as a reusable capability for Claude, Cursor, or Codex-powered trading agents
- Free tier supports ~250-300 requests per day
Economic Calendar Fetcher by the numbers
- 959 all-time installs (skills.sh)
- +50 installs in the week ending Jul 28, 2026 (Skillselion tracking)
- Ranked #1,103 of 16,659 AI & Agent Building skills by installs in the Skillselion catalog
- Security screen: LOW risk (skills.sh audit)
- Data as of Jul 28, 2026 (Skillselion catalog sync)
npx skills add https://github.com/tradermonty/claude-trading-skills --skill economic-calendar-fetcherAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 959 |
|---|---|
| repo stars | ★ 2.5k |
| Security audit | 3 / 3 scanners passed |
| Last updated | July 26, 2026 |
| Repository | tradermonty/claude-trading-skills ↗ |
How do you fetch economic calendar data via API?
Let their trading or finance agent automatically pull upcoming economic events, interest-rate decisions, and market-moving releases from the Financial Modeling Prep API
Who is it for?
Developers building trading or finance agents that need programmatic access to scheduled macro releases and central bank decision dates.
Skip if: Developers needing live price feeds, order execution, or macro analysis without Financial Modeling Prep API access.
When should I use this skill?
A developer asks to fetch economic calendar events, integrate FMP macro data, or schedule alerts around market-moving releases.
What you get
Structured economic calendar event data from the FMP economic_calendar API endpoint with authenticated requests.
- Economic calendar API integration
- Scheduled macro event data
Files
Economic Calendar Fetcher
Overview
Retrieve upcoming economic events and data releases from the Financial Modeling Prep (FMP) Economic Calendar API. This skill fetches scheduled economic indicators including central bank monetary policy decisions, employment reports, inflation data (CPI/PPI), GDP releases, retail sales, manufacturing data, and other market-moving events that impact financial markets.
The skill uses a Python script to query the FMP API and returns raw JSON or text output. The assistant then filters events, assesses market impact, and generates a chronological Markdown report for each scheduled event. No files are generated automatically.
Key Capabilities:
- Fetch economic events for specified date ranges (max 90 days)
- Support flexible API key provision (environment variable or CLI argument)
- Filter by impact level, country, or event type (filtering performed by the assistant)
- Present filtered results as structured Markdown reports with impact analysis (assistant-generated, not script-generated)
- Default to next 7 days for quick market outlook
Data Source:
- FMP Economic Calendar API:
https://financialmodelingprep.com/api/v3/economic_calendar - Covers major economies: US, EU, UK, Japan, China, Canada, Australia
- Event types: Central bank decisions, employment, inflation, GDP, trade, housing, surveys
When to Use This Skill
Use this skill when the user requests:
1. Economic Calendar Queries:
- "What economic events are coming up this week?"
- "Show me the economic calendar for the next two weeks"
- "When is the next FOMC meeting?"
- "What major economic data is being released next month?"
2. Market Event Planning:
- "What should I watch for in the markets this week?"
- "Are there any high-impact economic releases coming?"
- "When is the next jobs report / CPI release / GDP report?"
3. Specific Date Range Requests:
- "Get economic events from January 1 to January 31"
- "What's on the economic calendar for Q1 2025?"
4. Country-Specific Queries:
- "Show me US economic data releases next week"
- "What ECB events are scheduled?"
- "When is Japan releasing their inflation data?"
DO NOT use this skill for:
- Past economic events (use market-news-analyst for historical analysis)
- Corporate earnings calendars (this skill excludes earnings)
- Real-time market data or live quotes
- Technical analysis or chart interpretation
Prerequisites
- FMP API Key (required): Sign up at https://financialmodelingprep.com for a free key (250 requests/day). Set via
FMP_API_KEYenvironment variable or pass--api-keyto the script. - Python 3.10+: Required to run
skills/economic-calendar-fetcher/scripts/get_economic_calendar.py. - No third-party packages: The script uses only the Python standard library.
Workflow
Follow these steps to fetch and analyze the economic calendar:
Step 1: Obtain FMP API Key
Check for API key availability (in priority order):
1. Recommended: Check if FMP_API_KEY environment variable is set — this keeps the key out of session logs 2. Acceptable: Use --api-key CLI argument for one-off runs 3. Not recommended: Asking the user to paste the key into chat — session logs may retain it 4. If user doesn't have an API key, provide instructions:
- Visit https://financialmodelingprep.com
- Sign up for free account (250 requests/day limit)
- Navigate to API dashboard to obtain key
Example user interaction:
User: "Show me economic events for next week"
Assistant: "I'll fetch the economic calendar. I'll use the FMP_API_KEY environment variable if it's set. Otherwise, please pass the key via --api-key when running the script."Step 2: Determine Date Range
Set appropriate date range based on user request:
Default (no specific dates): Today + 7 days User specifies period: Use exact dates (validate format: YYYY-MM-DD) Maximum range: 90 days (FMP API limitation)
Examples:
- "Next week" → Today to +7 days
- "Next two weeks" → Today to +14 days
- "January 2025" → 2025-01-01 to 2025-01-31
- "Q1 2025" → 2025-01-01 to 2025-03-31
Validate date range:
- Ensure start date ≤ end date
- Ensure range ≤ 90 days
- Warn if querying past dates
Step 3: Execute API Fetch Script
Run the get_economic_calendar.py script with appropriate parameters:
Basic usage (default 7 days):
python3 skills/economic-calendar-fetcher/scripts/get_economic_calendar.py --api-key YOUR_KEYWith specific date range:
python3 skills/economic-calendar-fetcher/scripts/get_economic_calendar.py \
--from 2025-01-01 \
--to 2025-01-31 \
--api-key YOUR_KEY \
--format jsonUsing environment variable (no --api-key needed):
export FMP_API_KEY=your_key_here
python3 skills/economic-calendar-fetcher/scripts/get_economic_calendar.py \
--from 2025-01-01 \
--to 2025-01-07Script parameters:
--from: Start date (YYYY-MM-DD) - default: today--to: End date (YYYY-MM-DD) - default: today + 7 days--api-key: FMP API key (optional if FMP_API_KEY env var set)--format: Output format (json or text) - default: json--output: Output file path (optional, default: stdout)
Handle errors and empty results:
- Invalid API key → Ask user to verify key
- Rate limit exceeded (429) → Suggest waiting or upgrading FMP tier
- Network errors → Check your connection and re-run the script
- Invalid date format → Provide correct format example
- Unexpected empty list for a plausible current/future range: Do not declare the calendar empty yet. Verify the same range against the primary v3 endpoint directly, then locally filter rows by parsed
datebecause FMP may return adjacent-date rows. This applies even when the helper script itself returned[](not only when a stable endpoint was used).
Direct v3 fallback probe:
python3 - <<'PY'
import os, json, urllib.parse, urllib.request, datetime
start = datetime.date.fromisoformat("YYYY-MM-DD")
end = datetime.date.fromisoformat("YYYY-MM-DD")
url = "https://financialmodelingprep.com/api/v3/economic_calendar?" + urllib.parse.urlencode({
"from": start.isoformat(), "to": end.isoformat(), "apikey": os.environ["FMP_API_KEY"]
})
with urllib.request.urlopen(url, timeout=30) as r:
data = json.loads(r.read())
filtered = [e for e in data if start <= datetime.date.fromisoformat(e["date"][:10]) <= end]
filtered.sort(key=lambda e: e.get("date", ""))
print(json.dumps(filtered, indent=2))
PYStep 4: Parse and Filter Events
Process the JSON response from the script:
1. Parse event data: Extract all events from API response 2. Apply user filters if specified:
- Impact level: "High", "Medium", "Low"
- Country: "US", "EU", "JP", "CN", etc.
- Event type: FOMC, CPI, Employment, GDP, etc.
- Currency: USD, EUR, JPY, etc.
Filter examples:
- "Show only high-impact events" → Filter impact == "High"
- "US events only" → Filter country == "US"
- "Central bank decisions" → Search event name for "Rate", "Policy", "FOMC", "ECB", "BOJ"
Event data structure:
{
"date": "2025-01-15 14:30:00",
"country": "US",
"event": "Consumer Price Index (CPI) YoY",
"currency": "USD",
"previous": 2.6,
"estimate": 2.7,
"actual": null,
"change": null,
"impact": "High",
"changePercentage": null
}Step 5: Assess Market Impact
Evaluate the market significance of each event:
Impact Level Classification (from FMP):
- High Impact: Major market-moving events
- FOMC rate decisions, ECB/BOJ policy meetings
- Non-Farm Payrolls (NFP), CPI, GDP
- Market typically shows 0.5-2%+ intraday volatility
- Medium Impact: Significant but less volatile
- Retail Sales, Industrial Production
- PMI surveys, Consumer Confidence
- Housing data, Durable Goods Orders
- Low Impact: Minor indicators
- Weekly jobless claims (unless extreme)
- Regional manufacturing surveys
- Minor auction results
Additional Context Factors:
1. Current Market Sensitivity:
- High inflation environment → CPI/PPI elevated importance
- Recession fears → Employment data more critical
- Rate cut speculation → Central bank meetings crucial
2. Surprise Potential:
- Compare estimate vs. previous reading
- Large expected changes = higher attention
- Consensus uncertainty = higher impact potential
3. Event Clustering:
- Multiple related events same day = amplified impact
- Example: CPI + Retail Sales + Fed speech = Very High impact day
4. Forward Significance:
- Does this event influence upcoming central bank decisions?
- Is this a preliminary or final reading?
- Will this data be revised?
Step 6: Generate Output Report
Responsibility: The script outputs raw JSON or text. This step is performed by the assistant using the script's output. No Markdown files are generated automatically; results are displayed in chat and can be saved to reports/ on request.Create structured markdown report with the following sections:
Report Header:
# Economic Calendar
**Period:** [Start Date] to [End Date]
**Report Generated:** [Timestamp]
**Total Events:** [Count]
**High Impact Events:** [Count]Event Listing (Chronological):
For each event, provide:
## [Date] - [Day of Week]
### [Event Name] ([Impact Level])
- **Country:** [Country Code] ([Currency])
- **Time:** [HH:MM UTC]
- **Previous:** [Value]
- **Estimate:** [Consensus Forecast]
- **Impact Assessment:** [Your analysis]
**Market Implications:**
[2-3 sentences on why this matters, what markets watch for, typical reaction patterns]
---Example Event Entry:
## 2025-01-15 - Wednesday
### Consumer Price Index (CPI) YoY (High Impact)
- **Country:** US (USD)
- **Time:** 14:30 UTC (8:30 AM ET)
- **Previous:** 2.6%
- **Estimate:** 2.7%
- **Impact Assessment:** Very High - Core inflation metric for Fed policy decisions
**Market Implications:**
CPI reading above estimate (>2.7%) likely strengthens hawkish Fed expectations, potentially pressuring equities and supporting USD. Reading at or below 2.7% could reinforce disinflation narrative and support risk assets. Options market pricing 1.2% S&P 500 move on release day.
---Summary Section:
Add analytical summary at the end:
## Key Takeaways
**Highest Impact Days:**
- [Date]: [Events] - [Combined impact rationale]
- [Date]: [Events] - [Combined impact rationale]
**Central Bank Activity:**
- [Summary of any scheduled Fed/ECB/BOJ meetings or speeches]
**Major Data Releases:**
- Employment: [NFP, Unemployment Rate dates]
- Inflation: [CPI, PPI dates]
- Growth: [GDP, Retail Sales dates]
**Market Positioning Considerations:**
[2-3 bullets on how traders might position around these events]
**Risk Events:**
[Highlight any particularly high-uncertainty or surprise-potential events]Filtering Notes:
If user requested specific filters, note at top:
**Filters Applied:**
- Impact Level: High only
- Country: US
- Events shown: [X] of [Y] total events in date rangeOutput:
- Results are displayed in chat. No files are generated automatically.
- To save raw JSON/text data: use
--output reports/economic_calendar_[START]_to_[END].jsonwhen running the script. - To save the Markdown report: ask the assistant to write it to
reports/after generating it in chat.
Assistant-Generated Report Format
Markdown structure requirements:
1. Chronological ordering: Events sorted by date and time (earliest first) 2. Impact level indicators: Use (High Impact), (Medium Impact), (Low Impact) labels 3. Time zone clarity: Always specify UTC; ET/PT conversions are performed by the assistant based on US DST calendar 4. Data completeness: Include all available fields (previous, estimate, actual if past) 5. Null handling: Display "N/A" or "No estimate" for null values 6. Impact assessment: Every high/medium impact event must have market implications analysis
Table format option (for dense listings):
| Date/Time (UTC) | Event | Country | Impact | Previous | Estimate | Assessment |
|-----------------|-------|---------|--------|----------|----------|------------|
| 01-15 14:30 | CPI YoY | US | High | 2.6% | 2.7% | Core inflation metric |Language: All reports in English
Resources
Python Script:
skills/economic-calendar-fetcher/scripts/get_economic_calendar.py: Main API fetch script with CLI interface
Reference Documentation:
references/fmp_api_documentation.md: Complete FMP Economic Calendar API reference- Authentication and API key management
- Request parameters and date formats
- Response field definitions
- Rate limits and error handling
- Best practices for caching and efficiency
API Details:
- Primary endpoint:
https://financialmodelingprep.com/api/v3/economic_calendar - Stable endpoint caveat: if a helper script or docs use
https://financialmodelingprep.com/stable/economics-calendarand it returns404or[]for an otherwise valid date range, fall back to the v3 endpoint above before declaring the calendar empty. - Date-range caveat: v3 responses can include rows just outside the requested
from/towindow; after fetching, filter events locally by parseddateso only the requested date range is reported. - Authentication: API key required (free tier: 250 requests/day)
- Max date range: 90 days per request
- Response format: JSON array of event objects
- Rate limits: 5 requests/second (free tier)
Event Coverage:
- Major economies: US, EU, UK, Japan, China, Canada, Australia, Switzerland
- Event categories: Monetary policy, Employment, Inflation, GDP, Trade, Housing, Surveys
- Update frequency: Real-time (events added/updated as scheduled)
- Historical data: Available for past events with actual values
Usage Tips: 1. Cache results to minimize API calls (events rarely change once scheduled) 2. Query 7-30 day ranges for optimal request efficiency 3. Don't query >6 months in future (sparse data, speculative dates) 4. Refresh cache daily for upcoming week to catch time changes 5. Use smaller ranges (1-7 days) for real-time event monitoring
Error Handling:
- API key errors: Clear user guidance for obtaining free key
- Rate limits (429): Suggest waiting or upgrading FMP tier; re-run the script after the wait
- Network failures: Check connection and re-run; no automatic retry or cache in the script
- Stable endpoint returns
404or an empty list for a valid range: retry the same range throughhttps://financialmodelingprep.com/api/v3/economic_calendar, then locally filter returned events to the requested dates before reporting. - Invalid dates: Validation with helpful error messages
FMP Economic Calendar API Documentation
Overview
The Financial Modeling Prep (FMP) Economic Calendar API provides access to upcoming and historical economic data releases, central bank decisions, and other market-moving events. This API enables traders and investors to stay informed about scheduled economic events that may impact financial markets.
API Endpoint
https://financialmodelingprep.com/api/v3/economic_calendarAuthentication
API access requires a valid FMP API key, which must be included as a query parameter in all requests.
Parameter: apikey Format: String Required: Yes
Obtaining an API Key
1. Visit https://financialmodelingprep.com 2. Sign up for an account (free and paid tiers available) 3. Navigate to the API dashboard to view your API key 4. Free tier allows limited requests per day (~250-300 requests) 5. Paid tiers offer higher rate limits and additional features
Request Parameters
Required Parameters
| Parameter | Type | Description | Example |
|---|---|---|---|
from | date | Start date for calendar period | 2025-01-01 |
to | date | End date for calendar period | 2025-01-31 |
apikey | string | Your FMP API key | YOUR_API_KEY |
Date Format
- Format:
YYYY-MM-DD(ISO 8601 date format) - Example:
2025-07-20 - Maximum Range: 90 days between
fromandtodates - Timezone: All dates are in UTC
Date Range Limitations
- Minimum range: 1 day
- Maximum range: 90 days
- Past dates: API returns historical events with actual values
- Future dates: API returns scheduled events with estimates (actual values will be null)
Response Format
The API returns a JSON array of economic event objects.
Response Structure
[
{
"date": "2024-03-01 03:35:00",
"country": "JP",
"event": "3-Month Bill Auction",
"currency": "JPY",
"previous": -0.112,
"estimate": null,
"actual": -0.096,
"change": 0.016,
"impact": "Low",
"changePercentage": 14.286
}
]Response Fields
| Field | Type | Description | Nullable |
|---|---|---|---|
date | string | Event date and time in UTC (format: YYYY-MM-DD HH:MM:SS) | No |
country | string | ISO 2-letter country code (e.g., US, JP, GB, EU) | No |
event | string | Name/description of the economic event | No |
currency | string | ISO 3-letter currency code (e.g., USD, EUR, JPY) | No |
previous | number | Previous reading/value for this indicator | Yes |
estimate | number | Market consensus estimate/forecast | Yes |
actual | number | Actual released value (null for future events) | Yes |
change | number | Absolute change from previous reading | Yes |
impact | string | Market impact level: "High", "Medium", "Low" | No |
changePercentage | number | Percentage change from previous reading | Yes |
Field Details
`date`:
- Format:
YYYY-MM-DD HH:MM:SSin UTC timezone - Represents the scheduled release time for the economic data
- For future events, this is the expected release time
- Times may be adjusted if releases are delayed
`country`:
- ISO 3166-1 alpha-2 country codes
- Special codes:
EU: European Union (ECB-related events)G7: G7 summit/collaborative events- International organizations may use special codes
`event`:
- Descriptive name of the economic indicator or event
- Examples:
"Non-Farm Payrolls""Consumer Price Index (CPI)""Federal Funds Rate Decision""GDP Growth Rate QoQ""Unemployment Rate"
`currency`:
- ISO 4217 currency codes
- Indicates which currency's economy the event affects
- May differ from country (e.g., EU events affect EUR across multiple countries)
`previous`:
- The last reported value for this indicator
- Used as baseline for comparing current release
- May be revised from originally reported value
nullif no prior data available (new indicator)
`estimate`:
- Market consensus forecast compiled from analyst surveys
- Typically from Bloomberg, Reuters, or other consensus services
nullif no consensus exists or for less-watched indicators- Comparing
actualtoestimateshows "surprise" factor
`actual`:
- The officially released value when data is published
nullfor future events (not yet released)- This is the critical field that moves markets when released
- May be revised in subsequent releases (preliminary → final revisions)
`change`:
- Calculated as:
actual - previous(for past events) nullif eitheractualorpreviousis null- Sign indicates direction: positive = increase, negative = decrease
- Absolute value, not percentage
`impact`:
- Qualitative assessment of market-moving potential
- Three levels:
"High": Major market-moving events (NFP, FOMC, CPI)"Medium": Significant but less volatile (Retail Sales, PMI)"Low": Minor indicators, routine data releases- Determined by FMP based on historical volatility impact
`changePercentage`:
- Calculated as:
((actual - previous) / previous) * 100 nullif either value is null or ifpreviousis zero- Percentage representation of the change
- Useful for comparing relative magnitude across different indicators
Example Requests
Fetch Events for Next 7 Days
curl "https://financialmodelingprep.com/api/v3/economic_calendar?from=2025-01-01&to=2025-01-07&apikey=YOUR_API_KEY"Fetch High-Impact Events Only (Post-Processing)
Note: API does not have an impact filter parameter, so filtering must be done after retrieval.
import requests
response = requests.get(
"https://financialmodelingprep.com/api/v3/economic_calendar",
params={
"from": "2025-01-01",
"to": "2025-01-31",
"apikey": "YOUR_API_KEY"
}
)
events = response.json()
high_impact_events = [e for e in events if e["impact"] == "High"]Fetch Events for Specific Country (Post-Processing)
us_events = [e for e in events if e["country"] == "US"]
eu_events = [e for e in events if e["country"] == "EU"]Rate Limits
Rate limits depend on your FMP subscription tier:
| Tier | Requests/Day | Requests/Second |
|---|---|---|
| Free | 250 | 5 |
| Starter | 500 | 10 |
| Professional | 1,000+ | 20+ |
If you exceed rate limits, the API returns HTTP 429 (Too Many Requests).
Error Handling
HTTP Status Codes
| Code | Meaning | Description |
|---|---|---|
| 200 | Success | Request successful, data returned |
| 400 | Bad Request | Invalid parameters (malformed dates, missing required params) |
| 401 | Unauthorized | Invalid or missing API key |
| 403 | Forbidden | API key valid but lacks permission (expired subscription) |
| 429 | Too Many Requests | Rate limit exceeded |
| 500 | Internal Server Error | FMP server error (retry after delay) |
Error Response Format
{
"Error Message": "Invalid API KEY. Please retry or visit our documentation to create one FREE https://financialmodelingprep.com/developer/docs"
}Common Errors
Invalid API Key:
{"Error Message": "Invalid API KEY..."}Solution: Verify API key is correct, active subscription
Date Range Too Large:
{"Error Message": "Maximum date range is 90 days"}Solution: Reduce date range to 90 days or less
Rate Limit Exceeded:
- HTTP 429 response
Solution: Wait before next request, upgrade subscription tier
Best Practices
1. Respect Rate Limits
Implement exponential backoff for retries:
import time
def fetch_with_retry(url, params, max_retries=3):
for attempt in range(max_retries):
response = requests.get(url, params=params)
if response.status_code == 429:
wait_time = 2 ** attempt # Exponential backoff
time.sleep(wait_time)
continue
return response
raise Exception("Max retries exceeded")2. Cache Results
Economic calendar data doesn't change frequently once released:
- Cache past events indefinitely (actual values don't change)
- Cache future events for 1-24 hours (estimates rarely change)
- Refresh cache after event release time passes
3. Efficient Date Ranges
- Query 7-30 day ranges to minimize API calls
- Don't query dates more than 3-6 months in future (sparse data)
- Use smaller ranges (1-7 days) for real-time monitoring
4. Handle Null Values
Many fields can be null, especially for future events:
event_value = event.get("actual") or event.get("estimate") or event.get("previous")
if event_value is None:
print("No value available for this event")5. Time Zone Awareness
All API times are UTC:
from datetime import datetime, timezone
utc_time = datetime.strptime(event["date"], "%Y-%m-%d %H:%M:%S")
utc_time = utc_time.replace(tzinfo=timezone.utc)
# Convert to local timezone
local_time = utc_time.astimezone()Data Accuracy and Timeliness
Release Time Accuracy
- Most release times accurate within ±1 minute
- Delayed releases possible (technical issues, holidays)
- Times may shift due to daylight saving time changes
Data Revisions
Economic data is often revised:
- Preliminary: First release (most market impact)
- Revised: 1-2 months later
- Final: 2-3 months later
The API previous field reflects the latest revised value, not necessarily the original preliminary release.
Coverage
FMP Economic Calendar covers:
- Major Economies: US, EU, UK, Japan, China, Canada, Australia
- Event Types:
- Employment data (NFP, unemployment rate)
- Inflation (CPI, PPI, PCE)
- Growth (GDP, retail sales, industrial production)
- Central bank decisions (FOMC, ECB, BOJ, BOE)
- Surveys (PMI, consumer confidence, sentiment indices)
- Trade data (trade balance, exports/imports)
- Housing data (starts, permits, sales)
Comparison with Other Sources
| Feature | FMP API | Forex Factory | Investing.com |
|---|---|---|---|
| API Access | Yes | No (scraping only) | No (scraping only) |
| Historical Data | Yes | Limited | Yes (web only) |
| Free Tier | Yes (250/day) | N/A | N/A |
| Data Format | JSON | HTML | HTML |
| Reliability | High | Medium (changes) | Medium (changes) |
FMP is a reliable, legitimate API source compared to scraping financial calendar websites (which violates ToS and is fragile).
Support and Documentation
- Official Docs: https://financialmodelingprep.com/developer/docs/economic-calendar-api
- API Status: https://status.financialmodelingprep.com
- Support: support@financialmodelingprep.com
- Community: Active Discord and forum for FMP users
#!/usr/bin/env python3
"""
Economic Calendar Fetcher using FMP API
Retrieves economic events and data releases for specified date range
"""
import argparse
import json
import os
import sys
import urllib.error
import urllib.parse
import urllib.request
from datetime import datetime, timedelta
from typing import Optional
def get_api_key() -> Optional[str]:
"""
Get FMP API key from environment variable.
Returns:
API key string or None if not found
"""
api_key = os.environ.get("FMP_API_KEY")
if not api_key:
print("Warning: FMP_API_KEY environment variable not set", file=sys.stderr)
return api_key
def fetch_economic_calendar(from_date: str, to_date: str, api_key: str) -> list[dict]:
"""
Fetch economic calendar data from FMP API.
Args:
from_date: Start date in YYYY-MM-DD format
to_date: End date in YYYY-MM-DD format
api_key: FMP API key
Returns:
List of economic event dictionaries
Raises:
urllib.error.HTTPError: If API request fails
ValueError: If response is invalid
"""
base_url = "https://financialmodelingprep.com/stable/economics-calendar"
# Build query parameters (stable API uses apikey as query param)
params = {"from": from_date, "to": to_date, "apikey": api_key}
# Construct URL with parameters
url = f"{base_url}?{urllib.parse.urlencode(params)}"
try:
# Make API request
request = urllib.request.Request(url)
with urllib.request.urlopen(request) as response:
if response.status != 200:
raise ValueError(f"API returned status code {response.status}")
data = json.loads(response.read().decode("utf-8"))
if not isinstance(data, list):
raise ValueError(f"Unexpected API response format: {type(data)}")
return data
except urllib.error.HTTPError as e:
error_body = e.read().decode("utf-8") if e.fp else "No error details"
# Stable API returns 404 with [] when no events exist
if e.code == 404 and error_body.strip() == "[]":
return []
raise urllib.error.HTTPError(
e.url, e.code, f"FMP API error: {e.reason}. Details: {error_body}", e.hdrs, e.fp
)
except urllib.error.URLError as e:
raise ValueError(f"Network error: {e.reason}")
def validate_date_range(from_date: str, to_date: str) -> None:
"""
Validate date range is within FMP API limits (max 90 days).
Args:
from_date: Start date in YYYY-MM-DD format
to_date: End date in YYYY-MM-DD format
Raises:
ValueError: If date range is invalid or exceeds 90 days
"""
try:
start = datetime.strptime(from_date, "%Y-%m-%d")
end = datetime.strptime(to_date, "%Y-%m-%d")
except ValueError as e:
raise ValueError(f"Invalid date format. Use YYYY-MM-DD: {e}")
if start > end:
raise ValueError(f"Start date {from_date} is after end date {to_date}")
delta = (end - start).days
if delta > 90:
raise ValueError(f"Date range ({delta} days) exceeds maximum of 90 days")
# Warn if querying past dates
today = datetime.now().date()
if end.date() < today:
print(f"Warning: End date {to_date} is in the past", file=sys.stderr)
def format_event_output(events: list[dict], output_format: str = "json") -> str:
"""
Format economic events for output.
Args:
events: List of event dictionaries from FMP API
output_format: Output format ('json' or 'text')
Returns:
Formatted string
"""
if output_format == "json":
return json.dumps(events, indent=2, ensure_ascii=False)
elif output_format == "text":
lines = []
lines.append(f"Economic Calendar Events (Total: {len(events)})")
lines.append("=" * 80)
for event in events:
lines.append(f"\nDate: {event.get('date', 'N/A')}")
lines.append(f"Country: {event.get('country', 'N/A')}")
lines.append(f"Event: {event.get('event', 'N/A')}")
lines.append(f"Currency: {event.get('currency', 'N/A')}")
lines.append(f"Impact: {event.get('impact', 'N/A')}")
previous = event.get("previous")
estimate = event.get("estimate")
actual = event.get("actual")
if previous is not None:
lines.append(f"Previous: {previous}")
if estimate is not None:
lines.append(f"Estimate: {estimate}")
if actual is not None:
lines.append(f"Actual: {actual}")
change = event.get("change")
change_pct = event.get("changePercentage")
if change is not None:
lines.append(f"Change: {change}")
if change_pct is not None:
lines.append(f"Change %: {change_pct}%")
lines.append("-" * 80)
return "\n".join(lines)
else:
raise ValueError(f"Unknown output format: {output_format}")
def main():
"""Main execution function."""
parser = argparse.ArgumentParser(
description="Fetch economic calendar events from FMP API",
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog="""
Examples:
# Fetch events for next 7 days (default)
python get_economic_calendar.py
# Fetch events for specific date range
python get_economic_calendar.py --from 2025-01-01 --to 2025-01-31
# Provide API key via argument (overrides environment variable)
python get_economic_calendar.py --api-key YOUR_KEY_HERE
# Output as formatted text instead of JSON
python get_economic_calendar.py --format text
# Save output to file
python get_economic_calendar.py --output calendar.json
""",
)
# Date range arguments
today = datetime.now().date()
default_from = today.strftime("%Y-%m-%d")
default_to = (today + timedelta(days=7)).strftime("%Y-%m-%d")
parser.add_argument(
"--from",
dest="from_date",
default=default_from,
help=f"Start date in YYYY-MM-DD format (default: {default_from})",
)
parser.add_argument(
"--to",
dest="to_date",
default=default_to,
help=f"End date in YYYY-MM-DD format (default: {default_to})",
)
# API key argument
parser.add_argument(
"--api-key", dest="api_key", help="FMP API key (overrides FMP_API_KEY environment variable)"
)
# Output format
parser.add_argument(
"--format", choices=["json", "text"], default="json", help="Output format (default: json)"
)
# Output file
parser.add_argument("--output", "-o", help="Output file path (default: stdout)")
# Parse arguments
args = parser.parse_args()
# Get API key
api_key = args.api_key or get_api_key()
if not api_key:
print(
"Error: FMP API key is required. Set FMP_API_KEY environment variable or use --api-key",
file=sys.stderr,
)
sys.exit(1)
try:
# Validate date range
validate_date_range(args.from_date, args.to_date)
# Fetch events
print(
f"Fetching economic calendar from {args.from_date} to {args.to_date}...",
file=sys.stderr,
)
events = fetch_economic_calendar(args.from_date, args.to_date, api_key)
print(f"Retrieved {len(events)} events", file=sys.stderr)
# Format output
output = format_event_output(events, args.format)
# Write output
if args.output:
with open(args.output, "w", encoding="utf-8") as f:
f.write(output)
print(f"Output written to {args.output}", file=sys.stderr)
else:
print(output)
sys.exit(0)
except Exception as e:
print(f"Error: {e}", file=sys.stderr)
sys.exit(1)
if __name__ == "__main__":
main()
"""Tests for get_economic_calendar.py"""
import json
import os
import sys
from datetime import datetime, timedelta
import pytest
# Add parent directory to path so we can import the script module
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from get_economic_calendar import (
format_event_output,
get_api_key,
validate_date_range,
)
# ---------------------------------------------------------------------------
# Sample fixtures
# ---------------------------------------------------------------------------
SAMPLE_EVENTS = [
{
"date": "2025-01-15 14:30:00",
"country": "US",
"event": "Consumer Price Index (CPI) YoY",
"currency": "USD",
"previous": 2.6,
"estimate": 2.7,
"actual": None,
"change": None,
"impact": "High",
"changePercentage": None,
},
{
"date": "2025-01-16 10:00:00",
"country": "EU",
"event": "ECB Interest Rate Decision",
"currency": "EUR",
"previous": 4.5,
"estimate": 4.5,
"actual": None,
"change": None,
"impact": "High",
"changePercentage": None,
},
]
# ---------------------------------------------------------------------------
# get_api_key tests
# ---------------------------------------------------------------------------
class TestGetApiKey:
def test_returns_key_when_set(self, monkeypatch):
monkeypatch.setenv("FMP_API_KEY", "test_key_123")
assert get_api_key() == "test_key_123"
def test_returns_none_when_not_set(self, monkeypatch):
monkeypatch.delenv("FMP_API_KEY", raising=False)
assert get_api_key() is None
# ---------------------------------------------------------------------------
# validate_date_range tests
# ---------------------------------------------------------------------------
class TestValidateDateRange:
def test_valid_range(self):
validate_date_range("2025-01-01", "2025-01-31")
def test_same_day(self):
validate_date_range("2025-06-15", "2025-06-15")
def test_max_90_days(self):
validate_date_range("2025-01-01", "2025-03-31") # 89 days
def test_exceeds_90_days(self):
with pytest.raises(ValueError, match="exceeds maximum of 90 days"):
validate_date_range("2025-01-01", "2025-06-01")
def test_start_after_end(self):
with pytest.raises(ValueError, match="after end date"):
validate_date_range("2025-03-01", "2025-01-01")
def test_invalid_date_format(self):
with pytest.raises(ValueError, match="Invalid date format"):
validate_date_range("01-01-2025", "2025-01-31")
def test_invalid_date_value(self):
with pytest.raises(ValueError, match="Invalid date format"):
validate_date_range("2025-13-01", "2025-14-01")
def test_past_dates_warns(self, capsys):
past = (datetime.now() - timedelta(days=30)).strftime("%Y-%m-%d")
past_end = (datetime.now() - timedelta(days=20)).strftime("%Y-%m-%d")
validate_date_range(past, past_end)
captured = capsys.readouterr()
assert "in the past" in captured.err
# ---------------------------------------------------------------------------
# format_event_output tests
# ---------------------------------------------------------------------------
class TestFormatEventOutput:
def test_json_format_roundtrip(self):
output = format_event_output(SAMPLE_EVENTS, "json")
parsed = json.loads(output)
assert len(parsed) == 2
assert parsed[0]["event"] == "Consumer Price Index (CPI) YoY"
def test_json_empty_list(self):
output = format_event_output([], "json")
assert json.loads(output) == []
def test_text_format_header(self):
output = format_event_output(SAMPLE_EVENTS, "text")
assert "Total: 2" in output
def test_text_format_contains_event_name(self):
output = format_event_output(SAMPLE_EVENTS, "text")
assert "Consumer Price Index (CPI) YoY" in output
assert "ECB Interest Rate Decision" in output
def test_text_format_shows_previous(self):
output = format_event_output(SAMPLE_EVENTS, "text")
assert "Previous: 2.6" in output
def test_text_format_omits_none_actual(self):
output = format_event_output(SAMPLE_EVENTS, "text")
assert "Actual:" not in output
def test_text_format_shows_actual_when_present(self):
events = [
{
"date": "2025-01-10 14:30:00",
"country": "US",
"event": "NFP",
"currency": "USD",
"previous": 200,
"estimate": 210,
"actual": 256,
"change": 56,
"impact": "High",
"changePercentage": 28.0,
}
]
output = format_event_output(events, "text")
assert "Actual: 256" in output
assert "Change: 56" in output
assert "Change %: 28.0%" in output
def test_unknown_format_raises(self):
with pytest.raises(ValueError, match="Unknown output format"):
format_event_output([], "csv")
Related skills
How it compares
Use this skill for scheduled macro event calendars via FMP rather than real-time price streaming or broker order execution integrations.
FAQ
Which API endpoint does Economic Calendar Fetcher use?
Economic Calendar Fetcher documents the Financial Modeling Prep endpoint https://financialmodelingprep.com/api/v3/economic_calendar. It returns upcoming and historical economic data releases, central bank decisions, and other scheduled market-moving events.
How do you authenticate FMP economic calendar requests?
Economic Calendar Fetcher requires a valid FMP API key passed as the apikey query parameter on every request. Developers obtain keys by registering at financialmodelingprep.com.
Is Economic Calendar Fetcher safe to install?
skills.sh reports 3 of 3 security scanners passed. Review the Security Audits panel on this page before installing in production.