Any backtest, indicator, or model needs history. For the Saudi market there are a few real ways to get it, and the right one depends on what you're doing. Here's the honest version — no single source wins for every job.
Your options
| Source | Best for | Watch out for |
|---|---|---|
| Licensed data API (e.g. SAHMK) | Production apps needing raw, redistributable, comprehensive TASI data + fundamentals | Paid tiers; you build the storage/backtest layer yourself |
| yfinance | Quick, free exploration in a notebook (2222.SR) | Delayed, coverage/quality gaps on some TASI names, unofficial |
| Kaggle datasets | One-off study on a fixed window | Static snapshots that go stale; no live updates |
R tasi package | R users wanting prices + financial statements | R ecosystem, not Python |
| Tasilab | Backtesting & paper trading in one sandbox — bars + orders + experiments together | 15-min delayed on free tier; a sandbox, not a raw-data reseller |
If you need raw data to redistribute inside your own product, a licensed provider is the right tool. If you want to test strategies on that market — bars, simulated orders, and logged results in one place — that's what Tasilab is for.
Historical bars with Tasilab
Get a free key, then pull a date range and drop it straight into pandas:
import os
import pandas as pd
from tasilab import Tasilab
tasi = Tasilab(api_key=os.environ["TASILAB_API_KEY"])
data = tasi.get_historical("2222", "2024-01-01", "2025-12-31") # Saudi Aramco
df = pd.DataFrame(data["bars"])
df["date"] = pd.to_datetime(df["date"])
df = df.set_index("date")
print(df[["open", "high", "low", "close", "volume"]].tail())
Each bar carries symbol, date, open, high, low, close, adj_close, and volume — standard OHLCV, ready for indicators, resampling, or a chart. The same data is one GET away over HTTP:
curl "https://api.tasilab.com/v1/historical/2222?start=2024-01-01&end=2025-12-31" \
-H "X-API-Key: $TASILAB_API_KEY"
adj_close when you need returns that account for splits and dividends; use close for the raw traded price. Mixing the two is a classic source of wrong backtest numbers.