pkscreener 0.46.20250728.754__tar.gz → 0.46.20250908.764__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.
Files changed (65) hide show
  1. {pkscreener-0.46.20250728.754 → pkscreener-0.46.20250908.764}/PKG-INFO +10 -11
  2. {pkscreener-0.46.20250728.754 → pkscreener-0.46.20250908.764}/README.md +6 -6
  3. {pkscreener-0.46.20250728.754 → pkscreener-0.46.20250908.764}/pkscreener/LICENSE-Others.txt +1 -1
  4. {pkscreener-0.46.20250728.754 → pkscreener-0.46.20250908.764}/pkscreener/README.txt +6 -6
  5. {pkscreener-0.46.20250728.754 → pkscreener-0.46.20250908.764}/pkscreener/__init__.py +2 -2
  6. {pkscreener-0.46.20250728.754 → pkscreener-0.46.20250908.764}/pkscreener/classes/AssetsManager.py +13 -29
  7. {pkscreener-0.46.20250728.754 → pkscreener-0.46.20250908.764}/pkscreener/classes/Backtest.py +5 -5
  8. {pkscreener-0.46.20250728.754 → pkscreener-0.46.20250908.764}/pkscreener/classes/CandlePatterns.py +23 -23
  9. {pkscreener-0.46.20250728.754 → pkscreener-0.46.20250908.764}/pkscreener/classes/ConfigManager.py +14 -2
  10. {pkscreener-0.46.20250728.754 → pkscreener-0.46.20250908.764}/pkscreener/classes/ConsoleUtility.py +1 -1
  11. {pkscreener-0.46.20250728.754 → pkscreener-0.46.20250908.764}/pkscreener/classes/Fetcher.py +26 -20
  12. {pkscreener-0.46.20250728.754 → pkscreener-0.46.20250908.764}/pkscreener/classes/ImageUtility.py +1 -1
  13. {pkscreener-0.46.20250728.754 → pkscreener-0.46.20250908.764}/pkscreener/classes/MarketMonitor.py +6 -6
  14. {pkscreener-0.46.20250728.754 → pkscreener-0.46.20250908.764}/pkscreener/classes/MarketStatus.py +3 -2
  15. {pkscreener-0.46.20250728.754 → pkscreener-0.46.20250908.764}/pkscreener/classes/MenuOptions.py +4 -4
  16. {pkscreener-0.46.20250728.754 → pkscreener-0.46.20250908.764}/pkscreener/classes/PKMarketOpenCloseAnalyser.py +14 -14
  17. {pkscreener-0.46.20250728.754 → pkscreener-0.46.20250908.764}/pkscreener/classes/PKScanRunner.py +2 -2
  18. {pkscreener-0.46.20250728.754 → pkscreener-0.46.20250908.764}/pkscreener/classes/Pktalib.py +36 -36
  19. {pkscreener-0.46.20250728.754 → pkscreener-0.46.20250908.764}/pkscreener/classes/PortfolioXRay.py +5 -5
  20. {pkscreener-0.46.20250728.754 → pkscreener-0.46.20250908.764}/pkscreener/classes/ScreeningStatistics.py +457 -445
  21. {pkscreener-0.46.20250728.754 → pkscreener-0.46.20250908.764}/pkscreener/classes/StockScreener.py +47 -34
  22. {pkscreener-0.46.20250728.754 → pkscreener-0.46.20250908.764}/pkscreener/classes/Utility.py +4 -3
  23. pkscreener-0.46.20250908.764/pkscreener/classes/__init__.py +1 -0
  24. {pkscreener-0.46.20250728.754 → pkscreener-0.46.20250908.764}/pkscreener/globals.py +26 -24
  25. {pkscreener-0.46.20250728.754 → pkscreener-0.46.20250908.764}/pkscreener/pkscreenerbot.py +1 -0
  26. {pkscreener-0.46.20250728.754 → pkscreener-0.46.20250908.764}/pkscreener/pkscreenercli.py +9 -9
  27. {pkscreener-0.46.20250728.754 → pkscreener-0.46.20250908.764}/pkscreener/requirements.txt +3 -3
  28. {pkscreener-0.46.20250728.754 → pkscreener-0.46.20250908.764}/pkscreener.egg-info/PKG-INFO +10 -11
  29. {pkscreener-0.46.20250728.754 → pkscreener-0.46.20250908.764}/pkscreener.egg-info/requires.txt +2 -3
  30. pkscreener-0.46.20250728.754/pkscreener/classes/__init__.py +0 -1
  31. {pkscreener-0.46.20250728.754 → pkscreener-0.46.20250908.764}/LICENSE +0 -0
  32. {pkscreener-0.46.20250728.754 → pkscreener-0.46.20250908.764}/pkscreener/Disclaimer.txt +0 -0
  33. {pkscreener-0.46.20250728.754 → pkscreener-0.46.20250908.764}/pkscreener/LICENSE.txt +0 -0
  34. {pkscreener-0.46.20250728.754 → pkscreener-0.46.20250908.764}/pkscreener/LogoWM.txt +0 -0
  35. {pkscreener-0.46.20250728.754 → pkscreener-0.46.20250908.764}/pkscreener/classes/ArtTexts.py +0 -0
  36. {pkscreener-0.46.20250728.754 → pkscreener-0.46.20250908.764}/pkscreener/classes/Barometer.py +0 -0
  37. {pkscreener-0.46.20250728.754 → pkscreener-0.46.20250908.764}/pkscreener/classes/BaseScreeningStatistics.py +0 -0
  38. {pkscreener-0.46.20250728.754 → pkscreener-0.46.20250908.764}/pkscreener/classes/Changelog.py +0 -0
  39. {pkscreener-0.46.20250728.754 → pkscreener-0.46.20250908.764}/pkscreener/classes/ConsoleMenuUtility.py +0 -0
  40. {pkscreener-0.46.20250728.754 → pkscreener-0.46.20250908.764}/pkscreener/classes/GlobalStore.py +0 -0
  41. {pkscreener-0.46.20250728.754 → pkscreener-0.46.20250908.764}/pkscreener/classes/Messenger.py +0 -0
  42. {pkscreener-0.46.20250728.754 → pkscreener-0.46.20250908.764}/pkscreener/classes/OtaUpdater.py +0 -0
  43. {pkscreener-0.46.20250728.754 → pkscreener-0.46.20250908.764}/pkscreener/classes/PKAnalytics.py +0 -0
  44. {pkscreener-0.46.20250728.754 → pkscreener-0.46.20250908.764}/pkscreener/classes/PKDataService.py +0 -0
  45. {pkscreener-0.46.20250728.754 → pkscreener-0.46.20250908.764}/pkscreener/classes/PKDemoHandler.py +0 -0
  46. {pkscreener-0.46.20250728.754 → pkscreener-0.46.20250908.764}/pkscreener/classes/PKPremiumHandler.py +0 -0
  47. {pkscreener-0.46.20250728.754 → pkscreener-0.46.20250908.764}/pkscreener/classes/PKScheduledTaskProgress.py +0 -0
  48. {pkscreener-0.46.20250728.754 → pkscreener-0.46.20250908.764}/pkscreener/classes/PKScheduler.py +0 -0
  49. {pkscreener-0.46.20250728.754 → pkscreener-0.46.20250908.764}/pkscreener/classes/PKSpreadsheets.py +0 -0
  50. {pkscreener-0.46.20250728.754 → pkscreener-0.46.20250908.764}/pkscreener/classes/PKTask.py +0 -0
  51. {pkscreener-0.46.20250728.754 → pkscreener-0.46.20250908.764}/pkscreener/classes/PKUserRegistration.py +0 -0
  52. {pkscreener-0.46.20250728.754 → pkscreener-0.46.20250908.764}/pkscreener/classes/Portfolio.py +0 -0
  53. {pkscreener-0.46.20250728.754 → pkscreener-0.46.20250908.764}/pkscreener/classes/StockSentiment.py +0 -0
  54. {pkscreener-0.46.20250728.754 → pkscreener-0.46.20250908.764}/pkscreener/classes/UserMenuChoicesHandler.py +0 -0
  55. {pkscreener-0.46.20250728.754 → pkscreener-0.46.20250908.764}/pkscreener/classes/WorkflowManager.py +0 -0
  56. {pkscreener-0.46.20250728.754 → pkscreener-0.46.20250908.764}/pkscreener/classes/keys.py +0 -0
  57. {pkscreener-0.46.20250728.754 → pkscreener-0.46.20250908.764}/pkscreener/courbd.ttf +0 -0
  58. {pkscreener-0.46.20250728.754 → pkscreener-0.46.20250908.764}/pkscreener/pkscreener.ini +0 -0
  59. {pkscreener-0.46.20250728.754 → pkscreener-0.46.20250908.764}/pkscreener.egg-info/SOURCES.txt +0 -0
  60. {pkscreener-0.46.20250728.754 → pkscreener-0.46.20250908.764}/pkscreener.egg-info/dependency_links.txt +0 -0
  61. {pkscreener-0.46.20250728.754 → pkscreener-0.46.20250908.764}/pkscreener.egg-info/entry_points.txt +0 -0
  62. {pkscreener-0.46.20250728.754 → pkscreener-0.46.20250908.764}/pkscreener.egg-info/not-zip-safe +0 -0
  63. {pkscreener-0.46.20250728.754 → pkscreener-0.46.20250908.764}/pkscreener.egg-info/top_level.txt +0 -0
  64. {pkscreener-0.46.20250728.754 → pkscreener-0.46.20250908.764}/setup.cfg +0 -0
  65. {pkscreener-0.46.20250728.754 → pkscreener-0.46.20250908.764}/setup.py +0 -0
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pkscreener
3
- Version: 0.46.20250728.754
3
+ Version: 0.46.20250908.764
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.20250728.754.zip
6
+ Download-URL: https://github.com/pkjmesra/pkscreener/archive/v0.46.20250908.764.zip
7
7
  Author: pkjmesra
