pkscreener 0.46.20250810.756__cp312-cp312-win_amd64.whl → 0.46.20250908.766__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.20250810.756.data → pkscreener-0.46.20250908.766.data}/purelib/pkscreener/LICENSE-Others.txt +1 -1
  2. {pkscreener-0.46.20250810.756.data → pkscreener-0.46.20250908.766.data}/purelib/pkscreener/README.txt +6 -6
  3. {pkscreener-0.46.20250810.756.data → pkscreener-0.46.20250908.766.data}/purelib/pkscreener/__init__.py +2 -2
  4. {pkscreener-0.46.20250810.756.data → pkscreener-0.46.20250908.766.data}/purelib/pkscreener/classes/AssetsManager.py +13 -29
  5. {pkscreener-0.46.20250810.756.data → pkscreener-0.46.20250908.766.data}/purelib/pkscreener/classes/Backtest.py +5 -5
  6. {pkscreener-0.46.20250810.756.data → pkscreener-0.46.20250908.766.data}/purelib/pkscreener/classes/CandlePatterns.py +23 -23
  7. {pkscreener-0.46.20250810.756.data → pkscreener-0.46.20250908.766.data}/purelib/pkscreener/classes/ConfigManager.py +13 -1
  8. {pkscreener-0.46.20250810.756.data → pkscreener-0.46.20250908.766.data}/purelib/pkscreener/classes/ConsoleUtility.py +1 -1
  9. {pkscreener-0.46.20250810.756.data → pkscreener-0.46.20250908.766.data}/purelib/pkscreener/classes/Fetcher.py +26 -20
  10. {pkscreener-0.46.20250810.756.data → pkscreener-0.46.20250908.766.data}/purelib/pkscreener/classes/ImageUtility.py +1 -1
  11. {pkscreener-0.46.20250810.756.data → pkscreener-0.46.20250908.766.data}/purelib/pkscreener/classes/MarketMonitor.py +6 -6
  12. {pkscreener-0.46.20250810.756.data → pkscreener-0.46.20250908.766.data}/purelib/pkscreener/classes/MarketStatus.py +3 -2
  13. {pkscreener-0.46.20250810.756.data → pkscreener-0.46.20250908.766.data}/purelib/pkscreener/classes/PKMarketOpenCloseAnalyser.py +14 -14
  14. {pkscreener-0.46.20250810.756.data → pkscreener-0.46.20250908.766.data}/purelib/pkscreener/classes/PKScanRunner.py +2 -2
  15. {pkscreener-0.46.20250810.756.data → pkscreener-0.46.20250908.766.data}/purelib/pkscreener/classes/Pktalib.py +36 -36
  16. {pkscreener-0.46.20250810.756.data → pkscreener-0.46.20250908.766.data}/purelib/pkscreener/classes/PortfolioXRay.py +5 -5
  17. {pkscreener-0.46.20250810.756.data → pkscreener-0.46.20250908.766.data}/purelib/pkscreener/classes/ScreeningStatistics.py +457 -445
  18. {pkscreener-0.46.20250810.756.data → pkscreener-0.46.20250908.766.data}/purelib/pkscreener/classes/StockScreener.py +47 -34
  19. {pkscreener-0.46.20250810.756.data → pkscreener-0.46.20250908.766.data}/purelib/pkscreener/classes/Utility.py +4 -3
  20. pkscreener-0.46.20250908.766.data/purelib/pkscreener/classes/__init__.py +1 -0
  21. {pkscreener-0.46.20250810.756.data → pkscreener-0.46.20250908.766.data}/purelib/pkscreener/globals.py +25 -23
  22. {pkscreener-0.46.20250810.756.data → pkscreener-0.46.20250908.766.data}/purelib/pkscreener/pkscreenerbot.py +24 -21
  23. {pkscreener-0.46.20250810.756.data → pkscreener-0.46.20250908.766.data}/purelib/pkscreener/pkscreenercli.py +9 -9
  24. {pkscreener-0.46.20250810.756.data → pkscreener-0.46.20250908.766.data}/purelib/pkscreener/requirements.txt +3 -3
  25. {pkscreener-0.46.20250810.756.dist-info → pkscreener-0.46.20250908.766.dist-info}/METADATA +8 -8
  26. pkscreener-0.46.20250908.766.dist-info/RECORD +58 -0
  27. pkscreener-0.46.20250810.756.data/purelib/pkscreener/classes/__init__.py +0 -1
  28. pkscreener-0.46.20250810.756.dist-info/RECORD +0 -58
  29. {pkscreener-0.46.20250810.756.data → pkscreener-0.46.20250908.766.data}/purelib/pkscreener/Disclaimer.txt +0 -0
  30. {pkscreener-0.46.20250810.756.data → pkscreener-0.46.20250908.766.data}/purelib/pkscreener/LICENSE.txt +0 -0
  31. {pkscreener-0.46.20250810.756.data → pkscreener-0.46.20250908.766.data}/purelib/pkscreener/LogoWM.txt +0 -0
  32. {pkscreener-0.46.20250810.756.data → pkscreener-0.46.20250908.766.data}/purelib/pkscreener/classes/ArtTexts.py +0 -0
  33. {pkscreener-0.46.20250810.756.data → pkscreener-0.46.20250908.766.data}/purelib/pkscreener/classes/Barometer.py +0 -0
  34. {pkscreener-0.46.20250810.756.data → pkscreener-0.46.20250908.766.data}/purelib/pkscreener/classes/BaseScreeningStatistics.py +0 -0
  35. {pkscreener-0.46.20250810.756.data → pkscreener-0.46.20250908.766.data}/purelib/pkscreener/classes/Changelog.py +0 -0
  36. {pkscreener-0.46.20250810.756.data → pkscreener-0.46.20250908.766.data}/purelib/pkscreener/classes/ConsoleMenuUtility.py +0 -0
  37. {pkscreener-0.46.20250810.756.data → pkscreener-0.46.20250908.766.data}/purelib/pkscreener/classes/GlobalStore.py +0 -0
  38. {pkscreener-0.46.20250810.756.data → pkscreener-0.46.20250908.766.data}/purelib/pkscreener/classes/MenuOptions.py +0 -0
  39. {pkscreener-0.46.20250810.756.data → pkscreener-0.46.20250908.766.data}/purelib/pkscreener/classes/Messenger.py +0 -0
  40. {pkscreener-0.46.20250810.756.data → pkscreener-0.46.20250908.766.data}/purelib/pkscreener/classes/OtaUpdater.py +0 -0
  41. {pkscreener-0.46.20250810.756.data → pkscreener-0.46.20250908.766.data}/purelib/pkscreener/classes/PKAnalytics.py +0 -0
  42. {pkscreener-0.46.20250810.756.data → pkscreener-0.46.20250908.766.data}/purelib/pkscreener/classes/PKDataService.py +0 -0
  43. {pkscreener-0.46.20250810.756.data → pkscreener-0.46.20250908.766.data}/purelib/pkscreener/classes/PKDemoHandler.py +0 -0
  44. {pkscreener-0.46.20250810.756.data → pkscreener-0.46.20250908.766.data}/purelib/pkscreener/classes/PKPremiumHandler.py +0 -0
  45. {pkscreener-0.46.20250810.756.data → pkscreener-0.46.20250908.766.data}/purelib/pkscreener/classes/PKScheduledTaskProgress.py +0 -0
  46. {pkscreener-0.46.20250810.756.data → pkscreener-0.46.20250908.766.data}/purelib/pkscreener/classes/PKScheduler.py +0 -0
  47. {pkscreener-0.46.20250810.756.data → pkscreener-0.46.20250908.766.data}/purelib/pkscreener/classes/PKSpreadsheets.py +0 -0
  48. {pkscreener-0.46.20250810.756.data → pkscreener-0.46.20250908.766.data}/purelib/pkscreener/classes/PKTask.py +0 -0
  49. {pkscreener-0.46.20250810.756.data → pkscreener-0.46.20250908.766.data}/purelib/pkscreener/classes/PKUserRegistration.py +0 -0
  50. {pkscreener-0.46.20250810.756.data → pkscreener-0.46.20250908.766.data}/purelib/pkscreener/classes/Portfolio.py +0 -0
  51. {pkscreener-0.46.20250810.756.data → pkscreener-0.46.20250908.766.data}/purelib/pkscreener/classes/StockSentiment.py +0 -0
  52. {pkscreener-0.46.20250810.756.data → pkscreener-0.46.20250908.766.data}/purelib/pkscreener/classes/UserMenuChoicesHandler.py +0 -0
  53. {pkscreener-0.46.20250810.756.data → pkscreener-0.46.20250908.766.data}/purelib/pkscreener/classes/WorkflowManager.py +0 -0
  54. {pkscreener-0.46.20250810.756.data → pkscreener-0.46.20250908.766.data}/purelib/pkscreener/classes/keys.py +0 -0
  55. {pkscreener-0.46.20250810.756.data → pkscreener-0.46.20250908.766.data}/purelib/pkscreener/courbd.ttf +0 -0
  56. {pkscreener-0.46.20250810.756.data → pkscreener-0.46.20250908.766.data}/purelib/pkscreener/pkscreener.ini +0 -0
  57. {pkscreener-0.46.20250810.756.dist-info → pkscreener-0.46.20250908.766.dist-info}/WHEEL +0 -0
  58. {pkscreener-0.46.20250810.756.dist-info → pkscreener-0.46.20250908.766.dist-info}/entry_points.txt +0 -0
  59. {pkscreener-0.46.20250810.756.dist-info → pkscreener-0.46.20250908.766.dist-info}/licenses/LICENSE +0 -0
  60. {pkscreener-0.46.20250810.756.dist-info → pkscreener-0.46.20250908.766.dist-info}/top_level.txt +0 -0
