pkscreener 0.46.20250210.703__tar.gz → 0.46.20250213.705__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.
- {pkscreener-0.46.20250210.703 → pkscreener-0.46.20250213.705}/PKG-INFO +12 -10
- {pkscreener-0.46.20250210.703 → pkscreener-0.46.20250213.705}/README.md +9 -7
- {pkscreener-0.46.20250210.703 → pkscreener-0.46.20250213.705}/pkscreener/README.txt +9 -7
- {pkscreener-0.46.20250210.703 → pkscreener-0.46.20250213.705}/pkscreener/classes/MarketMonitor.py +80 -33
- pkscreener-0.46.20250213.705/pkscreener/classes/__init__.py +1 -0
- {pkscreener-0.46.20250210.703 → pkscreener-0.46.20250213.705}/pkscreener/globals.py +6 -3
- {pkscreener-0.46.20250210.703 → pkscreener-0.46.20250213.705}/pkscreener/pkscreenerbot.py +285 -210
- {pkscreener-0.46.20250210.703 → pkscreener-0.46.20250213.705}/pkscreener/requirements.txt +1 -1
- {pkscreener-0.46.20250210.703 → pkscreener-0.46.20250213.705}/pkscreener.egg-info/PKG-INFO +12 -10
- {pkscreener-0.46.20250210.703 → pkscreener-0.46.20250213.705}/pkscreener.egg-info/requires.txt +1 -1
- pkscreener-0.46.20250210.703/pkscreener/classes/__init__.py +0 -1
- {pkscreener-0.46.20250210.703 → pkscreener-0.46.20250213.705}/LICENSE +0 -0
- {pkscreener-0.46.20250210.703 → pkscreener-0.46.20250213.705}/pkscreener/Disclaimer.txt +0 -0
- {pkscreener-0.46.20250210.703 → pkscreener-0.46.20250213.705}/pkscreener/LICENSE-Others.txt +0 -0
- {pkscreener-0.46.20250210.703 → pkscreener-0.46.20250213.705}/pkscreener/LICENSE.txt +0 -0
- {pkscreener-0.46.20250210.703 → pkscreener-0.46.20250213.705}/pkscreener/LogoWM.txt +0 -0
- {pkscreener-0.46.20250210.703 → pkscreener-0.46.20250213.705}/pkscreener/__init__.py +0 -0
- {pkscreener-0.46.20250210.703 → pkscreener-0.46.20250213.705}/pkscreener/classes/ArtTexts.py +0 -0
- {pkscreener-0.46.20250210.703 → pkscreener-0.46.20250213.705}/pkscreener/classes/AssetsManager.py +0 -0
- {pkscreener-0.46.20250210.703 → pkscreener-0.46.20250213.705}/pkscreener/classes/Backtest.py +0 -0
- {pkscreener-0.46.20250210.703 → pkscreener-0.46.20250213.705}/pkscreener/classes/Barometer.py +0 -0
- {pkscreener-0.46.20250210.703 → pkscreener-0.46.20250213.705}/pkscreener/classes/BaseScreeningStatistics.py +0 -0
- {pkscreener-0.46.20250210.703 → pkscreener-0.46.20250213.705}/pkscreener/classes/CandlePatterns.py +0 -0
- {pkscreener-0.46.20250210.703 → pkscreener-0.46.20250213.705}/pkscreener/classes/Changelog.py +0 -0
- {pkscreener-0.46.20250210.703 → pkscreener-0.46.20250213.705}/pkscreener/classes/ConfigManager.py +0 -0
- {pkscreener-0.46.20250210.703 → pkscreener-0.46.20250213.705}/pkscreener/classes/ConsoleMenuUtility.py +0 -0
- {pkscreener-0.46.20250210.703 → pkscreener-0.46.20250213.705}/pkscreener/classes/ConsoleUtility.py +0 -0
- {pkscreener-0.46.20250210.703 → pkscreener-0.46.20250213.705}/pkscreener/classes/Fetcher.py +0 -0
- {pkscreener-0.46.20250210.703 → pkscreener-0.46.20250213.705}/pkscreener/classes/GlobalStore.py +0 -0
- {pkscreener-0.46.20250210.703 → pkscreener-0.46.20250213.705}/pkscreener/classes/ImageUtility.py +0 -0
- {pkscreener-0.46.20250210.703 → pkscreener-0.46.20250213.705}/pkscreener/classes/MarketStatus.py +0 -0
- {pkscreener-0.46.20250210.703 → pkscreener-0.46.20250213.705}/pkscreener/classes/MenuOptions.py +0 -0
- {pkscreener-0.46.20250210.703 → pkscreener-0.46.20250213.705}/pkscreener/classes/Messenger.py +0 -0
- {pkscreener-0.46.20250210.703 → pkscreener-0.46.20250213.705}/pkscreener/classes/OtaUpdater.py +0 -0
- {pkscreener-0.46.20250210.703 → pkscreener-0.46.20250213.705}/pkscreener/classes/PKAnalytics.py +0 -0
- {pkscreener-0.46.20250210.703 → pkscreener-0.46.20250213.705}/pkscreener/classes/PKDataService.py +0 -0
- {pkscreener-0.46.20250210.703 → pkscreener-0.46.20250213.705}/pkscreener/classes/PKDemoHandler.py +0 -0
- {pkscreener-0.46.20250210.703 → pkscreener-0.46.20250213.705}/pkscreener/classes/PKMarketOpenCloseAnalyser.py +0 -0
- {pkscreener-0.46.20250210.703 → pkscreener-0.46.20250213.705}/pkscreener/classes/PKPremiumHandler.py +0 -0
- {pkscreener-0.46.20250210.703 → pkscreener-0.46.20250213.705}/pkscreener/classes/PKScanRunner.py +0 -0
- {pkscreener-0.46.20250210.703 → pkscreener-0.46.20250213.705}/pkscreener/classes/PKScheduledTaskProgress.py +0 -0
- {pkscreener-0.46.20250210.703 → pkscreener-0.46.20250213.705}/pkscreener/classes/PKScheduler.py +0 -0
- {pkscreener-0.46.20250210.703 → pkscreener-0.46.20250213.705}/pkscreener/classes/PKSpreadsheets.py +0 -0
- {pkscreener-0.46.20250210.703 → pkscreener-0.46.20250213.705}/pkscreener/classes/PKTask.py +0 -0
- {pkscreener-0.46.20250210.703 → pkscreener-0.46.20250213.705}/pkscreener/classes/PKUserRegistration.py +0 -0
- {pkscreener-0.46.20250210.703 → pkscreener-0.46.20250213.705}/pkscreener/classes/Pktalib.py +0 -0
- {pkscreener-0.46.20250210.703 → pkscreener-0.46.20250213.705}/pkscreener/classes/Portfolio.py +0 -0
- {pkscreener-0.46.20250210.703 → pkscreener-0.46.20250213.705}/pkscreener/classes/PortfolioXRay.py +0 -0
- {pkscreener-0.46.20250210.703 → pkscreener-0.46.20250213.705}/pkscreener/classes/ScreeningStatistics.py +0 -0
- {pkscreener-0.46.20250210.703 → pkscreener-0.46.20250213.705}/pkscreener/classes/StockScreener.py +0 -0
- {pkscreener-0.46.20250210.703 → pkscreener-0.46.20250213.705}/pkscreener/classes/StockSentiment.py +0 -0
- {pkscreener-0.46.20250210.703 → pkscreener-0.46.20250213.705}/pkscreener/classes/UserMenuChoicesHandler.py +0 -0
- {pkscreener-0.46.20250210.703 → pkscreener-0.46.20250213.705}/pkscreener/classes/Utility.py +0 -0
- {pkscreener-0.46.20250210.703 → pkscreener-0.46.20250213.705}/pkscreener/classes/WorkflowManager.py +0 -0
- {pkscreener-0.46.20250210.703 → pkscreener-0.46.20250213.705}/pkscreener/classes/keys.py +0 -0
- {pkscreener-0.46.20250210.703 → pkscreener-0.46.20250213.705}/pkscreener/courbd.ttf +0 -0
- {pkscreener-0.46.20250210.703 → pkscreener-0.46.20250213.705}/pkscreener/pkscreener.ini +0 -0
- {pkscreener-0.46.20250210.703 → pkscreener-0.46.20250213.705}/pkscreener/pkscreenercli.py +0 -0
- {pkscreener-0.46.20250210.703 → pkscreener-0.46.20250213.705}/pkscreener.egg-info/SOURCES.txt +0 -0
- {pkscreener-0.46.20250210.703 → pkscreener-0.46.20250213.705}/pkscreener.egg-info/dependency_links.txt +0 -0
- {pkscreener-0.46.20250210.703 → pkscreener-0.46.20250213.705}/pkscreener.egg-info/entry_points.txt +0 -0
- {pkscreener-0.46.20250210.703 → pkscreener-0.46.20250213.705}/pkscreener.egg-info/not-zip-safe +0 -0
- {pkscreener-0.46.20250210.703 → pkscreener-0.46.20250213.705}/pkscreener.egg-info/top_level.txt +0 -0
- {pkscreener-0.46.20250210.703 → pkscreener-0.46.20250213.705}/setup.cfg +0 -0
- {pkscreener-0.46.20250210.703 → pkscreener-0.46.20250213.705}/setup.py +0 -0
@@ -1,9 +1,9 @@
|
|
1
1
|
Metadata-Version: 2.2
|
2
2
|
Name: pkscreener
|
3
|
-
Version: 0.46.
|
3
|
+
Version: 0.46.20250213.705
|
4
4
|
Summary: A Python-based stock screener for NSE, India with alerts to Telegram Channel (pkscreener)
|
5
5
|
Home-page: https://github.com/pkjmesra/pkscreener
|
6
|
-
Download-URL: https://github.com/pkjmesra/pkscreener/archive/v0.46.
|
6
|
+
Download-URL: https://github.com/pkjmesra/pkscreener/archive/v0.46.20250213.705.zip
|
7
7
|
Author: pkjmesra
|
8
8
|
Author-email: pkjmesra@gmail.com
|
9
9
|
License: OSI Approved (MIT)
|
@@ -33,7 +33,7 @@ Requires-Dist: pandas
|
|
33
33
|
Requires-Dist: pandas_ta
|
34
34
|
Requires-Dist: pefile<2024.8.26,>=2023.2.7
|
35
35
|
Requires-Dist: Pillow
|
36
|
-
Requires-Dist: PKDevTools>=0.13.20250126.
|
36
|
+
Requires-Dist: PKDevTools>=0.13.20250126.230
|
37
37
|
Requires-Dist: PKNSETools>=0.1.20250122.136
|
38
38
|
Requires-Dist: Pyarrow
|
39
39
|
Requires-Dist: pyppeteer
|
@@ -68,8 +68,8 @@ Dynamic: summary
|
|
68
68
|
| [![MADE-IN-INDIA][MADE-IN-INDIA-badge]][MADE-IN-INDIA] | [![GitHub release (latest by date)][GitHub release (latest by date)-badge]][GitHub release (latest by date)] | [![Downloads][Downloads-badge]][Downloads] | ![latest download][Latest-Downloads-badge] | [![Docker Pulls][Docker Pulls-badge]][Docker Status] |
|
69
69
|
| :-------------: | :-----------------: | :-----------------: | :-----------------: | :-----------------: |
|
70
70
|
| Platforms | [![Windows][Windows-badge]][Windows] | [![Linux(x64)][Linux-badge_x64]][Linux_x64] [![Linux(arm64)][Linux-badge_arm64]][Linux_arm64] | [![Mac OS(x64)][Mac OS-badge_x64]][Mac OS_x64] [![Mac OS(arm64)][Mac OS-badge_arm64]][Mac OS_arm64] | [![Docker Status][Docker Status-badge]][Docker Status] |
|
71
|
-
| Package / Docs | [![Documentation][Documentation-badge]][Documentation] | [![PyPI][pypi-badge]][pypi] | [![is wheel][wheel-badge]][pypi] | ![github license][github-license] |
|
72
|
-
| Tests | [![CodeFactor][Codefactor-badge]][Codefactor] | [![Coverage Status][Coverage-Status-badge]][Coverage-Status] | [![codecov][codecov-badge]][codecov] | [![After Market][After Market-badge]][After Market] |
|
71
|
+
| Package / Docs | [![Documentation][Documentation-badge]][Documentation] [![OpenSSF Best Practices][OpenSSF-Badge]][OpenSSF-pkscreener] | [![PyPI][pypi-badge]][pypi] | [![is wheel][wheel-badge]][pypi] | ![github license][github-license] |
|
72
|
+
| Tests/Code-Quality | [![CodeFactor][Codefactor-badge]][Codefactor] | [![Coverage Status][Coverage-Status-badge]][Coverage-Status] | [![codecov][codecov-badge]][codecov] | [![After Market][After Market-badge]][After Market] |
|
73
73
|
|
74
74
|
## What is PKScreener?
|
75
75
|
| Telegram Alerts | Nifty AI Prediction | Scheduling Cron Jobs | On-Demand Telegram Bot | Backtesting / Growth of 10k|
|
@@ -392,15 +392,15 @@ After you have finished the run, go to that copied path, zip the contents of the
|
|
392
392
|
[MADE-IN-INDIA-badge]: https://img.shields.io/badge/MADE%20WITH%20%E2%9D%A4%20IN-INDIA-orange
|
393
393
|
[MADE-IN-INDIA]: https://en.wikipedia.org/wiki/India
|
394
394
|
[Windows-badge]: https://img.shields.io/badge/Windows-0078D6?logo=windows&logoColor=white
|
395
|
-
[Windows]: https://github.com/pkjmesra/PKScreener/releases/download/0.46.
|
395
|
+
[Windows]: https://github.com/pkjmesra/PKScreener/releases/download/0.46.20250212.704/pkscreenercli.exe
|
396
396
|
[Linux-badge_x64]: https://img.shields.io/badge/Linux(x64)-FCC624?logo=linux&logoColor=black
|
397
|
-
[Linux_x64]: https://github.com/pkjmesra/PKScreener/releases/download/0.46.
|
397
|
+
[Linux_x64]: https://github.com/pkjmesra/PKScreener/releases/download/0.46.20250212.704/pkscreenercli_x64.bin
|
398
398
|
[Linux-badge_arm64]: https://img.shields.io/badge/Linux(arm64)-FCC624?logo=linux&logoColor=black
|
399
|
-
[Linux_arm64]: https://github.com/pkjmesra/PKScreener/releases/download/0.46.
|
399
|
+
[Linux_arm64]: https://github.com/pkjmesra/PKScreener/releases/download/0.46.20250212.704/pkscreenercli_arm64.bin
|
400
400
|
[Mac OS-badge_x64]: https://img.shields.io/badge/mac%20os(x64)-D3D3D3?logo=apple&logoColor=000000
|
401
|
-
[Mac OS_x64]: https://github.com/pkjmesra/PKScreener/releases/download/0.46.
|
401
|
+
[Mac OS_x64]: https://github.com/pkjmesra/PKScreener/releases/download/0.46.20250212.704/pkscreenercli_x64.run
|
402
402
|
[Mac OS-badge_arm64]: https://img.shields.io/badge/mac%20os(arm64)-D3D3D3?logo=apple&logoColor=000000
|
403
|
-
[Mac OS_arm64]: https://github.com/pkjmesra/PKScreener/releases/download/0.46.
|
403
|
+
[Mac OS_arm64]: https://github.com/pkjmesra/PKScreener/releases/download/0.46.20250212.704/pkscreenercli_arm64.run
|
404
404
|
[GitHub release (latest by date)-badge]: https://img.shields.io/github/v/release/pkjmesra/PKScreener
|
405
405
|
[GitHub release (latest by date)]: https://github.com/pkjmesra/PKScreener/releases/latest
|
406
406
|
[pypi-badge]: https://img.shields.io/pypi/v/pkscreener.svg?style=flat-square
|
@@ -436,6 +436,8 @@ After you have finished the run, go to that copied path, zip the contents of the
|
|
436
436
|
[New Release]: https://github.com/pkjmesra/PKScreener/actions/workflows/w1-workflow-build-matrix.yml
|
437
437
|
[Docker-Build-badge]: https://github.com/pkjmesra/PKScreener/actions/workflows/w15-docker-image.yml/badge.svg
|
438
438
|
[Docker-Build]: https://github.com/pkjmesra/PKScreener/actions/workflows/w15-docker-image.yml
|
439
|
+
[OpenSSF-Badge]:https://www.bestpractices.dev/projects/10011/badge
|
440
|
+
[OpenSSF-pkscreener]: https://www.bestpractices.dev/projects/10011
|
439
441
|
|
440
442
|
<!-- [![Docker Build][Docker-Build-badge]][Docker-Build] [![PKScreener Test - New Features][New Features-badge]][New Features] [![w9. After-Market Data Gen][After Market-badge]][After Market] [![1. PKScreener Build - New Release][New Release-badge]][New Release] [![Documentation][Documentation-badge]][Documentation]
|
441
443
|
|
@@ -4,8 +4,8 @@
|
|
4
4
|
| [![MADE-IN-INDIA][MADE-IN-INDIA-badge]][MADE-IN-INDIA] | [![GitHub release (latest by date)][GitHub release (latest by date)-badge]][GitHub release (latest by date)] | [![Downloads][Downloads-badge]][Downloads] | ![latest download][Latest-Downloads-badge] | [![Docker Pulls][Docker Pulls-badge]][Docker Status] |
|
5
5
|
| :-------------: | :-----------------: | :-----------------: | :-----------------: | :-----------------: |
|
6
6
|
| Platforms | [![Windows][Windows-badge]][Windows] | [![Linux(x64)][Linux-badge_x64]][Linux_x64] [![Linux(arm64)][Linux-badge_arm64]][Linux_arm64] | [![Mac OS(x64)][Mac OS-badge_x64]][Mac OS_x64] [![Mac OS(arm64)][Mac OS-badge_arm64]][Mac OS_arm64] | [![Docker Status][Docker Status-badge]][Docker Status] |
|
7
|
-
| Package / Docs | [![Documentation][Documentation-badge]][Documentation] | [![PyPI][pypi-badge]][pypi] | [![is wheel][wheel-badge]][pypi] | ![github license][github-license] |
|
8
|
-
| Tests | [![CodeFactor][Codefactor-badge]][Codefactor] | [![Coverage Status][Coverage-Status-badge]][Coverage-Status] | [![codecov][codecov-badge]][codecov] | [![After Market][After Market-badge]][After Market] |
|
7
|
+
| Package / Docs | [![Documentation][Documentation-badge]][Documentation] [![OpenSSF Best Practices][OpenSSF-Badge]][OpenSSF-pkscreener] | [![PyPI][pypi-badge]][pypi] | [![is wheel][wheel-badge]][pypi] | ![github license][github-license] |
|
8
|
+
| Tests/Code-Quality | [![CodeFactor][Codefactor-badge]][Codefactor] | [![Coverage Status][Coverage-Status-badge]][Coverage-Status] | [![codecov][codecov-badge]][codecov] | [![After Market][After Market-badge]][After Market] |
|
9
9
|
|
10
10
|
## What is PKScreener?
|
11
11
|
| Telegram Alerts | Nifty AI Prediction | Scheduling Cron Jobs | On-Demand Telegram Bot | Backtesting / Growth of 10k|
|
@@ -328,15 +328,15 @@ After you have finished the run, go to that copied path, zip the contents of the
|
|
328
328
|
[MADE-IN-INDIA-badge]: https://img.shields.io/badge/MADE%20WITH%20%E2%9D%A4%20IN-INDIA-orange
|
329
329
|
[MADE-IN-INDIA]: https://en.wikipedia.org/wiki/India
|
330
330
|
[Windows-badge]: https://img.shields.io/badge/Windows-0078D6?logo=windows&logoColor=white
|
331
|
-
[Windows]: https://github.com/pkjmesra/PKScreener/releases/download/0.46.
|
331
|
+
[Windows]: https://github.com/pkjmesra/PKScreener/releases/download/0.46.20250212.704/pkscreenercli.exe
|
332
332
|
[Linux-badge_x64]: https://img.shields.io/badge/Linux(x64)-FCC624?logo=linux&logoColor=black
|
333
|
-
[Linux_x64]: https://github.com/pkjmesra/PKScreener/releases/download/0.46.
|
333
|
+
[Linux_x64]: https://github.com/pkjmesra/PKScreener/releases/download/0.46.20250212.704/pkscreenercli_x64.bin
|
334
334
|
[Linux-badge_arm64]: https://img.shields.io/badge/Linux(arm64)-FCC624?logo=linux&logoColor=black
|
335
|
-
[Linux_arm64]: https://github.com/pkjmesra/PKScreener/releases/download/0.46.
|
335
|
+
[Linux_arm64]: https://github.com/pkjmesra/PKScreener/releases/download/0.46.20250212.704/pkscreenercli_arm64.bin
|
336
336
|
[Mac OS-badge_x64]: https://img.shields.io/badge/mac%20os(x64)-D3D3D3?logo=apple&logoColor=000000
|
337
|
-
[Mac OS_x64]: https://github.com/pkjmesra/PKScreener/releases/download/0.46.
|
337
|
+
[Mac OS_x64]: https://github.com/pkjmesra/PKScreener/releases/download/0.46.20250212.704/pkscreenercli_x64.run
|
338
338
|
[Mac OS-badge_arm64]: https://img.shields.io/badge/mac%20os(arm64)-D3D3D3?logo=apple&logoColor=000000
|
339
|
-
[Mac OS_arm64]: https://github.com/pkjmesra/PKScreener/releases/download/0.46.
|
339
|
+
[Mac OS_arm64]: https://github.com/pkjmesra/PKScreener/releases/download/0.46.20250212.704/pkscreenercli_arm64.run
|
340
340
|
[GitHub release (latest by date)-badge]: https://img.shields.io/github/v/release/pkjmesra/PKScreener
|
341
341
|
[GitHub release (latest by date)]: https://github.com/pkjmesra/PKScreener/releases/latest
|
342
342
|
[pypi-badge]: https://img.shields.io/pypi/v/pkscreener.svg?style=flat-square
|
@@ -372,6 +372,8 @@ After you have finished the run, go to that copied path, zip the contents of the
|
|
372
372
|
[New Release]: https://github.com/pkjmesra/PKScreener/actions/workflows/w1-workflow-build-matrix.yml
|
373
373
|
[Docker-Build-badge]: https://github.com/pkjmesra/PKScreener/actions/workflows/w15-docker-image.yml/badge.svg
|
374
374
|
[Docker-Build]: https://github.com/pkjmesra/PKScreener/actions/workflows/w15-docker-image.yml
|
375
|
+
[OpenSSF-Badge]:https://www.bestpractices.dev/projects/10011/badge
|
376
|
+
[OpenSSF-pkscreener]: https://www.bestpractices.dev/projects/10011
|
375
377
|
|
376
378
|
<!-- [![Docker Build][Docker-Build-badge]][Docker-Build] [![PKScreener Test - New Features][New Features-badge]][New Features] [![w9. After-Market Data Gen][After Market-badge]][After Market] [![1. PKScreener Build - New Release][New Release-badge]][New Release] [![Documentation][Documentation-badge]][Documentation]
|
377
379
|
|
@@ -4,8 +4,8 @@
|
|
4
4
|
| [![MADE-IN-INDIA][MADE-IN-INDIA-badge]][MADE-IN-INDIA] | [![GitHub release (latest by date)][GitHub release (latest by date)-badge]][GitHub release (latest by date)] | [![Downloads][Downloads-badge]][Downloads] | ![latest download][Latest-Downloads-badge] | [![Docker Pulls][Docker Pulls-badge]][Docker Status] |
|
5
5
|
| :-------------: | :-----------------: | :-----------------: | :-----------------: | :-----------------: |
|
6
6
|
| Platforms | [![Windows][Windows-badge]][Windows] | [![Linux(x64)][Linux-badge_x64]][Linux_x64] [![Linux(arm64)][Linux-badge_arm64]][Linux_arm64] | [![Mac OS(x64)][Mac OS-badge_x64]][Mac OS_x64] [![Mac OS(arm64)][Mac OS-badge_arm64]][Mac OS_arm64] | [![Docker Status][Docker Status-badge]][Docker Status] |
|
7
|
-
| Package / Docs | [![Documentation][Documentation-badge]][Documentation] | [![PyPI][pypi-badge]][pypi] | [![is wheel][wheel-badge]][pypi] | ![github license][github-license] |
|
8
|
-
| Tests | [![CodeFactor][Codefactor-badge]][Codefactor] | [![Coverage Status][Coverage-Status-badge]][Coverage-Status] | [![codecov][codecov-badge]][codecov] | [![After Market][After Market-badge]][After Market] |
|
7
|
+
| Package / Docs | [![Documentation][Documentation-badge]][Documentation] [![OpenSSF Best Practices][OpenSSF-Badge]][OpenSSF-pkscreener] | [![PyPI][pypi-badge]][pypi] | [![is wheel][wheel-badge]][pypi] | ![github license][github-license] |
|
8
|
+
| Tests/Code-Quality | [![CodeFactor][Codefactor-badge]][Codefactor] | [![Coverage Status][Coverage-Status-badge]][Coverage-Status] | [![codecov][codecov-badge]][codecov] | [![After Market][After Market-badge]][After Market] |
|
9
9
|
|
10
10
|
## What is PKScreener?
|
11
11
|
| Telegram Alerts | Nifty AI Prediction | Scheduling Cron Jobs | On-Demand Telegram Bot | Backtesting / Growth of 10k|
|
@@ -328,15 +328,15 @@ After you have finished the run, go to that copied path, zip the contents of the
|
|
328
328
|
[MADE-IN-INDIA-badge]: https://img.shields.io/badge/MADE%20WITH%20%E2%9D%A4%20IN-INDIA-orange
|
329
329
|
[MADE-IN-INDIA]: https://en.wikipedia.org/wiki/India
|
330
330
|
[Windows-badge]: https://img.shields.io/badge/Windows-0078D6?logo=windows&logoColor=white
|
331
|
-
[Windows]: https://github.com/pkjmesra/PKScreener/releases/download/0.46.
|
331
|
+
[Windows]: https://github.com/pkjmesra/PKScreener/releases/download/0.46.20250212.704/pkscreenercli.exe
|
332
332
|
[Linux-badge_x64]: https://img.shields.io/badge/Linux(x64)-FCC624?logo=linux&logoColor=black
|
333
|
-
[Linux_x64]: https://github.com/pkjmesra/PKScreener/releases/download/0.46.
|
333
|
+
[Linux_x64]: https://github.com/pkjmesra/PKScreener/releases/download/0.46.20250212.704/pkscreenercli_x64.bin
|
334
334
|
[Linux-badge_arm64]: https://img.shields.io/badge/Linux(arm64)-FCC624?logo=linux&logoColor=black
|
335
|
-
[Linux_arm64]: https://github.com/pkjmesra/PKScreener/releases/download/0.46.
|
335
|
+
[Linux_arm64]: https://github.com/pkjmesra/PKScreener/releases/download/0.46.20250212.704/pkscreenercli_arm64.bin
|
336
336
|
[Mac OS-badge_x64]: https://img.shields.io/badge/mac%20os(x64)-D3D3D3?logo=apple&logoColor=000000
|
337
|
-
[Mac OS_x64]: https://github.com/pkjmesra/PKScreener/releases/download/0.46.
|
337
|
+
[Mac OS_x64]: https://github.com/pkjmesra/PKScreener/releases/download/0.46.20250212.704/pkscreenercli_x64.run
|
338
338
|
[Mac OS-badge_arm64]: https://img.shields.io/badge/mac%20os(arm64)-D3D3D3?logo=apple&logoColor=000000
|
339
|
-
[Mac OS_arm64]: https://github.com/pkjmesra/PKScreener/releases/download/0.46.
|
339
|
+
[Mac OS_arm64]: https://github.com/pkjmesra/PKScreener/releases/download/0.46.20250212.704/pkscreenercli_arm64.run
|
340
340
|
[GitHub release (latest by date)-badge]: https://img.shields.io/github/v/release/pkjmesra/PKScreener
|
341
341
|
[GitHub release (latest by date)]: https://github.com/pkjmesra/PKScreener/releases/latest
|
342
342
|
[pypi-badge]: https://img.shields.io/pypi/v/pkscreener.svg?style=flat-square
|
@@ -372,6 +372,8 @@ After you have finished the run, go to that copied path, zip the contents of the
|
|
372
372
|
[New Release]: https://github.com/pkjmesra/PKScreener/actions/workflows/w1-workflow-build-matrix.yml
|
373
373
|
[Docker-Build-badge]: https://github.com/pkjmesra/PKScreener/actions/workflows/w15-docker-image.yml/badge.svg
|
374
374
|
[Docker-Build]: https://github.com/pkjmesra/PKScreener/actions/workflows/w15-docker-image.yml
|
375
|
+
[OpenSSF-Badge]:https://www.bestpractices.dev/projects/10011/badge
|
376
|
+
[OpenSSF-pkscreener]: https://www.bestpractices.dev/projects/10011
|
375
377
|
|
376
378
|
<!-- [![Docker Build][Docker-Build-badge]][Docker-Build] [![PKScreener Test - New Features][New Features-badge]][New Features] [![w9. After-Market Data Gen][After Market-badge]][After Market] [![1. PKScreener Build - New Release][New Release-badge]][New Release] [![Documentation][Documentation-badge]][Documentation]
|
377
379
|
|
{pkscreener-0.46.20250210.703 → pkscreener-0.46.20250213.705}/pkscreener/classes/MarketMonitor.py
RENAMED
@@ -54,6 +54,7 @@ class MarketMonitor(SingletonMixin, metaclass=SingletonType):
|
|
54
54
|
self.alertOptions = alertOptions
|
55
55
|
self.hiddenColumns = ""
|
56
56
|
self.alertStocks = []
|
57
|
+
self.firstAlertTriggered = False
|
57
58
|
self.pinnedIntervalWaitSeconds = pinnedIntervalWaitSeconds
|
58
59
|
# self.monitorNames = {}
|
59
60
|
# We are going to present the dataframes in a 3x3 matrix with limited set of columns
|
@@ -127,23 +128,42 @@ class MarketMonitor(SingletonMixin, metaclass=SingletonType):
|
|
127
128
|
if self.isPinnedSingleMonitorMode:
|
128
129
|
screen_monitor_df = screen_monitor_df[screen_monitor_df.columns[:14]]
|
129
130
|
self.monitor_df = screen_monitor_df
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
131
|
+
if "RUNNER" in os.environ.keys():
|
132
|
+
self.monitor_df.reset_index(inplace=True)
|
133
|
+
with pd.option_context('mode.chained_assignment', None):
|
134
|
+
self.monitor_df = self.monitor_df[["Stock", "LTP", "%Chng","52Wk-H","RSI/i" if "RSI/i" in self.monitor_df.columns else "RSI","Volume"]]
|
135
|
+
# Import Utility here since Utility has dependency on PKScheduler which in turn has dependency on
|
136
|
+
# multiprocessing, which behaves erratically if imported at the top.
|
137
|
+
self.monitor_df.loc[:, "%Chng"] = self.monitor_df.loc[:, "%Chng"].astype(str).apply(
|
138
|
+
lambda x: ImageUtility.PKImageTools.roundOff(str(x).split("% (")[0] + colorText.END,0)
|
139
|
+
)
|
140
|
+
self.monitor_df.loc[:, "52Wk-H"] = self.monitor_df.loc[:, "52Wk-H"].astype(str).apply(
|
141
|
+
lambda x: ImageUtility.PKImageTools.roundOff(x,0)
|
137
142
|
)
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
143
|
+
self.monitor_df.loc[:, "Volume"] = self.monitor_df.loc[:, "Volume"].astype(str).apply(
|
144
|
+
lambda x: ImageUtility.PKImageTools.roundOff(x,0)
|
145
|
+
)
|
146
|
+
self.monitor_df.rename(columns={"%Chng": "Ch%","Volume":"Vol","52Wk-H":"52WkH", "RSI":"RSI/i"}, inplace=True)
|
147
|
+
telegram_df = self.updateDataFrameForTelegramMode(telegram or "RUNNER" in os.environ.keys(), self.monitor_df)
|
148
|
+
self.monitor_df.set_index("Stock",inplace=True)
|
149
|
+
|
150
|
+
if not self.isPinnedSingleMonitorMode:
|
151
|
+
screen_monitor_df.reset_index(inplace=True)
|
152
|
+
with pd.option_context('mode.chained_assignment', None):
|
153
|
+
screen_monitor_df = screen_monitor_df[["Stock", "LTP", "%Chng","52Wk-H","RSI/i" if "RSI/i" in screen_monitor_df.columns else "RSI","Volume"]].head(self.maxNumRowsInEachResult-1)
|
154
|
+
# Import Utility here since Utility has dependency on PKScheduler which in turn has dependency on
|
155
|
+
# multiprocessing, which behaves erratically if imported at the top.
|
156
|
+
screen_monitor_df.loc[:, "%Chng"] = screen_monitor_df.loc[:, "%Chng"].astype(str).apply(
|
157
|
+
lambda x: ImageUtility.PKImageTools.roundOff(str(x).split("% (")[0] + colorText.END,0)
|
158
|
+
)
|
159
|
+
screen_monitor_df.loc[:, "52Wk-H"] = screen_monitor_df.loc[:, "52Wk-H"].astype(str).apply(
|
160
|
+
lambda x: ImageUtility.PKImageTools.roundOff(x,0)
|
161
|
+
)
|
162
|
+
screen_monitor_df.loc[:, "Volume"] = screen_monitor_df.loc[:, "Volume"].astype(str).apply(
|
163
|
+
lambda x: ImageUtility.PKImageTools.roundOff(x,0)
|
164
|
+
)
|
165
|
+
screen_monitor_df.rename(columns={"%Chng": "Ch%","Volume":"Vol","52Wk-H":"52WkH", "RSI":"RSI/i"}, inplace=True)
|
166
|
+
telegram_df = self.updateDataFrameForTelegramMode(telegram or "RUNNER" in os.environ.keys(), screen_monitor_df)
|
147
167
|
|
148
168
|
if monitorPosition is not None:
|
149
169
|
startRowIndex, startColIndex = monitorPosition
|
@@ -197,7 +217,8 @@ class MarketMonitor(SingletonMixin, metaclass=SingletonType):
|
|
197
217
|
stockName = (f"{colorText.BOLD}{colorText.WHITE_FG_BRED_BG}{stock}{colorText.END}") if stockName in self.alertStocks else stock
|
198
218
|
updatedStocks.append(stockName)
|
199
219
|
self.monitor_df.reset_index(inplace=True)
|
200
|
-
|
220
|
+
with pd.option_context('mode.chained_assignment', None):
|
221
|
+
self.monitor_df["Stock"] = updatedStocks
|
201
222
|
self.monitor_df.set_index("Stock",inplace=True)
|
202
223
|
|
203
224
|
self.monitor_df = self.monitor_df.replace(np.nan, "-", regex=True)
|
@@ -241,6 +262,21 @@ class MarketMonitor(SingletonMixin, metaclass=SingletonType):
|
|
241
262
|
if telegram:
|
242
263
|
self.updateIfRunningInTelegramBotMode(screenOptions, chosenMenu, dbTimestamp, telegram, telegram_df)
|
243
264
|
else:
|
265
|
+
if ((screenOptions in self.alertOptions and numRecords > 3) or len(self.alertStocks) > 0 or not self.firstAlertTriggered): # Alert conditions met? Sound alert!
|
266
|
+
# numRecords is actually new lines. Top 3 lines are only headers
|
267
|
+
if telegram_df is not None:
|
268
|
+
telegram_df.reset_index(inplace=True)
|
269
|
+
notify_df = telegram_df[telegram_df["Stock"].isin(self.alertStocks)] if self.firstAlertTriggered else telegram_df
|
270
|
+
notify_df = notify_df[["Stock","LTP","Ch%","Vol"]].head(50)
|
271
|
+
if len(notify_df) > 0:
|
272
|
+
notify_output = self.updateIfRunningInTelegramBotMode(screenOptions, chosenMenu, dbTimestamp, False, notify_df,maxcolwidths=None)
|
273
|
+
if len(notify_output) > 0:
|
274
|
+
from PKDevTools.classes.pubsub.publisher import PKUserService
|
275
|
+
from PKDevTools.classes.pubsub.subscriber import notification_service
|
276
|
+
PKUserService().notify_user(scannerID=self.getScanOptionName(screenOptions),notification=notify_output)
|
277
|
+
self.firstAlertTriggered = True
|
278
|
+
# notify_df = self.monitor_df.reindex(self.alertStocks) # Includes missing stocks, if any. Returns NaN for such cases
|
279
|
+
Utility.tools.alertSound(beeps=5)
|
244
280
|
sleep(self.pinnedIntervalWaitSeconds)
|
245
281
|
|
246
282
|
def updateDataFrameForTelegramMode(self, telegram, screen_monitor_df):
|
@@ -272,34 +308,45 @@ class MarketMonitor(SingletonMixin, metaclass=SingletonType):
|
|
272
308
|
pass
|
273
309
|
return telegram_df
|
274
310
|
|
275
|
-
def updateIfRunningInTelegramBotMode(self, screenOptions, chosenMenu, dbTimestamp, telegram, telegram_df):
|
276
|
-
|
311
|
+
def updateIfRunningInTelegramBotMode(self, screenOptions, chosenMenu, dbTimestamp, telegram, telegram_df,maxcolwidths=[None,None,4,3]):
|
312
|
+
result_output = ""
|
313
|
+
telegram_df_tabulated = ""
|
314
|
+
if telegram_df is not None:
|
277
315
|
STD_ENCODING=sys.stdout.encoding if sys.stdout is not None else 'utf-8'
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
316
|
+
try:
|
317
|
+
telegram_df_tabulated = colorText.miniTabulator().tabulate(
|
318
|
+
telegram_df,
|
319
|
+
headers="keys",
|
320
|
+
tablefmt=colorText.No_Pad_GridFormat,
|
321
|
+
showindex=False,
|
322
|
+
maxcolwidths=maxcolwidths if maxcolwidths is not None else None
|
323
|
+
).encode("utf-8").decode(STD_ENCODING).replace("-K-----S-----C-----R","-K-----S----C---R").replace("% ","% ").replace("=K=====S=====C=====R","=K=====S====C===R").replace("Vol |","Vol|").replace("x ","x")
|
324
|
+
except Exception as e:
|
325
|
+
default_logger().debug(e,exc_info=True)
|
326
|
+
pass
|
286
327
|
telegram_df_tabulated = telegram_df_tabulated.replace("-E-----N-----E-----R","-E-----N----E---R").replace("=E=====N=====E=====R","=E=====N====E===R")
|
287
328
|
choiceSegments = chosenMenu.split(">")
|
288
329
|
optionName = self.getScanOptionName(screenOptions)
|
289
330
|
chosenMenu = f"{choiceSegments[-2]}>{choiceSegments[-1]}" if (len(choiceSegments)>=4 or len(choiceSegments[-1]) <= 10) else f"{choiceSegments[-1]}"
|
290
|
-
result_output = f"Latest data as of
|
331
|
+
result_output = f"Latest data as of {dbTimestamp}\n<b>[{optionName}] {chosenMenu}</b> [{screenOptions}]\n<pre>{telegram_df_tabulated}</pre>"
|
291
332
|
try:
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
333
|
+
if telegram:
|
334
|
+
filePath = os.path.join(Archiver.get_user_data_dir(), f"monitor_outputs_{self.monitorIndex}.txt")
|
335
|
+
f = open(filePath, "w")
|
336
|
+
f.write(result_output)
|
337
|
+
f.close()
|
296
338
|
except: # pragma: no cover
|
297
339
|
pass
|
340
|
+
return result_output
|
298
341
|
|
299
342
|
def getScanOptionName(self, screenOptions):
|
300
343
|
from pkscreener.classes.MenuOptions import PREDEFINED_SCAN_MENU_VALUES
|
301
344
|
if screenOptions is None:
|
302
345
|
return ""
|
346
|
+
baseIndex = 12
|
347
|
+
baseIndices = screenOptions.split(":")
|
348
|
+
if len(baseIndices) > 1:
|
349
|
+
baseIndex = baseIndices[1]
|
303
350
|
choices = f"--systemlaunched -a y -e -o '{screenOptions.replace('C:','X:').replace('D:','')}'"
|
304
351
|
indexNum = -1
|
305
352
|
try:
|
@@ -308,5 +355,5 @@ class MarketMonitor(SingletonMixin, metaclass=SingletonType):
|
|
308
355
|
pass
|
309
356
|
optionName = ""
|
310
357
|
if indexNum >= 0:
|
311
|
-
optionName = f"{('P_1_'+str(indexNum +1)+'
|
358
|
+
optionName = f"{('P_1_'+str(indexNum +1)+'_'+str(baseIndex)) if '>|' in choices else screenOptions.replace(':D','').replace(':','_')}"
|
312
359
|
return optionName
|
@@ -0,0 +1 @@
|
|
1
|
+
VERSION='0.46.20250213.705'
|
@@ -1145,6 +1145,9 @@ def main(userArgs=None,optionalFinalOutcome_df=None):
|
|
1145
1145
|
stockListParam = f" --stocklist {userPassedArgs.stocklist}" if userPassedArgs.stocklist else ""
|
1146
1146
|
slicewindowParam = f" --slicewindow {userPassedArgs.slicewindow}" if userPassedArgs.slicewindow else ""
|
1147
1147
|
fnameParam = f" --fname {resultsContentsEncoded}" if resultsContentsEncoded else ""
|
1148
|
+
if userPassedArgs.monitor and "-e -o" in scannerOptionQuoted:
|
1149
|
+
# We've been launched in monitor mode. Get rid of -e -o
|
1150
|
+
scannerOptionQuoted = scannerOptionQuoted.replace("-e -o","-m")
|
1148
1151
|
OutputControls().printOutput(f"{colorText.GREEN}Launching PKScreener with piped scanners. If it does not launch, please try with the following:{colorText.END}\n{colorText.FAIL}{launcher} {scannerOptionQuoted}{requestingUser}{enableLog}{backtestParam}{enableTelegramMode}{stockListParam}{slicewindowParam}{fnameParam}{colorText.END}")
|
1149
1152
|
sleep(2)
|
1150
1153
|
os.system(f"{launcher} {scannerOptionQuoted}{requestingUser}{enableLog}{backtestParam}{enableTelegramMode}{stockListParam}{slicewindowParam}{fnameParam}")
|
@@ -3995,9 +3998,9 @@ def sendMessageToTelegramChannel(
|
|
3995
3998
|
os.remove(f)
|
3996
3999
|
except: # pragma: no cover
|
3997
4000
|
pass
|
3998
|
-
if message is None and mediagroup:
|
3999
|
-
|
4000
|
-
|
4001
|
+
# if message is None and mediagroup:
|
4002
|
+
# sendMessageToTelegramChannel(message=f"No scan results found for {menuChoiceHierarchy}", user=user)
|
4003
|
+
# return
|
4001
4004
|
handleAlertSubscriptions(user,message)
|
4002
4005
|
if user is not None:
|
4003
4006
|
if str(user) != str(DEV_CHANNEL_ID) and userPassedArgs is not None and not userPassedArgs.monitor:
|