Historical exchange rate data is essential for forex analysis, international business planning, and financial research. This guide shows you how to build a scraper that collects and analyzes currency exchange rates over time.
Why Scrape Exchange Rates?
Commercial forex data APIs charge hundreds per month. Many free sources limit historical access. Web scraping lets you build comprehensive datasets going back years from multiple sources.
Setup
pip install requests beautifulsoup4 pandas matplotlib
Scraping Exchange Rate Data
Here's a scraper for historical exchange rates:
import requests
from bs4 import BeautifulSoup
import pandas as pd
from datetime import datetime, timedelta
def scrape_exchange_rates(base="USD", target="EUR", days=365):
rates = []
for i in range(0, days, 30): # Monthly snapshots
date = (datetime.now() - timedelta(days=i)).strftime("%Y-%m-%d")
params = {
"api_key": "YOUR_SCRAPERAPI_KEY",
"url": f"https://www.x-rates.com/historical/?from={base}&amount=1&date={date}"
}
response = requests.get("https://api.scraperapi.com", params=params)
soup = BeautifulSoup(response.text, "html.parser")
table = soup.select_one(".ratesTable")
if table:
for row in table.select("tr")[1:]:
cells = row.select("td")
if len(cells) >= 2:
currency = cells[0].text.strip()
rate = cells[1].text.strip()
try:
rates.append({
"date": date,
"base": base,
"currency": currency,
"rate": float(rate)
})
except ValueError:
continue
return pd.DataFrame(rates)
df = scrape_exchange_rates("USD", "EUR", 365)
print(f"Collected {len(df)} rate records")
Multi-Currency Collection
Scrape rates for a basket of currencies simultaneously:
def scrape_currency_basket(base="USD", targets=None, days=180):
if targets is None:
targets = ["EUR", "GBP", "JPY", "CHF", "AUD", "CAD", "CNY"]
all_rates = scrape_exchange_rates(base, targets[0], days)
# Filter for target currencies
basket = all_rates[all_rates["currency"].isin(targets)]
return basket.pivot(index="date", columns="currency", values="rate")
basket = scrape_currency_basket()
print(basket.head(10))
Analyzing Exchange Rate Trends
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
def analyze_volatility(df, currency):
currency_data = df[currency].dropna().sort_index()
# Calculate daily returns
returns = currency_data.pct_change().dropna()
volatility = returns.std() * (252 ** 0.5) # Annualized
mean_rate = currency_data.mean()
min_rate = currency_data.min()
max_rate = currency_data.max()
spread = (max_rate - min_rate) / mean_rate * 100
print(f"\n{currency} Analysis:")
print(f" Mean rate: {mean_rate:.4f}")
print(f" Range: {min_rate:.4f} - {max_rate:.4f}")
print(f" Spread: {spread:.2f}%")
print(f" Annualized volatility: {volatility:.4f}")
return {"volatility": volatility, "spread": spread, "mean": mean_rate}
for currency in ["EUR", "GBP", "JPY"]:
analyze_volatility(basket, currency)
Building a Rate Alert System
def check_rate_alerts(current_rates, alerts):
triggered = []
for alert in alerts:
currency = alert["currency"]
if currency in current_rates:
rate = current_rates[currency]
if alert["direction"] == "above" and rate > alert["threshold"]:
triggered.append({
"currency": currency,
"rate": rate,
"threshold": alert["threshold"],
"direction": "above"
})
elif alert["direction"] == "below" and rate < alert["threshold"]:
triggered.append({
"currency": currency,
"rate": rate,
"threshold": alert["threshold"],
"direction": "below"
})
return triggered
my_alerts = [
{"currency": "EUR", "direction": "below", "threshold": 0.90},
{"currency": "GBP", "direction": "above", "threshold": 0.82},
{"currency": "JPY", "direction": "above", "threshold": 155.0},
]
# Check latest rates against alerts
latest = basket.iloc[-1].to_dict()
triggered = check_rate_alerts(latest, my_alerts)
for t in triggered:
print(f"ALERT: {t['currency']} is {t['direction']} {t['threshold']} (current: {t['rate']:.4f})")
Recommended Scraping Tools
- ScraperAPI handles JavaScript rendering and proxy rotation for financial sites
- ThorData provides geo-targeted proxies for region-specific exchange rates
- ScrapeOps monitors your scraping pipeline health
Conclusion
Building your own exchange rate scraper gives you unlimited historical data without expensive API subscriptions. Start with major currency pairs, validate your data against known rates, and gradually expand your coverage. Always implement rate limiting and respect the source websites' usage policies.
Top comments (0)