Python Stock API Tutorial:
Get Real-Time Market Data
in Minutes [2026]

Tutorial March 13, 2026 15 min read

This is the complete Python stock API tutorial for 2026. You will build three real mini-projects — a portfolio tracker, a moving average calculator, and an earnings calendar — all powered by the MarketLens API with 222+ free endpoints.

By the end of this guide, you will have working Python scripts that fetch real-time stock data, compute technical indicators, track earnings dates, and send price alerts via webhooks. We also cover async requests, error handling, and how MarketLens compares to yfinance, Alpha Vantage, and Polygon.

Get 50% off with code FOUNDER50

500 calls/day on the free tier. Use FOUNDER50 for 50% off Pro when you need more.

View Pricing

What You Will Build

The portfolio tracker will:

  • Fetch real-time stock quotes for all your holdings via the MarketLens API
  • Calculate unrealized P&L (profit and loss) per position and for the total portfolio
  • Show percentage returns and total portfolio value
  • Pull historical price data for performance charting
  • Set up price alerts via the MarketLens webhook system

Prerequisites

  • Python 3.10 or later
  • A free MarketLens API key (500 calls/day on the free tier)
  • Basic Python knowledge (dicts, lists, f-strings)

Install the dependencies:

bash
pip install requests pandas tabulate

Download: Python Stock API Tutorial PDF

Get the complete tutorial as a PDF + bonus code snippets. Free API key included (500 calls/day).

Join 15,000+ developers. No spam.

1Get Your Free MarketLens API Key

Head to marketlens.dev/signup and create a free account. Your API key will appear on the dashboard immediately. The free tier gives you 500 API calls per day -- more than enough for a portfolio tracker that updates every few minutes.

python
import requests
import pandas as pd
from tabulate import tabulate

# Replace with your API key from https://marketlens.dev/checkout.html
API_KEY = "ml_your_api_key_here"
BASE_URL = "https://marketlens.dev/api/v1"
HEADERS = {"X-API-Key": API_KEY}

2Define Your Portfolio

Define your holdings as a list of dictionaries. Each entry has a ticker symbol, number of shares, and your average cost basis (the price you paid per share).

python
# Define your portfolio: symbol, shares, cost basis per share
portfolio = [
    {"symbol": "AAPL",  "shares": 50,  "cost_basis": 178.50},
    {"symbol": "MSFT",  "shares": 30,  "cost_basis": 415.20},
    {"symbol": "GOOGL", "shares": 20,  "cost_basis": 141.30},
    {"symbol": "NVDA",  "shares": 25,  "cost_basis": 875.00},
    {"symbol": "TSLA",  "shares": 15,  "cost_basis": 245.80},
]

3Fetch Real-Time Stock Prices

The MarketLens /stocks/{symbol} endpoint returns real-time quotes including price, change, volume, and more. Let us write a function that fetches a quote for any symbol.

python
def get_quote(symbol: str) -> dict:
    """Fetch a real-time stock quote from MarketLens."""
    url = f"{BASE_URL}/stocks/{symbol}"
    resp = requests.get(url, headers=HEADERS)
    resp.raise_for_status()
    return resp.json()["data"]

# Example: fetch Apple's current price
quote = get_quote("AAPL")
print(f"AAPL: ${quote['price']} ({quote['change_pct']}%)")
# Output: AAPL: $198.45 (+1.23%)

The response includes price, change_pct, volume, high, low, and market_cap. Each quote uses 1 API credit.

4Calculate Portfolio P&L

Now combine your portfolio positions with live prices to calculate the unrealized profit or loss for each holding and the total portfolio.

python
def calculate_portfolio(holdings: list) -> pd.DataFrame:
    """Calculate P&L for each position and the full portfolio."""
    rows = []
    for pos in holdings:
        quote = get_quote(pos["symbol"])
        current_price = quote["price"]
        cost = pos["cost_basis"]
        shares = pos["shares"]

        market_value = current_price * shares
        total_cost = cost * shares
        pnl = market_value - total_cost
        pnl_pct = (pnl / total_cost) * 100

        rows.append({
            "Symbol": pos["symbol"],
            "Shares": shares,
            "Cost Basis": f"${cost:,.2f}",
            "Current Price": f"${current_price:,.2f}",
            "Market Value": f"${market_value:,.2f}",
            "P&L": f"${pnl:,.2f}",
            "P&L %": f"{pnl_pct:+.2f}%",
        })

    return pd.DataFrame(rows)

