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.
pip install -U sahmk1. 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.
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")Saudi Arabian Oil Co (2222)
Sector: Energy / Oil & Gas
Price: 25.64 SARFundamentals (Starter+)
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:,}")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,000Technicals & Valuation (Pro)
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)")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 = 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")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 SARQuarterly Trend
Since the API returns multiple quarters, you can easily show a trend:
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}")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.
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
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
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}")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-014. 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 = 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")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:00You can also fetch all events across the market (omit symbol):
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:
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)============================================================
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
Nonedepending 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. - →
.rawfor export: Every response has a.rawdict — 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 2222orsahmk financials 2222from 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.