8
8
  Author-email: pkjmesra@gmail.com
9
9
  License: OSI Approved (MIT)
@@ -30,10 +30,10 @@ Requires-Dist: lxml==4.9.4
30
30
  Requires-Dist: numpy
31
31
  Requires-Dist: openpyxl
32
32
  Requires-Dist: pandas
33
- Requires-Dist: pandas_ta
33
+ Requires-Dist: pandas-ta-classic
34
34
  Requires-Dist: pefile<2024.8.26,>=2023.2.7
35
35
  Requires-Dist: Pillow
36
- Requires-Dist: PKDevTools>=0.13.20250126.266
36
+ Requires-Dist: PKDevTools>=0.13.20250908.302
37
37
  Requires-Dist: PKNSETools>=0.1.20250122.139
38
38
  Requires-Dist: Pyarrow
39
39
  Requires-Dist: pyppeteer
@@ -50,7 +50,6 @@ Requires-Dist: tensorflow==2.16.1
50
50
  Requires-Dist: urllib3
51
51
  Requires-Dist: vectorbt
52
52
  Requires-Dist: xlsxwriter
53
- Requires-Dist: yfinance==0.2.54
54
53
  Requires-Dist: advanced_ta
55
54
  Dynamic: author
56
55
  Dynamic: author-email
@@ -245,7 +244,7 @@ The story is similar for other low severity vulnerabilities that docker might sh
245
244
  # Installing the latest version from PyPi.
246
245
  * Go ahead and install using `pip install pkscreener`. The releases page also has the latest wheels for multiple platforms.
247
246
  * This should install all of the major dependencies, except maybe, TA-Lib.
248
- * This app can still run without TA-Lib, but if you need to install TA-Lib for technical indicators (which otherwise is used from `pandas_ta` in the absence of TA-Lib), you can do this: Head to `.github/dependencies/` under this repo. Download the respective TA-Lib file/whl file and install either from the .whl file or from source. Check out any of the workflow files for steps to install TA-Lib.
247
+ * This app can still run without TA-Lib, but if you need to install TA-Lib for technical indicators (which otherwise is used from `pandas_ta_classic` in the absence of TA-Lib), you can do this: Head to `.github/dependencies/` under this repo. Download the respective TA-Lib file/whl file and install either from the .whl file or from source. Check out any of the workflow files for steps to install TA-Lib.
249
248
 
250
249
  For example:
251
250
 
@@ -398,15 +397,15 @@ If you are a 3rd year or final year engineering graduate or pursuing masters in
398
397
  [MADE-IN-INDIA-badge]: https://img.shields.io/badge/MADE%20WITH%20%E2%9D%A4%20IN-INDIA-orange
399
398
  [MADE-IN-INDIA]: https://en.wikipedia.org/wiki/India
400
399
  [Windows-badge]: https://img.shields.io/badge/Windows-0078D6?logo=windows&logoColor=white
401
- [Windows]: https://github.com/pkjmesra/PKScreener/releases/download/0.46.20250728.753/pkscreenercli.exe
400
+ [Windows]: https://github.com/pkjmesra/PKScreener/releases/download/0.46.20250810.756/pkscreenercli.exe
402
401
  [Linux-badge_x64]: https://img.shields.io/badge/Linux(x64)-FCC624?logo=linux&logoColor=black
