Info onlyNot investment advice. GSE prices are end-of-day; FX and news refresh live.How we source
GSE · Closed · Weekend
Live
GSE-CI14,873.11 0.00%GSE-FSI1,745.04 +2.81%MTNGHGH₵2.45 +1.66%GCBGH₵6.85 -0.72%EGHGH₵8.25 +1.85%SCBGH₵24.50 +1.66%CALGH₵0.38 -7.32%SOGEGHGH₵1.35 +1.50%ACCESSGH₵4.10 +1.23%RBGHGH₵0.72 +2.86%EGLGH₵3.20 +2.56%SICGH₵0.44 +2.33%FMLGH₵5.20 +0.39%UNILGH₵14.50 +2.11%GGBLGH₵3.10 +1.64%PZCGH₵0.68 +1.49%GOILGH₵1.55 +1.97%TOTALGH₵9.40 +1.08%TLWGH₵16.80 -1.75%BOPPGH₵22.50 +0.90%AYRTNGH₵0.11 0.00%MACGH₵5.40 0.00%ADBGH₵5.06 0.00%AGAGH₵37.00 0.00%ALWGH₵0.10 0.00%ASGGH₵8.87 0.00%CLYDGH₵0.03 0.00%CMLTGH₵0.10 0.00%CPCGH₵0.02 0.00%DASPHARMAGH₵0.40 0.00%DIGICUTGH₵0.09 0.00%ETIGH₵0.15 0.00%HORDSGH₵0.10 0.00%IILGH₵0.04 0.00%MMHGH₵0.11 0.00%GSE-CI14,873.11 0.00%GSE-FSI1,745.04 +2.81%MTNGHGH₵2.45 +1.66%GCBGH₵6.85 -0.72%EGHGH₵8.25 +1.85%SCBGH₵24.50 +1.66%CALGH₵0.38 -7.32%SOGEGHGH₵1.35 +1.50%ACCESSGH₵4.10 +1.23%RBGHGH₵0.72 +2.86%EGLGH₵3.20 +2.56%SICGH₵0.44 +2.33%FMLGH₵5.20 +0.39%UNILGH₵14.50 +2.11%GGBLGH₵3.10 +1.64%PZCGH₵0.68 +1.49%GOILGH₵1.55 +1.97%TOTALGH₵9.40 +1.08%TLWGH₵16.80 -1.75%BOPPGH₵22.50 +0.90%AYRTNGH₵0.11 0.00%MACGH₵5.40 0.00%ADBGH₵5.06 0.00%AGAGH₵37.00 0.00%ALWGH₵0.10 0.00%ASGGH₵8.87 0.00%CLYDGH₵0.03 0.00%CMLTGH₵0.10 0.00%CPCGH₵0.02 0.00%DASPHARMAGH₵0.40 0.00%DIGICUTGH₵0.09 0.00%ETIGH₵0.15 0.00%HORDSGH₵0.10 0.00%IILGH₵0.04 0.00%MMHGH₵0.11 0.00%
Trust · Methodology

How every metric on Nkosuo is calculated.

Plain English where possible, formulas where helpful, and limitations called out honestly. Each user-facing metric on the site links back here via a “How calculated?” anchor.

Market (nominal) return

return = (endPrice − startPrice) / startPrice

The simple percentage change in price between two dates. 'Day change' uses end-of-day close vs previous close; horizon returns use close at horizon start vs latest close.

Inputs
  • Close prices from the Ghana Stock Exchange
Refresh

End-of-day after GSE session close.

Assumptions

No dividends reinvested. No fees or tax deducted.

Limitations: Total shareholder return differs — it adds reinvested dividends. For thinly traded names, prices may lag or flatline.

Worked example. If MTN Ghana closed at GHS 2.41 yesterday and GHS 2.45 today: (2.45 − 2.41) / 2.41 ≈ +1.66% day change.

Real (inflation-adjusted) return — Fisher equation

real = (1 + nominal) / (1 + inflation) − 1

The return after inflation erodes your purchasing power. For diaspora users we also layer in cedi depreciation against the target currency.

Inputs
  • Nominal return (see above)
  • Ghana headline CPI — GSS / World Bank WDI
  • Cedi depreciation vs target currency — Bank of Ghana interbank rate
Refresh

Inflation monthly; FX daily.

Assumptions

We use current CPI and 1-year cedi depreciation as first-order approximations for the portfolio's full holding period.

Limitations: Fisher is approximate for large returns. For multi-year horizons, the compounded exact identity is more accurate but we prefer the plain-English version.

Worked example. Nominal return 18%, inflation 17.8% → real GHS return (1.18 / 1.178) − 1 ≈ 0.17%.

