pypsx-toolkit 3.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pypsx_toolkit/__init__.py +304 -0
- pypsx_toolkit/__init__.pyi +99 -0
- pypsx_toolkit/analysis/__init__.py +222 -0
- pypsx_toolkit/analysis/__init__.pyi +348 -0
- pypsx_toolkit/api.pyi +294 -0
- pypsx_toolkit/core/__init__.py +6 -0
- pypsx_toolkit/core/errors.pyi +38 -0
- pypsx_toolkit/core/stream.pyi +66 -0
- pypsx_toolkit/endpoints/__init__.py +1 -0
- pypsx_toolkit/endpoints/constants.py +121 -0
- pypsx_toolkit/format/__init__.py +1 -0
- pypsx_toolkit/market.pyi +158 -0
- pypsx_toolkit/models.py +224 -0
- pypsx_toolkit/models.pyi +199 -0
- pypsx_toolkit/py.typed +0 -0
- pypsx_toolkit/ticker.pyi +237 -0
- pypsx_toolkit-3.0.0.dist-info/METADATA +744 -0
- pypsx_toolkit-3.0.0.dist-info/RECORD +22 -0
- pypsx_toolkit-3.0.0.dist-info/WHEEL +5 -0
- pypsx_toolkit-3.0.0.dist-info/entry_points.txt +2 -0
- pypsx_toolkit-3.0.0.dist-info/licenses/LICENSE +17 -0
- pypsx_toolkit-3.0.0.dist-info/top_level.txt +1 -0
pypsx_toolkit/models.pyi
ADDED
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
"""Type stubs for pypsx.models — data model dataclasses."""
|
|
2
|
+
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
from typing import Any, Dict, List, Optional
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
@dataclass
|
|
8
|
+
class SymbolInfo:
|
|
9
|
+
"""Basic metadata for a PSX-listed security."""
|
|
10
|
+
symbol: str
|
|
11
|
+
company_name: str
|
|
12
|
+
sector: str
|
|
13
|
+
listing_date: Optional[str]
|
|
14
|
+
face_value: Optional[float]
|
|
15
|
+
shares_outstanding: Optional[float]
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@dataclass
|
|
19
|
+
class SectorSummary:
|
|
20
|
+
"""Aggregate statistics for a PSX sector."""
|
|
21
|
+
sector_code: str
|
|
22
|
+
sector_name: str
|
|
23
|
+
companies_count: int
|
|
24
|
+
market_cap: float
|
|
25
|
+
change_pct: float
|
|
26
|
+
volume: int
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
@dataclass
|
|
30
|
+
class SectorCompany:
|
|
31
|
+
"""A company entry within a sector listing."""
|
|
32
|
+
symbol: str
|
|
33
|
+
company_name: str
|
|
34
|
+
market_cap: float
|
|
35
|
+
change_pct: float
|
|
36
|
+
volume: int
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
@dataclass
|
|
40
|
+
class CompanyMarketWatch:
|
|
41
|
+
"""Live market watch row for a single company."""
|
|
42
|
+
symbol: str
|
|
43
|
+
company_name: str
|
|
44
|
+
sector: str
|
|
45
|
+
ldcp: float
|
|
46
|
+
open: float
|
|
47
|
+
high: float
|
|
48
|
+
low: float
|
|
49
|
+
current: float
|
|
50
|
+
change: float
|
|
51
|
+
change_pct: float
|
|
52
|
+
volume: int
|
|
53
|
+
value: float
|
|
54
|
+
trades: int
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
@dataclass
|
|
58
|
+
class IndexConstituent:
|
|
59
|
+
"""A single company entry in a PSX index."""
|
|
60
|
+
symbol: str
|
|
61
|
+
company_name: str
|
|
62
|
+
sector: str
|
|
63
|
+
weight: float
|
|
64
|
+
market_cap: float
|
|
65
|
+
shares: float
|
|
66
|
+
price: float
|
|
67
|
+
change_pct: float
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
@dataclass
|
|
71
|
+
class IndexMeta:
|
|
72
|
+
"""Metadata and current value of a PSX index."""
|
|
73
|
+
index_code: str
|
|
74
|
+
index_name: str
|
|
75
|
+
current: float
|
|
76
|
+
change: float
|
|
77
|
+
change_pct: float
|
|
78
|
+
high: float
|
|
79
|
+
low: float
|
|
80
|
+
volume: int
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
@dataclass
|
|
84
|
+
class TradingBoardRow:
|
|
85
|
+
"""Live trading board entry with bid/ask spread."""
|
|
86
|
+
symbol: str
|
|
87
|
+
bid: float
|
|
88
|
+
ask: float
|
|
89
|
+
ltp: float
|
|
90
|
+
volume: int
|
|
91
|
+
trades: int
|
|
92
|
+
high: float
|
|
93
|
+
low: float
|
|
94
|
+
ldcp: float
|
|
95
|
+
change_pct: float
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
@dataclass
|
|
99
|
+
class TopActiveStock:
|
|
100
|
+
"""Most-active stock by volume."""
|
|
101
|
+
symbol: str
|
|
102
|
+
company_name: str
|
|
103
|
+
volume: int
|
|
104
|
+
value: float
|
|
105
|
+
change_pct: float
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
@dataclass
|
|
109
|
+
class TopAdvancer:
|
|
110
|
+
"""Top gaining stock for the session."""
|
|
111
|
+
symbol: str
|
|
112
|
+
company_name: str
|
|
113
|
+
price: float
|
|
114
|
+
change_pct: float
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
@dataclass
|
|
118
|
+
class TopDecliner:
|
|
119
|
+
"""Top declining stock for the session."""
|
|
120
|
+
symbol: str
|
|
121
|
+
company_name: str
|
|
122
|
+
price: float
|
|
123
|
+
change_pct: float
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
@dataclass
|
|
127
|
+
class IntradayBar:
|
|
128
|
+
"""A single intraday price tick."""
|
|
129
|
+
time: str
|
|
130
|
+
price: float
|
|
131
|
+
volume: int
|
|
132
|
+
change: float
|
|
133
|
+
change_pct: float
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
@dataclass
|
|
137
|
+
class EODBar:
|
|
138
|
+
"""End-of-day OHLCV bar."""
|
|
139
|
+
date: str
|
|
140
|
+
open: float
|
|
141
|
+
high: float
|
|
142
|
+
low: float
|
|
143
|
+
close: float
|
|
144
|
+
volume: int
|
|
145
|
+
change_pct: float
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
@dataclass
|
|
149
|
+
class ListingEntry:
|
|
150
|
+
"""A PSX listing entry (from compliant/non-compliant/defaulter lists)."""
|
|
151
|
+
symbol: str
|
|
152
|
+
company_name: str
|
|
153
|
+
listing_type: str
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
@dataclass
|
|
157
|
+
class CompanyFundamentals:
|
|
158
|
+
"""Company fundamental financial metrics."""
|
|
159
|
+
symbol: str
|
|
160
|
+
pe_ratio: Optional[float]
|
|
161
|
+
eps: Optional[float]
|
|
162
|
+
book_value: Optional[float]
|
|
163
|
+
dividend_yield: Optional[float]
|
|
164
|
+
roe: Optional[float]
|
|
165
|
+
roa: Optional[float]
|
|
166
|
+
debt_to_equity: Optional[float]
|
|
167
|
+
current_ratio: Optional[float]
|
|
168
|
+
market_cap: Optional[float]
|
|
169
|
+
shares_outstanding: Optional[float]
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
@dataclass
|
|
173
|
+
class Announcement:
|
|
174
|
+
"""A PSX corporate announcement."""
|
|
175
|
+
date: str
|
|
176
|
+
category: str
|
|
177
|
+
subject: str
|
|
178
|
+
description: str
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
@dataclass
|
|
182
|
+
class DividendInfo:
|
|
183
|
+
"""Latest dividend details for a symbol."""
|
|
184
|
+
symbol: str
|
|
185
|
+
dividend_type: str
|
|
186
|
+
rate: float
|
|
187
|
+
face_value: float
|
|
188
|
+
ex_date: Optional[str]
|
|
189
|
+
payment_date: Optional[str]
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
@dataclass
|
|
193
|
+
class DividendHistory:
|
|
194
|
+
"""Historical dividend payment record."""
|
|
195
|
+
date: str
|
|
196
|
+
dividend_type: str
|
|
197
|
+
rate: float
|
|
198
|
+
face_value: float
|
|
199
|
+
announcement_date: Optional[str]
|
pypsx_toolkit/py.typed
ADDED
|
File without changes
|
pypsx_toolkit/ticker.pyi
ADDED
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
"""Type stubs for pypsx.ticker — PSXTicker (yfinance-style interface)."""
|
|
2
|
+
|
|
3
|
+
from typing import Any, Callable, Dict, List, Optional, Union
|
|
4
|
+
import pandas as pd
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class PSXTicker:
|
|
8
|
+
"""
|
|
9
|
+
PSX stock ticker — yfinance-compatible interface for Pakistan Stock Exchange data.
|
|
10
|
+
|
|
11
|
+
Supports equity symbols (e.g. "ENGRO", "HBL") and index symbols (e.g. "KSE100", "KMI30").
|
|
12
|
+
|
|
13
|
+
Example:
|
|
14
|
+
>>> import pypsx
|
|
15
|
+
>>> t = pypsx.Ticker("ENGRO")
|
|
16
|
+
>>> df = t.history(period="1y")
|
|
17
|
+
>>> print(df.head())
|
|
18
|
+
>>> print(t.info["sector"])
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
symbol: str
|
|
22
|
+
|
|
23
|
+
def __init__(self, symbol: str) -> None:
|
|
24
|
+
"""
|
|
25
|
+
Create a ticker for a PSX-listed symbol.
|
|
26
|
+
|
|
27
|
+
Args:
|
|
28
|
+
symbol: PSX ticker symbol (case-insensitive), e.g. "ENGRO", "HBL", "KSE100".
|
|
29
|
+
|
|
30
|
+
Raises:
|
|
31
|
+
PSXNotFoundError: If the symbol is not listed on PSX.
|
|
32
|
+
"""
|
|
33
|
+
...
|
|
34
|
+
|
|
35
|
+
# -------------------------------------------------------------------------
|
|
36
|
+
# Properties
|
|
37
|
+
# -------------------------------------------------------------------------
|
|
38
|
+
|
|
39
|
+
@property
|
|
40
|
+
def info(self) -> Dict[str, Any]:
|
|
41
|
+
"""
|
|
42
|
+
Comprehensive company information dictionary.
|
|
43
|
+
|
|
44
|
+
Keys include: symbol, company_name, sector, market_cap, pe_ratio,
|
|
45
|
+
eps, book_value, dividend_yield, shares_outstanding, float_shares,
|
|
46
|
+
current_price, fifty_two_week_high, fifty_two_week_low, volume,
|
|
47
|
+
average_volume, and more.
|
|
48
|
+
|
|
49
|
+
Returns:
|
|
50
|
+
dict with company fundamentals and market data.
|
|
51
|
+
|
|
52
|
+
Example:
|
|
53
|
+
>>> t = pypsx.Ticker("OGDC")
|
|
54
|
+
>>> print(t.info["pe_ratio"])
|
|
55
|
+
"""
|
|
56
|
+
...
|
|
57
|
+
|
|
58
|
+
@property
|
|
59
|
+
def fast_info(self) -> Dict[str, Any]:
|
|
60
|
+
"""
|
|
61
|
+
Quick snapshot of key price metrics (lighter than .info).
|
|
62
|
+
|
|
63
|
+
Keys include: last_price, change, change_pct, volume, high, low,
|
|
64
|
+
open, prev_close.
|
|
65
|
+
|
|
66
|
+
Returns:
|
|
67
|
+
dict with real-time price snapshot.
|
|
68
|
+
"""
|
|
69
|
+
...
|
|
70
|
+
|
|
71
|
+
@property
|
|
72
|
+
def snapshot(self) -> Dict[str, Any]:
|
|
73
|
+
"""
|
|
74
|
+
Multi-tab market snapshot (combines price, fundamentals, and trading stats).
|
|
75
|
+
|
|
76
|
+
Returns:
|
|
77
|
+
Nested dict with tabs: price, fundamentals, trading_stats, company.
|
|
78
|
+
"""
|
|
79
|
+
...
|
|
80
|
+
|
|
81
|
+
# -------------------------------------------------------------------------
|
|
82
|
+
# Historical / OHLCV data
|
|
83
|
+
# -------------------------------------------------------------------------
|
|
84
|
+
|
|
85
|
+
def history(
|
|
86
|
+
self,
|
|
87
|
+
period: str = "1mo",
|
|
88
|
+
interval: str = "1d",
|
|
89
|
+
to_csv: Optional[str] = None,
|
|
90
|
+
) -> pd.DataFrame:
|
|
91
|
+
"""
|
|
92
|
+
Fetch OHLCV history using a period shorthand (yfinance-compatible).
|
|
93
|
+
|
|
94
|
+
Args:
|
|
95
|
+
period: Time period string. Valid values:
|
|
96
|
+
"1d", "5d", "1mo", "3mo", "6mo", "1y", "2y", "5y", "10y", "ytd", "max"
|
|
97
|
+
interval: Bar interval. Currently only "1d" (daily) is supported.
|
|
98
|
+
to_csv: Optional file path to export the DataFrame as CSV.
|
|
99
|
+
|
|
100
|
+
Returns:
|
|
101
|
+
DataFrame with columns [Date, Open, High, Low, Close, Volume, Change%].
|
|
102
|
+
Date is the index.
|
|
103
|
+
|
|
104
|
+
Raises:
|
|
105
|
+
PSXNotFoundError: If the symbol does not exist.
|
|
106
|
+
PSXHTTPError: If the PSX server returns an error.
|
|
107
|
+
|
|
108
|
+
Example:
|
|
109
|
+
>>> t = pypsx.Ticker("ENGRO")
|
|
110
|
+
>>> df = t.history(period="1y")
|
|
111
|
+
>>> df = t.history(period="5y", to_csv="engro_5y.csv")
|
|
112
|
+
"""
|
|
113
|
+
...
|
|
114
|
+
|
|
115
|
+
def get_historical(
|
|
116
|
+
self,
|
|
117
|
+
start_date: str,
|
|
118
|
+
end_date: str,
|
|
119
|
+
max_workers: int = 4,
|
|
120
|
+
show_progress: bool = False,
|
|
121
|
+
) -> pd.DataFrame:
|
|
122
|
+
"""
|
|
123
|
+
Fetch historical OHLCV data between two specific dates.
|
|
124
|
+
|
|
125
|
+
Args:
|
|
126
|
+
start_date: Start date in "YYYY-MM-DD" format.
|
|
127
|
+
end_date: End date in "YYYY-MM-DD" format.
|
|
128
|
+
max_workers: Number of parallel HTTP workers (speeds up long date ranges).
|
|
129
|
+
show_progress: If True, show a tqdm progress bar.
|
|
130
|
+
|
|
131
|
+
Returns:
|
|
132
|
+
DataFrame with columns [Date, Open, High, Low, Close, Volume, Change%].
|
|
133
|
+
|
|
134
|
+
Example:
|
|
135
|
+
>>> t = pypsx.Ticker("HBL")
|
|
136
|
+
>>> df = t.get_historical("2020-01-01", "2024-12-31")
|
|
137
|
+
"""
|
|
138
|
+
...
|
|
139
|
+
|
|
140
|
+
# -------------------------------------------------------------------------
|
|
141
|
+
# Intraday / real-time
|
|
142
|
+
# -------------------------------------------------------------------------
|
|
143
|
+
|
|
144
|
+
def intraday(self) -> pd.DataFrame:
|
|
145
|
+
"""
|
|
146
|
+
Fetch intraday tick data for the last 2 trading days.
|
|
147
|
+
|
|
148
|
+
Returns:
|
|
149
|
+
DataFrame with columns [Time, Price, Volume, Change, Change%].
|
|
150
|
+
Each row is a trade tick.
|
|
151
|
+
|
|
152
|
+
Example:
|
|
153
|
+
>>> t = pypsx.Ticker("SYS")
|
|
154
|
+
>>> ticks = t.intraday()
|
|
155
|
+
"""
|
|
156
|
+
...
|
|
157
|
+
|
|
158
|
+
def market_watch(self) -> pd.DataFrame:
|
|
159
|
+
"""
|
|
160
|
+
Live market watch entry for this symbol (price, volume, change, etc.).
|
|
161
|
+
|
|
162
|
+
Returns:
|
|
163
|
+
Single-row DataFrame with live market data.
|
|
164
|
+
"""
|
|
165
|
+
...
|
|
166
|
+
|
|
167
|
+
def orderbook(self) -> pd.DataFrame:
|
|
168
|
+
"""
|
|
169
|
+
Order book / market depth for this symbol.
|
|
170
|
+
|
|
171
|
+
Returns:
|
|
172
|
+
DataFrame with bid/ask price levels and volumes.
|
|
173
|
+
"""
|
|
174
|
+
...
|
|
175
|
+
|
|
176
|
+
# -------------------------------------------------------------------------
|
|
177
|
+
# Corporate actions
|
|
178
|
+
# -------------------------------------------------------------------------
|
|
179
|
+
|
|
180
|
+
def announcements(self) -> pd.DataFrame:
|
|
181
|
+
"""
|
|
182
|
+
Fetch company announcements (dividends, results, AGM notices, etc.).
|
|
183
|
+
|
|
184
|
+
Returns:
|
|
185
|
+
DataFrame with columns [Date, Category, Subject, Description].
|
|
186
|
+
|
|
187
|
+
Example:
|
|
188
|
+
>>> t = pypsx.Ticker("ENGRO")
|
|
189
|
+
>>> df = t.announcements()
|
|
190
|
+
"""
|
|
191
|
+
...
|
|
192
|
+
|
|
193
|
+
def dividends(self) -> pd.DataFrame:
|
|
194
|
+
"""
|
|
195
|
+
Dividend history for this symbol.
|
|
196
|
+
|
|
197
|
+
Returns:
|
|
198
|
+
DataFrame with columns [Date, Type, Rate, Face_Value, Announcement_Date].
|
|
199
|
+
|
|
200
|
+
Example:
|
|
201
|
+
>>> t = pypsx.Ticker("OGDC")
|
|
202
|
+
>>> df = t.dividends()
|
|
203
|
+
"""
|
|
204
|
+
...
|
|
205
|
+
|
|
206
|
+
# -------------------------------------------------------------------------
|
|
207
|
+
# Sector / index
|
|
208
|
+
# -------------------------------------------------------------------------
|
|
209
|
+
|
|
210
|
+
def sector(self) -> pd.DataFrame:
|
|
211
|
+
"""
|
|
212
|
+
Sector membership and sector-level statistics for this symbol.
|
|
213
|
+
|
|
214
|
+
Returns:
|
|
215
|
+
DataFrame with sector name, peer companies, and sector indices.
|
|
216
|
+
"""
|
|
217
|
+
...
|
|
218
|
+
|
|
219
|
+
def constituents(self) -> pd.DataFrame:
|
|
220
|
+
"""
|
|
221
|
+
For index symbols (e.g. "KSE100"), return all constituent companies.
|
|
222
|
+
|
|
223
|
+
Returns:
|
|
224
|
+
DataFrame with columns [Symbol, Company, Sector, Weight, Market_Cap].
|
|
225
|
+
|
|
226
|
+
Raises:
|
|
227
|
+
PSXScopeError: If called on an equity symbol (not an index).
|
|
228
|
+
|
|
229
|
+
Example:
|
|
230
|
+
>>> idx = pypsx.Ticker("KSE100")
|
|
231
|
+
>>> df = idx.constituents()
|
|
232
|
+
"""
|
|
233
|
+
...
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
# Alias for yfinance-compatibility
|
|
237
|
+
Ticker = PSXTicker
|