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,744 @@
1
+ Metadata-Version: 2.4
2
+ Name: pypsx-toolkit
3
+ Version: 3.0.0
4
+ Summary: Pakistan Stock Exchange (PSX) data library with yfinance-like API
5
+ Author-email: PyPSX Team <contact@pypsx.dev>
6
+ Maintainer-email: PyPSX Team <contact@pypsx.dev>
7
+ License: Copyright (c) 2026 PyPSX Team. All rights reserved.
8
+
9
+ This software and associated documentation files (the "Software") are the
10
+ proprietary property of PyPSX Team. Unauthorized copying, modification,
11
+ distribution, sublicensing, or use of this Software, via any medium, is
12
+ strictly prohibited without the prior written permission of PyPSX Team.
13
+
14
+ No license, express or implied, to any intellectual property rights is
15
+ granted by this document.
16
+
17
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23
+ DEALINGS IN THE SOFTWARE.
24
+
25
+ Project-URL: Homepage, https://pypsx.com
26
+ Project-URL: Documentation, https://markets.pypsx.com/docs
27
+ Project-URL: Changelog, https://markets.pypsx.com/docs/changelog
28
+ Keywords: psx,pakistan,stock,finance,data,api,pandas,yfinance,market-data
29
+ Classifier: Development Status :: 4 - Beta
30
+ Classifier: Intended Audience :: Developers
31
+ Classifier: Intended Audience :: Financial and Insurance Industry
32
+ Classifier: License :: Other/Proprietary License
33
+ Classifier: Operating System :: OS Independent
34
+ Classifier: Programming Language :: Python :: 3
35
+ Classifier: Programming Language :: Python :: 3.8
36
+ Classifier: Programming Language :: Python :: 3.9
37
+ Classifier: Programming Language :: Python :: 3.10
38
+ Classifier: Programming Language :: Python :: 3.11
39
+ Classifier: Programming Language :: Python :: 3.12
40
+ Classifier: Programming Language :: Python :: 3 :: Only
41
+ Classifier: Topic :: Office/Business :: Financial
42
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
43
+ Classifier: Topic :: Scientific/Engineering :: Information Analysis
44
+ Requires-Python: >=3.8
45
+ Description-Content-Type: text/markdown
46
+ License-File: LICENSE
47
+ Requires-Dist: requests>=2.31.0
48
+ Requires-Dist: beautifulsoup4>=4.12.0
49
+ Requires-Dist: lxml>=4.9.0
50
+ Requires-Dist: pandas>=2.0.0
51
+ Requires-Dist: loguru>=0.7.0
52
+ Requires-Dist: numpy>=1.24.0
53
+ Provides-Extra: plot
54
+ Requires-Dist: matplotlib>=3.5.0; extra == "plot"
55
+ Requires-Dist: seaborn>=0.11.0; extra == "plot"
56
+ Provides-Extra: dev
57
+ Requires-Dist: pytest>=7.0.0; extra == "dev"
58
+ Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
59
+ Requires-Dist: requests-mock>=1.10.0; extra == "dev"
60
+ Requires-Dist: black>=23.0.0; extra == "dev"
61
+ Requires-Dist: flake8>=6.0.0; extra == "dev"
62
+ Requires-Dist: mypy>=1.0.0; extra == "dev"
63
+ Requires-Dist: isort>=5.12.0; extra == "dev"
64
+ Provides-Extra: all
65
+ Requires-Dist: pypsx-toolkit[dev,plot]; extra == "all"
66
+ Dynamic: license-file
67
+
68
+ # PyPSX - Pakistan Stock Exchange Data Library (v3)
69
+
70
+ A clean, simple Python library to fetch and analyze Pakistan Stock Exchange (PSX) data from official DPS endpoints. Get real-time market data, historical prices, and powerful analysis tools all in one package.
71
+
72
+ ## Installation
73
+
74
+ ```bash
75
+ pip install pypsx
76
+ ```
77
+
78
+ ## Quick Start
79
+
80
+ ### Basic Usage - Get Stock Information
81
+
82
+ ```python
83
+ import pypsx
84
+
85
+ # Create a ticker object for any stock symbol
86
+ ticker = pypsx.PSXTicker("OGDC") # or use pypsx.Ticker("OGDC")
87
+
88
+ # Get company information
89
+ info = ticker.info
90
+ print(f"Company: {info.get('Sector')}")
91
+ print(f"Current Price: {info.get('Current')}")
92
+
93
+ # Get comprehensive snapshot data (OHLCV, bid/ask, circuit breaker, ranges, ratios, etc.)
94
+ snapshot = ticker.snapshot
95
+ print(f"Open: {snapshot.get('REG', {}).get('Open')}")
96
+ print(f"High: {snapshot.get('REG', {}).get('High')}")
97
+ print(f"52-Week Range: {snapshot.get('REG', {}).get('52-WEEK RANGE ^')}")
98
+ print(f"P/E Ratio: {snapshot.get('REG', {}).get('P/E Ratio (TTM) **')}")
99
+
100
+ # Get market watch data for this stock
101
+ market_data = ticker.market_watch()
102
+ print(market_data)
103
+
104
+ # Get historical price data (1 year)
105
+ history = ticker.history(period="1y", interval="1d")
106
+ print(history.head())
107
+
108
+ # Get recent intraday trades (last 2 days)
109
+ intraday = ticker.intraday()
110
+ print(intraday.head())
111
+ ```
112
+
113
+ ### Market Data
114
+
115
+ ```python
116
+ import pypsx
117
+
118
+ # Get full market watch (all stocks)
119
+ # Note: Different endpoints return different symbol counts
120
+ # Market Watch: ~486 symbols (includes all actively traded)
121
+ # Trading Board: ~479 symbols (order book data)
122
+ market_watch = pypsx.market_watch()
123
+ print(f"Total stocks in market watch: {len(market_watch)}")
124
+
125
+ # Get top performers
126
+ performers = pypsx.top_performers()
127
+ print("Top Gainers:")
128
+ print(performers["top_gainers"].head())
129
+
130
+ print("Top Decliners:")
131
+ print(performers["top_decliners"].head())
132
+
133
+ print("Most Active:")
134
+ print(performers["top_actives"].head())
135
+
136
+ # Get sector summary
137
+ sectors = pypsx.sector_summary()
138
+ print(sectors.head())
139
+
140
+ # Get all available stock symbols from trading board
141
+ # get_symbols() returns a list of clean symbols (without suffixes XD, NC, XR)
142
+ symbols_list = pypsx.get_symbols()
143
+ print(f"Total symbols: {len(symbols_list)}")
144
+
145
+ # To get DataFrame with Symbol, Name, Tag columns (Tag shows suffix if present)
146
+ from endpoints.trading_board import get_symbols as get_symbols_df
147
+ symbols_df = get_symbols_df() # Returns DataFrame with Symbol, Name, Tag columns
148
+ print(f"Total symbols (DataFrame): {len(symbols_df)}")
149
+ print(symbols_df.head())
150
+ ```
151
+
152
+ ### Historical Data
153
+
154
+ ```python
155
+ import pypsx
156
+
157
+ # Get 1 year of historical data for a stock
158
+ ticker = pypsx.PSXTicker("OGDC")
159
+ history = ticker.history(period="1y", interval="1d")
160
+
161
+ # Get full OHLCV data for specific date range
162
+ full_data = ticker.get_historical(start_date="2024-01-01", end_date="2024-12-31")
163
+ print(full_data.head())
164
+
165
+ # Download multiple symbols at once
166
+ df = pypsx.download(["OGDC", "PPL", "KEL"], period="6mo", interval="1d")
167
+ print(df.head())
168
+ ```
169
+
170
+ ### Indices and Sectors
171
+
172
+ ```python
173
+ import pypsx
174
+
175
+ # Get all indices overview
176
+ indices = pypsx.get_indices()
177
+ print(indices.head())
178
+
179
+ # Get constituents of an index (e.g., KSE100)
180
+ kse100 = pypsx.index_constituents("KSE100")
181
+ print(f"KSE100 has {len(kse100)} constituents")
182
+ print(kse100.head())
183
+
184
+ # Get sector information
185
+ sectors = pypsx.sector_summary()
186
+ print(sectors.head())
187
+
188
+ # Get complete indices breakdown with statistics
189
+ indices_breakdown = pypsx.get_indices_breakdown()
190
+ print(f"Total indices: {indices_breakdown['total_indices']}")
191
+ print(f"Total unique symbols: {indices_breakdown['unique_symbols']}")
192
+ for idx, count, stats in indices_breakdown['indices'][:5]:
193
+ print(f"{idx}: {count} symbols (Current: {stats.get('current', 'N/A')})")
194
+
195
+ # Get complete sector breakdown with company counts and averages
196
+ sector_breakdown = pypsx.get_sector_breakdown()
197
+ print(f"\nTotal sectors: {sector_breakdown['total_sectors']}")
198
+ print(f"Total companies: {sector_breakdown['total_companies']}")
199
+ for sector in sector_breakdown['sectors'][:5]:
200
+ name = sector['name']
201
+ count = sector['company_count']
202
+ avg_price = sector['averages'].get('current', 'N/A')
203
+ print(f"{name}: {count} companies (Avg Price: {avg_price})")
204
+ ```
205
+
206
+ ## Main Features
207
+
208
+ ### 1. Stock Information (`PSXTicker`)
209
+
210
+ Create a ticker object for any stock symbol:
211
+
212
+ ```python
213
+ ticker = pypsx.PSXTicker("OGDC")
214
+ ```
215
+
216
+ **Available Properties:**
217
+ - `ticker.info` - Get company information (price, sector, volume, etc.)
218
+ - `ticker.snapshot` - Get comprehensive snapshot data from all tabs (OHLCV, bid/ask, circuit breaker, ranges, ratios, etc.)
219
+
220
+ **Available Methods:**
221
+ - `ticker.market_watch()` - Get current market watch row for this stock
222
+ - `ticker.sector()` - Get sector-level information
223
+ - `ticker.history(period="1y", interval="1d")` - Get historical data
224
+ - `ticker.intraday()` - Get intraday trades (last ~2 days)
225
+ - `ticker.get_historical(start_date, end_date)` - Get full OHLCV data for date range
226
+ - `ticker.dividends()` - Get dividend information (external source)
227
+ - `ticker.announcements()` - Get company announcements
228
+ - `ticker.orderbook()` - Get trading board data (bid/ask prices)
229
+
230
+ ### 2. Market Data Functions
231
+
232
+ ```python
233
+ # Full market watch
234
+ market_watch = pypsx.market_watch()
235
+
236
+ # Top performers
237
+ performers = pypsx.top_performers() # Returns dict with "top_gainers", "top_decliners", "top_actives"
238
+
239
+ # Sector summary
240
+ sectors = pypsx.sector_summary()
241
+
242
+ # Trading board (order book)
243
+ orderbook = pypsx.trading_board()
244
+
245
+ # Get detailed quote data for a symbol (OHLCV, bid/ask, PE ratio, 52-week range, etc.)
246
+ quote = pypsx.get_quote("OGDC")
247
+ print(quote)
248
+
249
+ # Get quotes for multiple symbols
250
+ quotes = pypsx.get_quote_batch(["OGDC", "PPL", "KEL"])
251
+ for symbol, quote_df in quotes.items():
252
+ if quote_df is not None:
253
+ print(f"{symbol}: {quote_df}")
254
+
255
+ # Get company fundamentals (business description, financials, ratios, equity profile)
256
+ fundamentals = pypsx.get_company_fundamentals("OGDC")
257
+ print(fundamentals.head())
258
+ # Returns DataFrame with CATEGORY, METRIC, VALUE columns
259
+ # Categories include: Profile, Governance, Financials Annual, Financials Quarterly, Ratios, Equity Profile
260
+
261
+ # Get all symbols
262
+ symbols = pypsx.get_symbols()
263
+ ```
264
+
265
+ ### 3. Batch Downloads
266
+
267
+ ```python
268
+ # Download multiple symbols at once
269
+ df = pypsx.download(["OGDC", "PPL", "KEL"], period="1y", interval="1d")
270
+ print(df.head())
271
+
272
+ # Get intraday data for multiple symbols
273
+ intraday_multi = pypsx.get_intraday_multiple(["OGDC", "PPL"])
274
+ print(intraday_multi.head())
275
+ ```
276
+
277
+ ## Charting and Visualization
278
+
279
+ PyPSX includes powerful charting capabilities to visualize stock data:
280
+
281
+ ### Price Charts
282
+
283
+ ```python
284
+ import matplotlib.pyplot as plt
285
+ from endpoints.charts import create_price_chart, create_technical_analysis_chart
286
+
287
+ # Create a candlestick chart
288
+ fig = create_price_chart("OGDC", period="1y", chart_type="candlestick")
289
+ plt.show()
290
+
291
+ # Create a line chart
292
+ fig = create_price_chart("PPL", period="6mo", chart_type="line")
293
+ plt.show()
294
+
295
+ # Create technical analysis chart with indicators
296
+ fig = create_technical_analysis_chart("OGDC", period="1y")
297
+ plt.show()
298
+ ```
299
+
300
+ ### Comparison Charts
301
+
302
+ ```python
303
+ from endpoints.charts import create_multi_symbol_chart, create_index_comparison_chart
304
+
305
+ # Compare multiple stocks
306
+ fig = create_multi_symbol_chart(["OGDC", "PPL", "KEL"], period="1y")
307
+ plt.show()
308
+
309
+ # Compare indices
310
+ fig = create_index_comparison_chart(["KSE100", "KMI30"], period="1y")
311
+ plt.show()
312
+ ```
313
+
314
+ ### Correlation Analysis
315
+
316
+ ```python
317
+ from endpoints.charts import create_correlation_heatmap
318
+
319
+ # Create correlation heatmap
320
+ fig = create_correlation_heatmap(["OGDC", "PPL", "KEL", "PSO"], period="1y")
321
+ plt.show()
322
+ ```
323
+
324
+ **Available Chart Functions:**
325
+ - `create_price_chart(symbol, period, chart_type)` - Price charts (candlestick, line, OHLC)
326
+ - `create_technical_analysis_chart(symbol, period)` - Charts with technical indicators
327
+ - `create_multi_symbol_chart(symbols, period)` - Compare multiple stocks
328
+ - `create_index_comparison_chart(indices, period)` - Compare indices
329
+ - `create_correlation_heatmap(symbols, period)` - Correlation analysis
330
+
331
+ ## Analysis and Statistics
332
+
333
+ PyPSX includes comprehensive analysis tools for stock data:
334
+
335
+ ### Statistical Analysis
336
+
337
+ ```python
338
+ from pypsx.analysis import returns, volatility, correlation, sharpe_ratio
339
+
340
+ ticker = pypsx.PSXTicker("OGDC")
341
+ df = ticker.history(period="1y")
342
+
343
+ # Calculate returns
344
+ rets = returns(df)
345
+ print(rets.head())
346
+
347
+ # Calculate volatility
348
+ vol = volatility(df)
349
+ print(vol.head())
350
+
351
+ # Calculate Sharpe ratio
352
+ sharpe = sharpe_ratio(df)
353
+ print(f"Sharpe Ratio: {sharpe:.3f}")
354
+ ```
355
+
356
+ ### Technical Indicators
357
+
358
+ ```python
359
+ # Import indicators
360
+ from analysis import moving_average, rsi, macd, bollinger_bands, exponential_moving_average
361
+ # Or: from pypsx.analysis import moving_average, rsi, macd, bollinger_bands
362
+
363
+ ticker = pypsx.PSXTicker("OGDC")
364
+ df = ticker.history(period="1y")
365
+
366
+ # Moving averages
367
+ df['SMA20'] = moving_average(df, window=20)
368
+ df['EMA12'] = exponential_moving_average(df, window=12)
369
+
370
+ # RSI (supports both 'period' and 'window' parameter names)
371
+ df['RSI'] = rsi(df, period=14)
372
+
373
+ # MACD
374
+ macd_line, signal, histogram = macd(df)
375
+ df['MACD'] = macd_line
376
+ df['Signal'] = signal
377
+
378
+ # Bollinger Bands
379
+ ma, upper, lower = bollinger_bands(df, window=20)
380
+ df['BB_Upper'] = upper
381
+ df['BB_Lower'] = lower
382
+ ```
383
+
384
+ ### Automated Insights
385
+
386
+ ```python
387
+ # Import insight functions
388
+ from analysis import interpret_stock, quick_analysis
389
+ # Or: from pypsx.analysis import interpret_stock, quick_analysis
390
+
391
+ ticker = pypsx.PSXTicker("OGDC")
392
+ df = ticker.history(period="1y")
393
+
394
+ # Generate comprehensive insights
395
+ insights = interpret_stock(df, "OGDC")
396
+ print("Insights:")
397
+ for insight in insights['insights']:
398
+ print(f" - {insight}")
399
+
400
+ # Quick analysis
401
+ analysis = quick_analysis(df, "OGDC")
402
+ print(f"Trading Signal: {analysis['trading_signal']}")
403
+ print(f"Sharpe Ratio: {analysis['key_metrics']['sharpe_ratio']:.3f}")
404
+ print(f"Max Drawdown: {analysis['key_metrics']['max_drawdown']:.3f}")
405
+ print(f"Total Return: {analysis['key_metrics']['total_return']:.2%}")
406
+
407
+ # Get trading signals directly
408
+ from analysis import generate_trading_signals
409
+ signals = generate_trading_signals(df, "OGDC")
410
+ print(f"Primary Signal: {signals['primary_signal']}")
411
+ print(f"Confidence: {signals['confidence']:.2%}")
412
+ ```
413
+
414
+ **Available Analysis Functions:**
415
+
416
+ All analysis functions are available from the `analysis` package:
417
+
418
+ - **Statistics**: `returns()`, `volatility()`, `correlation()`, `beta()`, `correlation_matrix()`
419
+ - **Indicators**: `moving_average()`, `rsi()`, `macd()`, `bollinger_bands()`, `stochastic()`, `williams_r()`, `atr()`, `adx()`, `cci()`, `obv()`, `vwap()`
420
+ - **Performance**: `sharpe_ratio()`, `sortino_ratio()`, `calmar_ratio()`, `drawdown()`, `max_drawdown()`, `information_ratio()`, `treynor_ratio()`
421
+ - **Insights**: `interpret_stock()`, `quick_analysis()`, `portfolio_analysis()`, `market_sentiment_analysis()`, `generate_trading_signals()`
422
+
423
+ Import them like: `from analysis import sharpe_ratio, rsi` or `from pypsx.analysis import sharpe_ratio, rsi`
424
+
425
+ ## Market Analysis and Breakdowns
426
+
427
+ ### Indices Breakdown
428
+
429
+ Get a comprehensive breakdown of all PSX indices with constituent counts and statistics:
430
+
431
+ ```python
432
+ import pypsx
433
+
434
+ # Get indices breakdown
435
+ breakdown = pypsx.get_indices_breakdown()
436
+
437
+ print(f"Total Indices: {breakdown['total_indices']}")
438
+ print(f"Total Symbols Analyzed: {breakdown['total_symbols_analyzed']}")
439
+ print(f"Unique Symbols: {breakdown['unique_symbols']}")
440
+
441
+ # Print breakdown
442
+ for idx, count, stats in breakdown['indices']:
443
+ current = stats.get('current', 'N/A')
444
+ change_pct = stats.get('percentage_change', 'N/A')
445
+ print(f"{idx}: {count} symbols (Current: {current}, Change: {change_pct}%)")
446
+ ```
447
+
448
+ **Output includes:**
449
+ - Total number of indices
450
+ - Constituent count for each index
451
+ - Index statistics (Current value, Change, Change %)
452
+ - Total symbols analyzed (with duplicates across indices)
453
+ - Unique symbols across all indices
454
+
455
+ **Example Output:**
456
+ ```
457
+ PSX Indices Summary
458
+
459
+ **Total Indices in PSX: 18 unique indices**
460
+
461
+ Complete Breakdown:
462
+
463
+ 1. *ALLSHR* - 549 symbols (Current: 98254.73, Change: 2590.07, Change %: 2.71%)
464
+ 2. *KMIALLSHR* - 259 symbols (Current: 64179.60, Change: 1496.52, Change %: 2.39%)
465
+ 3. *KSE100* - 100 symbols (Current: 161631.73, Change: 4898.86, Change %: 3.13%)
466
+ ...
467
+
468
+ *Total symbols analyzed: 1217* across all indices.
469
+
470
+ *Total unique symbols: 549* across all indices.
471
+ ```
472
+
473
+ ### Sector Breakdown
474
+
475
+ Get a comprehensive breakdown of all PSX sectors with company counts and computed averages:
476
+
477
+ ```python
478
+ import pypsx
479
+
480
+ # Get sector breakdown
481
+ breakdown = pypsx.get_sector_breakdown()
482
+
483
+ print(f"Total Sectors: {breakdown['total_sectors']}")
484
+ print(f"Total Companies: {breakdown['total_companies']}")
485
+
486
+ # Print breakdown
487
+ for sector in breakdown['sectors'][:10]: # Top 10 sectors
488
+ name = sector['name']
489
+ count = sector['company_count']
490
+ code = sector['code']
491
+ avg_price = sector['averages'].get('current', 0)
492
+ avg_change = sector['averages'].get('change_%', 0)
493
+ advances = sector['advances']
494
+ declines = sector['declines']
495
+
496
+ print(f"{name} (Code: {code}):")
497
+ print(f" Companies: {count}")
498
+ print(f" Avg Price: {avg_price:.2f}")
499
+ print(f" Avg Change %: {avg_change:.2f}%")
500
+ print(f" Advances: {advances}, Declines: {declines}")
501
+ print()
502
+ ```
503
+
504
+ **Output includes:**
505
+ - Total number of sectors
506
+ - Company count per sector
507
+ - Average prices, volumes, changes per sector
508
+ - Sector-level statistics (advances, declines, turnover)
509
+ - Total companies across all sectors
510
+
511
+ **Example Output:**
512
+ ```
513
+ PSX Sectorwise Summary
514
+
515
+ **Total Sectors in PSX: 37 unique sectors**
516
+
517
+ Complete Breakdown:
518
+
519
+ 1. *TEXTILE SPINNING* (Code: 830) - 46 companies (Avg Price: 78.31, Avg Volume: 435833) [Advances: 24, Declines: 14, Turnover: 20048323]
520
+ 2. *TEXTILE COMPOSITE* (Code: 829) - 39 companies (Avg Price: 192.50, Avg Volume: 254652) [Advances: 25, Declines: 8, Turnover: 9931432]
521
+ 3. *INV. BANKS / INV. COS. / SECURITIES COS.* (Code: 813) - 35 companies (Avg Price: 756.90, Avg Volume: 2230213) [Advances: 30, Declines: 2, Turnover: 77778422]
522
+ ...
523
+
524
+ *Total companies analyzed: 486* across all sectors.
525
+ ```
526
+
527
+ ## Advanced Usage
528
+
529
+ ### Company Information
530
+
531
+ ```python
532
+ import pypsx
533
+
534
+ ticker = pypsx.PSXTicker("OGDC")
535
+
536
+ # Get detailed quote data (includes OHLCV, bid/ask prices, PE ratio, 52-week range, VAR, etc.)
537
+ quote = pypsx.get_quote("OGDC")
538
+ print(quote)
539
+ # Output includes: OPEN, HIGH, LOW, VOLUME, BID_PRICE, ASK_PRICE, PE_RATIO, VAR, HAIRCUT, etc.
540
+
541
+ # Get quotes for multiple symbols
542
+ quotes = pypsx.get_quote_batch(["OGDC", "PPL", "KEL"])
543
+ for symbol, quote_df in quotes.items():
544
+ if quote_df is not None:
545
+ print(f"{symbol} Quote:")
546
+ print(quote_df)
547
+
548
+ # Get company fundamentals (business description, financials, ratios, equity profile)
549
+ fundamentals = pypsx.get_company_fundamentals("OGDC")
550
+ print(fundamentals.head())
551
+
552
+ # Get comprehensive snapshot data from all tabs (most holistic approach)
553
+ snapshot = pypsx.get_snapshot("BOP")
554
+ print(snapshot['REG']) # REG tab contains: OHLCV, circuit breaker, ranges, bid/ask, ratios, etc.
555
+ # Or use ticker.snapshot property:
556
+ ticker = pypsx.PSXTicker("BOP")
557
+ snap = ticker.snapshot
558
+ print(f"Open: {snap['REG']['Open']}")
559
+ print(f"52-Week Range: {snap['REG']['52-WEEK RANGE ^']}")
560
+
561
+ # Get announcements
562
+ announcements = ticker.announcements()
563
+ print(announcements.head())
564
+
565
+ # Get dividends
566
+ dividends = ticker.dividends()
567
+ print(dividends)
568
+
569
+ # Get order book
570
+ orderbook = ticker.orderbook()
571
+ print(orderbook)
572
+ ```
573
+
574
+ ### Custom Date Ranges
575
+
576
+ ```python
577
+ ticker = pypsx.PSXTicker("OGDC")
578
+
579
+ # Get historical data for specific date range
580
+ historical = ticker.get_historical(
581
+ start_date="2024-01-01",
582
+ end_date="2024-12-31"
583
+ )
584
+ print(historical.head())
585
+ ```
586
+
587
+ ## Data Sources
588
+
589
+ PyPSX uses official Pakistan Stock Exchange DPS endpoints:
590
+ - Market Watch: `https://dps.psx.com.pk/market-watch`
591
+ - Sector Summary: `https://dps.psx.com.pk/sector-summary/sectorwise`
592
+ - Indices: `https://dps.psx.com.pk/indices/{INDEX}`
593
+ - Trading Board: `https://dps.psx.com.pk/trading-board/REG/main`
594
+ - Performers: `https://dps.psx.com.pk/performers`
595
+ - Timeseries: `https://dps.psx.com.pk/timeseries/int/{SYMBOL}`, `.../eod/{SYMBOL}`
596
+ - Historical OHLCV: `https://dps.psx.com.pk/historical`
597
+
598
+ ## Examples
599
+
600
+ ### Example 1: Find Top Volume Stocks
601
+
602
+ ```python
603
+ import pypsx
604
+
605
+ # Get market watch
606
+ mw = pypsx.market_watch()
607
+
608
+ # Sort by volume and get top 5
609
+ top_volume = mw.nlargest(5, "Volume")[['Current', 'Change %', 'Volume']]
610
+ print(top_volume)
611
+ ```
612
+
613
+ ### Example 2: Compare Stock Performance
614
+
615
+ ```python
616
+ import pypsx
617
+ from endpoints.charts import create_multi_symbol_chart
618
+ import matplotlib.pyplot as plt
619
+
620
+ # Compare three stocks
621
+ fig = create_multi_symbol_chart(["OGDC", "PPL", "KEL"], period="6mo")
622
+ plt.show()
623
+
624
+ # Save chart to file
625
+ fig = create_multi_symbol_chart(["OGDC", "PPL"], period="1y", save_path="comparison.png")
626
+ ```
627
+
628
+ ### Example 3: Technical Analysis
629
+
630
+ ```python
631
+ import pypsx
632
+ from analysis import rsi, macd, bollinger_bands
633
+ import pandas as pd
634
+
635
+ ticker = pypsx.PSXTicker("OGDC")
636
+ df = ticker.history(period="1y")
637
+
638
+ # Add technical indicators
639
+ df['RSI'] = rsi(df, period=14)
640
+ macd_line, signal, _ = macd(df)
641
+ df['MACD'] = macd_line
642
+ df['Signal'] = signal
643
+
644
+ ma, upper, lower = bollinger_bands(df)
645
+ df['BB_Upper'] = upper
646
+ df['BB_Lower'] = lower
647
+
648
+ # Simple trading signal (SMA crossover)
649
+ df['SMA20'] = df['CLOSE'].rolling(20).mean()
650
+ df['SMA50'] = df['CLOSE'].rolling(50).mean()
651
+ df['Signal'] = (df['SMA20'] > df['SMA50']).astype(int)
652
+
653
+ print(df[['CLOSE', 'RSI', 'MACD', 'Signal']].tail())
654
+ ```
655
+
656
+ ### Example 4: Portfolio Analysis
657
+
658
+ ```python
659
+ import pypsx
660
+ from analysis import portfolio_analysis
661
+
662
+ # Create a portfolio
663
+ portfolio = {
664
+ "OGDC": pypsx.PSXTicker("OGDC").history(period="1y"),
665
+ "PPL": pypsx.PSXTicker("PPL").history(period="1y"),
666
+ "PPL": pypsx.PSXTicker("PPL").history(period="1y")
667
+ }
668
+
669
+ # Analyze portfolio
670
+ analysis = portfolio_analysis(portfolio)
671
+ print(f"Portfolio Sharpe Ratio: {analysis['sharpe_ratio']:.3f}")
672
+ print(f"Portfolio Volatility: {analysis['volatility']:.3f}")
673
+ ```
674
+
675
+ ## API Reference
676
+
677
+ ### PSXTicker Class
678
+
679
+ ```python
680
+ ticker = pypsx.PSXTicker(symbol: str)
681
+
682
+ # Properties
683
+ ticker.info # Dict with company info
684
+ ticker.snapshot # Dict with comprehensive snapshot data from all tabs
685
+ ticker.fast_info # Quick metrics dict
686
+
687
+ # Methods
688
+ ticker.history(period="1y", interval="1d") # Historical data
689
+ ticker.intraday() # Intraday trades
690
+ ticker.get_historical(start_date, end_date) # Full OHLCV data
691
+ ticker.market_watch() # Market watch row
692
+ ticker.sector() # Sector information
693
+ ticker.orderbook() # Trading board data
694
+ ticker.dividends() # DataFrame with dividends
695
+ ticker.announcements() # DataFrame with announcements
696
+ ```
697
+
698
+ ### Market Functions
699
+
700
+ ```python
701
+ pypsx.market_watch() # Full market watch DataFrame
702
+ pypsx.top_performers() # Dict: {top_gainers, top_decliners, top_actives}
703
+ pypsx.sector_summary() # Sector summary DataFrame
704
+ pypsx.get_indices() # Indices overview DataFrame
705
+ pypsx.get_indices_breakdown() # Complete indices breakdown with counts and stats
706
+ pypsx.get_sector_breakdown() # Complete sector breakdown with company counts and averages
707
+ pypsx.get_symbols() # List of all stock symbols
708
+ pypsx.trading_board() # Trading board DataFrame
709
+
710
+ # Quote functions - Get detailed quote data (OHLCV, bid/ask, PE ratio, 52-week range, etc.)
711
+ pypsx.get_quote(symbol) # Get detailed quote for a single symbol
712
+ pypsx.get_quote_batch(symbols) # Get quotes for multiple symbols (returns dict)
713
+
714
+ # Company fundamentals - Get comprehensive company data (business description, financials, ratios, etc.)
715
+ pypsx.get_company_fundamentals(symbol) # Get company fundamentals (returns DataFrame)
716
+
717
+ # Snapshot - Get comprehensive snapshot data from all tabs (most holistic approach)
718
+ pypsx.get_snapshot(symbol) # Get snapshot data from all tabs (returns dict with tab names as keys)
719
+ # Or use ticker.snapshot property for easier access
720
+ ```
721
+
722
+ ### Download Functions
723
+
724
+ ```python
725
+ pypsx.download(symbols, period="1y", interval="1d") # Batch download
726
+ pypsx.get_intraday_multiple(symbols) # Multiple intraday
727
+ pypsx.get_historical(symbol, start_date, end_date) # Historical OHLCV
728
+ ```
729
+
730
+ ## Backward Compatibility
731
+
732
+ The library maintains backward compatibility:
733
+ - `pypsx.Ticker` is an alias for `pypsx.PSXTicker`
734
+ - `pypsx.PSXSymbol` is also available (legacy)
735
+
736
+ ## Notes
737
+
738
+ - **Dividends**: PSX doesn't provide a dividends endpoint. The `dividends` property uses an external data source.
739
+ - **Data Availability**: Some data may not be available when the market is closed.
740
+ - **Symbol Names**: Use official PSX symbols (e.g., "OGDC", "PPL", "KEL").
741
+
742
+ ## License
743
+
744
+ Proprietary — All rights reserved. Unauthorized use, copying, or distribution is prohibited.