pypsx-toolkit 3.0.3__tar.gz → 3.1.0__tar.gz
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-3.0.3 → pypsx_toolkit-3.1.0}/PKG-INFO +32 -36
- {pypsx_toolkit-3.0.3 → pypsx_toolkit-3.1.0}/README.md +23 -28
- {pypsx_toolkit-3.0.3 → pypsx_toolkit-3.1.0}/pyproject.toml +30 -14
- {pypsx_toolkit-3.0.3 → pypsx_toolkit-3.1.0}/pypsx_toolkit/__init__.py +86 -14
- {pypsx_toolkit-3.0.3 → pypsx_toolkit-3.1.0}/pypsx_toolkit/analysis/__init__.py +10 -1
- {pypsx_toolkit-3.0.3 → pypsx_toolkit-3.1.0}/pypsx_toolkit/api.pyi +10 -4
- {pypsx_toolkit-3.0.3 → pypsx_toolkit-3.1.0}/setup.py +21 -0
- {pypsx_toolkit-3.0.3 → pypsx_toolkit-3.1.0}/LICENSE +0 -0
- {pypsx_toolkit-3.0.3 → pypsx_toolkit-3.1.0}/MANIFEST.in +0 -0
- {pypsx_toolkit-3.0.3 → pypsx_toolkit-3.1.0}/pypsx_toolkit/__init__.pyi +0 -0
- {pypsx_toolkit-3.0.3 → pypsx_toolkit-3.1.0}/pypsx_toolkit/analysis/__init__.pyi +0 -0
- {pypsx_toolkit-3.0.3 → pypsx_toolkit-3.1.0}/pypsx_toolkit/core/__init__.py +0 -0
- {pypsx_toolkit-3.0.3 → pypsx_toolkit-3.1.0}/pypsx_toolkit/core/errors.pyi +0 -0
- {pypsx_toolkit-3.0.3 → pypsx_toolkit-3.1.0}/pypsx_toolkit/core/stream.pyi +0 -0
- {pypsx_toolkit-3.0.3 → pypsx_toolkit-3.1.0}/pypsx_toolkit/endpoints/__init__.py +0 -0
- {pypsx_toolkit-3.0.3 → pypsx_toolkit-3.1.0}/pypsx_toolkit/endpoints/constants.py +0 -0
- {pypsx_toolkit-3.0.3 → pypsx_toolkit-3.1.0}/pypsx_toolkit/format/__init__.py +0 -0
- {pypsx_toolkit-3.0.3 → pypsx_toolkit-3.1.0}/pypsx_toolkit/market.pyi +0 -0
- {pypsx_toolkit-3.0.3 → pypsx_toolkit-3.1.0}/pypsx_toolkit/models.py +0 -0
- {pypsx_toolkit-3.0.3 → pypsx_toolkit-3.1.0}/pypsx_toolkit/models.pyi +0 -0
- {pypsx_toolkit-3.0.3 → pypsx_toolkit-3.1.0}/pypsx_toolkit/py.typed +0 -0
- {pypsx_toolkit-3.0.3 → pypsx_toolkit-3.1.0}/pypsx_toolkit/ticker.pyi +0 -0
- {pypsx_toolkit-3.0.3 → pypsx_toolkit-3.1.0}/pypsx_toolkit.egg-info/SOURCES.txt +0 -0
- {pypsx_toolkit-3.0.3 → pypsx_toolkit-3.1.0}/setup.cfg +0 -0
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pypsx-toolkit
|
|
3
|
-
Version: 3.0
|
|
3
|
+
Version: 3.1.0
|
|
4
4
|
Summary: Pakistan Stock Exchange (PSX) data library with yfinance-like API
|
|
5
|
-
Author-email: PyPSX Team <
|
|
6
|
-
Maintainer-email: PyPSX Team <
|
|
5
|
+
Author-email: PyPSX Team <pypsxofficial@gmail.com>
|
|
6
|
+
Maintainer-email: PyPSX Team <pypsxofficial@gmail.com>
|
|
7
7
|
License: Copyright (c) 2026 PyPSX Team. All rights reserved.
|
|
8
8
|
|
|
9
9
|
This software and associated documentation files (the "Software") are the
|
|
@@ -32,24 +32,25 @@ Classifier: Intended Audience :: Financial and Insurance Industry
|
|
|
32
32
|
Classifier: License :: Other/Proprietary License
|
|
33
33
|
Classifier: Operating System :: OS Independent
|
|
34
34
|
Classifier: Programming Language :: Python :: 3
|
|
35
|
-
Classifier: Programming Language :: Python :: 3.8
|
|
36
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
37
35
|
Classifier: Programming Language :: Python :: 3.10
|
|
38
36
|
Classifier: Programming Language :: Python :: 3.11
|
|
39
37
|
Classifier: Programming Language :: Python :: 3.12
|
|
38
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
39
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
40
40
|
Classifier: Programming Language :: Python :: 3 :: Only
|
|
41
41
|
Classifier: Topic :: Office/Business :: Financial
|
|
42
42
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
43
43
|
Classifier: Topic :: Scientific/Engineering :: Information Analysis
|
|
44
|
-
Requires-Python: >=3.
|
|
44
|
+
Requires-Python: >=3.10
|
|
45
45
|
Description-Content-Type: text/markdown
|
|
46
46
|
License-File: LICENSE
|
|
47
47
|
Requires-Dist: requests>=2.31.0
|
|
48
48
|
Requires-Dist: beautifulsoup4>=4.12.0
|
|
49
49
|
Requires-Dist: lxml>=4.9.0
|
|
50
|
-
Requires-Dist: pandas<
|
|
50
|
+
Requires-Dist: pandas<3.0.0,>=2.0.0
|
|
51
51
|
Requires-Dist: loguru>=0.7.0
|
|
52
|
-
Requires-Dist: numpy<2.
|
|
52
|
+
Requires-Dist: numpy<2.4.0,>=1.24.0
|
|
53
|
+
Requires-Dist: tqdm>=4.66.0
|
|
53
54
|
Provides-Extra: plot
|
|
54
55
|
Requires-Dist: matplotlib>=3.5.0; extra == "plot"
|
|
55
56
|
Requires-Dist: seaborn>=0.11.0; extra == "plot"
|
|
@@ -67,7 +68,7 @@ Dynamic: license-file
|
|
|
67
68
|
|
|
68
69
|
# pypsx-toolkit — Pakistan Stock Exchange Data Library
|
|
69
70
|
|
|
70
|
-
A clean, simple Python library to fetch and analyze Pakistan Stock Exchange (PSX) data
|
|
71
|
+
A clean, simple Python library to fetch and analyze Pakistan Stock Exchange (PSX) market data. Get real-time market data, historical prices, and powerful analysis tools all in one package — no authentication required.
|
|
71
72
|
|
|
72
73
|
## Installation
|
|
73
74
|
|
|
@@ -218,7 +219,7 @@ ticker = pypsx_toolkit.PSXTicker("OGDC")
|
|
|
218
219
|
- `ticker.history(period="1y", interval="1d")` - Get historical data
|
|
219
220
|
- `ticker.intraday()` - Get intraday trades (last ~2 days)
|
|
220
221
|
- `ticker.get_historical(start_date, end_date)` - Get full OHLCV data for date range
|
|
221
|
-
- `ticker.dividends()` - Get dividend information
|
|
222
|
+
- `ticker.dividends()` - Get dividend information
|
|
222
223
|
- `ticker.announcements()` - Get company announcements
|
|
223
224
|
- `ticker.orderbook()` - Get trading board data (bid/ask prices)
|
|
224
225
|
|
|
@@ -505,17 +506,6 @@ historical = ticker.get_historical(
|
|
|
505
506
|
print(historical.head())
|
|
506
507
|
```
|
|
507
508
|
|
|
508
|
-
## Data Sources
|
|
509
|
-
|
|
510
|
-
PyPSX Toolkit uses official Pakistan Stock Exchange DPS endpoints:
|
|
511
|
-
- Market Watch: `https://dps.psx.com.pk/market-watch`
|
|
512
|
-
- Sector Summary: `https://dps.psx.com.pk/sector-summary/sectorwise`
|
|
513
|
-
- Indices: `https://dps.psx.com.pk/indices/{INDEX}`
|
|
514
|
-
- Trading Board: `https://dps.psx.com.pk/trading-board/REG/main`
|
|
515
|
-
- Performers: `https://dps.psx.com.pk/performers`
|
|
516
|
-
- Timeseries: `https://dps.psx.com.pk/timeseries/int/{SYMBOL}`, `.../eod/{SYMBOL}`
|
|
517
|
-
- Historical OHLCV: `https://dps.psx.com.pk/historical`
|
|
518
|
-
|
|
519
509
|
## Examples
|
|
520
510
|
|
|
521
511
|
### Example 1: Find Top Volume Stocks
|
|
@@ -605,22 +595,24 @@ for insight in analysis["portfolio_insights"]:
|
|
|
605
595
|
### PSXTicker Class
|
|
606
596
|
|
|
607
597
|
```python
|
|
608
|
-
|
|
598
|
+
import pypsx_toolkit
|
|
599
|
+
|
|
600
|
+
ticker = pypsx_toolkit.PSXTicker("OGDC")
|
|
609
601
|
|
|
610
|
-
# Properties
|
|
602
|
+
# Properties (no parentheses)
|
|
611
603
|
ticker.info # Dict with company info
|
|
612
604
|
ticker.snapshot # Dict with comprehensive snapshot data from all tabs
|
|
613
|
-
ticker.fast_info
|
|
605
|
+
ticker.fast_info # Quick metrics dict
|
|
614
606
|
|
|
615
607
|
# Methods
|
|
616
|
-
ticker.history(period="1y", interval="1d")
|
|
617
|
-
ticker.intraday()
|
|
618
|
-
ticker.get_historical(
|
|
619
|
-
ticker.market_watch()
|
|
620
|
-
ticker.sector()
|
|
621
|
-
ticker.orderbook()
|
|
622
|
-
ticker.dividends()
|
|
623
|
-
ticker.announcements()
|
|
608
|
+
ticker.history(period="1y", interval="1d") # Historical data
|
|
609
|
+
ticker.intraday() # Intraday trades
|
|
610
|
+
ticker.get_historical("2024-01-01", "2024-12-31") # Full OHLCV data
|
|
611
|
+
ticker.market_watch() # Market watch row
|
|
612
|
+
ticker.sector() # Sector information
|
|
613
|
+
ticker.orderbook() # Trading board data
|
|
614
|
+
ticker.dividends() # DataFrame with dividends
|
|
615
|
+
ticker.announcements() # DataFrame with announcements
|
|
624
616
|
```
|
|
625
617
|
|
|
626
618
|
### Market Functions
|
|
@@ -650,9 +642,13 @@ pypsx_toolkit.get_snapshot(symbol) # Get snapshot data from all tab
|
|
|
650
642
|
### Download Functions
|
|
651
643
|
|
|
652
644
|
```python
|
|
653
|
-
pypsx_toolkit
|
|
654
|
-
|
|
655
|
-
|
|
645
|
+
import pypsx_toolkit
|
|
646
|
+
|
|
647
|
+
symbols = ["OGDC", "HBL"]
|
|
648
|
+
|
|
649
|
+
pypsx_toolkit.download(symbols, period="1y", interval="1d") # Batch download
|
|
650
|
+
pypsx_toolkit.get_intraday_multiple(symbols) # Multiple intraday
|
|
651
|
+
pypsx_toolkit.get_historical("OGDC", "2024-01-01", "2024-12-31") # Historical OHLCV
|
|
656
652
|
```
|
|
657
653
|
|
|
658
654
|
## Backward Compatibility
|
|
@@ -663,7 +659,7 @@ The library maintains backward compatibility:
|
|
|
663
659
|
|
|
664
660
|
## Notes
|
|
665
661
|
|
|
666
|
-
- **Dividends**:
|
|
662
|
+
- **Dividends**: dividend records use their own column naming, which differs from the conventions used elsewhere in the toolkit.
|
|
667
663
|
- **Data Availability**: Some data may not be available when the market is closed.
|
|
668
664
|
- **Symbol Names**: Use official PSX symbols (e.g., "OGDC", "PPL", "KEL").
|
|
669
665
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# pypsx-toolkit — Pakistan Stock Exchange Data Library
|
|
2
2
|
|
|
3
|
-
A clean, simple Python library to fetch and analyze Pakistan Stock Exchange (PSX) data
|
|
3
|
+
A clean, simple Python library to fetch and analyze Pakistan Stock Exchange (PSX) market data. Get real-time market data, historical prices, and powerful analysis tools all in one package — no authentication required.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
@@ -151,7 +151,7 @@ ticker = pypsx_toolkit.PSXTicker("OGDC")
|
|
|
151
151
|
- `ticker.history(period="1y", interval="1d")` - Get historical data
|
|
152
152
|
- `ticker.intraday()` - Get intraday trades (last ~2 days)
|
|
153
153
|
- `ticker.get_historical(start_date, end_date)` - Get full OHLCV data for date range
|
|
154
|
-
- `ticker.dividends()` - Get dividend information
|
|
154
|
+
- `ticker.dividends()` - Get dividend information
|
|
155
155
|
- `ticker.announcements()` - Get company announcements
|
|
156
156
|
- `ticker.orderbook()` - Get trading board data (bid/ask prices)
|
|
157
157
|
|
|
@@ -438,17 +438,6 @@ historical = ticker.get_historical(
|
|
|
438
438
|
print(historical.head())
|
|
439
439
|
```
|
|
440
440
|
|
|
441
|
-
## Data Sources
|
|
442
|
-
|
|
443
|
-
PyPSX Toolkit uses official Pakistan Stock Exchange DPS endpoints:
|
|
444
|
-
- Market Watch: `https://dps.psx.com.pk/market-watch`
|
|
445
|
-
- Sector Summary: `https://dps.psx.com.pk/sector-summary/sectorwise`
|
|
446
|
-
- Indices: `https://dps.psx.com.pk/indices/{INDEX}`
|
|
447
|
-
- Trading Board: `https://dps.psx.com.pk/trading-board/REG/main`
|
|
448
|
-
- Performers: `https://dps.psx.com.pk/performers`
|
|
449
|
-
- Timeseries: `https://dps.psx.com.pk/timeseries/int/{SYMBOL}`, `.../eod/{SYMBOL}`
|
|
450
|
-
- Historical OHLCV: `https://dps.psx.com.pk/historical`
|
|
451
|
-
|
|
452
441
|
## Examples
|
|
453
442
|
|
|
454
443
|
### Example 1: Find Top Volume Stocks
|
|
@@ -538,22 +527,24 @@ for insight in analysis["portfolio_insights"]:
|
|
|
538
527
|
### PSXTicker Class
|
|
539
528
|
|
|
540
529
|
```python
|
|
541
|
-
|
|
530
|
+
import pypsx_toolkit
|
|
531
|
+
|
|
532
|
+
ticker = pypsx_toolkit.PSXTicker("OGDC")
|
|
542
533
|
|
|
543
|
-
# Properties
|
|
534
|
+
# Properties (no parentheses)
|
|
544
535
|
ticker.info # Dict with company info
|
|
545
536
|
ticker.snapshot # Dict with comprehensive snapshot data from all tabs
|
|
546
|
-
ticker.fast_info
|
|
537
|
+
ticker.fast_info # Quick metrics dict
|
|
547
538
|
|
|
548
539
|
# Methods
|
|
549
|
-
ticker.history(period="1y", interval="1d")
|
|
550
|
-
ticker.intraday()
|
|
551
|
-
ticker.get_historical(
|
|
552
|
-
ticker.market_watch()
|
|
553
|
-
ticker.sector()
|
|
554
|
-
ticker.orderbook()
|
|
555
|
-
ticker.dividends()
|
|
556
|
-
ticker.announcements()
|
|
540
|
+
ticker.history(period="1y", interval="1d") # Historical data
|
|
541
|
+
ticker.intraday() # Intraday trades
|
|
542
|
+
ticker.get_historical("2024-01-01", "2024-12-31") # Full OHLCV data
|
|
543
|
+
ticker.market_watch() # Market watch row
|
|
544
|
+
ticker.sector() # Sector information
|
|
545
|
+
ticker.orderbook() # Trading board data
|
|
546
|
+
ticker.dividends() # DataFrame with dividends
|
|
547
|
+
ticker.announcements() # DataFrame with announcements
|
|
557
548
|
```
|
|
558
549
|
|
|
559
550
|
### Market Functions
|
|
@@ -583,9 +574,13 @@ pypsx_toolkit.get_snapshot(symbol) # Get snapshot data from all tab
|
|
|
583
574
|
### Download Functions
|
|
584
575
|
|
|
585
576
|
```python
|
|
586
|
-
pypsx_toolkit
|
|
587
|
-
|
|
588
|
-
|
|
577
|
+
import pypsx_toolkit
|
|
578
|
+
|
|
579
|
+
symbols = ["OGDC", "HBL"]
|
|
580
|
+
|
|
581
|
+
pypsx_toolkit.download(symbols, period="1y", interval="1d") # Batch download
|
|
582
|
+
pypsx_toolkit.get_intraday_multiple(symbols) # Multiple intraday
|
|
583
|
+
pypsx_toolkit.get_historical("OGDC", "2024-01-01", "2024-12-31") # Historical OHLCV
|
|
589
584
|
```
|
|
590
585
|
|
|
591
586
|
## Backward Compatibility
|
|
@@ -596,7 +591,7 @@ The library maintains backward compatibility:
|
|
|
596
591
|
|
|
597
592
|
## Notes
|
|
598
593
|
|
|
599
|
-
- **Dividends**:
|
|
594
|
+
- **Dividends**: dividend records use their own column naming, which differs from the conventions used elsewhere in the toolkit.
|
|
600
595
|
- **Data Availability**: Some data may not be available when the market is closed.
|
|
601
596
|
- **Symbol Names**: Use official PSX symbols (e.g., "OGDC", "PPL", "KEL").
|
|
602
597
|
|
|
@@ -4,16 +4,18 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "pypsx-toolkit"
|
|
7
|
-
version = "3.0
|
|
7
|
+
version = "3.1.0"
|
|
8
8
|
description = "Pakistan Stock Exchange (PSX) data library with yfinance-like API"
|
|
9
9
|
readme = "README.md"
|
|
10
|
-
|
|
10
|
+
# 3.10 is the real floor: `pandas>=2.0` already excludes 3.8/3.9, and
|
|
11
|
+
# core/utils.py uses PEP 604 (`int | None`) in a runtime signature.
|
|
12
|
+
requires-python = ">=3.10"
|
|
11
13
|
license = { file = "LICENSE" }
|
|
12
14
|
authors = [
|
|
13
|
-
{ name = "PyPSX Team", email = "
|
|
15
|
+
{ name = "PyPSX Team", email = "pypsxofficial@gmail.com" }
|
|
14
16
|
]
|
|
15
17
|
maintainers = [
|
|
16
|
-
{ name = "PyPSX Team", email = "
|
|
18
|
+
{ name = "PyPSX Team", email = "pypsxofficial@gmail.com" }
|
|
17
19
|
]
|
|
18
20
|
keywords = ["psx", "pakistan", "stock", "finance", "data", "api", "pandas", "yfinance", "market-data"]
|
|
19
21
|
classifiers = [
|
|
@@ -23,11 +25,11 @@ classifiers = [
|
|
|
23
25
|
"License :: Other/Proprietary License",
|
|
24
26
|
"Operating System :: OS Independent",
|
|
25
27
|
"Programming Language :: Python :: 3",
|
|
26
|
-
"Programming Language :: Python :: 3.8",
|
|
27
|
-
"Programming Language :: Python :: 3.9",
|
|
28
28
|
"Programming Language :: Python :: 3.10",
|
|
29
29
|
"Programming Language :: Python :: 3.11",
|
|
30
30
|
"Programming Language :: Python :: 3.12",
|
|
31
|
+
"Programming Language :: Python :: 3.13",
|
|
32
|
+
"Programming Language :: Python :: 3.14",
|
|
31
33
|
"Programming Language :: Python :: 3 :: Only",
|
|
32
34
|
"Topic :: Office/Business :: Financial",
|
|
33
35
|
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
@@ -38,9 +40,17 @@ dependencies = [
|
|
|
38
40
|
"requests>=2.31.0",
|
|
39
41
|
"beautifulsoup4>=4.12.0",
|
|
40
42
|
"lxml>=4.9.0",
|
|
41
|
-
|
|
43
|
+
# See pypsx_dev/pyproject.toml's identical pins for the reasoning: the
|
|
44
|
+
# ceiling must not exclude the first cp314-wheel release (pandas 2.3.3,
|
|
45
|
+
# numpy 2.3.2), and is deliberately kept below pandas 3.0 (mandatory CoW +
|
|
46
|
+
# other breaking changes) pending its own review.
|
|
47
|
+
"pandas>=2.0.0,<3.0.0",
|
|
42
48
|
"loguru>=0.7.0",
|
|
43
|
-
"numpy>=1.24.0,<2.
|
|
49
|
+
"numpy>=1.24.0,<2.4.0",
|
|
50
|
+
# Imported by api.py, endpoints/historical.py and core/utils.py. Those imports
|
|
51
|
+
# are try/except-guarded with a no-op fallback, but the fallback path is
|
|
52
|
+
# untested and every target environment (including Colab) already ships tqdm.
|
|
53
|
+
"tqdm>=4.66.0",
|
|
44
54
|
]
|
|
45
55
|
|
|
46
56
|
[project.optional-dependencies]
|
|
@@ -61,8 +71,12 @@ Homepage = "https://pypsx.com"
|
|
|
61
71
|
Documentation = "https://markets.pypsx.com/docs"
|
|
62
72
|
Changelog = "https://markets.pypsx.com/docs/changelog"
|
|
63
73
|
|
|
64
|
-
[project.scripts]
|
|
65
|
-
pypsx-toolkit = "pypsx_toolkit:quick_start"
|
|
74
|
+
# NOTE: no [project.scripts]. This previously declared
|
|
75
|
+
# pypsx-toolkit = "pypsx_toolkit:quick_start"
|
|
76
|
+
# but `quick_start` does not exist anywhere in the package, so the installed
|
|
77
|
+
# console script raised AttributeError on every invocation. This library has no
|
|
78
|
+
# CLI; removing the entry point is the honest fix. If a CLI is wanted later,
|
|
79
|
+
# implement the target function first.
|
|
66
80
|
|
|
67
81
|
[tool.setuptools]
|
|
68
82
|
include-package-data = true
|
|
@@ -152,8 +166,10 @@ markers = [
|
|
|
152
166
|
"integration: marks tests as integration tests",
|
|
153
167
|
"unit: marks tests as unit tests",
|
|
154
168
|
]
|
|
155
|
-
filterwarnings = [
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
169
|
+
# NOTE: deliberately no blanket `filterwarnings = ["ignore::DeprecationWarning"]`
|
|
170
|
+
# here. The Colab-mirror suite (b2c/tests/colab_mirror/) runs under
|
|
171
|
+
# `filterwarnings = error` because a warning in a notebook cell is a user-visible
|
|
172
|
+
# defect. A blanket ignore at this level hides exactly the class of bug that
|
|
173
|
+
# suite exists to catch. Allow-list individual warnings there, with an owner and
|
|
174
|
+
# an expiry, instead of re-adding a catch-all.
|
|
159
175
|
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
PSX yfinance-style API
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
|
-
__version__ = "3.0
|
|
5
|
+
__version__ = "3.1.0"
|
|
6
6
|
__author__ = "PyPSX Team"
|
|
7
|
-
__email__ = "
|
|
7
|
+
__email__ = "pypsxofficial@gmail.com"
|
|
8
8
|
|
|
9
9
|
from pypsx_toolkit.ticker import PSXTicker, Ticker
|
|
10
10
|
|
|
@@ -37,6 +37,14 @@ from pypsx_toolkit.endpoints.sectors import get_sector_constituents as _get_sect
|
|
|
37
37
|
from pypsx_toolkit.endpoints.compliant_listings import get_symbols_by_sector as _get_symbols_by_sector
|
|
38
38
|
from pypsx_toolkit.endpoints.snapshot import get_snapshot
|
|
39
39
|
|
|
40
|
+
# Financial reports. Implemented and working, but previously not reachable from
|
|
41
|
+
# anywhere in the public surface.
|
|
42
|
+
from pypsx_toolkit.endpoints.reports import get_reports
|
|
43
|
+
|
|
44
|
+
# Cache control. Useful in notebooks, where a stale cached response is a common
|
|
45
|
+
# source of "why is my data wrong" confusion.
|
|
46
|
+
from pypsx_toolkit.core.cache import clear_pypsx_cache, get_cache_stats
|
|
47
|
+
|
|
40
48
|
from pypsx_toolkit.market import (
|
|
41
49
|
top_performers,
|
|
42
50
|
sector_summary,
|
|
@@ -70,18 +78,29 @@ from pypsx_toolkit.models import (
|
|
|
70
78
|
DividendHistory,
|
|
71
79
|
)
|
|
72
80
|
|
|
73
|
-
#
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
81
|
+
# Exceptions. Previously these were reachable only via the private
|
|
82
|
+
# `pypsx_toolkit.core.errors` path, which the docs told users to import from.
|
|
83
|
+
# Re-exported here as the supported location; the old path still works.
|
|
84
|
+
from pypsx_toolkit.core.errors import (
|
|
85
|
+
PSXError,
|
|
86
|
+
PSXHTTPError,
|
|
87
|
+
PSXTimeoutError,
|
|
88
|
+
PSXNotFoundError,
|
|
89
|
+
PSXScopeError,
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
# Analysis module. This is NOT optional -- it depends only on pandas and numpy,
|
|
93
|
+
# both hard requirements of this package. It was previously wrapped in a
|
|
94
|
+
# `try/except ImportError: pass`, which silently turned any genuine bug inside
|
|
95
|
+
# the analysis package into a confusing AttributeError at call time.
|
|
96
|
+
from pypsx_toolkit import analysis
|
|
97
|
+
from pypsx_toolkit.analysis import (
|
|
98
|
+
interpret_stock,
|
|
99
|
+
sharpe_ratio,
|
|
100
|
+
rsi,
|
|
101
|
+
macd,
|
|
102
|
+
bollinger_bands,
|
|
103
|
+
)
|
|
85
104
|
|
|
86
105
|
__all__ = [
|
|
87
106
|
"__version__",
|
|
@@ -129,6 +148,14 @@ __all__ = [
|
|
|
129
148
|
"get_sector_constituents",
|
|
130
149
|
"get_symbols_by_sector",
|
|
131
150
|
"get_snapshot",
|
|
151
|
+
"get_reports",
|
|
152
|
+
# Cache control
|
|
153
|
+
"clear_pypsx_cache",
|
|
154
|
+
"get_cache_stats",
|
|
155
|
+
# NOTE: `charts` is deliberately NOT listed here. It resolves lazily via
|
|
156
|
+
# __getattr__ and needs the optional `[plot]` extra, so including it would
|
|
157
|
+
# make `from pypsx_toolkit import *` raise ImportError on a plain install.
|
|
158
|
+
# Access it as `pypsx_toolkit.charts` (see the Charting docs).
|
|
132
159
|
# Models
|
|
133
160
|
"SymbolInfo",
|
|
134
161
|
"SectorSummary",
|
|
@@ -147,8 +174,53 @@ __all__ = [
|
|
|
147
174
|
"Announcement",
|
|
148
175
|
"DividendInfo",
|
|
149
176
|
"DividendHistory",
|
|
177
|
+
# Exceptions. Also available at the original `pypsx_toolkit.core.errors` path.
|
|
178
|
+
"PSXError",
|
|
179
|
+
"PSXHTTPError",
|
|
180
|
+
"PSXTimeoutError",
|
|
181
|
+
"PSXNotFoundError",
|
|
182
|
+
"PSXScopeError",
|
|
183
|
+
# Analysis. `analysis` is the submodule (documented usage is
|
|
184
|
+
# `import pypsx_toolkit.analysis as pa`); the rest are convenience
|
|
185
|
+
# re-exports that were importable before but absent from __all__.
|
|
186
|
+
"analysis",
|
|
187
|
+
"interpret_stock",
|
|
188
|
+
"sharpe_ratio",
|
|
189
|
+
"rsi",
|
|
190
|
+
"macd",
|
|
191
|
+
"bollinger_bands",
|
|
150
192
|
]
|
|
151
193
|
|
|
194
|
+
# `market_watch_func` / `get_indices_func` are internal aliases created to avoid
|
|
195
|
+
# colliding with the same-named api.py functions. They stay bound for backward
|
|
196
|
+
# compatibility but are deliberately excluded from __all__ above -- they are not
|
|
197
|
+
# part of the supported surface. Use `market_watch()` / `get_indices()`.
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
def __getattr__(name: str):
|
|
201
|
+
"""
|
|
202
|
+
Lazily expose `pypsx_toolkit.charts`.
|
|
203
|
+
|
|
204
|
+
The charting helpers need matplotlib/seaborn, which ship only under the
|
|
205
|
+
optional `[plot]` extra. Importing them eagerly would make a plain
|
|
206
|
+
`pip install pypsx-toolkit` fail at `import pypsx_toolkit`, so resolution is
|
|
207
|
+
deferred until first access and a missing extra produces an actionable
|
|
208
|
+
message instead of a bare ModuleNotFoundError.
|
|
209
|
+
"""
|
|
210
|
+
if name == "charts":
|
|
211
|
+
import sys
|
|
212
|
+
|
|
213
|
+
try:
|
|
214
|
+
from pypsx_toolkit.endpoints import charts as _charts
|
|
215
|
+
except ImportError as exc: # pragma: no cover - depends on install extras
|
|
216
|
+
raise ImportError(
|
|
217
|
+
"pypsx_toolkit.charts requires the optional plotting dependencies. "
|
|
218
|
+
"Install them with: pip install 'pypsx-toolkit[plot]'"
|
|
219
|
+
) from exc
|
|
220
|
+
setattr(sys.modules[__name__], "charts", _charts)
|
|
221
|
+
return _charts
|
|
222
|
+
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
|
|
223
|
+
|
|
152
224
|
|
|
153
225
|
# Legacy compatibility wrappers used by audit script (clean outputs only)
|
|
154
226
|
|
|
@@ -70,7 +70,16 @@ __all__ = [
|
|
|
70
70
|
|
|
71
71
|
# Insight engine
|
|
72
72
|
'interpret_stock', 'interpret_portfolio', 'detect_patterns',
|
|
73
|
-
'generate_trading_signals', 'market_sentiment_analysis'
|
|
73
|
+
'generate_trading_signals', 'market_sentiment_analysis',
|
|
74
|
+
|
|
75
|
+
# Composite helpers (defined in this module, below)
|
|
76
|
+
'quick_analysis', 'portfolio_analysis',
|
|
77
|
+
|
|
78
|
+
# Short aliases (defined at the bottom of this module). These are used in
|
|
79
|
+
# the published documentation, so they are part of the supported surface.
|
|
80
|
+
'ma', 'ema', 'bb', 'sharpe', 'sortino', 'calmar', 'cum_returns', 'max_dd',
|
|
81
|
+
'win_rate_pct', 'pl_ratio', 'recovery', 'perf_summary', 'interpret',
|
|
82
|
+
'patterns', 'signals', 'sentiment',
|
|
74
83
|
]
|
|
75
84
|
|
|
76
85
|
|
|
@@ -6,9 +6,10 @@ import pandas as pd
|
|
|
6
6
|
|
|
7
7
|
def download(
|
|
8
8
|
symbols: Union[str, List[str]],
|
|
9
|
-
period: str = "
|
|
9
|
+
period: str = "1y",
|
|
10
10
|
interval: str = "1d",
|
|
11
11
|
to_csv: Optional[str] = None,
|
|
12
|
+
show_progress: bool = True,
|
|
12
13
|
) -> pd.DataFrame:
|
|
13
14
|
"""
|
|
14
15
|
Download historical OHLCV data for one or more PSX symbols (yfinance-style).
|
|
@@ -18,6 +19,8 @@ def download(
|
|
|
18
19
|
period: Time period — "1d","5d","1mo","3mo","6mo","1y","2y","5y","10y","ytd","max".
|
|
19
20
|
interval: Bar interval. Only "1d" is currently supported.
|
|
20
21
|
to_csv: Optional path to save the result as CSV.
|
|
22
|
+
show_progress: Display a progress bar while fetching. Set False in
|
|
23
|
+
notebooks, reports or logs where the bar is just noise.
|
|
21
24
|
|
|
22
25
|
Returns:
|
|
23
26
|
For a single symbol: DataFrame with [Open, High, Low, Close, Volume, Change%].
|
|
@@ -61,8 +64,6 @@ def get_intraday(symbol: str) -> pd.DataFrame:
|
|
|
61
64
|
"""
|
|
62
65
|
Fetch intraday tick data for the last 2 trading days.
|
|
63
66
|
|
|
64
|
-
Runs on the user's local machine to distribute scraping traffic.
|
|
65
|
-
|
|
66
67
|
Args:
|
|
67
68
|
symbol: PSX ticker symbol.
|
|
68
69
|
|
|
@@ -75,12 +76,17 @@ def get_intraday(symbol: str) -> pd.DataFrame:
|
|
|
75
76
|
...
|
|
76
77
|
|
|
77
78
|
|
|
78
|
-
def get_intraday_multiple(
|
|
79
|
+
def get_intraday_multiple(
|
|
80
|
+
symbols: List[str],
|
|
81
|
+
show_progress: bool = True,
|
|
82
|
+
) -> pd.DataFrame:
|
|
79
83
|
"""
|
|
80
84
|
Fetch intraday tick data for multiple symbols in parallel.
|
|
81
85
|
|
|
82
86
|
Args:
|
|
83
87
|
symbols: List of PSX ticker symbols.
|
|
88
|
+
show_progress: Display a progress bar while fetching. Set False in
|
|
89
|
+
notebooks, reports or logs where the bar is just noise.
|
|
84
90
|
|
|
85
91
|
Returns:
|
|
86
92
|
Concatenated DataFrame with an additional "Symbol" column.
|
|
@@ -85,6 +85,27 @@ def main():
|
|
|
85
85
|
# embedsignature=True: embeds the Python call signature in the docstring
|
|
86
86
|
# so IDEs can show it even when the .pyi stub is absent.
|
|
87
87
|
"embedsignature": True,
|
|
88
|
+
# annotation_typing defaults to True, which makes Cython treat a
|
|
89
|
+
# PEP 484 parameter annotation like
|
|
90
|
+
# `def correlation_matrix(df_dict: Dict[str, pd.DataFrame])`
|
|
91
|
+
# as a `cdef dict` declaration and enforce it at the C level.
|
|
92
|
+
#
|
|
93
|
+
# Two problems, both COMPILED-ONLY -- they cannot reproduce from
|
|
94
|
+
# source, which is the worst possible failure mode here:
|
|
95
|
+
#
|
|
96
|
+
# 1. Cython's builtin-container coercion is exact-type-only, so
|
|
97
|
+
# passing an OrderedDict/defaultdict/Counter to a
|
|
98
|
+
# Dict[...]-annotated parameter raises TypeError even though
|
|
99
|
+
# it is a perfectly good Mapping.
|
|
100
|
+
# 2. It pre-empts the library's own validation. The argument
|
|
101
|
+
# checks in analysis/stats.py exist to say "correlation_matrix()
|
|
102
|
+
# expects {symbol: DataFrame}, got a single DataFrame" -- but
|
|
103
|
+
# with annotation_typing on, Cython rejects the call first with
|
|
104
|
+
# a terse message naming neither the function nor the fix.
|
|
105
|
+
#
|
|
106
|
+
# pypsx set this to False for the same reason; the toolkit had
|
|
107
|
+
# been left on the default.
|
|
108
|
+
"annotation_typing": False,
|
|
88
109
|
},
|
|
89
110
|
build_dir="build",
|
|
90
111
|
annotate=False,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|