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
str
default:"~/.psxdata/cache/"
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
str
required
PSX ticker symbol, e.g.
"ENGRO". Case-insensitive — converted to uppercase
internally.date | str | None
default:"None"
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.date | str | None
default:"None"
End date (inclusive). Accepts the same types as
start. None means today.bool
default:"True"
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.
datetime64[ns]
required
Trading date.
float64
required
Opening price.
float64
required
Intraday high price.
float64
required
Intraday low price.
float64
required
Closing price.
int64
required
Number of shares traded.
bool
required
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
str
required
PSX ticker symbol, e.g.
"ENGRO". Case-insensitive.bool
default:"True"
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.
object
required
PSX ticker symbol.
object
required
Sector name as listed on PSX.
float64
required
Last day’s closing price.
float64
required
Current market price.
float64
required
Market capitalisation in PKR.
float64
required
Price-to-earnings ratio. May be
NaN for loss-making companies.float64
required
Trailing dividend yield as a decimal, e.g.
0.045 for 4.5 %.float64
required
Absolute price change from LDCP.
float64
required
Percentage price change from LDCP.
Exceptions
psxdata.screener()
Return the full PSX screener table, unfiltered. Shares the same"screener_all" cache key as quote(), so calling both within the same
15-minute window never results in a double network request.
Parameters
bool
default:"True"
If
False, bypass the local cache and always fetch the full screener.Return value
Returns apd.DataFrame with one row per PSX-listed symbol (approximately 729 rows).
Returns an empty DataFrame if PSX returns no data.
object
required
PSX ticker symbol.
float64
required
Raw numeric sector code as returned by PSX — not enriched to a sector name. Join
against
psxdata.symbols() on sector_name if you need the sector label.object
required
Market board the symbol is listed in.
float64
required
Market capitalisation in PKR.
float64
required
Current market price.
float64
required
Price-to-earnings ratio. May be
NaN for loss-making companies.float64
required
Trailing dividend yield as a decimal, e.g.
0.045 for 4.5 %.float64
required
Free-float shares as a percentage of total shares outstanding.
float64
required
30-day average trading volume.
float64
required
Percentage price change over the trailing 1 year.
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
str | None
default:"None"
Index name, e.g.
"KSE100". None returns all listed symbols. See
psxdata/constants.py (INDEX_NAMES) for the full list of valid names.bool
default:"True"
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
bool
default:"True"
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.
object
required
PSX ticker symbol.
object
required
Full company or instrument name.
object
required
Full sector name, e.g.
"CEMENT". Useful for filtering symbols by sector.bool
required
True if the symbol is an exchange-traded fund.bool
required
True if the symbol is a debt instrument (e.g. a TFC).bool
required
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
str
required
Index name, e.g.
"KSE100". See psxdata/constants.py (INDEX_NAMES) for valid
values.bool
default:"True"
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.
object
required
PSX ticker symbol.
float64
required
Current index level contributed by this constituent.
float64
required
Weight of the constituent in the index, as a percentage.
float64
required
Index points contributed by this constituent.
float64
required
Market capitalisation in millions of PKR.
float64
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
bool
default:"True"
If
False, bypass the local cache.Return value
Returns apd.DataFrame.
object
required
Short sector identifier code used internally by PSX.
object
required
Full sector name.
int64
required
Number of stocks that advanced (price increased) in the session.
int64
required
Number of stocks that declined (price decreased) in the session.
int64
required
Number of stocks with no price change in the session.
float64
required
Total sector turnover in PKR for the session.
float64
required
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
str | None
default:"None"
If provided, return only filings for this ticker. Case-insensitive.
None returns
all available filings.bool
default:"True"
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.
object
required
PSX ticker symbol of the filing company.
int64
required
Financial year to which the filing belongs.
object
required
Report type, e.g.
"Annual", "Half Yearly", "Quarterly".object
required
End date of the reporting period (formatted string as returned by PSX).
object
required
Date the filing was posted to PSX.
object
required
Time the filing was posted to PSX.
object
required
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
bool
default:"True"
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
bool
default:"True"
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".