CodeForFinance
Python

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 pandas

Step 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    coingecko

Next 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.

Browse All Tutorials →

Developer Essentials

As an Amazon Associate we may earn from qualifying purchases.