FX-adjusted real return (diaspora view)

real_fx = (1 + nominal) / ((1 + inflation) × (1 + depreciation)) − 1

Sequential deflation by Ghana CPI and cedi depreciation against the target currency (USD / GBP / EUR).

Inputs
  • Nominal return
  • Ghana CPI
  • Cedi depreciation vs target currency
Refresh

Monthly.

Assumptions

Same-period deflation factors apply across the whole return period.

Limitations: Ignores cross-currency inflation differentials past Ghana. For a fuller picture a diaspora user should also deflate by their own local CPI.

Trailing dividend yield

yield = dividendPerShareTTM / currentPrice × 100

Trailing twelve-month declared dividend per share divided by today's price. Does not project future dividends.

Inputs
  • DPS from issuer announcements and GSE notices
  • End-of-day price
Refresh

Event-driven (issuer announcements).

Assumptions

Assumes latest declared DPS repeats; adjust if the board has signalled otherwise.

Limitations: Doesn't adjust for payout ratio sustainability. See the financial-health scorecard for that.

Market capitalisation

mcap = price × sharesOutstanding

Number of shares issued × latest price. 'Total listed market cap' sums this across tracked equities.

Inputs
  • Shares outstanding from issuer filings
  • End-of-day price
Refresh

Shares outstanding refreshed after every corporate action (rights, bonus, buyback). Price refreshed daily.

Assumptions

Assumes the share count is unchanged between updates.

Limitations: Free-float market cap is smaller than total cap; Nkosuo currently publishes total cap and flags free-float figures only when issuer discloses them.

Portfolio market value (user-entered)

value = Σ (quantityᵢ × currentPriceᵢ)

Sum of each lot's quantity multiplied by the latest end-of-day price.

Inputs
  • User-entered quantity + cost basis
  • End-of-day prices
Refresh

Whenever you add, edit, or delete a lot. Prices refresh daily.

Assumptions

Does not include fees, tax, or FX conversion. Based entirely on what you've entered.

Limitations: Nkosuo does not verify that the holdings exist at a broker. For the empty state, no values are computed.

Unrealised gain / loss

pl = (currentPrice − avgCostBasis) × quantity

Only for open positions. Realised P/L (from sales) is a Phase 2 addition.

Inputs
  • Avg cost basis (user-entered)
  • Current price
Refresh

Daily with price.

Assumptions

Weighted-average cost method.

Limitations: No tax or commission adjustments.

Benchmark comparison — vs GSE-CI

outperformance = portfolioReturn − benchmarkReturn

Portfolio return minus the trailing 1-year GSE-CI return. Purely descriptive.

Inputs
  • Portfolio total return
  • GSE-CI 1y return
Refresh

Daily.

Assumptions

GSE-CI is used as a domestic equity benchmark by convention.

Limitations: GSE-CI is heavily bank-weighted; concentrated portfolios may outperform or underperform it for structural reasons unrelated to stock selection.

Concentration — Herfindahl-Hirschman Index

