Client & core functions
psxdata exposes two usage patterns. You can call module-level convenience functions
directly — no class instantiation needed — or create a PSXClient instance when you
need a dedicated cache directory or want to manage the client lifetime explicitly.
cache parameter respect a 15-minute TTL for intraday data; historical rows
(before today) are cached indefinitely.
PSXClient
Public Python API for Pakistan Stock Exchange data. All scrapers are instantiated once in__init__ and reused across calls. Caching is managed by the client — scrapers
never touch the cache directly.
Constructor
Path to the on-disk cache directory. A tilde (
~) is expanded to the current user’s
home directory. The directory is created automatically if it does not exist.Module-level functions
psxdata.stocks()
Fetch historical OHLCV data for a PSX-listed symbol. PSX returns the full price history in a single HTTP request. The response is split at today’s boundary and stored under two cache keys:{SYMBOL}_historical— rows before today, never expires.{SYMBOL}_today— rows from today, expires after 15 minutes.
Parameters
PSX ticker symbol, e.g.
"ENGRO". Case-insensitive — converted to uppercase
internally.Start date (inclusive). Accepts a
datetime.date, an ISO-format string such as
"2024-01-01", or None. None means the earliest available date for the symbol.End date (inclusive). Accepts the same types as
start. None means today.If
False, bypass the local cache and always fetch fresh data from PSX.Return value
Returns apd.DataFrame. Returns an empty DataFrame if no data is available for the
given date range.
Trading date.
Opening price.
Intraday high price.
Intraday low price.
Closing price.
Number of shares traded.
True if the row was flagged as anomalous during scraping (e.g. zero-volume days
with unchanged prices). Useful for filtering before analysis.Exceptions
psxdata.quote()
Fetch the latest screener snapshot for a symbol. The full screener (approximately 729 symbols) is fetched in a single request and cached for 15 minutes. Successive calls for different symbols reuse the same cached screener, so only the first call within a 15-minute window incurs a network request.Parameters
PSX ticker symbol, e.g.
"ENGRO". Case-insensitive.If
False, bypass the local cache and always fetch the full screener.Return value
Returns a single-rowpd.DataFrame with screener columns. Returns an empty DataFrame
if the symbol is not present in the screener.
PSX ticker symbol.
Sector name as listed on PSX.
Last day’s closing price.
Current market price.
Market capitalisation in PKR.
Price-to-earnings ratio. May be
NaN for loss-making companies.Trailing dividend yield as a decimal, e.g.
0.045 for 4.5 %.Absolute price change from LDCP.
Percentage price change from LDCP.
Exceptions
psxdata.tickers()
Return PSX ticker symbols, optionally filtered to a named index.tickers(index="KSE100") and indices("KSE100") share the same cache key
(indices_KSE100), so calling both methods never results in a double network request.
Parameters
Index name, e.g.
"KSE100". None returns all listed symbols. See
psxdata/constants.py (INDEX_NAMES) for the full list of valid names.If
False, bypass the local cache.Return value
Returnslist[str] — ticker strings, e.g. ["ENGRO", "LUCK", ...]. Returns an empty
list if no symbols are found.
Exceptions
psxdata.symbols()
Return all listed PSX symbols with sector names. Reuses thesymbols_all cache key shared with tickers(index=None), so calling both
functions never results in a double network request.
Parameters
If
False, bypass the local cache and always fetch fresh data from PSX.Return value
Returns apd.DataFrame. Returns an empty DataFrame if PSX returns no data.
PSX ticker symbol.
Full company or instrument name.
Full sector name, e.g.
"CEMENT". Useful for filtering symbols by sector.True if the symbol is an exchange-traded fund.True if the symbol is a debt instrument (e.g. a TFC).True if the symbol is listed on the Growth Enterprise Market (GEM) board.Exceptions
psxdata.indices()
Fetch constituent data for a PSX index. Returns detailed per-stock data for every constituent of the named index, including index weights and market capitalisation figures.Parameters
Index name, e.g.
"KSE100". See psxdata/constants.py (INDEX_NAMES) for valid
values.If
False, bypass the local cache.Return value
Returns apd.DataFrame. Returns an empty DataFrame if PSX returns no data for the
given index name.
PSX ticker symbol.
Current index level contributed by this constituent.
Weight of the constituent in the index, as a percentage.
Index points contributed by this constituent.
Market capitalisation in millions of PKR.
Free-float market capitalisation in millions of PKR. Present for free-float-weighted
indices (e.g. KSE100). Absent for indices that use total shares.
Total shares in millions. Present for indices that use total shares weighting. Absent
when
freefloat_m is present.Exceptions
psxdata.sectors()
Fetch the PSX sector summary. Returns one row per sector with advance/decline breadth and aggregate market capitalisation figures.Parameters
If
False, bypass the local cache.Return value
Returns apd.DataFrame.
Short sector identifier code used internally by PSX.
Full sector name.
Number of stocks that advanced (price increased) in the session.
Number of stocks that declined (price decreased) in the session.
Number of stocks with no price change in the session.
Total sector turnover in PKR for the session.
Aggregate sector market capitalisation in billions of PKR.
Exceptions
psxdata.fundamentals()
Fetch the PSX financial reports filing list. PSX returns all filings in a single request. Whensymbol is provided, the result is
filtered in memory — no additional network requests are made.
Parameters
If provided, return only filings for this ticker. Case-insensitive.
None returns
all available filings.If
False, bypass the local cache.Return value
Returns apd.DataFrame. Returns an empty DataFrame if outside the reporting season
or if PSX returns no data.
PSX ticker symbol of the filing company.
Financial year to which the filing belongs.
Report type, e.g.
"Annual", "Half Yearly", "Quarterly".End date of the reporting period (formatted string as returned by PSX).
Date the filing was posted to PSX.
Time the filing was posted to PSX.
URL or filename of the filing document.
Exceptions
psxdata.debt_market()
Fetch all PSX debt market instrument tables. Returns 4 tables covering the various instrument categories listed on the PSX debt market page. The page does not include<h2> headings before its tables, so the keys are positional rather than
descriptive.
Parameters
If
False, bypass the local cache and always fetch from PSX.Return value
Returnsdict[str, pd.DataFrame] — a mapping of table keys to DataFrames. Returns an
empty dict if no tables are found on the page.
These key names are load-bearing. Do not rely on positional integer indexing —
always use the string keys
"table_0" through "table_3".Exceptions
psxdata.eligible_scrips()
Fetch all PSX margin-trading eligible scrip tables. Returns 9 tables covering the instrument categories listed on the PSX eligible scrips page. The<h2> headings on that page are not direct siblings of the <table> elements, so
keys are positional rather than descriptive.
Parameters
If
False, bypass the local cache and always fetch from PSX.Return value
Returnsdict[str, pd.DataFrame] — a mapping of table keys to DataFrames. Returns an
empty dict if no tables are found on the page.
These key names are load-bearing. Do not rely on positional integer indexing —
always use the string keys
"table_0" through "table_8".