Build a Saudi Stock Tracker in Python with SAHMK API
In this tutorial, you'll learn how to use the SAHMK API to fetch real-time stock data from the Saudi Stock Exchange (Tadawul), track TASI market movers, and build a simple portfolio tracker — all in Python.
1. Prerequisites & Setup
Before we start, you'll need:
- Python 3.7+ installed on your machine
- A free SAHMK API key — sign up at sahmk.sa/developers (100 free requests/day)
- The
requestslibrary
Install the requests library:
pip install requestsThe SAHMK API gives you access to 350+ companies listed on Tadawul (TASI and Nomu markets), including real-time quotes, historical data, financial statements, dividends, and more. The free tier includes delayed prices (15-minute delay) — perfect for learning and building.
2. Your First API Request — Get a Stock Quote
Let's start by fetching a quote for Aramco (symbol: 2222), the world's largest publicly traded company:
import requests
API_KEY = "your_api_key_here"
BASE_URL = "https://app.sahmk.sa/api/v1"
headers = {"X-API-Key": API_KEY}
# Fetch Aramco stock quote
response = requests.get(f"{BASE_URL}/quote/2222/", headers=headers)
data = response.json()
print(f"Company: {data['name_en']}")
print(f"Symbol: {data['symbol']}")
print(f"Price: {data['price']} SAR")
print(f"Change: {data['change_value']} ({data['change_percent']}%)")
print(f"Volume: {data['volume']:,}")Company: Saudi Aramco
Symbol: 2222
Price: 28.30 SAR
Change: -0.15 (-0.53%)
Volume: 8,432,150The /quote/{symbol}/ endpoint returns comprehensive data including price, change, volume, day range, 52-week range, and more. Check the full API reference for all available fields.
3. Market Overview — Gainers, Losers & Volume Leaders
The SAHMK API provides endpoints to get today's top market movers. This is useful for building market dashboards or screening tools:
import requests
API_KEY = "your_api_key_here"
BASE_URL = "https://app.sahmk.sa/api/v1"
headers = {"X-API-Key": API_KEY}
# Get today's top gainers
gainers = requests.get(f"{BASE_URL}/market/gainers/", headers=headers).json()
print("📈 Top 5 Gainers Today")
print("-" * 50)
for stock in gainers[:5]:
print(f" {stock['name_en']:<25} {stock['change_percent']:>+6.2f}% {stock['price']} SAR")
print()
# Get today's top losers
losers = requests.get(f"{BASE_URL}/market/losers/", headers=headers).json()
print("📉 Top 5 Losers Today")
print("-" * 50)
for stock in losers[:5]:
print(f" {stock['name_en']:<25} {stock['change_percent']:>+6.2f}% {stock['price']} SAR")
print()
# Get market summary (TASI index)
summary = requests.get(f"{BASE_URL}/market/summary/", headers=headers).json()
print("🏛️ Market Summary")
print("-" * 50)
for index_data in summary:
print(f" {index_data['name_en']}: {index_data['value']} ({index_data['change_percent']:+.2f}%)")📈 Top 5 Gainers Today
--------------------------------------------------
Aldrees Petroleum +9.97% 142.00 SAR
Alujain Corp +7.42% 38.50 SAR
Saudi Ceramic +5.18% 61.00 SAR
Zamil Industrial +4.85% 27.30 SAR
Batic Investments +4.23% 39.75 SAR
📉 Top 5 Losers Today
--------------------------------------------------
Alinma Bank -3.12% 27.95 SAR
Savola Group -2.87% 32.10 SAR
Yanbu Cement -2.45% 54.80 SAR
Saudi Kayan -2.31% 12.68 SAR
Etihad Etisalat -1.98% 51.20 SAR
🏛️ Market Summary
--------------------------------------------------
TASI: 12,456.32 (+0.45%)
Nomu: 28,234.10 (-0.12%)Other market endpoints include /market/most-volume/, /market/most-value/, and /market/sectors/ for sector-level analysis.
4. Build a Portfolio Tracker
Now let's build something practical — a portfolio tracker that shows your current holdings, their value, and profit/loss:
import requests
API_KEY = "your_api_key_here"
BASE_URL = "https://app.sahmk.sa/api/v1"
headers = {"X-API-Key": API_KEY}
# Define your portfolio: symbol, shares, avg cost
portfolio = [
{"symbol": "2222", "shares": 100, "avg_cost": 27.50}, # Aramco
{"symbol": "1180", "shares": 50, "avg_cost": 32.00}, # Al Rajhi Bank
{"symbol": "2350", "shares": 200, "avg_cost": 8.50}, # Saudi Kayan
{"symbol": "7010", "shares": 75, "avg_cost": 98.00}, # STC
]
print("📊 Portfolio Summary")
print("=" * 70)
print(f" {'Stock':<20} {'Shares':>6} {'Avg Cost':>10} {'Price':>10} {'P/L':>12}")
print("-" * 70)
total_cost = 0
total_value = 0
for holding in portfolio:
response = requests.get(
f"{BASE_URL}/quote/{holding['symbol']}/",
headers=headers
)
stock = response.json()
current_price = float(stock["price"])
cost_basis = holding["shares"] * holding["avg_cost"]
market_value = holding["shares"] * current_price
pnl = market_value - cost_basis
pnl_pct = (pnl / cost_basis) * 100
total_cost += cost_basis
total_value += market_value
sign = "+" if pnl >= 0 else ""
print(
f" {stock['name_en']:<20} "
f"{holding['shares']:>6} "
f"{holding['avg_cost']:>9.2f} "
f"{current_price:>9.2f} "
f"{sign}{pnl:>8.2f} ({sign}{pnl_pct:.1f}%)"
)
total_pnl = total_value - total_cost
total_pnl_pct = (total_pnl / total_cost) * 100
sign = "+" if total_pnl >= 0 else ""
print("=" * 70)
print(f" Total Cost: {total_cost:>10,.2f} SAR")
print(f" Market Value: {total_value:>10,.2f} SAR")
print(f" Total P/L: {sign}{total_pnl:>10,.2f} SAR ({sign}{total_pnl_pct:.1f}%)")📊 Portfolio Summary
======================================================================
Stock Shares Avg Cost Price P/L
----------------------------------------------------------------------
Saudi Aramco 100 27.50 28.30 +80.00 (+2.9%)
Al Rajhi Bank 50 32.00 88.40 +2,820.00 (+176.3%)
Saudi Kayan 200 8.50 12.68 +836.00 (+49.2%)
STC 75 98.00 168.80 +5,310.00 (+72.2%)
======================================================================
Total Cost: 12,200.00 SAR
Market Value: 21,246.00 SAR
Total P/L: +9,046.00 SAR (+74.1%)5. Batch Quotes — Multiple Stocks in One Request
Instead of making separate requests for each stock, you can use the batch endpoint to fetch multiple quotes at once. This is more efficient and uses fewer API calls:
import requests
API_KEY = "your_api_key_here"
BASE_URL = "https://app.sahmk.sa/api/v1"
headers = {"X-API-Key": API_KEY}
# Fetch multiple stock quotes in a single request
symbols = "2222,1180,2350,7010,1010,2010"
response = requests.get(
f"{BASE_URL}/quote/batch/",
headers=headers,
params={"symbols": symbols}
)
stocks = response.json()
print(f"{'Symbol':<8} {'Company':<25} {'Price':>8} {'Change':>10}")
print("-" * 55)
for stock in stocks:
change = f"{stock['change_percent']:+.2f}%"
print(f"{stock['symbol']:<8} {stock['name_en']:<25} {stock['price']:>8} {change:>10}")Symbol Company Price Change
-------------------------------------------------------
2222 Saudi Aramco 28.30 -0.53%
1180 Al Rajhi Bank 88.40 +1.26%
2350 Saudi Kayan 12.68 -2.31%
7010 STC 168.80 +0.84%
1010 Riyad Bank 27.65 +0.36%
2010 SABIC 82.30 -0.48%The batch endpoint accepts up to 20 symbols per request, making it ideal for portfolio dashboards and watchlists.
6. Next Steps
You now have a working Saudi stock tracker. Here are some ideas to take it further:
- →Historical data: Use the
/history/{symbol}/endpoint to chart price trends (Starter plan) - →Financial statements: Fetch balance sheets and income statements via
/financials/(Starter plan) - →Real-time streaming: Connect via WebSocket for live price updates (Pro plan)
- →Dividends: Track dividend announcements with
/dividends/ - →Build a web dashboard: Combine with Flask or Streamlit for a visual interface
Ready to start building?
Get your free API key and start fetching Tadawul stock data in minutes. 100 free requests per day, no credit card required.