HHI = Σ wᵢ² × 10,000 (where wᵢ is each holding's portfolio weight)

Classical concentration index. Below 1,500 = diversified, 1,500-2,500 = moderate, above 2,500 = concentrated.

Inputs
  • Portfolio weights from user-entered holdings
Refresh

Whenever holdings change.

Assumptions

Per-holding weights; an all-bank portfolio with multiple names may still score 'low' even if sector-concentrated.

Limitations: HHI is calculated per-holding, not per-sector. See sector-exposure donut for sector view.

Liquidity score (1–10, A–E grade)

score = 10 − penalties (days-since-trade, avg-volume tier, turnover tier)

Composite rule-based score. A-rated stocks trade regularly with healthy volume; E-rated stocks may not have traded for a week.

Inputs
  • Last-traded date
  • Daily volume
  • Turnover = (volume × price) / market cap
Refresh

Daily.

Assumptions

Demo data uses today's volume as a proxy for average; production will use a rolling 30-day median.

Limitations: Liquidity can change quickly on corporate-action news — a stale score doesn't guarantee you can exit at the displayed price.

Stale-price risk

An issuer flag surfaced when the last trade is more than 1 day old. On the stock page we show 'last traded N days ago' in bold red.

Inputs
  • Last-traded date
Refresh

Daily.

Assumptions

More than one calendar day ≠ one trading day; we'll refine after live feed lands.

Limitations: Does not distinguish holiday closures from genuine illiquidity.

T-Bill yields — discount vs investment

investmentYield = discount / (1 − discount × tenor/365)

BoG auctions report a discount rate; the investment yield (what you actually earn over the holding period) is derived from it.

Inputs
  • Discount rate from BoG auction
  • Tenor (91 / 182 / 364 days)
Refresh

Weekly after BoG's auction release.

Assumptions

Tenor converted using a 365-day year.

Limitations: Does not deduct withholding tax, where applicable. Roll-over risk exists — next auction's rate can differ.

Worked example. Discount 24.85%, 91 days → 0.2485 / (1 − 0.2485 × 91/365) ≈ 26.44% investment yield.

News relevance & entity matching

Each article is scanned against the instrument master. Ticker matches require whole-word matching so 'FML' never matches inside 'family'. Alias, display-name, legal-name, and former-name matches are scored separately.

Inputs
  • News item (title + summary)
  • Instrument master (tokens)
Refresh

Every 5 minutes.

Assumptions

Headlines are in English; we do not currently translate Akan or French sources.

Limitations: The matcher is rule-based, not ML. Confidence ≥ 0.7 classifies as 'direct-company'; below that we route as macro/market-wide or drop entirely.

SEC notice classification

Every notice is tagged with a kind (cautionary, warning, suspension, sanction, licensing, public education, enforcement, operator, unknown) and a verification status (verified, source-linked, unverified, demo).

Inputs
  • SEC Ghana publication
  • Document URL
  • Last checked timestamp
Refresh

Polled daily; upgraded editorially.

Assumptions

Editorial review before we upgrade status from demo/unverified to source-linked/verified.

Limitations: We never attribute fraud to a named entity unless SEC Ghana has done so on the record.

Data-freshness labels

Every price or number on Nkosuo carries one of 11 labels: Live, Delayed, End-of-day, Estimated, User-entered, Demo, Sample, Unavailable, Stale, Verified, Unverified. The label indicates how the value was produced and how fresh it is.

Inputs
  • Source kind
  • Source timestamp
  • Expected refresh cadence
Refresh

Continuous.

Assumptions

Where we lack a timestamp we show 'Unverified', never fabricate one.

Limitations: The label is only as good as the adapter's metadata; see DATA_SOURCES.md.

Anomaly flags

|today_return − mean_30d| > 2 × sigma_30d

A move more than 2 standard deviations from the 30-day mean fires an 'unusual move' flag. Combined with stale-price and thin-trade flags on the stock page.

Inputs
  • 30-day close history
Refresh

Daily.

Assumptions

Normality — an oversimplification for skewed return distributions.

Limitations: Small sample + non-normal returns means false positives are possible. Treat as a prompt to look closer, not a recommendation.

AI-generated explanations

If ANTHROPIC_API_KEY is configured, the per-stock Intelligence Report can be synthesised by Claude with a guardrail system prompt (no buy/sell, no price targets, no forecasts). The output schema is identical to the deterministic rule-based version so the UI shape is fixed.

Inputs
  • Session summary + liquidity + pressure + sentiment + fundamentals
  • Ghana-specific context
Refresh

Hourly ISR.

Assumptions

Claude is instructed to produce descriptive-only output. Every response carries a visible 'not a recommendation' disclaimer.

Limitations: LLM outputs can still be wrong. Every AI panel carries a visible disclaimer and a link back to this methodology page. If the API is down the app silently falls back to the rule-based report.

Portfolio transaction ledger (WACB)

The portfolio is derived from a transactions ledger (buys, sells, dividends, deposits, withdrawals, fees, taxes, transfers). Positions use weighted-average cost basis: sales realise P/L against the running average but do not change the average cost of the remaining shares.

Inputs
  • User-entered transactions
  • End-of-day prices for mark-to-market
Refresh

Whenever you add, edit, or delete a transaction. Prices refresh daily.

Assumptions

Fees and taxes on a buy are capitalised into cost basis; on a sell they reduce proceeds. Transfer-in accepts a stated cost basis; transfer-out reduces quantity without a P/L event.

Limitations: FIFO cost basis is a Phase-3 addition. No tax-lot optimisation today. We do not verify that the holdings exist at a broker.

Worked example. Buy 100 @ GHS 5, then 100 @ GHS 7. WACB = (500 + 700) / 200 = GHS 6. Sell 50 @ GHS 8 → realised P/L = (8 − 6) × 50 = GHS 100; remaining 150 stay at GHS 6 avg cost.

Time-weighted return (TWR)

TWR = Π(1 + HPRᵢ) − 1, where HPRᵢ = (end_value − net_external_flow − start_value) / start_value

Strips out the timing and size of contributions and withdrawals. Gives you pure investment performance — the return the portfolio would have earned if no cash had moved in or out. Preferred when comparing to benchmarks.

Inputs
  • Daily portfolio market values
  • External cash flows per date
Refresh

On every ledger update.

Assumptions

Sub-periods are bounded by external cash flows. Modified-Dietz style where intra-period flows are netted at period-end.

Limitations: Needs at least two observation points with a valid start value. No weighting for intra-period timing beyond netting at period-end.

Worked example. Start GHS 1,000 → grow to 1,100 (no flow, HPR +10%) → deposit 1,000 (value 2,100, HPR 0%) → grow to 2,310 (HPR +10%). Chained TWR = 1.10 × 1.00 × 1.10 − 1 = 21%.

Money-weighted return / IRR

Find r such that Σ CFᵢ / (1 + r)^(tᵢ) = 0

The internal rate of return of the cash flows between you and the portfolio. Unlike TWR, IRR gives credit (or blame) to the timing of your contributions. Often the more honest number for 'what did I actually earn'.

Inputs
  • Signed, dated cash flows from the ledger
  • Terminal market value (positions + cash) as a final positive flow
Refresh

On every ledger update.

Assumptions

Sign convention: contributions (deposit, transfer-in) are negative; distributions (withdrawal, transfer-out, dividend) are positive; buys/sells/fees/taxes are internal and captured in terminal value.

Limitations: Returns null when flows don't change sign (e.g. contributions only, no terminal value). Solved via bisection — accurate to 1e-6 but not closed-form.

Worked example. Deposit 1,000 on 2025-04-24, terminal value 1,100 on 2026-04-24 → IRR ≈ 10% annualised.

AI explanations framework — guardrails and fallbacks

Every plain-English explanation on the platform passes through a single contract: typed input per kind, schema'd JSON result (summary, key factors, cited inputs, limitations), a guardrail validator that rejects forbidden language (buy/sell/hold/target price/guaranteed), and a deterministic rule-based fallback that always works without an LLM. When ANTHROPIC_API_KEY is configured, the same call can be served by Claude Opus 4.7 with adaptive thinking and prompt caching; if the model produces flagged output, we discard it and return the rule-based version with the violation reasons attached as warnings.

Inputs
  • Per-kind structured inputs (stock, signals, notice, T-Bill auction, etc.)
  • Optional ANTHROPIC_API_KEY env var for live Claude calls
Refresh

Server-side per page render; client-side on demand for portfolio.

Assumptions

The rule-based fallback is the source of truth when the LLM disagrees with our guardrails. We do not silently let unsafe language reach the user.

Limitations: The 9 currently supported kinds are: stock-movement, portfolio-risk, dividend-announcement, tbill-auction, macro-impact, company-announcement, sec-notice, risk-change, stock-vs-tbill. New kinds require new typed inputs and a corresponding rule-based fallback.

T-Bill math — discount, yield, effective annual

price = 100 × (1 − d × days/365)   ·   yield = d / (1 − d × days/365)   ·   EAY = (1 + yield × days/365)^(365/days) − 1

Bank of Ghana publishes a discount rate at auction. The investment yield users earn is grossed up from the price paid, and the effective annual yield compounds the holding-period return forward to one year so tenors can be compared on the same basis.

Inputs
  • Discount rate
  • Tenor (91 / 182 / 364 days)
Refresh

Weekly after BoG's auction release.

Assumptions

365-day count. No fees, no brokerage markup.

Limitations: Rollover at the next auction is not guaranteed at today's yield. Tax treatment varies by investor type — the calculator accepts a user-entered rate.

Worked example. Discount 24.85%, 91 days → price per 100 = 93.80 → yield = 24.85 / 93.80 × (365/91) ≈ 26.49%.

T-Bill ladder & rollover planner

The ladder builder splits your principal across 91-, 182-, and 364-day tenors at user-chosen weights and computes each rung's price, face value, interest, and maturity date. The rollover planner projects the cascade of maturities over a horizon, reinvesting at the same yield each time (the 'constant-yield assumption').

Inputs
  • Principal
  • Weights per tenor (auto-normalised)
  • Latest BoG auction yields
  • Rollover horizon (months)
Refresh

Live in the UI.

Assumptions

Constant yield across rollovers. No transaction fees. The calendar increments maturity dates in 91 / 182 / 364-day blocks from today.

Limitations: Future auctions will price higher or lower. A ladder's value is in the maturity cadence (liquidity), not just the yield.

T-Bill scenario modelling

What-if analysis on the three levers that move real T-Bill returns: the auction yield itself, Ghana inflation, and cedi depreciation against USD. Defaults shock each lever by a plausible amount (yields −300bp, inflation +500bp, cedi +5%) so users see the sensitivity.

Inputs
  • Base yield, inflation, FX depreciation
  • Shock deltas
Refresh

Live in the UI.

Assumptions

Independent shocks — correlated shocks in the real world can be worse.

Limitations: Does not account for re-investment risk across multiple auctions or regime changes.

Auction demand — tendered vs accepted

cover = bids tendered / bids accepted

Cover > 1 means the auction was oversubscribed. Persistent undersubscription is a stress signal and often precedes yield moves.

Inputs
  • BoG auction bids tendered and accepted per tenor
Refresh

Weekly.

Assumptions

Amounts reported in GHS, without separation by dealer category.

Limitations: Quantity alone doesn't reveal price dispersion — a tightly clustered bid book tells a different story than wide dispersion at the same cover ratio.

Educational valuation calculators

DDM: fair = DPS × (1 + g) / (r − g). DCF: Σ FCFₜ / (1 + r)ᵗ + TV / (1 + r)ᴺ, TV = FCF_N × (1 + gₜ) / (r − gₜ). Equity = PV(FCF) − net debt.

The stock page offers a Dividend Discount Model and a two-stage DCF. Inputs are seeded from public fundamentals plus Ghana-aware defaults (22% discount, 6% terminal growth). Users can change every input. Outputs are implied fair value per share and upside vs market — labelled clearly as educational estimates, not targets.

Inputs
  • Fundamentals (EPS, DPS, FCF, shares, debt, cash)
  • User-adjustable growth + discount assumptions
Refresh

Live in the UI — recomputed on every input change.

Assumptions

DDM requires r > g or returns null. DCF requires r > terminal growth or returns null. Narrow gaps (<2-3%) surface warnings.

Limitations: Models are as good as their inputs. Fair-value sensitivity to discount and growth is high. Nothing here is investment advice; no buy, sell, hold, or target output.

Worked example. MTNGH at GHS 2.45, DPS 0.18, g 15%, r 22% → DDM fair value ≈ GHS 2.96 (+21%).

Sector-specific fundamentals

Each sector has its own diagnostic metrics. Banks: CAR, NPL ratio, NIM, cost-to-income, deposits, loans, impairment charges. Telecoms: active + data subscribers, ARPU, MoMo / data / service revenue, capex intensity. Insurance: claims ratio, combined ratio, solvency, investment income. Energy: commodity / FX / regulated-price exposure, gross + operating margin. Consumer: gross + operating margin, input-cost sensitivity, inventory turnover.

Inputs
  • Issuer financial statements
  • Regulatory reports (BoG, NIC)
Refresh

On issuer results release.

Assumptions

Grades (good / ok / watch / weak) use rules-of-thumb thresholds, not regulatory limits. Benchmarks shown where applicable (e.g. BoG CAR minimum 13%).

Limitations: Coverage is the set of tracked issuers — not every GSE listing has sector-specific data yet.

Peer multiples (P/E, P/B, dividend yield)

Auto-selected sector peers (by market-cap proximity) rendered alongside the subject stock. Medians shown for reference. Each multiple is tagged discount / premium / at-median (P/E and P/B use lower-is-cheap; dividend yield uses higher-is-better).

Inputs
  • Subject + peer prices, EPS, book value per share, DPS
Refresh

Daily.

Assumptions

Tolerance of ±5% around the median before a verdict flips. 'Discount' does not mean 'cheap' — weaker fundamentals can justify a lower multiple.

Limitations: Peer universe is sector-bounded and small. Absolute multiples should be cross-checked against the T-Bill yield (see /methodology#tbill-yield).

Portfolio risk signals

Nine descriptive signals (concentration, sector concentration, single-issuer, liquidity, stale-price, FX, inflation erosion, dividend dependency, T-Bill opportunity cost). Each returns a status (ok / elevated / high / unknown), a metric, a plain-English explanation, and the specific inputs the user can verify. Language is deliberately educational — never 'buy' or 'sell'.

Inputs
  • Derived positions and portfolio weights
  • Ghana macro baseline (CPI, cedi depreciation)
  • Latest T-Bill investment yield
  • Liquidity grade from the stock-level analytics
Refresh

On every ledger update.

Assumptions

Standard thresholds: HHI < 1,500 diversified, 1,500–2,500 moderate, > 2,500 concentrated. Single-issuer above 40% = high. Sector tilt above 60% = high. Stale-price exposure ≥ 30% = high.

Limitations: Thresholds are rules of thumb, not regulatory limits. A signal firing is not advice to act; it is a prompt to look closer.

Spotted a methodology issue?

Email methodology@nkosuo.com and we will log it on our public corrections page.