# Run it
df = calculate_portfolio(portfolio)
print(tabulate(df, headers="keys", tablefmt="github", showindex=False))

Sample output:

output
| Symbol | Shares | Cost Basis | Current Price | Market Value  | P&L        | P&L %   |
|--------|--------|------------|---------------|---------------|------------|---------|
| AAPL   |     50 | $178.50    | $198.45       | $9,922.50     | $997.50    | +11.18% |
| MSFT   |     30 | $415.20    | $432.10       | $12,963.00    | $507.00    | +4.07%  |
| GOOGL  |     20 | $141.30    | $168.75       | $3,375.00     | $549.00    | +19.43% |
| NVDA   |     25 | $875.00    | $924.30       | $23,107.50    | $1,232.50  | +5.63%  |
| TSLA   |     15 | $245.80    | $251.20       | $3,768.00     | $81.00     | +2.20%  |

5Portfolio Summary Statistics

Add a summary section that shows total portfolio value, total cost, and overall return.

python
def portfolio_summary(holdings: list):
    """Print a portfolio summary with total value and return."""
    total_value = 0
    total_cost = 0

    for pos in holdings:
        quote = get_quote(pos["symbol"])
        total_value += quote["price"] * pos["shares"]
        total_cost += pos["cost_basis"] * pos["shares"]

    total_pnl = total_value - total_cost
    total_return = (total_pnl / total_cost) * 100

    print(f"\n{'='*45}")
    print(f"  Portfolio Value:  ${total_value:>12,.2f}")
    print(f"  Total Cost:       ${total_cost:>12,.2f}")
    print(f"  Total P&L:        ${total_pnl:>12,.2f}")
    print(f"  Total Return:      {total_return:>11.2f}%")
    print(f"{'='*45}")

6Fetch Historical Performance

The MarketLens /stocks/{symbol}/history endpoint returns OHLCV data for any time range. Use it to chart your portfolio's historical performance.

python
def get_history(symbol: str, period: str = "3m") -> pd.DataFrame:
    """Fetch historical OHLCV data for a stock.

    Periods: 1d, 5d, 1m, 3m, 6m, 1y, 5y
    """
    url = f"{BASE_URL}/stocks/{symbol}/history"
    resp = requests.get(url, headers=HEADERS, params={"period": period})
    resp.raise_for_status()
    data = resp.json()["data"]["history"]
    return pd.DataFrame(data)

# Get 3 months of AAPL history
aapl_history = get_history("AAPL", "3m")
print(aapl_history[["date", "close", "volume"]].tail())
# Output:
#          date   close     volume
# 60 2026-03-07  196.30   45123000
# 61 2026-03-10  197.85   38456000
# 62 2026-03-11  199.10   42789000
# 63 2026-03-12  197.20   36912000
# 64 2026-03-13  198.45   41234000

7Set Up Price Alerts

MarketLens supports webhook-based price alerts. When a stock crosses your target price, the API sends a POST request to your webhook URL. Here is how to create an alert:

python
def create_alert(symbol: str, target_price: float,
                     direction: str = "above",
                     webhook_url: str = None):
    """Create a price alert via MarketLens API.

    direction: 'above' or 'below'
    """
    url = f"{BASE_URL}/alerts"
    payload = {
        "symbol": symbol,
        "target_price": target_price,
        "direction": direction,
    }
    if webhook_url:
        payload["webhook_url"] = webhook_url

    resp = requests.post(url, headers=HEADERS, json=payload)
    resp.raise_for_status()
    return resp.json()

# Alert when NVDA hits $1,000
create_alert("NVDA", 1000.00, "above",
             webhook_url="https://your-server.com/alerts")

