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.
@@ -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
@@ -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