@@ -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.20250730.755/pkscreenercli.exe
334
+ [Windows]: https://github.com/pkjmesra/PKScreener/releases/download/0.46.20250908.764/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.20250730.755/pkscreenercli_x64.bin
336
+ [Linux_x64]: https://github.com/pkjmesra/PKScreener/releases/download/0.46.20250908.764/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.20250730.755/pkscreenercli_arm64.bin
338
+ [Linux_arm64]: https://github.com/pkjmesra/PKScreener/releases/download/0.46.20250908.764/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.20250730.755/pkscreenercli_x64.run
340
+ [Mac OS_x64]: https://github.com/pkjmesra/PKScreener/releases/download/0.46.20250908.764/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.20250730.755/pkscreenercli_arm64.run
342
+ [Mac OS_arm64]: https://github.com/pkjmesra/PKScreener/releases/download/0.46.20250908.764/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=True)
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)
@@ -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,
@@ -31,23 +31,23 @@ from time import sleep
31
31
  warnings.simplefilter("ignore", DeprecationWarning)
32
32
  warnings.simplefilter("ignore", FutureWarning)
33
33
  import pandas as pd
34
- import yfinance as yf
35
- from yfinance import shared
34
+ # import yfinance as yf
35
+ # from yfinance import shared
36
36
  # from yfinance.const import USER_AGENTS
