pkscreener 0.46.20250219.725__cp312-cp312-win_amd64.whl → 0.46.20250220.727__cp312-cp312-win_amd64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. {pkscreener-0.46.20250219.725.data → pkscreener-0.46.20250220.727.data}/purelib/pkscreener/README.txt +5 -5
  2. {pkscreener-0.46.20250219.725.data → pkscreener-0.46.20250220.727.data}/purelib/pkscreener/classes/AssetsManager.py +32 -10
  3. {pkscreener-0.46.20250219.725.data → pkscreener-0.46.20250220.727.data}/purelib/pkscreener/classes/Fetcher.py +38 -8
  4. pkscreener-0.46.20250220.727.data/purelib/pkscreener/classes/__init__.py +1 -0
  5. {pkscreener-0.46.20250219.725.data → pkscreener-0.46.20250220.727.data}/purelib/pkscreener/globals.py +5 -1
  6. {pkscreener-0.46.20250219.725.data → pkscreener-0.46.20250220.727.data}/purelib/pkscreener/requirements.txt +1 -1
  7. {pkscreener-0.46.20250219.725.dist-info → pkscreener-0.46.20250220.727.dist-info}/METADATA +7 -7
  8. pkscreener-0.46.20250220.727.dist-info/RECORD +58 -0
  9. pkscreener-0.46.20250219.725.data/purelib/pkscreener/classes/__init__.py +0 -1
  10. pkscreener-0.46.20250219.725.dist-info/RECORD +0 -58
  11. {pkscreener-0.46.20250219.725.data → pkscreener-0.46.20250220.727.data}/purelib/pkscreener/Disclaimer.txt +0 -0
  12. {pkscreener-0.46.20250219.725.data → pkscreener-0.46.20250220.727.data}/purelib/pkscreener/LICENSE-Others.txt +0 -0
  13. {pkscreener-0.46.20250219.725.data → pkscreener-0.46.20250220.727.data}/purelib/pkscreener/LICENSE.txt +0 -0
  14. {pkscreener-0.46.20250219.725.data → pkscreener-0.46.20250220.727.data}/purelib/pkscreener/LogoWM.txt +0 -0
  15. {pkscreener-0.46.20250219.725.data → pkscreener-0.46.20250220.727.data}/purelib/pkscreener/__init__.py +0 -0
  16. {pkscreener-0.46.20250219.725.data → pkscreener-0.46.20250220.727.data}/purelib/pkscreener/classes/ArtTexts.py +0 -0
  17. {pkscreener-0.46.20250219.725.data → pkscreener-0.46.20250220.727.data}/purelib/pkscreener/classes/Backtest.py +0 -0
  18. {pkscreener-0.46.20250219.725.data → pkscreener-0.46.20250220.727.data}/purelib/pkscreener/classes/Barometer.py +0 -0
  19. {pkscreener-0.46.20250219.725.data → pkscreener-0.46.20250220.727.data}/purelib/pkscreener/classes/BaseScreeningStatistics.py +0 -0
  20. {pkscreener-0.46.20250219.725.data → pkscreener-0.46.20250220.727.data}/purelib/pkscreener/classes/CandlePatterns.py +0 -0
  21. {pkscreener-0.46.20250219.725.data → pkscreener-0.46.20250220.727.data}/purelib/pkscreener/classes/Changelog.py +0 -0
  22. {pkscreener-0.46.20250219.725.data → pkscreener-0.46.20250220.727.data}/purelib/pkscreener/classes/ConfigManager.py +0 -0
  23. {pkscreener-0.46.20250219.725.data → pkscreener-0.46.20250220.727.data}/purelib/pkscreener/classes/ConsoleMenuUtility.py +0 -0
  24. {pkscreener-0.46.20250219.725.data → pkscreener-0.46.20250220.727.data}/purelib/pkscreener/classes/ConsoleUtility.py +0 -0
  25. {pkscreener-0.46.20250219.725.data → pkscreener-0.46.20250220.727.data}/purelib/pkscreener/classes/GlobalStore.py +0 -0
  26. {pkscreener-0.46.20250219.725.data → pkscreener-0.46.20250220.727.data}/purelib/pkscreener/classes/ImageUtility.py +0 -0
  27. {pkscreener-0.46.20250219.725.data → pkscreener-0.46.20250220.727.data}/purelib/pkscreener/classes/MarketMonitor.py +0 -0
  28. {pkscreener-0.46.20250219.725.data → pkscreener-0.46.20250220.727.data}/purelib/pkscreener/classes/MarketStatus.py +0 -0
  29. {pkscreener-0.46.20250219.725.data → pkscreener-0.46.20250220.727.data}/purelib/pkscreener/classes/MenuOptions.py +0 -0
  30. {pkscreener-0.46.20250219.725.data → pkscreener-0.46.20250220.727.data}/purelib/pkscreener/classes/Messenger.py +0 -0
  31. {pkscreener-0.46.20250219.725.data → pkscreener-0.46.20250220.727.data}/purelib/pkscreener/classes/OtaUpdater.py +0 -0
  32. {pkscreener-0.46.20250219.725.data → pkscreener-0.46.20250220.727.data}/purelib/pkscreener/classes/PKAnalytics.py +0 -0
  33. {pkscreener-0.46.20250219.725.data → pkscreener-0.46.20250220.727.data}/purelib/pkscreener/classes/PKDataService.py +0 -0
  34. {pkscreener-0.46.20250219.725.data → pkscreener-0.46.20250220.727.data}/purelib/pkscreener/classes/PKDemoHandler.py +0 -0
  35. {pkscreener-0.46.20250219.725.data → pkscreener-0.46.20250220.727.data}/purelib/pkscreener/classes/PKMarketOpenCloseAnalyser.py +0 -0
  36. {pkscreener-0.46.20250219.725.data → pkscreener-0.46.20250220.727.data}/purelib/pkscreener/classes/PKPremiumHandler.py +0 -0
  37. {pkscreener-0.46.20250219.725.data → pkscreener-0.46.20250220.727.data}/purelib/pkscreener/classes/PKScanRunner.py +0 -0
  38. {pkscreener-0.46.20250219.725.data → pkscreener-0.46.20250220.727.data}/purelib/pkscreener/classes/PKScheduledTaskProgress.py +0 -0
  39. {pkscreener-0.46.20250219.725.data → pkscreener-0.46.20250220.727.data}/purelib/pkscreener/classes/PKScheduler.py +0 -0
  40. {pkscreener-0.46.20250219.725.data → pkscreener-0.46.20250220.727.data}/purelib/pkscreener/classes/PKSpreadsheets.py +0 -0
  41. {pkscreener-0.46.20250219.725.data → pkscreener-0.46.20250220.727.data}/purelib/pkscreener/classes/PKTask.py +0 -0
  42. {pkscreener-0.46.20250219.725.data → pkscreener-0.46.20250220.727.data}/purelib/pkscreener/classes/PKUserRegistration.py +0 -0
  43. {pkscreener-0.46.20250219.725.data → pkscreener-0.46.20250220.727.data}/purelib/pkscreener/classes/Pktalib.py +0 -0
  44. {pkscreener-0.46.20250219.725.data → pkscreener-0.46.20250220.727.data}/purelib/pkscreener/classes/Portfolio.py +0 -0
  45. {pkscreener-0.46.20250219.725.data → pkscreener-0.46.20250220.727.data}/purelib/pkscreener/classes/PortfolioXRay.py +0 -0
  46. {pkscreener-0.46.20250219.725.data → pkscreener-0.46.20250220.727.data}/purelib/pkscreener/classes/ScreeningStatistics.py +0 -0
  47. {pkscreener-0.46.20250219.725.data → pkscreener-0.46.20250220.727.data}/purelib/pkscreener/classes/StockScreener.py +0 -0
  48. {pkscreener-0.46.20250219.725.data → pkscreener-0.46.20250220.727.data}/purelib/pkscreener/classes/StockSentiment.py +0 -0
  49. {pkscreener-0.46.20250219.725.data → pkscreener-0.46.20250220.727.data}/purelib/pkscreener/classes/UserMenuChoicesHandler.py +0 -0
  50. {pkscreener-0.46.20250219.725.data → pkscreener-0.46.20250220.727.data}/purelib/pkscreener/classes/Utility.py +0 -0
  51. {pkscreener-0.46.20250219.725.data → pkscreener-0.46.20250220.727.data}/purelib/pkscreener/classes/WorkflowManager.py +0 -0
  52. {pkscreener-0.46.20250219.725.data → pkscreener-0.46.20250220.727.data}/purelib/pkscreener/classes/keys.py +0 -0
  53. {pkscreener-0.46.20250219.725.data → pkscreener-0.46.20250220.727.data}/purelib/pkscreener/courbd.ttf +0 -0
  54. {pkscreener-0.46.20250219.725.data → pkscreener-0.46.20250220.727.data}/purelib/pkscreener/pkscreener.ini +0 -0
  55. {pkscreener-0.46.20250219.725.data → pkscreener-0.46.20250220.727.data}/purelib/pkscreener/pkscreenerbot.py +0 -0
  56. {pkscreener-0.46.20250219.725.data → pkscreener-0.46.20250220.727.data}/purelib/pkscreener/pkscreenercli.py +0 -0
  57. {pkscreener-0.46.20250219.725.dist-info → pkscreener-0.46.20250220.727.dist-info}/LICENSE +0 -0
  58. {pkscreener-0.46.20250219.725.dist-info → pkscreener-0.46.20250220.727.dist-info}/WHEEL +0 -0
  59. {pkscreener-0.46.20250219.725.dist-info → pkscreener-0.46.20250220.727.dist-info}/entry_points.txt +0 -0
  60. {pkscreener-0.46.20250219.725.dist-info → pkscreener-0.46.20250220.727.dist-info}/top_level.txt +0 -0