403
- [Linux_x64]: https://github.com/pkjmesra/PKScreener/releases/download/0.46.20250728.753/pkscreenercli_x64.bin
402
+ [Linux_x64]: https://github.com/pkjmesra/PKScreener/releases/download/0.46.20250810.756/pkscreenercli_x64.bin
404
403
  [Linux-badge_arm64]: https://img.shields.io/badge/Linux(arm64)-FCC624?logo=linux&logoColor=black
405
- [Linux_arm64]: https://github.com/pkjmesra/PKScreener/releases/download/0.46.20250728.753/pkscreenercli_arm64.bin
404
+ [Linux_arm64]: https://github.com/pkjmesra/PKScreener/releases/download/0.46.20250810.756/pkscreenercli_arm64.bin
406
405
  [Mac OS-badge_x64]: https://img.shields.io/badge/mac%20os(x64)-D3D3D3?logo=apple&logoColor=000000
407
- [Mac OS_x64]: https://github.com/pkjmesra/PKScreener/releases/download/0.46.20250728.753/pkscreenercli_x64.run
406
+ [Mac OS_x64]: https://github.com/pkjmesra/PKScreener/releases/download/0.46.20250810.756/pkscreenercli_x64.run
408
407
  [Mac OS-badge_arm64]: https://img.shields.io/badge/mac%20os(arm64)-D3D3D3?logo=apple&logoColor=000000
409
- [Mac OS_arm64]: https://github.com/pkjmesra/PKScreener/releases/download/0.46.20250728.753/pkscreenercli_arm64.run
408
+ [Mac OS_arm64]: https://github.com/pkjmesra/PKScreener/releases/download/0.46.20250810.756/pkscreenercli_arm64.run
410
409
  [GitHub release (latest by date)-badge]: https://img.shields.io/github/v/release/pkjmesra/PKScreener
411
410
  [GitHub release (latest by date)]: https://github.com/pkjmesra/PKScreener/releases/latest
412
411
  [pypi-badge]: https://img.shields.io/pypi/v/pkscreener.svg?style=flat-square
@@ -178,7 +178,7 @@ The story is similar for other low severity vulnerabilities that docker might sh
178
178
  # Installing the latest version from PyPi.
179
179
  * Go ahead and install using `pip install pkscreener`. The releases page also has the latest wheels for multiple platforms.
180
180
  * This should install all of the major dependencies, except maybe, TA-Lib.
181
- * This app can still run without TA-Lib, but if you need to install TA-Lib for technical indicators (which otherwise is used from `pandas_ta` in the absence of TA-Lib), you can do this: Head to `.github/dependencies/` under this repo. Download the respective TA-Lib file/whl file and install either from the .whl file or from source. Check out any of the workflow files for steps to install TA-Lib.
181
+ * This app can still run without TA-Lib, but if you need to install TA-Lib for technical indicators (which otherwise is used from `pandas_ta_classic` in the absence of TA-Lib), you can do this: Head to `.github/dependencies/` under this repo. Download the respective TA-Lib file/whl file and install either from the .whl file or from source. Check out any of the workflow files for steps to install TA-Lib.
182
182
 
183
183
  For example:
184
184
 
@@ -331,15 +331,15 @@ If you are a 3rd year or final year engineering graduate or pursuing masters in
331
331
  [MADE-IN-INDIA-badge]: https://img.shields.io/badge/MADE%20WITH%20%E2%9D%A4%20IN-INDIA-orange
332
332
  [MADE-IN-INDIA]: https://en.wikipedia.org/wiki/India
333
333
  [Windows-badge]: https://img.shields.io/badge/Windows-0078D6?logo=windows&logoColor=white
334
- [Windows]: https://github.com/pkjmesra/PKScreener/releases/download/0.46.20250728.753/pkscreenercli.exe
334
+ [Windows]: https://github.com/pkjmesra/PKScreener/releases/download/0.46.20250810.756/pkscreenercli.exe
335
335
  [Linux-badge_x64]: https://img.shields.io/badge/Linux(x64)-FCC624?logo=linux&logoColor=black
336
- [Linux_x64]: https://github.com/pkjmesra/PKScreener/releases/download/0.46.20250728.753/pkscreenercli_x64.bin
336
+ [Linux_x64]: https://github.com/pkjmesra/PKScreener/releases/download/0.46.20250810.756/pkscreenercli_x64.bin
337
337
  [Linux-badge_arm64]: https://img.shields.io/badge/Linux(arm64)-FCC624?logo=linux&logoColor=black
338
- [Linux_arm64]: https://github.com/pkjmesra/PKScreener/releases/download/0.46.20250728.753/pkscreenercli_arm64.bin
338
+ [Linux_arm64]: https://github.com/pkjmesra/PKScreener/releases/download/0.46.20250810.756/pkscreenercli_arm64.bin
339
339
  [Mac OS-badge_x64]: https://img.shields.io/badge/mac%20os(x64)-D3D3D3?logo=apple&logoColor=000000
340
- [Mac OS_x64]: https://github.com/pkjmesra/PKScreener/releases/download/0.46.20250728.753/pkscreenercli_x64.run
340
+ [Mac OS_x64]: https://github.com/pkjmesra/PKScreener/releases/download/0.46.20250810.756/pkscreenercli_x64.run
341
341
  [Mac OS-badge_arm64]: https://img.shields.io/badge/mac%20os(arm64)-D3D3D3?logo=apple&logoColor=000000
342
- [Mac OS_arm64]: https://github.com/pkjmesra/PKScreener/releases/download/0.46.20250728.753/pkscreenercli_arm64.run
342
+ [Mac OS_arm64]: https://github.com/pkjmesra/PKScreener/releases/download/0.46.20250810.756/pkscreenercli_arm64.run
343
343
  [GitHub release (latest by date)-badge]: https://img.shields.io/github/v/release/pkjmesra/PKScreener
344
344
  [GitHub release (latest by date)]: https://github.com/pkjmesra/PKScreener/releases/latest
345
345
  [pypi-badge]: https://img.shields.io/pypi/v/pkscreener.svg?style=flat-square
@@ -4409,7 +4409,7 @@ PERFORMANCE OF THIS SOFTWARE.
4409
4409
  ============================================================================
4410
4410
  The MIT License (MIT)
4411
4411
 
4412
- Copyright (c) 2021+ pandas-ta
4412
+ Copyright (c) 2021+ pandas-ta-classic
4413
4413
 
4414
4414
  Permission is hereby granted, free of charge, to any person obtaining a copy
4415
4415
  of this software and associated documentation files (the "Software"), to deal
@@ -178,7 +178,7 @@ The story is similar for other low severity vulnerabilities that docker might sh
178
178
  # Installing the latest version from PyPi.
179
179
  * Go ahead and install using `pip install pkscreener`. The releases page also has the latest wheels for multiple platforms.
180
180
  * This should install all of the major dependencies, except maybe, TA-Lib.