37
37
  from PKDevTools.classes.Utils import USER_AGENTS
38
38
  import random
39
- from yfinance.version import version as yfVersion
40
- if yfVersion == "0.2.28":
41
- from yfinance.data import TickerData as YfData
42
- class YFPricesMissingError(Exception):
43
- pass
44
- class YFInvalidPeriodError(Exception):
45
- pass
46
- class YFRateLimitError(Exception):
47
- pass
48
- else:
49
- from yfinance.data import YfData
50
- from yfinance.exceptions import YFPricesMissingError, YFInvalidPeriodError, YFRateLimitError
39
+ # from yfinance.version import version as yfVersion
40
+ # if yfVersion == "0.2.28":
41
+ # from yfinance.data import TickerData as YfData
42
+ # class YFPricesMissingError(Exception):
43
+ # pass
44
+ # class YFInvalidPeriodError(Exception):
45
+ # pass
46
+ # class YFRateLimitError(Exception):
47
+ # pass
48
+ # else:
49
+ # from yfinance.data import YfData
50
+ # from yfinance.exceptions import YFPricesMissingError, YFInvalidPeriodError, YFRateLimitError
51
51
  from concurrent.futures import ThreadPoolExecutor
52
52
  from PKDevTools.classes.PKDateUtilities import PKDateUtilities