@@ -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.20250219.724/pkscreenercli.exe
331
+ [Windows]: https://github.com/pkjmesra/PKScreener/releases/download/0.46.20250220.726/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.20250219.724/pkscreenercli_x64.bin
333
+ [Linux_x64]: https://github.com/pkjmesra/PKScreener/releases/download/0.46.20250220.726/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.20250219.724/pkscreenercli_arm64.bin
335
+ [Linux_arm64]: https://github.com/pkjmesra/PKScreener/releases/download/0.46.20250220.726/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.20250219.724/pkscreenercli_x64.run
337
+ [Mac OS_x64]: https://github.com/pkjmesra/PKScreener/releases/download/0.46.20250220.726/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.20250219.724/pkscreenercli_arm64.run
339
+ [Mac OS_arm64]: https://github.com/pkjmesra/PKScreener/releases/download/0.46.20250220.726/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
@@ -32,6 +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
36
 
36
37
  from PKDevTools.classes.log import default_logger
37
38
  from PKDevTools.classes import Archiver
@@ -264,9 +265,24 @@ class PKAssetsManager:
264
265
  OutputControls().printOutput(colorText.GREEN + f"=> {cache_file}" + colorText.END)
265
266
  return cache_file
266
267
 
268
+ def had_rate_limit_errors():
269
+ """Checks if any stored errors are YFRateLimitError."""
270
+ err = ",".join(list(shared._ERRORS.values()))
271
+ hitRateLimit = "YFRateLimitError" in err
272
+ if hitRateLimit:
273
+ OutputControls().printOutput(
274
+ colorText.FAIL
275
+ + " [+] We hit a rate limit error in the previous request(s)!"
276
+ + colorText.END
277
+ )
278
+ return hitRateLimit
279
+
267
280
  @Halo(text=' [+] Downloading fresh data from Data Providers...', spinner='dots')
268
- def downloadLatestData(stockDict,configManager,stockCodes=[],exchangeSuffix=".NS",downloadOnly=False):
269
- numStocksPerIteration = (int(len(stockCodes)/int(len(stockCodes)/10)) if len(stockCodes) >= 10 else len(stockCodes)) + 1
281
+ def downloadLatestData(stockDict,configManager,stockCodes=[],exchangeSuffix=".NS",downloadOnly=False,numStocksPerIteration=0):
282
+ shared._ERRORS.clear() # Clear previous errors
283
+ # if numStocksPerIteration == 0:
284
+ maxParallelProcesses = 17
285
+ numStocksPerIteration = (int(len(stockCodes)/int(len(stockCodes)/maxParallelProcesses)) if len(stockCodes) >= maxParallelProcesses else len(stockCodes)) + 1
270
286
  queueCounter = 0
271
287
  iterations = int(len(stockCodes)/numStocksPerIteration) + 1
272
288
  tasksList = []
@@ -293,10 +309,10 @@ class PKAssetsManager:
293
309
  minAcceptableCompletionPercentage=(100 if downloadOnly else 100),
294
310
  showProgressBars=configManager.logsEnabled)
295
311
  for task in tasksList:
296
- if task.result is not None:
312
+ if task.result is not None and isinstance(task.result,pd.DataFrame) and not task.result.empty:
297
313
  for stock in task.userData:
298
314
  taskResult = task.result.get(f"{stock}{exchangeSuffix}")
299
- if taskResult is not None:
315
+ if taskResult is not None and isinstance(taskResult,pd.DataFrame) and not taskResult.empty:
300
316
  stockDict[stock] = taskResult.to_dict("split")
301
317
  processedStocks.append(stock)
302
318
  leftOutStocks = list(set(stockCodes)-set(processedStocks))
@@ -332,10 +348,12 @@ class PKAssetsManager:
332
348
  # stockCodes is not None mandates that we start our work based on the downloaded data from yesterday
333
349
  if (stockCodes is not None and len(stockCodes) > 0) and (isTrading or downloadOnly):
334
350
  recentDownloadFromOriginAttempted = True
335
- stockDict, leftOutStocks = PKAssetsManager.downloadLatestData(stockDict,configManager,stockCodes,exchangeSuffix=exchangeSuffix,downloadOnly=downloadOnly)
336
- if len(leftOutStocks) > int(len(stockCodes)*0.05):
351
+ stockDict, leftOutStocks = PKAssetsManager.downloadLatestData(stockDict,configManager,stockCodes,exchangeSuffix=exchangeSuffix,downloadOnly=downloadOnly,numStocksPerIteration=len(stockCodes) if stockCodes is not None else 0)
352
+ if len(leftOutStocks) > int(len(stockCodes)*0.05) and not PKAssetsManager.had_rate_limit_errors():
353
+ # During live market hours, we may not really get additional data if we didn't
354
+ # get it the first time
337
355
  # More than 5 % of stocks are still remaining
338
- stockDict, _ = PKAssetsManager.downloadLatestData(stockDict,configManager,leftOutStocks,exchangeSuffix=exchangeSuffix,downloadOnly=downloadOnly)
356
+ stockDict, _ = PKAssetsManager.downloadLatestData(stockDict,configManager,leftOutStocks,exchangeSuffix=exchangeSuffix,downloadOnly=downloadOnly,numStocksPerIteration=len(leftOutStocks) if leftOutStocks is not None else 0)
339
357
  # return stockDict
340
358
  if downloadOnly or isTrading:
341
359
  # We don't want to download from local stale pkl file or stale file at server
@@ -365,12 +383,16 @@ class PKAssetsManager:
365
383
  + " [+] Cache unavailable on pkscreener server, Continuing.."
366
384
  + colorText.END
367
385
  )
368
- if not stockDataLoaded and not recentDownloadFromOriginAttempted:
369
- stockDict, _ = PKAssetsManager.downloadLatestData(stockDict,configManager,stockCodes,exchangeSuffix=exchangeSuffix,downloadOnly=downloadOnly)
386
+ if not stockDataLoaded and not recentDownloadFromOriginAttempted and not PKAssetsManager.had_rate_limit_errors():
387
+ stockDict, _ = PKAssetsManager.downloadLatestData(stockDict,configManager,stockCodes,exchangeSuffix=exchangeSuffix,downloadOnly=downloadOnly,numStocksPerIteration=len(stockCodes) if stockCodes is not None else 0)
370
388
  # See if we need to save stock data
371
389
  stockDataLoaded = stockDataLoaded or (len(stockDict) > 0 and (len(stockDict) != initialLoadCount))
372
390
  if stockDataLoaded:
373
391
  PKAssetsManager.saveStockData(stockDict,configManager,initialLoadCount,isIntraday,downloadOnly, forceSave=stockDataLoaded)
392
+ leftOutStocks = list(set(stockCodes)-set(list(stockDict.keys())))
393
+ if len(leftOutStocks) > int(len(stockCodes)*0.05) and not PKAssetsManager.had_rate_limit_errors():
394
+ # More than 5 % of stocks are still remaining
395
+ stockDict, _ = PKAssetsManager.downloadLatestData(stockDict,configManager,leftOutStocks,exchangeSuffix=exchangeSuffix,downloadOnly=downloadOnly,numStocksPerIteration=len(leftOutStocks) if leftOutStocks is not None else 0)
374
396
  return stockDict
375
397
 
376
398
  @Halo(text=' [+] Loading data from local cache...', spinner='dots')
@@ -383,7 +405,7 @@ class PKAssetsManager:
383
405
  if not downloadOnly:
384
406
  OutputControls().printOutput(
385
407
  colorText.GREEN
386
- + f"\n [+] Automatically Using Cached Stock Data {'due to After-Market hours' if not PKDateUtilities.isTradingTime() else ''}!"
408
+ + f"\n [+] Automatically Using [{len(stockData)}] Tickers' Cached Stock Data {'due to After-Market hours' if not PKDateUtilities.isTradingTime() else ''}!"
387
409
  + colorText.END
388
410
  )
389
411
  if stockData is not None and len(stockData) > 0:
@@ -27,16 +27,21 @@ import os
27
27
  import sys
28
28
  import warnings
29
29
 
30
+ from time import sleep
30
31
  warnings.simplefilter("ignore", DeprecationWarning)
31
32
  warnings.simplefilter("ignore", FutureWarning)
32
33
  import pandas as pd
33
34
  import yfinance as yf
34
35
  from yfinance import shared
35
- # from yfinance.exceptions import YFPricesMissingError, YFInvalidPeriodError
36
- class YFPricesMissingError(Exception):
37
- pass
38
- class YFInvalidPeriodError(Exception):
39
- pass
36
+ # from yfinance.const import USER_AGENTS
37
+ from PKDevTools.classes.Utils import USER_AGENTS
38
+ from yfinance.data import YfData
39
+ import random
40
+ from yfinance.exceptions import YFPricesMissingError, YFInvalidPeriodError, YFRateLimitError
41
+ # class YFPricesMissingError(Exception):
42
+ # pass
43
+ # class YFInvalidPeriodError(Exception):
44
+ # pass
40
45
  from concurrent.futures import ThreadPoolExecutor
41
46
  from PKDevTools.classes.PKDateUtilities import PKDateUtilities
42
47
  from PKDevTools.classes.ColorText import colorText
@@ -94,7 +99,8 @@ class screenerStockDataFetcher(nseStockDataFetcher):
94
99
  printCounter=False,
95
100
  start=None,
96
101
  end=None,
97
- exchangeSuffix=".NS"
102
+ exchangeSuffix=".NS",
103
+ attempt = 0
98
104
  ):
99
105
  if isinstance(stockCode,list):
100
106
  if len(exchangeSuffix) > 0:
@@ -117,6 +123,8 @@ class screenerStockDataFetcher(nseStockDataFetcher):
117
123
  data = None
118
124
  with SuppressOutput(suppress_stdout=(not printCounter), suppress_stderr=(not printCounter)):
119
125
  try:
126
+ # YfData.user_agent_headers = {
127
+ # 'User-Agent': random.choice(USER_AGENTS)}
120
128
  data = yf.download(
121
129
  tickers=stockCode,
122
130
  period=period,
@@ -127,7 +135,8 @@ class screenerStockDataFetcher(nseStockDataFetcher):
127
135
  group_by='ticker',
128
136
  timeout=self.configManager.generalTimeout/4,
129
137
  start=start,
130
- end=end
138
+ end=end,
139
+ auto_adjust=True
131
140
  )
132
141
  if isinstance(stockCode,str):
133
142
  if (data is None or data.empty):
@@ -142,8 +151,13 @@ class screenerStockDataFetcher(nseStockDataFetcher):
142
151
  recommendedPeriod = str(err).split("[")[1].split("]")[0].split(",")[-1].strip()
143
152
  recommendedPeriod = recommendedPeriod.replace("'","").replace("\"","")
144
153
  # default_logger().debug(f"Sending request again for {ticker} with period:{recommendedPeriod}")
145
- data = self.fetchStockData(stockCode=ticker,period=recommendedPeriod,duration=duration,printCounter=printCounter, start=start,end=end)
154
+ data = self.fetchStockData(stockCode=ticker,period=period,duration=duration,printCounter=printCounter, start=start,end=end,proxyServer=proxyServer,)
146
155
  return data
156
+ elif "YFRateLimitError" in err:
157
+ if attempt <= 2:
158
+ default_logger().debug(f"YFRateLimitError Hit! Going for attempt : {attempt+1}")
159
+ # sleep(attempt*1) # Exponential backoff
160
+ # return self.fetchStockData(stockCode=stockCode,period=period,duration=duration,printCounter=printCounter, start=start,end=end,screenResultsCounter=screenResultsCounter,screenCounter=screenCounter,totalSymbols=totalSymbols,exchangeSuffix=exchangeSuffix,attempt=attempt+1)
147
161
  else:
148
162
  multiIndex = data.keys()
149
163
  if isinstance(multiIndex, pd.MultiIndex):
@@ -151,9 +165,25 @@ class screenerStockDataFetcher(nseStockDataFetcher):
151
165
  # we'd have received a multiindex dataframe
152
166
  listStockCodes = multiIndex.get_level_values(0)
153
167
  data = data.get(listStockCodes[0])
168
+ else:
169
+ if (data is None or data.empty):
170
+ if len(shared._ERRORS) > 0:
171
+ default_logger().debug(shared._ERRORS)
172
+ for ticker in shared._ERRORS:
173
+ err = shared._ERRORS.get(ticker)
174
+ if "YFRateLimitError" in err:
175
+ if attempt <= 2:
176
+ default_logger().debug(f"YFRateLimitError Hit! Going for attempt : {attempt+1}")
177
+ # sleep(attempt*2) # Exponential backoff
178
+ # return self.fetchStockData(stockCode=stockCode,period=period,duration=duration,printCounter=printCounter, start=start,end=end,screenResultsCounter=screenResultsCounter,screenCounter=screenCounter,totalSymbols=totalSymbols,exchangeSuffix=exchangeSuffix,attempt=attempt+1)
154
179
  except (KeyError,YFPricesMissingError) as e: # pragma: no cover
155
180
  default_logger().debug(e,exc_info=True)
156
181
  pass
182
+ except YFRateLimitError as e:
183
+ if attempt <= 2:
184
+ default_logger().debug(f"YFRateLimitError Hit! Going for attempt : {attempt+1}")
185
+ # sleep(attempt*2) # Exponential backoff
186
+ # return self.fetchStockData(stockCode=stockCode,period=period,duration=duration,printCounter=printCounter, start=start,end=end,screenResultsCounter=screenResultsCounter,screenCounter=screenCounter,totalSymbols=totalSymbols,exchangeSuffix=exchangeSuffix,attempt=attempt+1)
157
187
  except (YFInvalidPeriodError,Exception) as e: # pragma: no cover
158
188
  default_logger().debug(e,exc_info=True)
159
189
  if printCounter and type(screenCounter) != int:
@@ -0,0 +1 @@
1
+ VERSION='0.46.20250220.727'
@@ -1887,7 +1887,11 @@ def main(userArgs=None,optionalFinalOutcome_df=None):
1887
1887
  pass
1888
1888
 
1889
1889
  loadCount = len(stockDictPrimary) if stockDictPrimary is not None else 0
1890
-
1890
+ # Let's use screening only for the stocks for which we could get the data.
1891
+ savedOrDownloadedKeys = list(stockDictPrimary.keys())
1892
+ missingStocks = set(listStockCodes) - set(savedOrDownloadedKeys)
1893
+ OutputControls().printOutput(f"{colorText.GREEN} [+] Adding {len(listStockCodes)-len(missingStocks)} stocks out of {len(listStockCodes)} to the queue...{colorText.END}")
1894
+ listStockCodes = (set(listStockCodes)-set(missingStocks)) if not downloadOnly else listStockCodes
1891
1895
  if downloadOnly:
1892
1896
  OutputControls().printOutput(
1893
1897
  colorText.WARN
@@ -37,7 +37,7 @@ tensorflow==2.16.1 # https://github.com/tensorflow/tensorflow/issues/62075
37
37
  urllib3 #>=1.26.20
38
38
  vectorbt #>=0.26.2
39
39
  xlsxwriter #>=3.2.0
40
- yfinance==0.2.28 #>=0.2.44 #==0.1.87
40
+ yfinance==0.2.54 #>=0.2.44 #==0.1.87
41
41
  # windows-curses; "windows" in sys.platform
42
42
  # https://github.com/pkjmesra/PKScreener/blob/main/.github/dependencies/TA_Lib-0.4.28-cp311-cp311-win_amd64.whl; "windows" in sys.platform
43
43
 
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: pkscreener
3
- Version: 0.46.20250219.725
3
+ Version: 0.46.20250220.727
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.20250219.725.zip
6
+ Download-URL: https://github.com/pkjmesra/pkscreener/archive/v0.46.20250220.727.zip
7
7
  Author: pkjmesra
8
8
  Author-email: pkjmesra@gmail.com
9
9
  License: OSI Approved (MIT)
@@ -357,15 +357,15 @@ After you have finished the run, go to that copied path, zip the contents of the
357
357
  [MADE-IN-INDIA-badge]: https://img.shields.io/badge/MADE%20WITH%20%E2%9D%A4%20IN-INDIA-orange
358
358
  [MADE-IN-INDIA]: https://en.wikipedia.org/wiki/India
359
359
  [Windows-badge]: https://img.shields.io/badge/Windows-0078D6?logo=windows&logoColor=white
360
- [Windows]: https://github.com/pkjmesra/PKScreener/releases/download/0.46.20250219.724/pkscreenercli.exe
360
+ [Windows]: https://github.com/pkjmesra/PKScreener/releases/download/0.46.20250220.726/pkscreenercli.exe
361
361
  [Linux-badge_x64]: https://img.shields.io/badge/Linux(x64)-FCC624?logo=linux&logoColor=black
362
- [Linux_x64]: https://github.com/pkjmesra/PKScreener/releases/download/0.46.20250219.724/pkscreenercli_x64.bin
362
+ [Linux_x64]: https://github.com/pkjmesra/PKScreener/releases/download/0.46.20250220.726/pkscreenercli_x64.bin
363
363
  [Linux-badge_arm64]: https://img.shields.io/badge/Linux(arm64)-FCC624?logo=linux&logoColor=black
364
- [Linux_arm64]: https://github.com/pkjmesra/PKScreener/releases/download/0.46.20250219.724/pkscreenercli_arm64.bin
364
+ [Linux_arm64]: https://github.com/pkjmesra/PKScreener/releases/download/0.46.20250220.726/pkscreenercli_arm64.bin
365
365
  [Mac OS-badge_x64]: https://img.shields.io/badge/mac%20os(x64)-D3D3D3?logo=apple&logoColor=000000
366
- [Mac OS_x64]: https://github.com/pkjmesra/PKScreener/releases/download/0.46.20250219.724/pkscreenercli_x64.run
366
+ [Mac OS_x64]: https://github.com/pkjmesra/PKScreener/releases/download/0.46.20250220.726/pkscreenercli_x64.run
367
367
  [Mac OS-badge_arm64]: https://img.shields.io/badge/mac%20os(arm64)-D3D3D3?logo=apple&logoColor=000000
368
- [Mac OS_arm64]: https://github.com/pkjmesra/PKScreener/releases/download/0.46.20250219.724/pkscreenercli_arm64.run
368
+ [Mac OS_arm64]: https://github.com/pkjmesra/PKScreener/releases/download/0.46.20250220.726/pkscreenercli_arm64.run
369
369
  [GitHub release (latest by date)-badge]: https://img.shields.io/github/v/release/pkjmesra/PKScreener
370
370
  [GitHub release (latest by date)]: https://github.com/pkjmesra/PKScreener/releases/latest
371
371
  [pypi-badge]: https://img.shields.io/pypi/v/pkscreener.svg?style=flat-square
@@ -0,0 +1,58 @@
1
+ pkscreener-0.46.20250220.727.data/purelib/pkscreener/Disclaimer.txt,sha256=x7M9Clrb9qACqOa-Vnwh9wliISLgudW5Kv_dgEk3N_Q,1405
2
+ pkscreener-0.46.20250220.727.data/purelib/pkscreener/LICENSE-Others.txt,sha256=0put8oIYbAYz98IGnp2F1CpHoyR_iyk0PRYG5D-U1K0,277059
3
+ pkscreener-0.46.20250220.727.data/purelib/pkscreener/LICENSE.txt,sha256=q80QYQZCkhPymkaQKXZJwOFYU6X-4lUHRzCGYERdLpA,1099
4
+ pkscreener-0.46.20250220.727.data/purelib/pkscreener/LogoWM.txt,sha256=7Njnavpy_FKY4Iwbzv1JqsYMcOdkDSKAKXP3SAItKV0,14868
5
+ pkscreener-0.46.20250220.727.data/purelib/pkscreener/README.txt,sha256=PRcj2d50LGoaa-vksyNfQ05i_rhbeTRztIqHPY7hs2g,33186
6
+ pkscreener-0.46.20250220.727.data/purelib/pkscreener/__init__.py,sha256=cH0zxpSdH-dhmZihoe5mpE2NRRmF2Na_KaGMO9u33Rg,1669
7
+ pkscreener-0.46.20250220.727.data/purelib/pkscreener/courbd.ttf,sha256=SKpnp-BRs7AZcdI83nencS3Q7xe0anbbP1YMOxLlEhU,791436
8
+ pkscreener-0.46.20250220.727.data/purelib/pkscreener/globals.py,sha256=jo1btmCeNSPyEUFcfMt2J4FTIadhMs2NmYR9LZRaHPw,245862
9
+ pkscreener-0.46.20250220.727.data/purelib/pkscreener/pkscreener.ini,sha256=v0MV7kLxi0ehh1a013wg6TLXDeeLRO8PKapICSU1u-k,2451
10
+ pkscreener-0.46.20250220.727.data/purelib/pkscreener/pkscreenerbot.py,sha256=bmsLcactP0eWNzqYdHzwPvDzCjFId03tJD57PVNDu2k,119496
11
+ pkscreener-0.46.20250220.727.data/purelib/pkscreener/pkscreenercli.py,sha256=j5UBHU1YdKhLaT53uFlpZ73lvI41Iw_gjA_wrZaF5IA,59048
12
+ pkscreener-0.46.20250220.727.data/purelib/pkscreener/requirements.txt,sha256=ClGQ7mX8LL87JUGHmgOv1mpTIoZi6ov52bDsO0-tIAk,1503
13
+ pkscreener-0.46.20250220.727.data/purelib/pkscreener/classes/ArtTexts.py,sha256=UzU0v3LX4PsWcx_ATv5M-T4v93uLz2hmvyDtew6qzZk,19708
14
+ pkscreener-0.46.20250220.727.data/purelib/pkscreener/classes/AssetsManager.py,sha256=T1RQVHR5mX6LxEXARYrs70iYEng7IsuU7oso308FsWw,36094
15
+ pkscreener-0.46.20250220.727.data/purelib/pkscreener/classes/Backtest.py,sha256=VoNronl--07E477I9lhwfEjI4vK5VHu_tcDRO1K96hU,10784
16
+ pkscreener-0.46.20250220.727.data/purelib/pkscreener/classes/Barometer.py,sha256=aZWu0TFbwRBvnkyN_Ws4a_2FYNhKKuqEpoQAqokthPc,9640
17
+ pkscreener-0.46.20250220.727.data/purelib/pkscreener/classes/BaseScreeningStatistics.py,sha256=Dev8eCx8eGNqDsbXj-t68hLSDpKDICcyb9yH_n_IbYg,3086
18
+ pkscreener-0.46.20250220.727.data/purelib/pkscreener/classes/CandlePatterns.py,sha256=IFVUXzx175aqZlL7JlmNl308aeIkSD6Hugl4M9zg9Io,17419
19
+ pkscreener-0.46.20250220.727.data/purelib/pkscreener/classes/Changelog.py,sha256=S0hNTDYptWUxFrdTzqinjFLIywVAuKlYR1aCjepADn0,1511
20
+ pkscreener-0.46.20250220.727.data/purelib/pkscreener/classes/ConfigManager.py,sha256=ZIxZ-IqWjIXpo_7SWRLx5e8sc0b92gGnc4qqMZVproM,54426
21
+ pkscreener-0.46.20250220.727.data/purelib/pkscreener/classes/ConsoleMenuUtility.py,sha256=QZLPA0li0bfs1zNijfq_utovulY5fl4vXWk89CBpL5Q,10291
22
+ pkscreener-0.46.20250220.727.data/purelib/pkscreener/classes/ConsoleUtility.py,sha256=gNMAm4iQF0ClmVPBe6ZnsjWQ-rfnTq6R_mLBjA6GgyI,12330
23
+ pkscreener-0.46.20250220.727.data/purelib/pkscreener/classes/Fetcher.py,sha256=UA37RjcegNmdqHIC5bWW_9qzKn8McyU6mhELxmKuLzs,15080
24
+ pkscreener-0.46.20250220.727.data/purelib/pkscreener/classes/GlobalStore.py,sha256=UCYctbau2ZAShkWOLA7-p52Pg_irghCWRoa6UrIKYQQ,3799
25
+ pkscreener-0.46.20250220.727.data/purelib/pkscreener/classes/ImageUtility.py,sha256=DKPiM7u-fGPujD63VLCWUsvesgflVYDiLqyw_KWOK8g,37629
26
+ pkscreener-0.46.20250220.727.data/purelib/pkscreener/classes/MarketMonitor.py,sha256=--qQpmLt7XTljACGDWIIOZO01uWJpEbG78wyMRynTI4,22450
27
+ pkscreener-0.46.20250220.727.data/purelib/pkscreener/classes/MarketStatus.py,sha256=oBDTCTGazzOEhcclugxOOtyhu2VVT2XQ-t-GmY_pT7g,3823
28
+ pkscreener-0.46.20250220.727.data/purelib/pkscreener/classes/MenuOptions.py,sha256=RIPQ9mVC9I07GZubrmOtUAQg10GbCoYwF3fnvV1dvqY,65741
29
+ pkscreener-0.46.20250220.727.data/purelib/pkscreener/classes/Messenger.py,sha256=yKqq3eE2JkvTOeKcNZoPpCgxQ9FjcEeB1iHIKwwq8dA,8572
30
+ pkscreener-0.46.20250220.727.data/purelib/pkscreener/classes/OtaUpdater.py,sha256=jSjVqgiZ4CGVkieJMekNLHZGx_eOGN-Xg4RF3eZO_Nk,13816
31
+ pkscreener-0.46.20250220.727.data/purelib/pkscreener/classes/PKAnalytics.py,sha256=4LdzjSjbJExBpD2DM9wXWuFqKiC8QEr9HT2XFiJq7oA,5368
32
+ pkscreener-0.46.20250220.727.data/purelib/pkscreener/classes/PKDataService.py,sha256=InEI3AGt_ykYfbwq2v1_NWUefTqPluKHSh_4ksFSUzE,3456
33
+ pkscreener-0.46.20250220.727.data/purelib/pkscreener/classes/PKDemoHandler.py,sha256=wh48WLLFxBAFHML5Sq5G5-UFP96snJ9yKJgpKWuQ2Zs,2253
34
+ pkscreener-0.46.20250220.727.data/purelib/pkscreener/classes/PKMarketOpenCloseAnalyser.py,sha256=zscdvHwDb5GQttqnR4Ed0SsVfOFeqKQgfIo6LWukgH0,34366
35
+ pkscreener-0.46.20250220.727.data/purelib/pkscreener/classes/PKPremiumHandler.py,sha256=L3O3EwIZBE9PpdDFIGH-2Ec9Gi3IlzCd6RfQSXUd6So,5695
36
+ pkscreener-0.46.20250220.727.data/purelib/pkscreener/classes/PKScanRunner.py,sha256=9Qy6xouK6qkNExeWF8LrxYXynI3Ju9UrSY5kI5W81Ok,27313
37
+ pkscreener-0.46.20250220.727.data/purelib/pkscreener/classes/PKScheduledTaskProgress.py,sha256=wDMORWmyglcu06woVNpgDlESsMIiYX96MXO0VoBlLYg,1694
38
+ pkscreener-0.46.20250220.727.data/purelib/pkscreener/classes/PKScheduler.py,sha256=Od3Niv6Q_aHarau9agCVt7h194votlaDX4j1Xv-_ru4,8994
39
+ pkscreener-0.46.20250220.727.data/purelib/pkscreener/classes/PKSpreadsheets.py,sha256=BIICJx79QjGFPrnmQ34357jOGp79vuiknx6A_kC9y8Y,8466
40
+ pkscreener-0.46.20250220.727.data/purelib/pkscreener/classes/PKTask.py,sha256=YPxzn0dA5ty7CtRFi1wQphC9vCdK8tB2_3DYHje9jgc,1907
41
+ pkscreener-0.46.20250220.727.data/purelib/pkscreener/classes/PKUserRegistration.py,sha256=q5V3GChPEFl4-je4VFJDGDT4GK37t3sBT0UY9GT6L8s,11657
42
+ pkscreener-0.46.20250220.727.data/purelib/pkscreener/classes/Pktalib.py,sha256=yko7TZMOsLoBv-LbTuT903CsGdyckhypXldh7uoAXmo,34179
43
+ pkscreener-0.46.20250220.727.data/purelib/pkscreener/classes/Portfolio.py,sha256=dxviO0G3OqJza4Nbpj5OCph8PZlfkRCkL3LfLJYgqu0,14196
44
+ pkscreener-0.46.20250220.727.data/purelib/pkscreener/classes/PortfolioXRay.py,sha256=cMQ-yZrBPWo4gACxFqj3HNG9rqmyqXkS88qpy77JP_s,49612
45
+ pkscreener-0.46.20250220.727.data/purelib/pkscreener/classes/ScreeningStatistics.py,sha256=CoV2i5jJPL2hm4sIhQAPHbbfWw3vqgoShVmq4uir7k4,225756
46
+ pkscreener-0.46.20250220.727.data/purelib/pkscreener/classes/StockScreener.py,sha256=wL6RjojBvTqo9XUlh2qoCpERrKdGNTlcDtCTReA0jkI,68437
47
+ pkscreener-0.46.20250220.727.data/purelib/pkscreener/classes/StockSentiment.py,sha256=kc5jdXRGm2nIvDK-2y4i_Y1w47_2zWpunjlQsKB7IBY,3640
48
+ pkscreener-0.46.20250220.727.data/purelib/pkscreener/classes/UserMenuChoicesHandler.py,sha256=MXJrQPD4yvKSI4p_RcnHt5oZg8AZ59ME7Jf-Nryoy5g,5055
49
+ pkscreener-0.46.20250220.727.data/purelib/pkscreener/classes/Utility.py,sha256=6JpIich2-knaZ4sjsjyMoO_4S622KK-Jte2Hi4eYIOs,13870
50
+ pkscreener-0.46.20250220.727.data/purelib/pkscreener/classes/WorkflowManager.py,sha256=GS1Q_jwulpOjZv0w9ZDySRa5w51gJ8xDabbUpQGKVO0,5800
51
+ pkscreener-0.46.20250220.727.data/purelib/pkscreener/classes/__init__.py,sha256=SKNJQJJ4Pnl5P7IKBorihRsBebKCpNqc1flnEVwOYpw,28
52
+ pkscreener-0.46.20250220.727.data/purelib/pkscreener/classes/keys.py,sha256=tygV0iu8bKmSPo6HGj1Cb-rTtEWErGrsYRZY7SoCb1g,6957
53
+ pkscreener-0.46.20250220.727.dist-info/LICENSE,sha256=q80QYQZCkhPymkaQKXZJwOFYU6X-4lUHRzCGYERdLpA,1099
54
+ pkscreener-0.46.20250220.727.dist-info/METADATA,sha256=Ypv4BcaL6t05diUW_1DTsgYTdBPR9_7eBd6vQxOSolE,34208
55
+ pkscreener-0.46.20250220.727.dist-info/WHEEL,sha256=cRmSBGD-cl98KkuHMNqv9Ac9L9_VqTvcBYwpIvxN0cg,101
56
+ pkscreener-0.46.20250220.727.dist-info/entry_points.txt,sha256=Pm30xm4sU7YFtFJUC-Te8VlqOvYAvWKFFA5AfQE0xGY,120
57
+ pkscreener-0.46.20250220.727.dist-info/top_level.txt,sha256=oIfcPPw58Q4KU-GDqp25dXbrtvxYXJBCo_em6i5aVvY,11
58
+ pkscreener-0.46.20250220.727.dist-info/RECORD,,
@@ -1 +0,0 @@
1
- VERSION='0.46.20250219.725'
@@ -1,58 +0,0 @@
1
- pkscreener-0.46.20250219.725.data/purelib/pkscreener/Disclaimer.txt,sha256=x7M9Clrb9qACqOa-Vnwh9wliISLgudW5Kv_dgEk3N_Q,1405
2
- pkscreener-0.46.20250219.725.data/purelib/pkscreener/LICENSE-Others.txt,sha256=0put8oIYbAYz98IGnp2F1CpHoyR_iyk0PRYG5D-U1K0,277059
3
- pkscreener-0.46.20250219.725.data/purelib/pkscreener/LICENSE.txt,sha256=q80QYQZCkhPymkaQKXZJwOFYU6X-4lUHRzCGYERdLpA,1099
4
- pkscreener-0.46.20250219.725.data/purelib/pkscreener/LogoWM.txt,sha256=7Njnavpy_FKY4Iwbzv1JqsYMcOdkDSKAKXP3SAItKV0,14868
5
- pkscreener-0.46.20250219.725.data/purelib/pkscreener/README.txt,sha256=0VodvVuC3amU68Q25WjXr-4SCK6Q0EcY9gCt3DyO73w,33186
6
- pkscreener-0.46.20250219.725.data/purelib/pkscreener/__init__.py,sha256=cH0zxpSdH-dhmZihoe5mpE2NRRmF2Na_KaGMO9u33Rg,1669
7
- pkscreener-0.46.20250219.725.data/purelib/pkscreener/courbd.ttf,sha256=SKpnp-BRs7AZcdI83nencS3Q7xe0anbbP1YMOxLlEhU,791436
8
- pkscreener-0.46.20250219.725.data/purelib/pkscreener/globals.py,sha256=IqYmQZf_m1cr-Yz9b1JDMUXDtIKJxAhOTyCiVPXsdT4,245356
9
- pkscreener-0.46.20250219.725.data/purelib/pkscreener/pkscreener.ini,sha256=v0MV7kLxi0ehh1a013wg6TLXDeeLRO8PKapICSU1u-k,2451
10
- pkscreener-0.46.20250219.725.data/purelib/pkscreener/pkscreenerbot.py,sha256=bmsLcactP0eWNzqYdHzwPvDzCjFId03tJD57PVNDu2k,119496
11
- pkscreener-0.46.20250219.725.data/purelib/pkscreener/pkscreenercli.py,sha256=j5UBHU1YdKhLaT53uFlpZ73lvI41Iw_gjA_wrZaF5IA,59048
12
- pkscreener-0.46.20250219.725.data/purelib/pkscreener/requirements.txt,sha256=IsiYZzO2RFIPoDOULBL5qJu7tq2sGdgKbpYt2L0xlBw,1503
13
- pkscreener-0.46.20250219.725.data/purelib/pkscreener/classes/ArtTexts.py,sha256=UzU0v3LX4PsWcx_ATv5M-T4v93uLz2hmvyDtew6qzZk,19708
14
- pkscreener-0.46.20250219.725.data/purelib/pkscreener/classes/AssetsManager.py,sha256=0__n99u7SD0KHmpnybm_msu35CAlv5W6WwtT5LrSkNc,34313
15
- pkscreener-0.46.20250219.725.data/purelib/pkscreener/classes/Backtest.py,sha256=VoNronl--07E477I9lhwfEjI4vK5VHu_tcDRO1K96hU,10784
16
- pkscreener-0.46.20250219.725.data/purelib/pkscreener/classes/Barometer.py,sha256=aZWu0TFbwRBvnkyN_Ws4a_2FYNhKKuqEpoQAqokthPc,9640
17
- pkscreener-0.46.20250219.725.data/purelib/pkscreener/classes/BaseScreeningStatistics.py,sha256=Dev8eCx8eGNqDsbXj-t68hLSDpKDICcyb9yH_n_IbYg,3086
18
- pkscreener-0.46.20250219.725.data/purelib/pkscreener/classes/CandlePatterns.py,sha256=IFVUXzx175aqZlL7JlmNl308aeIkSD6Hugl4M9zg9Io,17419
19
- pkscreener-0.46.20250219.725.data/purelib/pkscreener/classes/Changelog.py,sha256=S0hNTDYptWUxFrdTzqinjFLIywVAuKlYR1aCjepADn0,1511
20
- pkscreener-0.46.20250219.725.data/purelib/pkscreener/classes/ConfigManager.py,sha256=ZIxZ-IqWjIXpo_7SWRLx5e8sc0b92gGnc4qqMZVproM,54426
21
- pkscreener-0.46.20250219.725.data/purelib/pkscreener/classes/ConsoleMenuUtility.py,sha256=QZLPA0li0bfs1zNijfq_utovulY5fl4vXWk89CBpL5Q,10291
22
- pkscreener-0.46.20250219.725.data/purelib/pkscreener/classes/ConsoleUtility.py,sha256=gNMAm4iQF0ClmVPBe6ZnsjWQ-rfnTq6R_mLBjA6GgyI,12330
23
- pkscreener-0.46.20250219.725.data/purelib/pkscreener/classes/Fetcher.py,sha256=ZwU9iW0nbGAgM0mKZNjYgy9sm8jRSw9PvYmyhuY7Pos,12620
24
- pkscreener-0.46.20250219.725.data/purelib/pkscreener/classes/GlobalStore.py,sha256=UCYctbau2ZAShkWOLA7-p52Pg_irghCWRoa6UrIKYQQ,3799
25
- pkscreener-0.46.20250219.725.data/purelib/pkscreener/classes/ImageUtility.py,sha256=DKPiM7u-fGPujD63VLCWUsvesgflVYDiLqyw_KWOK8g,37629
26
- pkscreener-0.46.20250219.725.data/purelib/pkscreener/classes/MarketMonitor.py,sha256=--qQpmLt7XTljACGDWIIOZO01uWJpEbG78wyMRynTI4,22450
27
- pkscreener-0.46.20250219.725.data/purelib/pkscreener/classes/MarketStatus.py,sha256=oBDTCTGazzOEhcclugxOOtyhu2VVT2XQ-t-GmY_pT7g,3823
28
- pkscreener-0.46.20250219.725.data/purelib/pkscreener/classes/MenuOptions.py,sha256=RIPQ9mVC9I07GZubrmOtUAQg10GbCoYwF3fnvV1dvqY,65741
29
- pkscreener-0.46.20250219.725.data/purelib/pkscreener/classes/Messenger.py,sha256=yKqq3eE2JkvTOeKcNZoPpCgxQ9FjcEeB1iHIKwwq8dA,8572
30
- pkscreener-0.46.20250219.725.data/purelib/pkscreener/classes/OtaUpdater.py,sha256=jSjVqgiZ4CGVkieJMekNLHZGx_eOGN-Xg4RF3eZO_Nk,13816
31
- pkscreener-0.46.20250219.725.data/purelib/pkscreener/classes/PKAnalytics.py,sha256=4LdzjSjbJExBpD2DM9wXWuFqKiC8QEr9HT2XFiJq7oA,5368
32
- pkscreener-0.46.20250219.725.data/purelib/pkscreener/classes/PKDataService.py,sha256=InEI3AGt_ykYfbwq2v1_NWUefTqPluKHSh_4ksFSUzE,3456
33
- pkscreener-0.46.20250219.725.data/purelib/pkscreener/classes/PKDemoHandler.py,sha256=wh48WLLFxBAFHML5Sq5G5-UFP96snJ9yKJgpKWuQ2Zs,2253
34
- pkscreener-0.46.20250219.725.data/purelib/pkscreener/classes/PKMarketOpenCloseAnalyser.py,sha256=zscdvHwDb5GQttqnR4Ed0SsVfOFeqKQgfIo6LWukgH0,34366
35
- pkscreener-0.46.20250219.725.data/purelib/pkscreener/classes/PKPremiumHandler.py,sha256=L3O3EwIZBE9PpdDFIGH-2Ec9Gi3IlzCd6RfQSXUd6So,5695
36
- pkscreener-0.46.20250219.725.data/purelib/pkscreener/classes/PKScanRunner.py,sha256=9Qy6xouK6qkNExeWF8LrxYXynI3Ju9UrSY5kI5W81Ok,27313
37
- pkscreener-0.46.20250219.725.data/purelib/pkscreener/classes/PKScheduledTaskProgress.py,sha256=wDMORWmyglcu06woVNpgDlESsMIiYX96MXO0VoBlLYg,1694
38
- pkscreener-0.46.20250219.725.data/purelib/pkscreener/classes/PKScheduler.py,sha256=Od3Niv6Q_aHarau9agCVt7h194votlaDX4j1Xv-_ru4,8994
39
- pkscreener-0.46.20250219.725.data/purelib/pkscreener/classes/PKSpreadsheets.py,sha256=BIICJx79QjGFPrnmQ34357jOGp79vuiknx6A_kC9y8Y,8466
40
- pkscreener-0.46.20250219.725.data/purelib/pkscreener/classes/PKTask.py,sha256=YPxzn0dA5ty7CtRFi1wQphC9vCdK8tB2_3DYHje9jgc,1907
41
- pkscreener-0.46.20250219.725.data/purelib/pkscreener/classes/PKUserRegistration.py,sha256=q5V3GChPEFl4-je4VFJDGDT4GK37t3sBT0UY9GT6L8s,11657
42
- pkscreener-0.46.20250219.725.data/purelib/pkscreener/classes/Pktalib.py,sha256=yko7TZMOsLoBv-LbTuT903CsGdyckhypXldh7uoAXmo,34179
43
- pkscreener-0.46.20250219.725.data/purelib/pkscreener/classes/Portfolio.py,sha256=dxviO0G3OqJza4Nbpj5OCph8PZlfkRCkL3LfLJYgqu0,14196
44
- pkscreener-0.46.20250219.725.data/purelib/pkscreener/classes/PortfolioXRay.py,sha256=cMQ-yZrBPWo4gACxFqj3HNG9rqmyqXkS88qpy77JP_s,49612
45
- pkscreener-0.46.20250219.725.data/purelib/pkscreener/classes/ScreeningStatistics.py,sha256=CoV2i5jJPL2hm4sIhQAPHbbfWw3vqgoShVmq4uir7k4,225756
46
- pkscreener-0.46.20250219.725.data/purelib/pkscreener/classes/StockScreener.py,sha256=wL6RjojBvTqo9XUlh2qoCpERrKdGNTlcDtCTReA0jkI,68437
47
- pkscreener-0.46.20250219.725.data/purelib/pkscreener/classes/StockSentiment.py,sha256=kc5jdXRGm2nIvDK-2y4i_Y1w47_2zWpunjlQsKB7IBY,3640
48
- pkscreener-0.46.20250219.725.data/purelib/pkscreener/classes/UserMenuChoicesHandler.py,sha256=MXJrQPD4yvKSI4p_RcnHt5oZg8AZ59ME7Jf-Nryoy5g,5055
49
- pkscreener-0.46.20250219.725.data/purelib/pkscreener/classes/Utility.py,sha256=6JpIich2-knaZ4sjsjyMoO_4S622KK-Jte2Hi4eYIOs,13870
50
- pkscreener-0.46.20250219.725.data/purelib/pkscreener/classes/WorkflowManager.py,sha256=GS1Q_jwulpOjZv0w9ZDySRa5w51gJ8xDabbUpQGKVO0,5800
51
- pkscreener-0.46.20250219.725.data/purelib/pkscreener/classes/__init__.py,sha256=B0ZsHVbm8GKemKpXfcjGPXy3WKG--Yvpq_lYAExzgqY,28
52
- pkscreener-0.46.20250219.725.data/purelib/pkscreener/classes/keys.py,sha256=tygV0iu8bKmSPo6HGj1Cb-rTtEWErGrsYRZY7SoCb1g,6957
53
- pkscreener-0.46.20250219.725.dist-info/LICENSE,sha256=q80QYQZCkhPymkaQKXZJwOFYU6X-4lUHRzCGYERdLpA,1099
54
- pkscreener-0.46.20250219.725.dist-info/METADATA,sha256=VC7RpGheS-D0CJp0ORhrQyq45pV7nUEPsZBci6oUKgY,34208
55
- pkscreener-0.46.20250219.725.dist-info/WHEEL,sha256=cRmSBGD-cl98KkuHMNqv9Ac9L9_VqTvcBYwpIvxN0cg,101
56
- pkscreener-0.46.20250219.725.dist-info/entry_points.txt,sha256=Pm30xm4sU7YFtFJUC-Te8VlqOvYAvWKFFA5AfQE0xGY,120
57
- pkscreener-0.46.20250219.725.dist-info/top_level.txt,sha256=oIfcPPw58Q4KU-GDqp25dXbrtvxYXJBCo_em6i5aVvY,11
58
- pkscreener-0.46.20250219.725.dist-info/RECORD,,