# Alert when TSLA drops below $200
create_alert("TSLA", 200.00, "below")

Complete Portfolio Tracker Code

Here is the full working script that ties everything together:

python
#!/usr/bin/env python3
"""Stock Portfolio Tracker powered by MarketLens API."""

import requests
import pandas as pd
from tabulate import tabulate

# === Configuration ===
API_KEY = "ml_your_api_key_here"   # Get yours at marketlens.dev/signup
BASE_URL = "https://marketlens.dev/api/v1"
HEADERS = {"X-API-Key": API_KEY}

# === Portfolio ===
portfolio = [
    {"symbol": "AAPL",  "shares": 50,  "cost_basis": 178.50},
    {"symbol": "MSFT",  "shares": 30,  "cost_basis": 415.20},
    {"symbol": "GOOGL", "shares": 20,  "cost_basis": 141.30},
    {"symbol": "NVDA",  "shares": 25,  "cost_basis": 875.00},
    {"symbol": "TSLA",  "shares": 15,  "cost_basis": 245.80},
]

def get_quote(symbol):
    resp = requests.get(f"{BASE_URL}/stocks/{symbol}", headers=HEADERS)
    resp.raise_for_status()
    return resp.json()["data"]

def track_portfolio(holdings):
    rows = []
    total_value, total_cost = 0, 0

    for pos in holdings:
        q = get_quote(pos["symbol"])
        mv = q["price"] * pos["shares"]
        tc = pos["cost_basis"] * pos["shares"]
        pnl = mv - tc

        rows.append({
            "Symbol": pos["symbol"],
            "Shares": pos["shares"],
            "Price": f"${q['price']:,.2f}",
            "Value": f"${mv:,.2f}",
            "P&L": f"${pnl:+,.2f}",
            "Return": f"{(pnl/tc)*100:+.1f}%",
        })
        total_value += mv
        total_cost += tc

    print(tabulate(rows, headers="keys", tablefmt="github"))
    print(f"\nTotal: ${total_value:,.2f}  |  P&L: ${total_value-total_cost:+,.2f} ({((total_value-total_cost)/total_cost)*100:+.1f}%)")

if __name__ == "__main__":
    track_portfolio(portfolio)

Mini-Project: Moving Average Calculator

Moving averages are the foundation of technical analysis. This mini-project fetches historical data and computes SMA and EMA to identify trend direction and crossover signals.

python
import requests
import pandas as pd

BASE_URL = "https://marketlens.dev/api/v1"
HEADERS = {"X-API-Key": "ml_your_api_key_here"}

def moving_averages(symbol, short=20, long=50):
    """Calculate SMA crossover signals for a stock."""
    resp = requests.get(
        f"{BASE_URL}/stocks/historical/{symbol}",
        headers=HEADERS, params={"range": "6mo"}
    )
    resp.raise_for_status()
    df = pd.DataFrame(resp.json()["data"]["historical"])
    df["close"] = pd.to_numeric(df["close"])

    # Simple Moving Averages
    df["SMA_20"] = df["close"].rolling(short).mean()
    df["SMA_50"] = df["close"].rolling(long).mean()

    # Exponential Moving Average
    df["EMA_20"] = df["close"].ewm(span=short).mean()

    # Detect crossovers
    df["signal"] = "HOLD"
    df.loc[df["SMA_20"] > df["SMA_50"], "signal"] = "BULLISH"
    df.loc[df["SMA_20"] < df["SMA_50"], "signal"] = "BEARISH"

    latest = df.iloc[-1]
    print(f"{symbol} Close: ${latest['close']:.2f}")
    print(f"  SMA(20): ${latest['SMA_20']:.2f}  SMA(50): ${latest['SMA_50']:.2f}")
    print(f"  Signal: {latest['signal']}")
    return df

moving_averages("AAPL")

A golden cross (short SMA crosses above long SMA) is a bullish signal. A death cross is bearish. See the API docs for pre-computed indicators via /technicals/SMA/{symbol}.

Mini-Project: Earnings Calendar Tracker

Earnings announcements move stock prices 5-15% in a single day. This script fetches upcoming earnings dates and tracks EPS estimates.

python
import requests
from datetime import datetime, timedelta

BASE_URL = "https://marketlens.dev/api/v1"
HEADERS = {"X-API-Key": "ml_your_api_key_here"}

def earnings_this_week():
    """Fetch upcoming earnings for the next 7 days."""
    today = datetime.now().strftime("%Y-%m-%d")
    end = (datetime.now() + timedelta(days=7)).strftime("%Y-%m-%d")
    resp = requests.get(
        f"{BASE_URL}/stocks/earnings-calendar",
        headers=HEADERS,
        params={"from": today, "to": end}
    )
    resp.raise_for_status()
    earnings = resp.json()["data"]
    print(f"Earnings this week ({today} to {end}):")
    print(f"{'Symbol':<8} {'Date':<12} {'EPS Est':>10} {'Revenue Est':>14}")
    print("-" * 48)
    for e in earnings[:15]:
        print(f"{e['symbol']:<8} {e['date']:<12} {e.get('epsEstimate', 'N/A'):>10} {e.get('revenueEstimate', 'N/A'):>14}")

earnings_this_week()

Sample output:

output
Earnings this week (2026-03-14 to 2026-03-21):
Symbol   Date         EPS Est    Revenue Est
------------------------------------------------
ORCL     2026-03-17      $1.48    $14.39B
ADBE     2026-03-18      $4.97    $5.63B
FDX      2026-03-20      $4.54    $22.1B
NKE      2026-03-20      $0.74    $11.27B

Advanced: Async Requests & Error Handling

Sequential API calls are fine for 5 stocks, but for 50+ symbols, async requests reduce total time from 25 seconds to under 2 seconds:

python
import asyncio, aiohttp, time

BASE_URL = "https://marketlens.dev/api/v1"
API_KEY = "ml_your_api_key_here"

async def fetch_quote(session, symbol):
    """Fetch a single quote with retry logic."""
    url = f"{BASE_URL}/stocks/quote/{symbol}"
    for attempt in range(3):
        try:
            async with session.get(url, headers={"X-API-Key": API_KEY}, timeout=10) as resp:
                if resp.status == 429:  # Rate limited
                    await asyncio.sleep(int(resp.headers.get("Retry-After", 2)))
                    continue
                resp.raise_for_status()
                data = await resp.json()
                return {"symbol": symbol, **data["data"]}
        except Exception as e:
            if attempt == 2: return {"symbol": symbol, "error": str(e)}
            await asyncio.sleep(1)

async def fetch_all(symbols):
    async with aiohttp.ClientSession() as session:
        return await asyncio.gather(*[fetch_quote(session, s) for s in symbols])

# Fetch 20 stocks in parallel (~1s vs ~10s sequential)
symbols = ["AAPL", "MSFT", "GOOGL", "AMZN", "NVDA",
           "TSLA", "META", "JPM", "V", "UNH",
           "JNJ", "WMT", "PG", "MA", "HD",
           "DIS", "NFLX", "PYPL", "INTC", "AMD"]
start = time.time()
results = asyncio.run(fetch_all(symbols))
print(f"Fetched {len(results)} quotes in {time.time()-start:.1f}s")

MarketLens vs Other Python Stock Libraries

How does MarketLens compare to popular Python stock data libraries?

Feature MarketLens yfinance Alpha Vantage Polygon.io
Price Free (500/day) Free $49/mo $29/mo
Endpoints 222+ ~15 ~25 ~50
Stability Official REST API Unofficial (breaks) Official Official
Real-time Data Yes 15min delay Yes (paid) Yes (paid)
Crypto + Forex Yes Limited Separate Separate
Technical Indicators Yes (API-side) No Yes No
Python SDK Yes Built-in Community Official

Bottom line: yfinance breaks in production. Alpha Vantage's free tier (25 calls/day) is too restrictive. MarketLens gives you 222+ endpoints with a generous free tier. Check our Python SDK for even easier integration.

Live API Demo

Try the MarketLens API right here — select an endpoint and click "Fetch Data".

Response
// Click "Fetch Data" to see a live API response

Ready to Build? Start Free, Scale When Ready

Use code FOUNDER50 for 50% off any paid plan

Free

$0/mo

500 calls/day

Get Started

Pro

$29/mo

$14.50/mo with FOUNDER50

10,000 calls/day

Upgrade

Enterprise

$99/mo

$49.50/mo with FOUNDER50

50,000 calls/day

Contact Sales

Next Steps

  • Add crypto: Use /crypto/{symbol} to add Bitcoin, Ethereum, and other crypto holdings to your tracker
  • Build a dashboard: Use Flask or Streamlit to create a web-based portfolio dashboard (see our stock dashboard tutorial)
  • Automate updates: Run the tracker on a schedule with cron or schedule to get email updates
  • Upgrade for more data: Use code FOUNDER50 for 50% off Pro -- 10,000 calls/day, real-time WebSocket, and 222+ endpoints

Get More Python Finance Tutorials

Weekly API tips, code examples, and market insights. Join 2,000+ developers building with financial data.

Ready to Build Your Portfolio Tracker?

Get your free API key and start tracking in under 60 seconds. Use FOUNDER50 for 50% off Pro.

Ready to Start Building?

Get 500 free API calls/day. No credit card required.

Join 15,000+ developers. No spam.

Frequently Asked Questions

What is the best Python stock API for a portfolio tracker?

MarketLens is the best Python stock API for building a portfolio tracker in 2026. It offers 222+ endpoints covering stocks, crypto, forex, and ETFs. The free tier includes 500 calls/day with no credit card required, and the JSON responses are designed to work directly with pandas DataFrames.

Is MarketLens API free to use?

Yes, MarketLens has a generous free tier with 500 API calls per day. No credit card is required to sign up. The free tier includes real-time stock quotes, historical data, screener endpoints, and basic portfolio tools. When you are ready for more, use code FOUNDER50 for 50% off Pro.

Can I track stocks and crypto in the same portfolio?

Absolutely. MarketLens provides a unified API for stocks, crypto, forex, ETFs, and indices. You can build a multi-asset portfolio tracker with a single API key. Use /stocks/{symbol} for equities and /crypto/{symbol} for cryptocurrency prices.

How often can I refresh portfolio prices?

With the free tier (500 calls/day), you can refresh a 10-stock portfolio about 50 times per day. The Pro plan (10,000 calls/day with FOUNDER50 discount at $14.50/mo) lets you refresh every few seconds during market hours.

How do I calculate moving averages with the MarketLens API?

Use the /stocks/{symbol}/history endpoint to fetch historical prices, then compute SMA/EMA in Python with pandas. MarketLens also provides pre-calculated technical indicators via /technicals/SMA/{symbol} and /technicals/EMA/{symbol}. See the moving average mini-project above for complete code.

How does MarketLens compare to yfinance for Python?

yfinance is an unofficial scraper that breaks when Yahoo changes their HTML. MarketLens is a production-grade REST API with 222+ endpoints, 99.9% uptime SLA, and consistent JSON responses. Use yfinance for quick prototypes; use MarketLens for production apps.

Can I use async requests with the MarketLens API?

Yes! Use Python's aiohttp or httpx with asyncio to make concurrent API calls. This fetches data for 10+ stocks in parallel (~200ms vs ~2s sequential). See the advanced async example above.

Does MarketLens provide earnings calendar data?

Yes, the /stocks/earnings-calendar endpoint returns upcoming and historical earnings dates, EPS estimates, and actual results. Filter by date range or specific symbols. See the earnings calendar mini-project above for a complete Python implementation.

What Python libraries do I need for this tutorial?

You need requests (HTTP calls), pandas (data analysis), and optionally tabulate (pretty printing). Install with: pip install requests pandas tabulate. For async examples, also install aiohttp. Check our Python SDK for an even easier setup.

Related Tutorials