PythonSDKIntermediate10 min read

Build a Stock Research Tool with the SAHMK Python SDK

A Python script that pulls together everything you need to evaluate a Tadawul stock: company profile, financial health, dividend history, analyst consensus, and recent events — all from the SAHMK API using the official SDK.

Prerequisites: Python 3.9+, SAHMK API key (get one free), Starter plan or higher for financials/dividends, Pro for events.

bash
pip install -U sahmk

1. Company Profile — Know What You're Looking At

Start by pulling the company profile. The response is tiered by plan: Free gets basic info, Starter adds fundamentals, Pro adds technicals, valuation, and analyst data.

company.py
from sahmk import SahmkClient

client = SahmkClient(api_key="your_api_key_here")

company = client.company("2222")

print(f"{company.name_en} ({company.symbol})")
print(f"Sector: {company.sector} / {company.industry}")
print(f"Price:  {company.current_price} SAR")
Output
Saudi Arabian Oil Co (2222)
Sector: Energy / Oil & Gas
Price:  25.64 SAR

Fundamentals (Starter+)

python
if company.fundamentals:
    f = company.fundamentals
    print(f"\nMarket Cap:      {f.market_cap / 1e9:,.0f}B SAR")
    print(f"P/E Ratio:       {f.pe_ratio}")
    print(f"EPS:             {f.eps} SAR")
    print(f"Price/Book:      {f.price_to_book}")
    print(f"Beta:            {f.beta}")
    print(f"52-Week Range:   {f.fifty_two_week_low} – {f.fifty_two_week_high} SAR")
    print(f"Float Shares:    {f.float_shares:,}")
Output
Market Cap:      6,258B SAR
P/E Ratio:       16.77
EPS:             1.54 SAR
Price/Book:      4.19
Beta:            0.104
52-Week Range:   23.04 – 27.85 SAR
Float Shares:    5,969,578,000

Technicals & Valuation (Pro)

python
if company.technicals:
    t = company.technicals
    print(f"\nRSI (14):        {t.rsi_14}")
    print(f"MACD:            {t.macd_line} (signal: {t.macd_signal})")
    print(f"Direction:       {t.price_direction}")

if company.valuation:
    v = company.valuation
    gap = ((v.fair_price - company.current_price) / company.current_price) * 100
    print(f"\nFair Price:      {v.fair_price} SAR (confidence: {v.fair_price_confidence})")
    print(f"vs Current:      {gap:+.1f}%")

if company.analysts:
    a = company.analysts
    print(f"\nAnalyst Target:  {a.target_mean} SAR (range: {a.target_low}–{a.target_high})")
    print(f"Consensus:       {a.consensus} ({a.num_analysts} analysts)")
Output
RSI (14):        55.3
MACD:            0.12 (signal: 0.08)
Direction:       bullish

Fair Price:      28.50 SAR (confidence: 0.85)
vs Current:      +11.1%

Analyst Target:  29.5 SAR (range: 24.0–35.0)
Consensus:       buy (15 analysts)

2. Financial Statements — Check the Numbers

Pull income statements, balance sheets, and cash flows. The API returns the most recent quarterly filings.

financials.py
financials = client.financials("2222")

print(f"Financial Statements for {financials.symbol}\n")

# Most recent income statement
if financials.income_statements:
    inc = financials.income_statements[0]
    print(f"Income Statement ({inc.report_date})")
    print(f"  Revenue:      {inc.total_revenue / 1e9:,.0f}B SAR")
    if inc.gross_profit:
        margin = (inc.gross_profit / inc.total_revenue) * 100
        print(f"  Gross Profit: {inc.gross_profit / 1e9:,.0f}B SAR ({margin:.0f}% margin)")
    print(f"  Net Income:   {inc.net_income / 1e9:,.0f}B SAR")

# Most recent balance sheet
if financials.balance_sheets:
    bs = financials.balance_sheets[0]
    print(f"\nBalance Sheet ({bs.report_date})")
    print(f"  Total Assets:  {bs.total_assets / 1e9:,.0f}B SAR")
    print(f"  Equity:        {bs.stockholders_equity / 1e9:,.0f}B SAR")
    print(f"  Total Debt:    {bs.total_debt / 1e9:,.0f}B SAR")

# Most recent cash flow
if financials.cash_flows:
    cf = financials.cash_flows[0]
    print(f"\nCash Flow ({cf.report_date})")
    print(f"  Operating:     {cf.operating_cash_flow / 1e9:,.0f}B SAR")
    print(f"  Free Cash:     {cf.free_cash_flow / 1e9:,.0f}B SAR")
Output
Financial Statements for 2222

Income Statement (2025-12-31)
  Revenue:      416B SAR
  Gross Profit: 216B SAR (52% margin)
  Net Income:   69B SAR

Balance Sheet (2025-12-31)
  Total Assets:  2,552B SAR
  Equity:        1,492B SAR
  Total Debt:    364B SAR

Cash Flow (2025-12-31)
  Operating:     153B SAR
  Free Cash:     103B SAR

Quarterly Trend

Since the API returns multiple quarters, you can easily show a trend:

python
print("Revenue Trend (Quarterly)")
for inc in financials.income_statements:
    bar = "█" * int(inc.total_revenue / 1e10)
    print(f"  {inc.report_date}: {inc.total_revenue / 1e9:>6,.0f}B  {bar}")
Output
Revenue Trend (Quarterly)
  2025-12-31:    416B  █████████████████████████████████████████
  2025-09-30:    418B  █████████████████████████████████████████
  2025-06-30:    407B  ████████████████████████████████████████
  2025-03-31:    430B  ██████████████████████████████████████████

3. Dividend Analysis — Track the Yield

For income-focused investors, dividends matter. The SDK gives you trailing yield, upcoming payments, and full history.

dividends.py
divs = client.dividends("2222")

print(f"Dividends for {divs.symbol}")
print(f"  Current Price:       {divs.current_price} SAR")
print(f"  Trailing 12M Yield:  {divs.trailing_12m_yield}%")
print(f"  Trailing 12M Total:  {divs.trailing_12m_dividends} SAR/share")
print(f"  Payments Last Year:  {divs.payments_last_year}")

Upcoming Distributions

python
if divs.upcoming:
    print("\nUpcoming Distributions:")
    for u in divs.upcoming:
        print(f"  {u.period}: {u.value} SAR/share")
        print(f"    Eligibility: {u.eligibility_date}")
        print(f"    Payment:     {u.distribution_date}")

Payment History

python
if divs.history:
    print("\nPayment History:")
    for h in divs.history[:4]:
        print(f"  {h.period} {h.fiscal_year}: {h.value} SAR ({h.value_percent}%) — paid {h.distribution_date}")
Output
Dividends for 2222
  Current Price:       25.64 SAR
  Trailing 12M Yield:  4.2%
  Trailing 12M Total:  1.60 SAR/share
  Payments Last Year:  4

Upcoming Distributions:
  Q4: 0.40 SAR/share
    Eligibility: 2026-03-15
    Payment:     2026-04-01

Payment History:
  Q3 2025: 0.40 SAR (1.5%) — paid 2025-10-01
  Q2 2025: 0.40 SAR (1.5%) — paid 2025-07-01
  Q1 2025: 0.40 SAR (1.5%) — paid 2025-04-01
  Q4 2024: 0.40 SAR (1.5%) — paid 2025-01-01

4. Stock Events — What's Happening?

The events endpoint returns AI-generated summaries of material events — earnings, dividends, management changes, and more. Pro plan required.

events.py
events = client.events(symbol="2222", limit=5)

print(f"Recent Events ({events.count} total)\n")
for e in events.events:
    sentiment_icon = {"positive": "↑", "negative": "↓", "neutral": "→"}.get(e.sentiment, "•")
    print(f"  {sentiment_icon} [{e.event_type}] {e.importance}")
    print(f"    {e.description}")
    print(f"    {e.article_date}\n")
Output
Recent Events (3 total)

  ↑ [FINANCIAL_REPORT] important
    أرامكو تعلن عن نتائج مالية قياسية للربع الرابع 2025 مع نمو أرباح بنسبة 13%
    2026-01-29T17:10:06+00:00

  ↑ [DIVIDEND_ANNOUNCEMENT] important
    مجلس إدارة أرامكو يوصي بتوزيع أرباح نقدية بقيمة 0.40 ريال للسهم
    2026-01-15T09:00:00+00:00

You can also fetch all events across the market (omit symbol):

python
all_events = client.events(limit=20)
print(f"Available event types: {all_events.available_types}")

5. Putting It All Together — A Research Report

Here's a complete script that generates a one-page research summary for any symbol:

research.py
from sahmk import SahmkClient, SahmkError

client = SahmkClient(api_key="your_api_key_here")

SYMBOL = "2222"

def research(symbol):
    company = client.company(symbol)
    print(f"{'=' * 60}")
    print(f"  {company.name_en} ({company.symbol})")
    print(f"  {company.sector} / {company.industry}")
    print(f"  Price: {company.current_price} SAR")
    print(f"{'=' * 60}")

    if company.fundamentals:
        f = company.fundamentals
        print(f"\n  P/E: {f.pe_ratio}  |  EPS: {f.eps}  |  Beta: {f.beta}")
        print(f"  52W: {f.fifty_two_week_low}–{f.fifty_two_week_high} SAR")

    if company.valuation:
        v = company.valuation
        gap = ((v.fair_price - company.current_price) / company.current_price) * 100
        label = "undervalued" if gap > 0 else "overvalued"
        print(f"  Fair Price: {v.fair_price} SAR ({gap:+.0f}% — {label})")

    if company.analysts:
        a = company.analysts
        print(f"  Consensus: {a.consensus.upper()} | Target: {a.target_mean} SAR ({a.num_analysts} analysts)")

    try:
        divs = client.dividends(symbol)
        print(f"\n  Dividend Yield: {divs.trailing_12m_yield}% trailing")
        if divs.upcoming:
            u = divs.upcoming[0]
            print(f"  Next Payment:   {u.value} SAR on {u.distribution_date}")
    except SahmkError:
        pass

    try:
        fin = client.financials(symbol)
        if fin.income_statements:
            inc = fin.income_statements[0]
            print(f"\n  Latest Revenue:    {inc.total_revenue / 1e9:,.0f}B SAR ({inc.report_date})")
            print(f"  Latest Net Income: {inc.net_income / 1e9:,.0f}B SAR")
        if fin.cash_flows:
            cf = fin.cash_flows[0]
            print(f"  Free Cash Flow:    {cf.free_cash_flow / 1e9:,.0f}B SAR")
    except SahmkError:
        pass

    try:
        events = client.events(symbol=symbol, limit=3)
        if events.events:
            print(f"\n  Recent Events:")
            for e in events.events:
                print(f"    [{e.event_type}] {e.description[:80]}")
    except SahmkError:
        pass

    print(f"\n{'=' * 60}")


research(SYMBOL)
Output
============================================================
  Saudi Arabian Oil Co (2222)
  Energy / Oil & Gas
  Price: 25.64 SAR
============================================================

  P/E: 16.77  |  EPS: 1.54  |  Beta: 0.104
  52W: 23.04–27.85 SAR
  Fair Price: 28.50 SAR (+11% — undervalued)
  Consensus: BUY | Target: 29.5 SAR (15 analysts)

  Dividend Yield: 4.2% trailing
  Next Payment:   0.40 SAR on 2026-04-01

  Latest Revenue:    416B SAR (2025-12-31)
  Latest Net Income: 69B SAR
  Free Cash Flow:    103B SAR

  Recent Events:
    [FINANCIAL_REPORT] أرامكو تعلن عن نتائج مالية قياسية للربع الرابع 2025 مع نمو أرباح بنسبة 13%
    [DIVIDEND_ANNOUNCEMENT] مجلس إدارة أرامكو يوصي بتوزيع أرباح نقدية بقيمة 0.40 ريال للسهم

============================================================

Change SYMBOL to any Tadawul ticker and run the same script.

6. Tips

  • Typed models everywhere: All SDK methods return typed objects. Use your IDE's autocomplete to explore available fields.
  • Graceful degradation: Some fields are None depending on your plan. Always check before using Pro/Starter fields.
  • Error handling: Wrap calls in try/except SahmkError — the SDK won't crash on plan-restricted endpoints, but it will raise a clear error.
  • .raw for export: Every response has a .raw dict — useful for saving to JSON, databases, or forwarding to frontends.

What's Next

  • Historical analysis: Use client.historical() for OHLCV data and build price charts
  • WebSocket streaming: Use client.stream() for real-time price updates
  • CLI shortcut: Run sahmk company 2222 or sahmk financials 2222 from your terminal
  • Compare stocks: Run the research function in a loop over multiple symbols

Resources

Ready to go deeper?

The SAHMK SDK gives you everything from quick quotes to full fundamental analysis. Start with the free tier, upgrade when you need financials, dividends, and real-time data.