53
53
  from PKDevTools.classes.ColorText import colorText
@@ -75,11 +75,11 @@ yf_limiter = Limiter(
75
75
  RequestRate(360*TRY_FACTOR, Duration.HOUR), # Max 360 requests per hour
76
76
  RequestRate(8000*TRY_FACTOR, Duration.DAY) # Max 8000 requests per day
77
77
  )
78
- yf_session = CachedLimiterSession(
79
- limiter=yf_limiter,
80
- bucket_class=MemoryQueueBucket,
81
- backend=SQLiteCache(db_path=os.path.join(Archiver.get_user_data_dir(),"yfinance.cache")),
82
- )
78
+ # yf_session = CachedLimiterSession(
79
+ # limiter=yf_limiter,
80
+ # bucket_class=MemoryQueueBucket,
81
+ # backend=SQLiteCache(db_path=os.path.join(Archiver.get_user_data_dir(),"yfinance.cache")),
82
+ # )
83
83
  class screenerStockDataFetcher(nseStockDataFetcher):
84
84
  _tickersInfoDict={}
85
85
  def fetchStockDataWithArgs(self, *args):
@@ -99,7 +99,7 @@ class screenerStockDataFetcher(nseStockDataFetcher):
99
99
  return result
100
100
 
101
101
  def get_stats(self,ticker):
102
- info = yf.Tickers(ticker).tickers[ticker].fast_info
102
+ info = None #yf.Tickers(ticker).tickers[ticker].fast_info
103
103
  screenerStockDataFetcher._tickersInfoDict[ticker] = {"marketCap":info.market_cap if info is not None else 0}
104
104
 
105
105
  def fetchAdditionalTickerInfo(self,ticker_list,exchangeSuffix=".NS"):
@@ -128,6 +128,7 @@ class screenerStockDataFetcher(nseStockDataFetcher):
128
128
  exchangeSuffix=".NS",
129
129
  attempt = 0
130
130
  ):
131
+ """
131
132
  if isinstance(stockCode,list):
132
133
  if len(exchangeSuffix) > 0:
133
134
  stockCode = [(f"{x}{exchangeSuffix}" if (not x.endswith(exchangeSuffix) and not x.startswith("^")) else x) for x in stockCode]
@@ -146,7 +147,9 @@ class screenerStockDataFetcher(nseStockDataFetcher):
146
147
  end = None
147
148
  # if duration == "1m" and period == "1d":
148
149
  # period = "5d" # Download 1m data for the last 5 days
150
+ """
149
151
  data = None
152
+ """
150
153
  with SuppressOutput(suppress_stdout=(not printCounter), suppress_stderr=(not printCounter)):
151
154
  try:
152
155
  if yfVersion == "0.2.28":
@@ -262,10 +265,12 @@ class screenerStockDataFetcher(nseStockDataFetcher):
262
265
  end="\r",
263
266
  flush=True,
264
267
  )
268
+ """
265
269
  return data