181
- * This app can still run without TA-Lib, but if you need to install TA-Lib for technical indicators (which otherwise is used from `pandas_ta` in the absence of TA-Lib), you can do this: Head to `.github/dependencies/` under this repo. Download the respective TA-Lib file/whl file and install either from the .whl file or from source. Check out any of the workflow files for steps to install TA-Lib.
181
+ * This app can still run without TA-Lib, but if you need to install TA-Lib for technical indicators (which otherwise is used from `pandas_ta_classic` in the absence of TA-Lib), you can do this: Head to `.github/dependencies/` under this repo. Download the respective TA-Lib file/whl file and install either from the .whl file or from source. Check out any of the workflow files for steps to install TA-Lib.
182
182
 
183
183
  For example:
184
184
 
@@ -331,15 +331,15 @@ If you are a 3rd year or final year engineering graduate or pursuing masters in
331
331
  [MADE-IN-INDIA-badge]: https://img.shields.io/badge/MADE%20WITH%20%E2%9D%A4%20IN-INDIA-orange
332
332
  [MADE-IN-INDIA]: https://en.wikipedia.org/wiki/India
333
333
  [Windows-badge]: https://img.shields.io/badge/Windows-0078D6?logo=windows&logoColor=white
334
- [Windows]: https://github.com/pkjmesra/PKScreener/releases/download/0.46.20250728.753/pkscreenercli.exe
334
+ [Windows]: https://github.com/pkjmesra/PKScreener/releases/download/0.46.20250810.756/pkscreenercli.exe
335
335
  [Linux-badge_x64]: https://img.shields.io/badge/Linux(x64)-FCC624?logo=linux&logoColor=black
336
- [Linux_x64]: https://github.com/pkjmesra/PKScreener/releases/download/0.46.20250728.753/pkscreenercli_x64.bin
336
+ [Linux_x64]: https://github.com/pkjmesra/PKScreener/releases/download/0.46.20250810.756/pkscreenercli_x64.bin
337
337
  [Linux-badge_arm64]: https://img.shields.io/badge/Linux(arm64)-FCC624?logo=linux&logoColor=black
338
- [Linux_arm64]: https://github.com/pkjmesra/PKScreener/releases/download/0.46.20250728.753/pkscreenercli_arm64.bin
338
+ [Linux_arm64]: https://github.com/pkjmesra/PKScreener/releases/download/0.46.20250810.756/pkscreenercli_arm64.bin
339
339
  [Mac OS-badge_x64]: https://img.shields.io/badge/mac%20os(x64)-D3D3D3?logo=apple&logoColor=000000
340
- [Mac OS_x64]: https://github.com/pkjmesra/PKScreener/releases/download/0.46.20250728.753/pkscreenercli_x64.run
340
+ [Mac OS_x64]: https://github.com/pkjmesra/PKScreener/releases/download/0.46.20250810.756/pkscreenercli_x64.run
341
341
  [Mac OS-badge_arm64]: https://img.shields.io/badge/mac%20os(arm64)-D3D3D3?logo=apple&logoColor=000000
342
- [Mac OS_arm64]: https://github.com/pkjmesra/PKScreener/releases/download/0.46.20250728.753/pkscreenercli_arm64.run
342
+ [Mac OS_arm64]: https://github.com/pkjmesra/PKScreener/releases/download/0.46.20250810.756/pkscreenercli_arm64.run
343
343
  [GitHub release (latest by date)-badge]: https://img.shields.io/github/v/release/pkjmesra/PKScreener
344
344
  [GitHub release (latest by date)]: https://github.com/pkjmesra/PKScreener/releases/latest
345
345
  [pypi-badge]: https://img.shields.io/pypi/v/pkscreener.svg?style=flat-square
@@ -28,9 +28,9 @@ Imports = {
28
28
  "scipy": find_spec("scipy") is not None,
29
29
  "sklearn": find_spec("sklearn") is not None,
30
30
  "talib": find_spec("talib") is not None or find_spec("ta-lib") is not None,
31
- "pandas_ta": find_spec("pandas_ta") is not None,
31
+ "pandas_ta_classic": find_spec("pandas_ta_classic") is not None,
32
32
  "tensorflow": find_spec("tensorflow") is not None,
33
33
  "keras": find_spec("keras") is not None,
34
- "yfinance": find_spec("yfinance") is not None,
34
+ # "yfinance": find_spec("yfinance") is not None,
35
35
  "vectorbt": find_spec("vectorbt") is not None,
36
36
  }
@@ -32,7 +32,7 @@ import pandas as pd
32
32
  import numpy as np
33
33
  from halo import Halo
34
34
  from alive_progress import alive_bar
35
- from yfinance import shared
35
+ # from yfinance import shared
36
36
 
37
37
  from PKDevTools.classes.log import default_logger
38
38
  from PKDevTools.classes import Archiver
@@ -187,29 +187,9 @@ class PKAssetsManager:
187
187
  return None
188
188
 
189
189
  def afterMarketStockDataExists(intraday=False, forceLoad=False):
190
- curr = PKDateUtilities.currentDateTime()
191
- openTime = curr.replace(hour=MarketHours().openHour, minute=MarketHours().openMinute)
192
- cache_date = PKDateUtilities.previousTradingDate(PKDateUtilities.nextTradingDate(curr)) #curr # for monday to friday
193
- weekday = curr.weekday()
194
- isTrading = PKDateUtilities.isTradingTime()
195
- if (forceLoad and isTrading) or isTrading:
196
- #curr = PKDateUtilities.tradingDate()
197
- cache_date = PKDateUtilities.previousTradingDate(curr) #curr - datetime.timedelta(1)
198
- # for monday to friday before market open or between market open to market close, we're backtesting
199
- if curr < openTime:
200
- cache_date = PKDateUtilities.previousTradingDate(curr) # curr - datetime.timedelta(1)
201
- if weekday == 0 and curr < openTime: # for monday before market open
202
- cache_date = PKDateUtilities.previousTradingDate(curr) #curr - datetime.timedelta(3)
203
- if weekday == 5 or weekday == 6: # for saturday and sunday
204
- cache_date = PKDateUtilities.previousTradingDate(curr) # curr - datetime.timedelta(days=weekday - 4)
205
- cache_date = cache_date.strftime("%d%m%y")
206
- pattern = f"{'intraday_' if intraday else ''}stock_data_"
207
- cache_file = pattern + str(cache_date) + ".pkl"
208
- exists = False
209
- for f in glob.glob(f"{pattern}*.pkl", root_dir=Archiver.get_user_data_dir()):
210
- if f.endswith(cache_file):
211
- exists = True
212
- break
190
+ exists, cache_file = Archiver.afterMarketStockDataExists(intraday=intraday,
191
+ forceLoad=forceLoad,
192
+ date_suffix=False)
213
193
  return exists, cache_file
