{ "cells": [ { "cell_type": "code", "execution_count": 5, "id": "e0114ca0-14f6-40f5-bbb2-a9a11cbf871b", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", " ╔═══════════════════════════════════════════════════════════════════════╗\n", " ║ MULTI-SOURCE NEWS FETCHER ║\n", " ║ For Trading & Economic News ║\n", " ╚═══════════════════════════════════════════════════════════════════════╝\n", "\n", " REQUIRED PACKAGES:\n", " pip install requests beautifulsoup4 pandas\n", "\n", " API KEYS (Optional but recommended):\n", " 1. Trading Economics: https://tradingeconomics.com/api/\n", " 2. NewsAPI.org: https://newsapi.org/\n", "\n", " \n", "\n", ">>> Fetching from free sources (Forex Factory & Investing.com)...\n", "\n", "\n", "====================================================================================================\n", "FETCHING NEWS FROM ALL SOURCES\n", "====================================================================================================\n", "\n", "[1/4] Fetching from Forex Factory...\n", "\n", "====================================================================================================\n", "FOREX FACTORY ECONOMIC CALENDAR\n", "====================================================================================================\n", "Error fetching Forex Factory data: 403 Client Error: Forbidden for url: https://www.forexfactory.com/calendar\n", "\n", "[2/4] Fetching from Investing.com...\n", "\n", "====================================================================================================\n", "INVESTING.COM ECONOMIC CALENDAR\n", "====================================================================================================\n", "\n", "Fetched 39 events from Investing.com\n", " Time Currency Importance Event Actual Forecast Previous\n", "01:00 RUB Medium S&P Global Services PMI (Dec) 52.3 52.2\n", "03:00 CHF Medium KOF Leading Indicators (Dec) 103.4 101.5 101.7\n", "03:00 EUR Low Core CPI (YoY) (Dec) 2.6% 2.6%\n", "03:00 EUR Low Spanish CPI (MoM) (Dec) 0.3% 0.2%\n", "03:00 EUR Medium Spanish CPI (YoY) (Dec) 2.9% 2.8% 3.0%\n", "03:00 EUR Low Spanish HICP (MoM) (Dec) 0.3% 0.0%\n", "03:00 EUR Medium Spanish HICP (YoY) (Dec) 3.0% 3.0% 3.2%\n", "03:00 EUR Low Spanish Retail Sales (YoY) (Nov) 6.0% 3.9%\n", "04:00 EUR Low Spanish Current account (Oct) 7.18B 1.87B\n", "06:17 ZAR Low Budget Balance (MoM) (Nov) -14.99B -35.83B\n", "06:30 BRL Low Net Debt-to-GDP ratio (Nov) 65.2% 65.0%\n", "06:30 BRL Low Budget Balance (Nov) -101.600B -86.400B -81.522B\n", "06:30 BRL Low Budget Surplus (Nov) -14.400B 32.392B\n", "06:30 BRL Medium Gross Debt-to-GDP ratio (MoM) (Nov) 79.0% 79.0% 78.6%\n", "07:00 INR Low Foreign Debt (USD) (Q3) 746.0B 747.2B\n", "07:00 INR Low M3 Money Supply 9.3% 10.2%\n", "07:00 BRL Medium Unemployment Rate (Nov) 5.2% 5.4% 5.4%\n", "08:55 USD Low Redbook (YoY) 7.6% 7.2%\n", "09:00 USD Low House Price Index (MoM) (Oct) 0.4% 0.1% -0.1%\n", "09:00 USD Low House Price Index (YoY) (Oct) 1.7% 1.8%\n", "09:00 USD Low House Price Index (Oct) 436.7 435.2\n", "09:00 USD Low S&P/CS HPI Composite - 20 s.a. (MoM) (Oct) 0.3% 0.2%\n", "09:00 USD Medium S&P/CS HPI Composite - 20 n.s.a. (YoY) (Oct) 1.3% 1.1% 1.4%\n", "09:00 USD Medium S&P/CS HPI Composite - 20 n.s.a. (MoM) (Oct) -0.3% -0.5%\n", "09:45 USD High Chicago PMI (Dec) 43.5 39.8 36.3\n", "10:30 USD Low Dallas Fed Services Revenues (Dec) 0.1 -2.5\n", "10:30 USD Low Texas Services Sector Outlook (Dec) -3.3 -2.3\n", "12:00 BRL Low CAGED Net Payroll Jobs (Nov) 85.86K 75.00K 85.15K\n", "13:00 USD Medium U.S. Baker Hughes Oil Rig Count 412 409\n", "13:00 USD Medium U.S. Baker Hughes Total Rig Count 546 545\n", "14:00 USD High FOMC Meeting Minutes \n", "16:30 USD Medium API Weekly Crude Oil Stock 1.700M 2.400M\n", "18:00 KRW Low CPI (YoY) (Dec) 2.3% 2.3% 2.4%\n", "18:00 KRW Low CPI (MoM) (Dec) 0.3% 0.2% -0.2%\n", "20:30 CNY Medium Chinese Composite PMI (Dec) 50.7 49.7\n", "20:30 CNY High Manufacturing PMI (Dec) 50.1 49.2 49.2\n", "20:30 CNY Medium Non-Manufacturing PMI (Dec) 50.2 49.6 49.5\n", "20:45 CNY Medium Caixin Manufacturing PMI (MoM) (Dec) 50.1 49.8 49.9\n", "23:30 SGD Low Bank Lending (Nov) 866.1B\n", "\n", "[3/4] Fetching from Trading Economics...\n", "\n", "====================================================================================================\n", "TRADING ECONOMICS API\n", "====================================================================================================\n", "\n", "API Key required!\n", "Get your free API key at: https://tradingeconomics.com/api/\n", "Then call: fetch_trading_economics_news(api_key='YOUR_KEY')\n", "\n", "[4/4] Fetching from NewsAPI.org...\n", "\n", "====================================================================================================\n", "NEWSAPI.ORG - FINANCIAL NEWS\n", "====================================================================================================\n", "\n", "API Key required!\n", "Get your free API key at: https://newsapi.org/\n", "Then call: fetch_newsapi_org(api_key='YOUR_KEY')\n", "\n", "====================================================================================================\n", "SUMMARY\n", "====================================================================================================\n", "✗ forexfactory: Failed or requires API key\n", "✓ investing: 39 items fetched\n", "✗ trading_economics: Failed or requires API key\n", "✗ newsapi: Failed or requires API key\n" ] } ], "source": [ "import requests\n", "from bs4 import BeautifulSoup\n", "import pandas as pd\n", "from datetime import datetime, timedelta\n", "import json\n", "\n", "# ============================================================================\n", "# 1. FOREX FACTORY CALENDAR API (Web Scraping - No official API)\n", "# ============================================================================\n", "\n", "def fetch_forexfactory_news():\n", " \"\"\"\n", " Fetch economic calendar from Forex Factory\n", " Note: Forex Factory doesn't have an official API, so we scrape the website\n", " \"\"\"\n", " print(\"\\n\" + \"=\"*100)\n", " print(\"FOREX FACTORY ECONOMIC CALENDAR\")\n", " print(\"=\"*100)\n", " \n", " try:\n", " url = \"https://www.forexfactory.com/calendar\"\n", " headers = {\n", " 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'\n", " }\n", " \n", " response = requests.get(url, headers=headers, timeout=10)\n", " response.raise_for_status()\n", " \n", " soup = BeautifulSoup(response.content, 'html.parser')\n", " \n", " # Find calendar table\n", " calendar_rows = soup.find_all('tr', class_='calendar__row')\n", " \n", " events = []\n", " current_date = None\n", " \n", " for row in calendar_rows:\n", " # Get date if available\n", " date_cell = row.find('td', class_='calendar__cell calendar__date')\n", " if date_cell and date_cell.text.strip():\n", " current_date = date_cell.text.strip()\n", " \n", " # Get time\n", " time_cell = row.find('td', class_='calendar__cell calendar__time')\n", " time_str = time_cell.text.strip() if time_cell else ''\n", " \n", " # Get currency\n", " currency_cell = row.find('td', class_='calendar__cell calendar__currency')\n", " currency = currency_cell.text.strip() if currency_cell else ''\n", " \n", " # Get impact (importance)\n", " impact_cell = row.find('td', class_='calendar__cell calendar__impact')\n", " impact_span = impact_cell.find('span') if impact_cell else None\n", " impact = ''\n", " if impact_span:\n", " if 'icon--ff-impact-red' in impact_span.get('class', []):\n", " impact = 'High'\n", " elif 'icon--ff-impact-ora' in impact_span.get('class', []):\n", " impact = 'Medium'\n", " elif 'icon--ff-impact-yel' in impact_span.get('class', []):\n", " impact = 'Low'\n", " \n", " # Get event name\n", " event_cell = row.find('td', class_='calendar__cell calendar__event')\n", " event_name = event_cell.text.strip() if event_cell else ''\n", " \n", " # Get actual, forecast, previous values\n", " actual_cell = row.find('td', class_='calendar__cell calendar__actual')\n", " actual = actual_cell.text.strip() if actual_cell else ''\n", " \n", " forecast_cell = row.find('td', class_='calendar__cell calendar__forecast')\n", " forecast = forecast_cell.text.strip() if forecast_cell else ''\n", " \n", " previous_cell = row.find('td', class_='calendar__cell calendar__previous')\n", " previous = previous_cell.text.strip() if previous_cell else ''\n", " \n", " if event_name:\n", " events.append({\n", " 'Date': current_date,\n", " 'Time': time_str,\n", " 'Currency': currency,\n", " 'Impact': impact,\n", " 'Event': event_name,\n", " 'Actual': actual,\n", " 'Forecast': forecast,\n", " 'Previous': previous\n", " })\n", " \n", " if events:\n", " df = pd.DataFrame(events)\n", " print(f\"\\nFetched {len(events)} events from Forex Factory\")\n", " print(df.to_string(index=False))\n", " return df\n", " else:\n", " print(\"No events found\")\n", " return None\n", " \n", " except Exception as e:\n", " print(f\"Error fetching Forex Factory data: {e}\")\n", " return None\n", "\n", "# ============================================================================\n", "# 2. INVESTING.COM ECONOMIC CALENDAR (Web Scraping)\n", "# ============================================================================\n", "\n", "def fetch_investing_com_news():\n", " \"\"\"\n", " Fetch economic calendar from Investing.com\n", " Note: Requires web scraping as API access is restricted\n", " \"\"\"\n", " print(\"\\n\" + \"=\"*100)\n", " print(\"INVESTING.COM ECONOMIC CALENDAR\")\n", " print(\"=\"*100)\n", " \n", " try:\n", " url = \"https://www.investing.com/economic-calendar/\"\n", " headers = {\n", " 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'\n", " }\n", " \n", " response = requests.get(url, headers=headers, timeout=10)\n", " response.raise_for_status()\n", " \n", " soup = BeautifulSoup(response.content, 'html.parser')\n", " \n", " # Find economic calendar events\n", " events = []\n", " \n", " # Look for calendar table/rows (structure may vary)\n", " table = soup.find('table', {'id': 'economicCalendarData'})\n", " \n", " if table:\n", " rows = table.find_all('tr', class_='js-event-item')\n", " \n", " for row in rows:\n", " time_cell = row.find('td', class_='time')\n", " currency_cell = row.find('td', class_='flagCur')\n", " event_cell = row.find('td', class_='event')\n", " actual_cell = row.find('td', {'id': lambda x: x and 'eventActual' in x})\n", " forecast_cell = row.find('td', {'id': lambda x: x and 'eventForecast' in x})\n", " previous_cell = row.find('td', {'id': lambda x: x and 'eventPrevious' in x})\n", " \n", " # Get importance (bull icons)\n", " importance_cell = row.find('td', class_='sentiment')\n", " importance = 'Low'\n", " if importance_cell:\n", " bulls = len(importance_cell.find_all('i', class_='grayFullBullishIcon'))\n", " if bulls == 3:\n", " importance = 'High'\n", " elif bulls == 2:\n", " importance = 'Medium'\n", " \n", " events.append({\n", " 'Time': time_cell.text.strip() if time_cell else '',\n", " 'Currency': currency_cell.text.strip() if currency_cell else '',\n", " 'Importance': importance,\n", " 'Event': event_cell.text.strip() if event_cell else '',\n", " 'Actual': actual_cell.text.strip() if actual_cell else '',\n", " 'Forecast': forecast_cell.text.strip() if forecast_cell else '',\n", " 'Previous': previous_cell.text.strip() if previous_cell else ''\n", " })\n", " \n", " if events:\n", " df = pd.DataFrame(events)\n", " print(f\"\\nFetched {len(events)} events from Investing.com\")\n", " print(df.to_string(index=False))\n", " return df\n", " else:\n", " print(\"No events found or structure changed\")\n", " return None\n", " \n", " except Exception as e:\n", " print(f\"Error fetching Investing.com data: {e}\")\n", " return None\n", "\n", "# ============================================================================\n", "# 3. TRADING ECONOMICS API (Requires API Key)\n", "# ============================================================================\n", "\n", "def fetch_trading_economics_news(api_key=None):\n", " \"\"\"\n", " Fetch economic calendar from Trading Economics API\n", " Get free API key at: https://tradingeconomics.com/api/\n", " \"\"\"\n", " print(\"\\n\" + \"=\"*100)\n", " print(\"TRADING ECONOMICS API\")\n", " print(\"=\"*100)\n", " \n", " if not api_key:\n", " print(\"\\nAPI Key required!\")\n", " print(\"Get your free API key at: https://tradingeconomics.com/api/\")\n", " print(\"Then call: fetch_trading_economics_news(api_key='YOUR_KEY')\")\n", " return None\n", " \n", " try:\n", " # Get today's calendar\n", " today = datetime.now().strftime('%Y-%m-%d')\n", " url = f\"https://api.tradingeconomics.com/calendar/country/all/{today}\"\n", " \n", " params = {\n", " 'c': api_key,\n", " 'f': 'json'\n", " }\n", " \n", " response = requests.get(url, params=params, timeout=10)\n", " response.raise_for_status()\n", " \n", " data = response.json()\n", " \n", " if data:\n", " events = []\n", " for item in data:\n", " events.append({\n", " 'Date': item.get('Date'),\n", " 'Country': item.get('Country'),\n", " 'Category': item.get('Category'),\n", " 'Event': item.get('Event'),\n", " 'Importance': item.get('Importance', 'N/A'),\n", " 'Actual': item.get('Actual'),\n", " 'Forecast': item.get('Forecast'),\n", " 'Previous': item.get('Previous'),\n", " 'Currency': item.get('Currency')\n", " })\n", " \n", " df = pd.DataFrame(events)\n", " print(f\"\\nFetched {len(events)} events from Trading Economics\")\n", " print(df.to_string(index=False))\n", " return df\n", " else:\n", " print(\"No events found\")\n", " return None\n", " \n", " except Exception as e:\n", " print(f\"Error fetching Trading Economics data: {e}\")\n", " return None\n", "\n", "# ============================================================================\n", "# 4. NEWSAPI.ORG (General News - Requires API Key)\n", "# ============================================================================\n", "\n", "def fetch_newsapi_org(api_key=None, query='forex OR economy OR trading', days_back=1):\n", " \"\"\"\n", " Fetch general news from NewsAPI.org\n", " Get free API key at: https://newsapi.org/\n", " \"\"\"\n", " print(\"\\n\" + \"=\"*100)\n", " print(\"NEWSAPI.ORG - FINANCIAL NEWS\")\n", " print(\"=\"*100)\n", " \n", " if not api_key:\n", " print(\"\\nAPI Key required!\")\n", " print(\"Get your free API key at: https://newsapi.org/\")\n", " print(\"Then call: fetch_newsapi_org(api_key='YOUR_KEY')\")\n", " return None\n", " \n", " try:\n", " # Calculate date range\n", " from_date = (datetime.now() - timedelta(days=days_back)).strftime('%Y-%m-%d')\n", " \n", " url = \"https://newsapi.org/v2/everything\"\n", " \n", " params = {\n", " 'apiKey': api_key,\n", " 'q': query,\n", " 'from': from_date,\n", " 'sortBy': 'publishedAt',\n", " 'language': 'en',\n", " 'pageSize': 100\n", " }\n", " \n", " response = requests.get(url, params=params, timeout=10)\n", " response.raise_for_status()\n", " \n", " data = response.json()\n", " \n", " if data.get('status') == 'ok' and data.get('articles'):\n", " articles = data['articles']\n", " \n", " news_list = []\n", " for article in articles:\n", " news_list.append({\n", " 'Published': article.get('publishedAt'),\n", " 'Source': article.get('source', {}).get('name'),\n", " 'Title': article.get('title'),\n", " 'Description': article.get('description'),\n", " 'URL': article.get('url')\n", " })\n", " \n", " df = pd.DataFrame(news_list)\n", " print(f\"\\nFetched {len(news_list)} news articles\")\n", " print(df[['Published', 'Source', 'Title']].to_string(index=False))\n", " return df\n", " else:\n", " print(f\"No articles found or error: {data.get('message', 'Unknown error')}\")\n", " return None\n", " \n", " except Exception as e:\n", " print(f\"Error fetching NewsAPI data: {e}\")\n", " return None\n", "\n", "# ============================================================================\n", "# MAIN FUNCTION - FETCH FROM ALL SOURCES\n", "# ============================================================================\n", "\n", "def fetch_all_news(trading_economics_key=None, newsapi_key=None):\n", " \"\"\"\n", " Fetch news from all available sources\n", " \"\"\"\n", " print(\"\\n\" + \"=\"*100)\n", " print(\"FETCHING NEWS FROM ALL SOURCES\")\n", " print(\"=\"*100)\n", " \n", " results = {}\n", " \n", " # 1. Forex Factory (free, no API key needed)\n", " print(\"\\n[1/4] Fetching from Forex Factory...\")\n", " results['forexfactory'] = fetch_forexfactory_news()\n", " \n", " # 2. Investing.com (free, no API key needed)\n", " print(\"\\n[2/4] Fetching from Investing.com...\")\n", " results['investing'] = fetch_investing_com_news()\n", " \n", " # 3. Trading Economics (requires API key)\n", " print(\"\\n[3/4] Fetching from Trading Economics...\")\n", " results['trading_economics'] = fetch_trading_economics_news(trading_economics_key)\n", " \n", " # 4. NewsAPI.org (requires API key)\n", " print(\"\\n[4/4] Fetching from NewsAPI.org...\")\n", " results['newsapi'] = fetch_newsapi_org(newsapi_key)\n", " \n", " print(\"\\n\" + \"=\"*100)\n", " print(\"SUMMARY\")\n", " print(\"=\"*100)\n", " for source, data in results.items():\n", " if data is not None:\n", " print(f\"✓ {source}: {len(data)} items fetched\")\n", " else:\n", " print(f\"✗ {source}: Failed or requires API key\")\n", " \n", " return results\n", "\n", "# ============================================================================\n", "# USAGE EXAMPLES\n", "# ============================================================================\n", "\n", "if __name__ == \"__main__\":\n", " print(\"\"\"\n", " ╔═══════════════════════════════════════════════════════════════════════╗\n", " ║ MULTI-SOURCE NEWS FETCHER ║\n", " ║ For Trading & Economic News ║\n", " ╚═══════════════════════════════════════════════════════════════════════╝\n", " \n", " REQUIRED PACKAGES:\n", " pip install requests beautifulsoup4 pandas\n", " \n", " API KEYS (Optional but recommended):\n", " 1. Trading Economics: https://tradingeconomics.com/api/\n", " 2. NewsAPI.org: https://newsapi.org/\n", " \n", " \"\"\")\n", " \n", " # Option 1: Fetch from all sources (free sources only)\n", " print(\"\\n>>> Fetching from free sources (Forex Factory & Investing.com)...\\n\")\n", " results = fetch_all_news()\n", " \n", " # Option 2: Fetch with API keys (uncomment and add your keys)\n", " # results = fetch_all_news(\n", " # trading_economics_key='YOUR_TRADING_ECONOMICS_KEY',\n", " # newsapi_key='YOUR_NEWSAPI_KEY'\n", " # )\n", " \n", " # Option 3: Fetch from individual sources\n", " # df_ff = fetch_forexfactory_news()\n", " # df_inv = fetch_investing_com_news()\n", " # df_te = fetch_trading_economics_news('YOUR_KEY')\n", " # df_news = fetch_newsapi_org('YOUR_KEY')" ] }, { "cell_type": "code", "execution_count": null, "id": "cf9fcbcc-1b52-4698-8a2c-89c609751810", "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.13.9" } }, "nbformat": 4, "nbformat_minor": 5 }