266
270
 
267
271
  # Get Daily Nifty 50 Index:
268
272
  def fetchLatestNiftyDaily(self, proxyServer=None):
273
+ return None
269
274
  data = yf.download(
270
275
  tickers="^NSEI",
271
276
  period="5d",
@@ -278,6 +283,7 @@ class screenerStockDataFetcher(nseStockDataFetcher):
278
283
 
279
284
  # Get Data for Five EMA strategy
280
285
  def fetchFiveEmaData(self, proxyServer=None):
286
+ return None
281
287
  nifty_sell = yf.download(
282
288
  tickers="^NSEI",
283
289
  period="5d",
@@ -545,7 +545,7 @@ class PKImageTools:
545
545
  legendText = "\n***1.Stock***: This is the NSE symbol/ticker for a company. Stocks that are NOT stage two, are coloured red.***2.Consol.***: It shows the price range in which stock is trading for the last 22 trading sessions(22 trading sessions per month)***3.Breakout(22Prds)***: The BO is Breakout level based on last 22 sessions. R is the resistance level (if available)."
546
546
  legendText = f"{legendText} An investor should consider both BO & R level to analyse entry / exits in their trading lessons. If the BO value is green, it means the stock has already broken out (is above BO level). If BO is in red, it means the stock is yet to break out.***4.LTP***: This is the last/latest trading/closing price of the given stock on a given date at NSE. The LTP in green/red means the"
547
547
  legendText = f"{legendText} stock price has increased / decreased since last trading session. (1.5%, 1.3%,1.8%) with LTP shows the stock price rose by 1.5%, 1.3% and 1.8% in the last 1, 2 and 3 trading sessions respectively.***5.%Chng***: This is the change(rise/fall in percentage) in closing/trading price from the previous trading session's closing price. Green means that price rose from the previous"
548
- legendText = f"{legendText} trading session. Red means it fell.***6.Volume***: This shows the relative volume in the most recent trading day /today with respect to last 20 trading periods moving average of Volume. For example, 8.5x would mean today's volume so far is 8.5 times the average volume traded in the last 20 trading sessions. Volume in green means that volume for the date so far has been at"
548
+ legendText = f"{legendText} trading session. Red means it fell.***6.volume***: This shows the relative volume in the most recent trading day /today with respect to last 20 trading periods moving average of Volume. For example, 8.5x would mean today's volume so far is 8.5 times the average volume traded in the last 20 trading sessions. Volume in green means that volume for the date so far has been at"
549
549
  legendText = f"{legendText} least 2.5 times more than the average volume of last 20 sessions. If the volume is in red, it means the given date's volume is less than 2.5 times the avg volume of the last 20 sessions.***7.MA-Signal***: It shows the price trend of the given stock by analyzing various 50-200 moving/exponential averages crossover strategies. Perform a Google search for the shown MA-Signals"
550
550
  legendText = f"{legendText} to learn about them more. If it is in green, the signal is bullish. Red means bearish.***8.RSI-or-RSI/i***: Relative Strength Index is a momentum index which describes 14-period relative strength at the given price. Generally, below 30 is considered oversold and above 80 is considered overbought. When RSI/i has value, say, 80/41, it means that the daily RSI value is 80 while"
551
551
  legendText = f"{legendText} the 1-minute intraday RSI is 41.***9.Trend(22Prds)***: This describes the average trendline computed based on the last 22 trading sessions. Their strength is displayed depending on the steepness of the trendlines. (Strong / Weak) Up / Down shows how high/low the demand is respectively. A Sideways trend is the horizontal price movement that occurs when the forces of supply"
@@ -145,7 +145,7 @@ class MarketMonitor(SingletonMixin, metaclass=SingletonType):
145
145
  if "RUNNER" in os.environ.keys():
146
146
  self.monitor_df.reset_index(inplace=True)
147
147
  with pd.option_context('mode.chained_assignment', None):
148
- self.monitor_df = self.monitor_df[["Stock", "LTP", "%Chng","52Wk-H","RSI/i" if "RSI/i" in self.monitor_df.columns else "RSI","Volume"]]
148
+ self.monitor_df = self.monitor_df[["Stock", "LTP", "%Chng","52Wk-H","RSI/i" if "RSI/i" in self.monitor_df.columns else "RSI","volume"]]
149
149
  # Import Utility here since Utility has dependency on PKScheduler which in turn has dependency on
150
150
  # multiprocessing, which behaves erratically if imported at the top.
151
151
  self.monitor_df.loc[:, "%Chng"] = self.monitor_df.loc[:, "%Chng"].astype(str).apply(
@@ -154,17 +154,17 @@ class MarketMonitor(SingletonMixin, metaclass=SingletonType):
154
154
  self.monitor_df.loc[:, "52Wk-H"] = self.monitor_df.loc[:, "52Wk-H"].astype(str).apply(
155
155
  lambda x: ImageUtility.PKImageTools.roundOff(x,0)
156
156
  )
157
- self.monitor_df.loc[:, "Volume"] = self.monitor_df.loc[:, "Volume"].astype(str).apply(
157
+ self.monitor_df.loc[:, "volume"] = self.monitor_df.loc[:, "volume"].astype(str).apply(
158
158
  lambda x: ImageUtility.PKImageTools.roundOff(x,0)
159
159
  )
160
- self.monitor_df.rename(columns={"%Chng": "Ch%","Volume":"Vol","52Wk-H":"52WkH", "RSI":"RSI/i"}, inplace=True)
160
+ self.monitor_df.rename(columns={"%Chng": "Ch%","volume":"Vol","52Wk-H":"52WkH", "RSI":"RSI/i"}, inplace=True)
161
161
  telegram_df = self.updateDataFrameForTelegramMode(telegram or "RUNNER" in os.environ.keys(), self.monitor_df)
162
162
  self.monitor_df.set_index("Stock",inplace=True)
163
163
 
164
164
  if not self.isPinnedSingleMonitorMode:
165
165
  screen_monitor_df.reset_index(inplace=True)
166
166
  with pd.option_context('mode.chained_assignment', None):
167
- 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)
167
+ 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)
168
168
  # Import Utility here since Utility has dependency on PKScheduler which in turn has dependency on
169
169
  # multiprocessing, which behaves erratically if imported at the top.
170
170
  screen_monitor_df.loc[:, "%Chng"] = screen_monitor_df.loc[:, "%Chng"].astype(str).apply(
@@ -173,10 +173,10 @@ class MarketMonitor(SingletonMixin, metaclass=SingletonType):
173
173
  screen_monitor_df.loc[:, "52Wk-H"] = screen_monitor_df.loc[:, "52Wk-H"].astype(str).apply(
174
174
  lambda x: ImageUtility.PKImageTools.roundOff(x,0)
175
175
  )
176
- screen_monitor_df.loc[:, "Volume"] = screen_monitor_df.loc[:, "Volume"].astype(str).apply(
176
+ screen_monitor_df.loc[:, "volume"] = screen_monitor_df.loc[:, "volume"].astype(str).apply(
177
177
  lambda x: ImageUtility.PKImageTools.roundOff(x,0)
178
178
  )
179
- screen_monitor_df.rename(columns={"%Chng": "Ch%","Volume":"Vol","52Wk-H":"52WkH", "RSI":"RSI/i"}, inplace=True)
179
+ screen_monitor_df.rename(columns={"%Chng": "Ch%","volume":"Vol","52Wk-H":"52WkH", "RSI":"RSI/i"}, inplace=True)
180
180
  telegram_df = self.updateDataFrameForTelegramMode(telegram or "RUNNER" in os.environ.keys(), screen_monitor_df)
181
181
 
182
182
  if monitorPosition is not None: