pkscreener 0.46.20250212.704__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.20250212.704 → pkscreener-0.46.20250213.705}/PKG-INFO +8 -8
- {pkscreener-0.46.20250212.704 → pkscreener-0.46.20250213.705}/README.md +5 -5
- {pkscreener-0.46.20250212.704 → pkscreener-0.46.20250213.705}/pkscreener/README.txt +5 -5
- {pkscreener-0.46.20250212.704 → pkscreener-0.46.20250213.705}/pkscreener/classes/MarketMonitor.py +71 -35
- pkscreener-0.46.20250213.705/pkscreener/classes/__init__.py +1 -0
- {pkscreener-0.46.20250212.704 → pkscreener-0.46.20250213.705}/pkscreener/globals.py +3 -0
- {pkscreener-0.46.20250212.704 → pkscreener-0.46.20250213.705}/pkscreener/requirements.txt +1 -1
- {pkscreener-0.46.20250212.704 → pkscreener-0.46.20250213.705}/pkscreener.egg-info/PKG-INFO +8 -8
- {pkscreener-0.46.20250212.704 → pkscreener-0.46.20250213.705}/pkscreener.egg-info/requires.txt +1 -1
- pkscreener-0.46.20250212.704/pkscreener/classes/__init__.py +0 -1
- {pkscreener-0.46.20250212.704 → pkscreener-0.46.20250213.705}/LICENSE +0 -0
- {pkscreener-0.46.20250212.704 → pkscreener-0.46.20250213.705}/pkscreener/Disclaimer.txt +0 -0
- {pkscreener-0.46.20250212.704 → pkscreener-0.46.20250213.705}/pkscreener/LICENSE-Others.txt +0 -0
- {pkscreener-0.46.20250212.704 → pkscreener-0.46.20250213.705}/pkscreener/LICENSE.txt +0 -0
- {pkscreener-0.46.20250212.704 → pkscreener-0.46.20250213.705}/pkscreener/LogoWM.txt +0 -0
- {pkscreener-0.46.20250212.704 → pkscreener-0.46.20250213.705}/pkscreener/__init__.py +0 -0
- {pkscreener-0.46.20250212.704 → pkscreener-0.46.20250213.705}/pkscreener/classes/ArtTexts.py +0 -0
- {pkscreener-0.46.20250212.704 → pkscreener-0.46.20250213.705}/pkscreener/classes/AssetsManager.py +0 -0
- {pkscreener-0.46.20250212.704 → pkscreener-0.46.20250213.705}/pkscreener/classes/Backtest.py +0 -0
- {pkscreener-0.46.20250212.704 → pkscreener-0.46.20250213.705}/pkscreener/classes/Barometer.py +0 -0
- {pkscreener-0.46.20250212.704 → pkscreener-0.46.20250213.705}/pkscreener/classes/BaseScreeningStatistics.py +0 -0
- {pkscreener-0.46.20250212.704 → pkscreener-0.46.20250213.705}/pkscreener/classes/CandlePatterns.py +0 -0
- {pkscreener-0.46.20250212.704 → pkscreener-0.46.20250213.705}/pkscreener/classes/Changelog.py +0 -0
- {pkscreener-0.46.20250212.704 → pkscreener-0.46.20250213.705}/pkscreener/classes/ConfigManager.py +0 -0
- {pkscreener-0.46.20250212.704 → pkscreener-0.46.20250213.705}/pkscreener/classes/ConsoleMenuUtility.py +0 -0
- {pkscreener-0.46.20250212.704 → pkscreener-0.46.20250213.705}/pkscreener/classes/ConsoleUtility.py +0 -0
- {pkscreener-0.46.20250212.704 → pkscreener-0.46.20250213.705}/pkscreener/classes/Fetcher.py +0 -0
- {pkscreener-0.46.20250212.704 → pkscreener-0.46.20250213.705}/pkscreener/classes/GlobalStore.py +0 -0
- {pkscreener-0.46.20250212.704 → pkscreener-0.46.20250213.705}/pkscreener/classes/ImageUtility.py +0 -0
- {pkscreener-0.46.20250212.704 → pkscreener-0.46.20250213.705}/pkscreener/classes/MarketStatus.py +0 -0
- {pkscreener-0.46.20250212.704 → pkscreener-0.46.20250213.705}/pkscreener/classes/MenuOptions.py +0 -0
- {pkscreener-0.46.20250212.704 → pkscreener-0.46.20250213.705}/pkscreener/classes/Messenger.py +0 -0
- {pkscreener-0.46.20250212.704 → pkscreener-0.46.20250213.705}/pkscreener/classes/OtaUpdater.py +0 -0
- {pkscreener-0.46.20250212.704 → pkscreener-0.46.20250213.705}/pkscreener/classes/PKAnalytics.py +0 -0
- {pkscreener-0.46.20250212.704 → pkscreener-0.46.20250213.705}/pkscreener/classes/PKDataService.py +0 -0
- {pkscreener-0.46.20250212.704 → pkscreener-0.46.20250213.705}/pkscreener/classes/PKDemoHandler.py +0 -0
- {pkscreener-0.46.20250212.704 → pkscreener-0.46.20250213.705}/pkscreener/classes/PKMarketOpenCloseAnalyser.py +0 -0
- {pkscreener-0.46.20250212.704 → pkscreener-0.46.20250213.705}/pkscreener/classes/PKPremiumHandler.py +0 -0
- {pkscreener-0.46.20250212.704 → pkscreener-0.46.20250213.705}/pkscreener/classes/PKScanRunner.py +0 -0
- {pkscreener-0.46.20250212.704 → pkscreener-0.46.20250213.705}/pkscreener/classes/PKScheduledTaskProgress.py +0 -0
- {pkscreener-0.46.20250212.704 → pkscreener-0.46.20250213.705}/pkscreener/classes/PKScheduler.py +0 -0
- {pkscreener-0.46.20250212.704 → pkscreener-0.46.20250213.705}/pkscreener/classes/PKSpreadsheets.py +0 -0
- {pkscreener-0.46.20250212.704 → pkscreener-0.46.20250213.705}/pkscreener/classes/PKTask.py +0 -0
- {pkscreener-0.46.20250212.704 → pkscreener-0.46.20250213.705}/pkscreener/classes/PKUserRegistration.py +0 -0
- {pkscreener-0.46.20250212.704 → pkscreener-0.46.20250213.705}/pkscreener/classes/Pktalib.py +0 -0
- {pkscreener-0.46.20250212.704 → pkscreener-0.46.20250213.705}/pkscreener/classes/Portfolio.py +0 -0
- {pkscreener-0.46.20250212.704 → pkscreener-0.46.20250213.705}/pkscreener/classes/PortfolioXRay.py +0 -0
- {pkscreener-0.46.20250212.704 → pkscreener-0.46.20250213.705}/pkscreener/classes/ScreeningStatistics.py +0 -0
- {pkscreener-0.46.20250212.704 → pkscreener-0.46.20250213.705}/pkscreener/classes/StockScreener.py +0 -0
- {pkscreener-0.46.20250212.704 → pkscreener-0.46.20250213.705}/pkscreener/classes/StockSentiment.py +0 -0
- {pkscreener-0.46.20250212.704 → pkscreener-0.46.20250213.705}/pkscreener/classes/UserMenuChoicesHandler.py +0 -0
- {pkscreener-0.46.20250212.704 → pkscreener-0.46.20250213.705}/pkscreener/classes/Utility.py +0 -0
- {pkscreener-0.46.20250212.704 → pkscreener-0.46.20250213.705}/pkscreener/classes/WorkflowManager.py +0 -0
- {pkscreener-0.46.20250212.704 → pkscreener-0.46.20250213.705}/pkscreener/classes/keys.py +0 -0
- {pkscreener-0.46.20250212.704 → pkscreener-0.46.20250213.705}/pkscreener/courbd.ttf +0 -0
- {pkscreener-0.46.20250212.704 → pkscreener-0.46.20250213.705}/pkscreener/pkscreener.ini +0 -0
- {pkscreener-0.46.20250212.704 → pkscreener-0.46.20250213.705}/pkscreener/pkscreenerbot.py +0 -0
- {pkscreener-0.46.20250212.704 → pkscreener-0.46.20250213.705}/pkscreener/pkscreenercli.py +0 -0
- {pkscreener-0.46.20250212.704 → pkscreener-0.46.20250213.705}/pkscreener.egg-info/SOURCES.txt +0 -0
- {pkscreener-0.46.20250212.704 → pkscreener-0.46.20250213.705}/pkscreener.egg-info/dependency_links.txt +0 -0
- {pkscreener-0.46.20250212.704 → pkscreener-0.46.20250213.705}/pkscreener.egg-info/entry_points.txt +0 -0
- {pkscreener-0.46.20250212.704 → pkscreener-0.46.20250213.705}/pkscreener.egg-info/not-zip-safe +0 -0
- {pkscreener-0.46.20250212.704 → pkscreener-0.46.20250213.705}/pkscreener.egg-info/top_level.txt +0 -0
- {pkscreener-0.46.20250212.704 → pkscreener-0.46.20250213.705}/setup.cfg +0 -0
- {pkscreener-0.46.20250212.704 → 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
|
@@ -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
|
@@ -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
|
@@ -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
|
{pkscreener-0.46.20250212.704 → 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,13 +262,20 @@ class MarketMonitor(SingletonMixin, metaclass=SingletonType):
|
|
241
262
|
if telegram:
|
242
263
|
self.updateIfRunningInTelegramBotMode(screenOptions, chosenMenu, dbTimestamp, telegram, telegram_df)
|
243
264
|
else:
|
244
|
-
if ((screenOptions in self.alertOptions and numRecords >
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
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
|
251
279
|
Utility.tools.alertSound(beeps=5)
|
252
280
|
sleep(self.pinnedIntervalWaitSeconds)
|
253
281
|
|
@@ -280,23 +308,27 @@ class MarketMonitor(SingletonMixin, metaclass=SingletonType):
|
|
280
308
|
pass
|
281
309
|
return telegram_df
|
282
310
|
|
283
|
-
def updateIfRunningInTelegramBotMode(self, screenOptions, chosenMenu, dbTimestamp, telegram, telegram_df):
|
311
|
+
def updateIfRunningInTelegramBotMode(self, screenOptions, chosenMenu, dbTimestamp, telegram, telegram_df,maxcolwidths=[None,None,4,3]):
|
284
312
|
result_output = ""
|
313
|
+
telegram_df_tabulated = ""
|
285
314
|
if telegram_df is not None:
|
286
315
|
STD_ENCODING=sys.stdout.encoding if sys.stdout is not None else 'utf-8'
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
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
|
295
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")
|
296
328
|
choiceSegments = chosenMenu.split(">")
|
297
329
|
optionName = self.getScanOptionName(screenOptions)
|
298
330
|
chosenMenu = f"{choiceSegments[-2]}>{choiceSegments[-1]}" if (len(choiceSegments)>=4 or len(choiceSegments[-1]) <= 10) else f"{choiceSegments[-1]}"
|
299
|
-
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>"
|
300
332
|
try:
|
301
333
|
if telegram:
|
302
334
|
filePath = os.path.join(Archiver.get_user_data_dir(), f"monitor_outputs_{self.monitorIndex}.txt")
|
@@ -311,6 +343,10 @@ class MarketMonitor(SingletonMixin, metaclass=SingletonType):
|
|
311
343
|
from pkscreener.classes.MenuOptions import PREDEFINED_SCAN_MENU_VALUES
|
312
344
|
if screenOptions is None:
|
313
345
|
return ""
|
346
|
+
baseIndex = 12
|
347
|
+
baseIndices = screenOptions.split(":")
|
348
|
+
if len(baseIndices) > 1:
|
349
|
+
baseIndex = baseIndices[1]
|
314
350
|
choices = f"--systemlaunched -a y -e -o '{screenOptions.replace('C:','X:').replace('D:','')}'"
|
315
351
|
indexNum = -1
|
316
352
|
try:
|
@@ -319,5 +355,5 @@ class MarketMonitor(SingletonMixin, metaclass=SingletonType):
|
|
319
355
|
pass
|
320
356
|
optionName = ""
|
321
357
|
if indexNum >= 0:
|
322
|
-
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(':','_')}"
|
323
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}")
|
@@ -19,7 +19,7 @@ pandas_ta #>=0.3.14b0
|
|
19
19
|
# and https://github.com/pyinstaller/pyinstaller/issues/7269
|
20
20
|
pefile>=2023.2.7,<2024.8.26
|
21
21
|
Pillow #>=9.5.0,<=9.5.0 # Keep at this version because getsize_multiline is deprecated/removed in higher versions
|
22
|
-
PKDevTools>=0.13.20250126.
|
22
|
+
PKDevTools>=0.13.20250126.230
|
23
23
|
PKNSETools>=0.1.20250122.136
|
24
24
|
Pyarrow #>=17.0.0
|
25
25
|
pyppeteer #>=2.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
|
@@ -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
|
@@ -1 +0,0 @@
|
|
1
|
-
VERSION='0.46.20250212.704'
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{pkscreener-0.46.20250212.704 → pkscreener-0.46.20250213.705}/pkscreener/classes/ArtTexts.py
RENAMED
File without changes
|
{pkscreener-0.46.20250212.704 → pkscreener-0.46.20250213.705}/pkscreener/classes/AssetsManager.py
RENAMED
File without changes
|
{pkscreener-0.46.20250212.704 → pkscreener-0.46.20250213.705}/pkscreener/classes/Backtest.py
RENAMED
File without changes
|
{pkscreener-0.46.20250212.704 → pkscreener-0.46.20250213.705}/pkscreener/classes/Barometer.py
RENAMED
File without changes
|
File without changes
|
{pkscreener-0.46.20250212.704 → pkscreener-0.46.20250213.705}/pkscreener/classes/CandlePatterns.py
RENAMED
File without changes
|
{pkscreener-0.46.20250212.704 → pkscreener-0.46.20250213.705}/pkscreener/classes/Changelog.py
RENAMED
File without changes
|
{pkscreener-0.46.20250212.704 → pkscreener-0.46.20250213.705}/pkscreener/classes/ConfigManager.py
RENAMED
File without changes
|
File without changes
|
{pkscreener-0.46.20250212.704 → pkscreener-0.46.20250213.705}/pkscreener/classes/ConsoleUtility.py
RENAMED
File without changes
|
File without changes
|
{pkscreener-0.46.20250212.704 → pkscreener-0.46.20250213.705}/pkscreener/classes/GlobalStore.py
RENAMED
File without changes
|
{pkscreener-0.46.20250212.704 → pkscreener-0.46.20250213.705}/pkscreener/classes/ImageUtility.py
RENAMED
File without changes
|
{pkscreener-0.46.20250212.704 → pkscreener-0.46.20250213.705}/pkscreener/classes/MarketStatus.py
RENAMED
File without changes
|
{pkscreener-0.46.20250212.704 → pkscreener-0.46.20250213.705}/pkscreener/classes/MenuOptions.py
RENAMED
File without changes
|
{pkscreener-0.46.20250212.704 → pkscreener-0.46.20250213.705}/pkscreener/classes/Messenger.py
RENAMED
File without changes
|
{pkscreener-0.46.20250212.704 → pkscreener-0.46.20250213.705}/pkscreener/classes/OtaUpdater.py
RENAMED
File without changes
|
{pkscreener-0.46.20250212.704 → pkscreener-0.46.20250213.705}/pkscreener/classes/PKAnalytics.py
RENAMED
File without changes
|
{pkscreener-0.46.20250212.704 → pkscreener-0.46.20250213.705}/pkscreener/classes/PKDataService.py
RENAMED
File without changes
|
{pkscreener-0.46.20250212.704 → pkscreener-0.46.20250213.705}/pkscreener/classes/PKDemoHandler.py
RENAMED
File without changes
|
File without changes
|
{pkscreener-0.46.20250212.704 → pkscreener-0.46.20250213.705}/pkscreener/classes/PKPremiumHandler.py
RENAMED
File without changes
|
{pkscreener-0.46.20250212.704 → pkscreener-0.46.20250213.705}/pkscreener/classes/PKScanRunner.py
RENAMED
File without changes
|
File without changes
|
{pkscreener-0.46.20250212.704 → pkscreener-0.46.20250213.705}/pkscreener/classes/PKScheduler.py
RENAMED
File without changes
|
{pkscreener-0.46.20250212.704 → pkscreener-0.46.20250213.705}/pkscreener/classes/PKSpreadsheets.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{pkscreener-0.46.20250212.704 → pkscreener-0.46.20250213.705}/pkscreener/classes/Portfolio.py
RENAMED
File without changes
|
{pkscreener-0.46.20250212.704 → pkscreener-0.46.20250213.705}/pkscreener/classes/PortfolioXRay.py
RENAMED
File without changes
|
File without changes
|
{pkscreener-0.46.20250212.704 → pkscreener-0.46.20250213.705}/pkscreener/classes/StockScreener.py
RENAMED
File without changes
|
{pkscreener-0.46.20250212.704 → pkscreener-0.46.20250213.705}/pkscreener/classes/StockSentiment.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
{pkscreener-0.46.20250212.704 → pkscreener-0.46.20250213.705}/pkscreener/classes/WorkflowManager.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{pkscreener-0.46.20250212.704 → pkscreener-0.46.20250213.705}/pkscreener.egg-info/SOURCES.txt
RENAMED
File without changes
|
File without changes
|
{pkscreener-0.46.20250212.704 → pkscreener-0.46.20250213.705}/pkscreener.egg-info/entry_points.txt
RENAMED
File without changes
|
{pkscreener-0.46.20250212.704 → pkscreener-0.46.20250213.705}/pkscreener.egg-info/not-zip-safe
RENAMED
File without changes
|
{pkscreener-0.46.20250212.704 → pkscreener-0.46.20250213.705}/pkscreener.egg-info/top_level.txt
RENAMED
File without changes
|
File without changes
|
File without changes
|