214
194
 
215
195
  @Halo(text='', spinner='dots')
@@ -268,8 +248,9 @@ class PKAssetsManager:
268
248
  return cache_file
269
249
 
270
250
  def had_rate_limit_errors():
251
+ return False
271
252
  """Checks if any stored errors are YFRateLimitError."""
272
- err = ",".join(list(shared._ERRORS.values()))
253
+ err = "" #",".join(list(shared._ERRORS.values()))
273
254
  hitRateLimit = "YFRateLimitError" in err or "Too Many Requests" in err or "429" in err
274
255
  if hitRateLimit:
275
256
  OutputControls().printOutput(
@@ -281,6 +262,7 @@ class PKAssetsManager:
281
262
 
282
263
  @Halo(text=' [+] Downloading fresh data from Data Providers...', spinner='dots')
283
264
  def downloadLatestData(stockDict,configManager,stockCodes=[],exchangeSuffix=".NS",downloadOnly=False,numStocksPerIteration=0):
265
+ """
284
266
  shared._ERRORS.clear() # Clear previous errors
285
267
  # if numStocksPerIteration == 0:
286
268
  # maxParallelProcesses = 17
@@ -300,8 +282,9 @@ class PKAssetsManager:
300
282
  if len(stocks) > 0:
301
283
  tasksList.append(task)
302
284
  queueCounter += 1
303
-
285
+ """
304
286
  processedStocks = []
287
+ """
305
288
  if len(tasksList) > 0:
306
289
  # Suppress any multiprocessing errors/warnings
307
290
  with SuppressOutput(suppress_stderr=True, suppress_stdout=True):
@@ -317,6 +300,7 @@ class PKAssetsManager:
317
300
  if taskResult is not None and isinstance(taskResult,pd.DataFrame) and not taskResult.empty:
318
301
  stockDict[stock] = taskResult.to_dict("split")
319
302
  processedStocks.append(stock)
303
+ """
320
304
  leftOutStocks = list(set(stockCodes)-set(processedStocks))
321
305
  default_logger().debug(f"Attempted fresh download of {len(stockCodes)} stocks and downloaded {len(processedStocks)} stocks. {len(leftOutStocks)} stocks remaining.")
322
306
  return stockDict, leftOutStocks
@@ -359,7 +343,7 @@ class PKAssetsManager:
359
343
  # return stockDict
360
344
  if downloadOnly or isTrading:
361
345
  # We don't want to download from local stale pkl file or stale file at server
362
- start_backup()
346
+ # start_backup()
363
347
  return stockDict
364
348
 
365
349
  default_logger().debug(
@@ -396,7 +380,7 @@ class PKAssetsManager:
396
380
  stockDict, _ = PKAssetsManager.downloadLatestData(stockDict,configManager,leftOutStocks,exchangeSuffix=exchangeSuffix,downloadOnly=downloadOnly,numStocksPerIteration=len(leftOutStocks) if leftOutStocks is not None else 0)
397
381
  if stockDataLoaded and downloadOnly:
398
382
  PKAssetsManager.saveStockData(stockDict,configManager,initialLoadCount,isIntraday,downloadOnly, forceSave=stockDataLoaded)
399
- start_backup()
383
+ # start_backup()
400
384
  return stockDict
401
385
 
402
386
  @Halo(text=' [+] Loading data from local cache...', spinner='dots')
@@ -486,7 +470,7 @@ class PKAssetsManager:
486
470
  MB = KB * 1024
487
471
  chunksize = MB if serverBytes >= MB else (KB if serverBytes >= KB else 1)
488
472
  filesize = int( serverBytes / chunksize)
489
- if filesize > 40 and chunksize == MB: # Saved data can't be in KBs. Something definitely went wrong. It should be upward of 40MB
473
+ if filesize > 20 and chunksize == MB: # Saved data can't be in KBs. Something definitely went wrong. It should be upward of 40MB
490
474
  bar, spinner = Utility.tools.getProgressbarStyle()
491
475
  try:
492
476
  f = open(
@@ -75,7 +75,7 @@ def backtest(
75
75
  return backTestedData
76
76
  data = data.head(max(calcPeriods) + 1)
77
77
  # Let's check the returns for the given strategy over a period ranging from 1 period to 30 periods.
78
- # columns=['Stock', 'Date', 'Volume', 'Trend', 'MA-Signal', 'LTP', '52Wk-H',
78
+ # columns=['Stock', 'Date', "volume", 'Trend', 'MA-Signal', 'LTP', '52Wk-H',
79
79
  # '52Wk-L', '1-Pd', '2-Pd', '3-Pd', '4-Pd', '5-Pd', '10-Pd', '15-Pd',
80
80
  # '22-Pd', '30-Pd', 'Consol.', 'Breakout', 'RSI', 'Pattern', 'CCI',
81
81
  # 'LTP1', 'Growth1', 'LTP2', 'Growth2', 'LTP3', 'Growth3', 'LTP4',
@@ -96,7 +96,7 @@ def backtest(
96
96
  columns=[
97
97
  "Stock",
98
98
  "Date",
99
- "Volume",
99
+ "volume",
100
100
  "Trend",
101
101
  "MA-Signal",
102
102
  "LTP",
@@ -106,7 +106,7 @@ def backtest(
106
106
  backTestedStock = {
107
107
  "Stock": "",
108
108
  "Date": "",
109
- "Volume": "",
109
+ "volume": "",
110
110
  "Trend": "",
111
111
  "MA-Signal": "",
112
112
  "LTP": "",
@@ -123,7 +123,7 @@ def backtest(
123
123
  backTestedStock["Consol."] = screenedDict["Consol."]
124
124
  backTestedStock["Breakout"] = screenedDict["Breakout"]
125
125
  backTestedStock["MA-Signal"] = screenedDict["MA-Signal"]
126
- backTestedStock["Volume"] = screenedDict["Volume"]
126
+ backTestedStock["volume"] = screenedDict["volume"]
127
127
  backTestedStock["LTP"] = screenedDict["LTP"]
128
128
  backTestedStock["52Wk-H"] = screenedDict["52Wk-H"]
129
129
  backTestedStock["52Wk-L"] = screenedDict["52Wk-L"]
@@ -136,7 +136,7 @@ def backtest(
136
136
  backTestedStock[f"{abs(prd)}-Pd"] = ""
137
137
  backTestedStock[f"LTP{prd}"] = ""
138
138
  backTestedStock[f"Growth{prd}"] = ""
139
- rolling_pct = data["Close"].pct_change(periods=prd) * 100
139
+ rolling_pct = data["close"].pct_change(periods=prd) * 100
140
140
  pct_change = rolling_pct.iloc[prd]
141
141
  if not sellSignal:
142
142
  colored_pct = colorText.GREEN if pct_change >= 0 else colorText.FAIL
@@ -73,17 +73,17 @@ class CandlePatterns:
73
73
  if "Pattern" not in saveDict.keys():
74
74
  saveDict["Pattern"] = ""
75
75
  dict["Pattern"] = ""
76
- # Only 'doji' and 'inside' is internally implemented by pandas_ta.
76
+ # Only 'doji' and 'inside' is internally implemented by pandas_ta_classic.
77
77
  # Otherwise, for the rest of the candle patterns, they also need
78
78
  # TA-Lib.
79
- check = pktalib.CDLDOJI(data["Open"], data["High"], data["Low"], data["Close"])
79
+ check = pktalib.CDLDOJI(data["open"], data["high"], data["low"], data["close"])
80
80
  if check is not None and check.tail(1).item() != 0:
81
81
  dict["Pattern"] = self.findCurrentSavedValue(dict,saveDict,"Pattern")[0] + colorText.GREEN + f"Doji" + colorText.END
82
82
  saveDict["Pattern"] = self.findCurrentSavedValue(dict,saveDict,"Pattern")[1] + f"Doji"
83
83
  hasCandleStickPattern = True
84
84
 
85
85
  check = pktalib.CDLMORNINGSTAR(
86
- data["Open"], data["High"], data["Low"], data["Close"]
86
+ data["open"], data["high"], data["low"], data["close"]
87
87
  )
88
88
  if check is not None and check.tail(1).item() != 0:
89
89
  dict["Pattern"] = (self.findCurrentSavedValue(dict,saveDict,"Pattern")[0] +
@@ -93,7 +93,7 @@ class CandlePatterns:
93
93
  hasCandleStickPattern = True
94
94
 
95
95
  check = pktalib.CDLCUPANDHANDLE(
96
- processedData["Open"], processedData["High"], processedData["Low"], processedData["Close"]
96
+ processedData["open"], processedData["high"], processedData["low"], processedData["close"]
97
97
  )
98
98
  if check:
99
99
  dict["Pattern"] = (self.findCurrentSavedValue(dict,saveDict,"Pattern")[0] +
@@ -103,7 +103,7 @@ class CandlePatterns:
103
103
  hasCandleStickPattern = True
104
104
 
105
105
  check = pktalib.CDLMORNINGDOJISTAR(
106
- data["Open"], data["High"], data["Low"], data["Close"]
106
+ data["open"], data["high"], data["low"], data["close"]
107
107
  )
108
108
  if check is not None and check.tail(1).item() != 0:
109
109
  dict["Pattern"] = (self.findCurrentSavedValue(dict,saveDict,"Pattern")[0] +
@@ -113,7 +113,7 @@ class CandlePatterns:
113
113
  hasCandleStickPattern = True
114
114
 
115
115
  check = pktalib.CDLEVENINGSTAR(
116
- data["Open"], data["High"], data["Low"], data["Close"]
116
+ data["open"], data["high"], data["low"], data["close"]
117
117
  )
118
118
  if check is not None and check.tail(1).item() != 0:
119
119
  dict["Pattern"] = (self.findCurrentSavedValue(dict,saveDict,"Pattern")[0] +
@@ -123,7 +123,7 @@ class CandlePatterns:
123
123
  hasCandleStickPattern = True
124
124
 
125
125
  check = pktalib.CDLEVENINGDOJISTAR(
126
- data["Open"], data["High"], data["Low"], data["Close"]
126
+ data["open"], data["high"], data["low"], data["close"]
127
127
  )
128
128
  if check is not None and check.tail(1).item() != 0:
129
129
  dict["Pattern"] = (self.findCurrentSavedValue(dict,saveDict,"Pattern")[0] +
@@ -133,7 +133,7 @@ class CandlePatterns:
133
133
  hasCandleStickPattern = True
134
134
 
135
135
  check = pktalib.CDLLADDERBOTTOM(
136
- data["Open"], data["High"], data["Low"], data["Close"]
136
+ data["open"], data["high"], data["low"], data["close"]
137
137
  )
138
138
  if check is not None and check.tail(1).item() != 0:
139
139
  if check.tail(1).item() > 0:
@@ -149,7 +149,7 @@ class CandlePatterns:
149
149
  hasCandleStickPattern = True
150
150
 
151
151
  check = pktalib.CDL3LINESTRIKE(
152
- data["Open"], data["High"], data["Low"], data["Close"]
152
+ data["open"], data["high"], data["low"], data["close"]
153
153
  )
154
154
  if check is not None and check.tail(1).item() != 0:
155
155
  if check.tail(1).item() > 0:
@@ -164,7 +164,7 @@ class CandlePatterns:
164
164
  hasCandleStickPattern = True
165
165
 
166
166
  check = pktalib.CDL3BLACKCROWS(
167
- data["Open"], data["High"], data["Low"], data["Close"]
167
+ data["open"], data["high"], data["low"], data["close"]
168
168
  )
169
169
  if check is not None and check.tail(1).item() != 0:
170
170
  dict["Pattern"] = (self.findCurrentSavedValue(dict,saveDict,"Pattern")[0] +
@@ -174,7 +174,7 @@ class CandlePatterns:
174
174
  hasCandleStickPattern = True
175
175
 
176
176
  check = pktalib.CDL3INSIDE(
177
- data["Open"], data["High"], data["Low"], data["Close"]
177
+ data["open"], data["high"], data["low"], data["close"]
178
178
  )
179
179
  if check is not None and check.tail(1).item() != 0:
180
180
  if check.tail(1).item() > 0:
@@ -190,7 +190,7 @@ class CandlePatterns:
190
190
  hasCandleStickPattern = True
191
191
 
192
192
  check = pktalib.CDL3OUTSIDE(
193
- data["Open"], data["High"], data["Low"], data["Close"]
193
+ data["open"], data["high"], data["low"], data["close"]
194
194
  )
195
195
  if check is not None and check.tail(1).item() != 0:
196
196
  if check.tail(1).item() > 0:
@@ -206,7 +206,7 @@ class CandlePatterns:
206
206
  hasCandleStickPattern = True
207
207
 
208
208
  check = pktalib.CDL3WHITESOLDIERS(
209
- data["Open"], data["High"], data["Low"], data["Close"]
209
+ data["open"], data["high"], data["low"], data["close"]
210
210
  )
211
211
  if check is not None and check.tail(1).item() != 0:
212
212
  dict["Pattern"] = (self.findCurrentSavedValue(dict,saveDict,"Pattern")[0] +
@@ -216,7 +216,7 @@ class CandlePatterns:
216
216
  hasCandleStickPattern = True
217
217
 
218
218
  check = pktalib.CDLHARAMI(
219
- data["Open"], data["High"], data["Low"], data["Close"]
219
+ data["open"], data["high"], data["low"], data["close"]
220
220
  )
221
221
  if check is not None and check.tail(1).item() != 0:
222
222
  if check.tail(1).item() > 0:
@@ -232,7 +232,7 @@ class CandlePatterns:
232
232
  hasCandleStickPattern = True
233
233
 
234
234
  check = pktalib.CDLHARAMICROSS(
235
- data["Open"], data["High"], data["Low"], data["Close"]
235
+ data["open"], data["high"], data["low"], data["close"]
236
236
  )
237
237
  if check is not None and check.tail(1).item() != 0:
238
238
  if check.tail(1).item() > 0:
@@ -252,7 +252,7 @@ class CandlePatterns:
252
252
  hasCandleStickPattern = True
253
253
 
254
254
  check = pktalib.CDLMARUBOZU(
255
- data["Open"], data["High"], data["Low"], data["Close"]
255
+ data["open"], data["high"], data["low"], data["close"]
256
256
  )
257
257
  if check is not None and check.tail(1).item() != 0:
258
258
  if check.tail(1).item() > 0:
@@ -270,7 +270,7 @@ class CandlePatterns:
270
270
  hasCandleStickPattern = True
271
271
 
272
272
  check = pktalib.CDLHANGINGMAN(
273
- data["Open"], data["High"], data["Low"], data["Close"]
273
+ data["open"], data["high"], data["low"], data["close"]
274
274
  )
275
275
  if check is not None and check.tail(1).item() != 0:
276
276
  dict["Pattern"] = (self.findCurrentSavedValue(dict,saveDict,"Pattern")[0] +
@@ -280,7 +280,7 @@ class CandlePatterns:
280
280
  hasCandleStickPattern = True
281
281
 
282
282
  check = pktalib.CDLHAMMER(
283
- data["Open"], data["High"], data["Low"], data["Close"]
283
+ data["open"], data["high"], data["low"], data["close"]
284
284
  )
285
285
  if check is not None and check.tail(1).item() != 0:
286
286
  dict["Pattern"] = (self.findCurrentSavedValue(dict,saveDict,"Pattern")[0] +
@@ -290,7 +290,7 @@ class CandlePatterns:
290
290
  hasCandleStickPattern = True
291
291
 
292
292
  check = pktalib.CDLINVERTEDHAMMER(
293
- data["Open"], data["High"], data["Low"], data["Close"]
293
+ data["open"], data["high"], data["low"], data["close"]
294
294
  )
295
295
  if check is not None and check.tail(1).item() != 0:
296
296
  dict["Pattern"] = (self.findCurrentSavedValue(dict,saveDict,"Pattern")[0] +
@@ -300,7 +300,7 @@ class CandlePatterns:
300
300
  hasCandleStickPattern = True
301
301
 
302
302
  check = pktalib.CDLSHOOTINGSTAR(
303
- data["Open"], data["High"], data["Low"], data["Close"]
303
+ data["open"], data["high"], data["low"], data["close"]
304
304
  )
305
305
  if check is not None and check.tail(1).item() != 0:
306
306
  dict["Pattern"] = (self.findCurrentSavedValue(dict,saveDict,"Pattern")[0] +
@@ -310,7 +310,7 @@ class CandlePatterns:
310
310
  hasCandleStickPattern = True
311
311
 
312
312
  check = pktalib.CDLDRAGONFLYDOJI(
313
- data["Open"], data["High"], data["Low"], data["Close"]
313
+ data["open"], data["high"], data["low"], data["close"]
314
314
  )
315
315
  if check is not None and check.tail(1).item() != 0:
316
316
  dict["Pattern"] = (self.findCurrentSavedValue(dict,saveDict,"Pattern")[0] +
@@ -320,7 +320,7 @@ class CandlePatterns:
320
320
  hasCandleStickPattern = True
321
321
 
322
322
  check = pktalib.CDLGRAVESTONEDOJI(
323
- data["Open"], data["High"], data["Low"], data["Close"]
323
+ data["open"], data["high"], data["low"], data["close"]
324
324
  )
325
325
  if check is not None and check.tail(1).item() != 0:
326
326
  dict["Pattern"] = (self.findCurrentSavedValue(dict,saveDict,"Pattern")[0] +
@@ -330,7 +330,7 @@ class CandlePatterns:
330
330
  hasCandleStickPattern = True
331
331
 
332
332
  check = pktalib.CDLENGULFING(
333
- data["Open"], data["High"], data["Low"], data["Close"]
333
+ data["open"], data["high"], data["low"], data["close"]
334
334
  )
335
335
  if check is not None and check.tail(1).item() != 0:
336
336
  if check.tail(1).item() > 0:
@@ -105,6 +105,7 @@ class tools(SingletonMixin, metaclass=SingletonType):
105
105
  self.vcpLegsToCheckForConsolidation = 3
106
106
  self.enableAdditionalVCPFilters = True
107
107
  self.enableAdditionalVCPEMAFilters = False
108
+ self.enableAdditionalTrendFilters = False
108
109
  self.enableUsageAnalytics = True
109
110
  # This determines how many days apart the backtest calculations are run.
110
111
  # For example, for weekly backtest calculations, set this to 5 (5 days = 1 week)
@@ -114,7 +115,7 @@ class tools(SingletonMixin, metaclass=SingletonType):
114
115
  self.maxDashboardWidgetsPerRow = 7
115
116
  self.maxNumResultRowsInMonitor = 3
116
117
  self.calculatersiintraday = False
117
- self.defaultMonitorOptions = "X:12:9:2.5:>|X:0:31:>|X:0:23:>|X:0:27:~X:12:9:2.5:>|X:0:31:>|X:0:27:~X:12:9:2.5:>|X:0:31:~X:12:9:2.5:>|X:0:27:~X:12:9:2.5:>|X:0:29:~X:12:9:2.5:>|X:0:27:>|X:12:30:1:~X:12:9:2.5:>|X:12:30:1:~X:12:31:>|X:0:27:~X:12:31:>|X:0:30:1:~X:12:27:>|X:0:30:1:~X:12:7:8:>|X:12:7:9:1:1:~X:12:7:4:>|X:12:7:9:1:1:~X:12:2:>|X:12:7:8:>|X:12:7:9:1:1:~X:12:30:1:>|X:12:7:8:~X:12:7:9:5:>|X:12:21:8:~X:12:7:4:~X:12:7:9:7:>|X:0:9:2.5:~X:12:7:9:7:>|X:0:31:>|X:0:30:1:~X:12:7:3:0.008:4:>|X:0:30:1:~X:12:7:3:0.008:4:>|X:12:7:9:7:>|X:0:7:3:0.008:4:~X:12:9:2.5~X:12:23~X:12:28~X:12:31~|{1}X:0:23:>|X:0:27:>|X:0:31:~|{2}X:0:31:~|{3}X:0:27:~X:12:7:3:.01:1~|{5}X:0:5:0:35:~X:12:7:6:1~X:12:11:~X:12:12:i 5m~X:12:17~X:12:24~X:12:6:7:1~X:12:6:3~X:12:6:8~X:12:6:9~X:12:2:>|X:12:7:8:>|X:12:7:9:1:1:~X:12:6:10:1~X:12:7:4:>|X:12:30:1:~X:12:7:3:.02:1~X:12:13:i 1m~X:12:2~|{1}X:0:29:"
118
+ self.defaultMonitorOptions = "X:12:9:2.5:>|X:0:31:>|X:0:23:>|X:0:27:~X:12:9:2.5:>|X:0:31:>|X:0:27:~X:12:9:2.5:>|X:0:31:~X:12:9:2.5:>|X:0:27:~X:12:9:2.5:>|X:0:29:~X:12:9:2.5:>|X:0:27:>|X:12:30:1:~X:12:9:2.5:>|X:12:30:1:~X:12:27:>|X:0:31:~X:12:31:>|X:0:30:1:~X:12:27:>|X:0:30:1:~X:12:7:8:>|X:12:7:9:1:1:~X:12:7:4:>|X:12:7:9:1:1:~X:12:2:>|X:12:7:8:>|X:12:7:9:1:1:~X:12:30:1:>|X:12:7:8:~X:12:7:9:5:>|X:12:21:8:~X:12:7:4:~X:12:7:9:7:>|X:0:9:2.5:~X:12:7:9:7:>|X:0:31:>|X:0:30:1:~X:12:7:3:0.008:4:>|X:0:30:1:~X:12:7:3:0.008:4:>|X:12:7:9:7:>|X:0:7:3:0.008:4:~X:12:9:2.5~X:12:23~X:12:28~X:12:31~|{1}X:0:23:>|X:0:27:>|X:0:31:~|{2}X:0:31:~|{3}X:0:27:~X:12:7:3:.01:1~|{5}X:0:5:0:35:~X:12:7:6:1~X:12:11:~X:12:12:i 5m~X:12:17~X:12:24~X:12:6:7:1~X:12:6:3~X:12:6:8~X:12:6:9~X:12:2:>|X:12:7:8:>|X:12:7:9:1:1:~X:12:6:10:1~X:12:7:4:>|X:12:30:1:~X:12:7:3:.02:1~X:12:13:i 1m~X:12:2~|{1}X:0:29:"
118
119
  self.myMonitorOptions = ""
119
120
  self.minimumChangePercentage = 0
120
121
  self.daysToLookback = 22 * self.backtestPeriodFactor # 1 month
@@ -246,6 +247,7 @@ class tools(SingletonMixin, metaclass=SingletonType):
246
247
  parser.set("config", "defaultMonitorOptions", str(self.defaultMonitorOptions))
247
248
  parser.set("config", "duration", self.duration)
248
249
  parser.set("config", "enableAdditionalVCPEMAFilters", "y" if (self.enableAdditionalVCPEMAFilters) else "n")
250
+ parser.set("config", "enableAdditionalTrendFilters", "y" if (self.enableAdditionalTrendFilters) else "n")
249
251
  parser.set("config", "enableAdditionalVCPFilters", "y" if (self.enableAdditionalVCPFilters) else "n")
250
252
  parser.set("config", "enablePortfolioCalculations", "y" if self.enablePortfolioCalculations else "n")
251
253
  parser.set("config", "enableUsageAnalytics", "y" if self.enableUsageAnalytics else "n")
@@ -478,7 +480,11 @@ class tools(SingletonMixin, metaclass=SingletonType):
478
480
  f" [+] Enable additional 20/50-EMA filters? [Y/N, Current: {colorText.FAIL}{'y' if self.enableAdditionalVCPEMAFilters else 'n'}{colorText.END}]: "
479
481
  ) or ('y' if self.enableAdditionalVCPEMAFilters else 'n')
480
482
  ).lower()
481
-
483
+ self.enableAdditionalTrendFilters = str(
484
+ input(
485
+ f" [+] Enable additional Trend filters? [Y/N, Current: {colorText.FAIL}{'y' if self.enableAdditionalTrendFilters else 'n'}{colorText.END}]: "
486
+ ) or ('y' if self.enableAdditionalTrendFilters else 'n')
487
+ ).lower()
482
488
  self.enableUsageAnalytics = str(
483
489
  input(
484
490
  f" [+] Enable usage analytics to be captured? [Y/N, Current: {colorText.FAIL}{'y' if self.enableUsageAnalytics else 'n'}{colorText.END}]: "
@@ -527,6 +533,7 @@ class tools(SingletonMixin, metaclass=SingletonType):
527
533
  endDuration = "d" if endDuration not in ["m","h","d","k","o"] else ""
528
534
  parser.set("config", "duration", str(self.duration + endDuration))
529
535
  parser.set("config", "enableAdditionalVCPEMAFilters", str(self.enableAdditionalVCPEMAFilters))
536
+ parser.set("config", "enableAdditionalTrendFilters", str(self.enableAdditionalTrendFilters))
530
537
  parser.set("config", "enableAdditionalVCPFilters", str(self.enableAdditionalVCPFilters))
531
538
  parser.set("config", "enablePortfolioCalculations", str(self.enablePortfolioCalculations))
532
539
  parser.set("config", "enableUsageAnalytics", str(self.enableUsageAnalytics))
@@ -706,6 +713,11 @@ class tools(SingletonMixin, metaclass=SingletonType):
706
713
  if "y" not in str(parser.get("config", "enableAdditionalVCPEMAFilters")).lower()
707
714
  else True
708
715
  )
716
+ self.enableAdditionalTrendFilters = (
717
+ False
718
+ if "y" not in str(parser.get("config", "enableAdditionalTrendFilters")).lower()
719
+ else True
720
+ )
709
721
  self.enableAdditionalVCPFilters = (
710
722
  False
711
723
  if "y" not in str(parser.get("config", "enableAdditionalVCPFilters")).lower()
@@ -177,7 +177,7 @@ class PKConsoleTools:
177
177
  + "\n [+] Showing recently screened results..\n"
178
178
  + colorText.END
179
179
  )
180
- df.sort_values(by=["Volume" if "Volume" in df.keys() else df.keys()[0]], ascending=False, inplace=True)
180
+ df.sort_values(by=["volume" if "volume" in df.keys() else df.keys()[0]], ascending=False, inplace=True)
181
181
  OutputControls().printOutput(
182
182
  colorText.miniTabulator().tabulate(
183
183
  df, headers="keys", tablefmt=colorText.No_Pad_GridFormat,