Fetching Market Data from Financial APIs
Every finance project starts with data. But market data is scattered across dozens of sources with different formats and rate limits. In this tutorial, we build a unified data pipeline that pulls from three free APIs and normalises everything into a consistent format.
Prerequisites
- ✓Basic Python
- ✓Understanding of REST APIs
- ✓Free API keys
Step 1.Install dependencies
requests for direct API calls, yfinance as a Yahoo Finance wrapper.
pip install requests yfinance pandasStep 2.Alpha Vantage: stock fundamentals
Alpha Vantage gives 5 free API calls per minute. Good for fundamentals and historical data.
import requests
import pandas as pd
from datetime import datetime
AV_KEY = "YOUR_KEY" # Get free at alphavantage.co
def alpha_vantage_quote(symbol: str) -> dict:
url = "https://www.alphavantage.co/query"
params = {
"function": "GLOBAL_QUOTE",
"symbol": symbol,
"apikey": AV_KEY
}
r = requests.get(url, params=params, timeout=10)
data = r.json().get("Global Quote", {})
return {
"symbol": data.get("01. symbol"),
"price": float(data.get("05. price", 0)),
"change_pct": data.get("10. change percent"),
"volume": int(data.get("06. volume", 0)),
"source": "alpha_vantage",
"timestamp": datetime.now().isoformat()
}
quote = alpha_vantage_quote("AAPL")
for k, v in quote.items():
print(f"{k}: {v}")Step 3.Yahoo Finance: historical OHLCV
yfinance is the easiest way to get OHLCV data. No API key needed but has rate limits.
import yfinance as yf
def yahoo_historical(symbol: str, period: str = "1mo") -> pd.DataFrame:
ticker = yf.Ticker(symbol)
df = ticker.history(period=period)
df = df[["Open", "High", "Low", "Close", "Volume"]]
df.columns = ["open", "high", "low", "close", "volume"]
df["source"] = "yahoo_finance"
return df
df = yahoo_historical("MSFT", "3mo")
print(f"Got {len(df)} days of MSFT data")
print(df.tail())Step 4.CoinGecko: crypto prices
CoinGecko is free with no API key for basic usage. Great for crypto data.
def coingecko_prices(coins: list) -> pd.DataFrame:
url = "https://api.coingecko.com/api/v3/simple/price"
params = {
"ids": ",".join(coins),
"vs_currencies": "usd,gbp",
"include_24hr_change": "true",
"include_market_cap": "true"
}
r = requests.get(url, params=params, timeout=10)
data = r.json()
rows = []
for coin, vals in data.items():
rows.append({
"symbol": coin,
"price_usd": vals.get("usd"),
"price_gbp": vals.get("gbp"),
"change_24h": vals.get("usd_24h_change"),
"market_cap": vals.get("usd_market_cap"),
"source": "coingecko"
})
return pd.DataFrame(rows)
crypto = coingecko_prices(["bitcoin", "ethereum", "solana"])
print(crypto.to_string(index=False))Step 5.Build unified data pipeline
A unified interface means the rest of your code does not need to know which API is being used.
class MarketDataPipeline:
def __init__(self, av_key: str = None):
self.av_key = av_key
self.cache = {}
def get_stock_price(self, symbol: str) -> dict:
ticker = yf.Ticker(symbol)
info = ticker.fast_info
return {
"symbol": symbol,
"price": round(info.last_price, 2),
"source": "yahoo",
"timestamp": datetime.now().isoformat()
}
def get_crypto_price(self, coin: str) -> dict:
df = coingecko_prices([coin])
return df.iloc[0].to_dict() if len(df) > 0 else {}
def get_historical(self, symbol: str, days: int = 30) -> pd.DataFrame:
return yahoo_historical(symbol, f"{days}d")
pipeline = MarketDataPipeline()
aapl = pipeline.get_stock_price("AAPL")
print(f'AAPL: ${aapl["price"]}')
btc = pipeline.get_crypto_price("bitcoin")
print(f'BTC: ${btc.get("price_usd", "N/A")}')Expected Output
Got 63 days of MSFT data
AAPL: $195.20
BTC: $84250.00
symbol price_usd price_gbp change_24h market_cap source
bitcoin 84250.00 67400.00 2.31 1.65e+12 coingecko
ethereum 3180.00 2544.00 1.85 3.82e+11 coingecko
solana 142.50 114.00 4.12 6.45e+10 coingeckoNext Steps
- →Add Redis caching to avoid hitting rate limits
- →Store data in a time-series database (InfluxDB)
- →Add WebSocket connections for real-time streaming
Recommended Reading
Python for Algorithmic Trading →As an Amazon Associate we may earn from qualifying purchases.