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.
- {pkscreener-0.46.20250810.756.data → pkscreener-0.46.20250908.766.data}/purelib/pkscreener/LICENSE-Others.txt +1 -1
- {pkscreener-0.46.20250810.756.data → pkscreener-0.46.20250908.766.data}/purelib/pkscreener/README.txt +6 -6
- {pkscreener-0.46.20250810.756.data → pkscreener-0.46.20250908.766.data}/purelib/pkscreener/__init__.py +2 -2
- {pkscreener-0.46.20250810.756.data → pkscreener-0.46.20250908.766.data}/purelib/pkscreener/classes/AssetsManager.py +13 -29
- {pkscreener-0.46.20250810.756.data → pkscreener-0.46.20250908.766.data}/purelib/pkscreener/classes/Backtest.py +5 -5
- {pkscreener-0.46.20250810.756.data → pkscreener-0.46.20250908.766.data}/purelib/pkscreener/classes/CandlePatterns.py +23 -23
- {pkscreener-0.46.20250810.756.data → pkscreener-0.46.20250908.766.data}/purelib/pkscreener/classes/ConfigManager.py +13 -1
- {pkscreener-0.46.20250810.756.data → pkscreener-0.46.20250908.766.data}/purelib/pkscreener/classes/ConsoleUtility.py +1 -1
- {pkscreener-0.46.20250810.756.data → pkscreener-0.46.20250908.766.data}/purelib/pkscreener/classes/Fetcher.py +26 -20
- {pkscreener-0.46.20250810.756.data → pkscreener-0.46.20250908.766.data}/purelib/pkscreener/classes/ImageUtility.py +1 -1
- {pkscreener-0.46.20250810.756.data → pkscreener-0.46.20250908.766.data}/purelib/pkscreener/classes/MarketMonitor.py +6 -6
- {pkscreener-0.46.20250810.756.data → pkscreener-0.46.20250908.766.data}/purelib/pkscreener/classes/MarketStatus.py +3 -2
- {pkscreener-0.46.20250810.756.data → pkscreener-0.46.20250908.766.data}/purelib/pkscreener/classes/PKMarketOpenCloseAnalyser.py +14 -14
- {pkscreener-0.46.20250810.756.data → pkscreener-0.46.20250908.766.data}/purelib/pkscreener/classes/PKScanRunner.py +2 -2
- {pkscreener-0.46.20250810.756.data → pkscreener-0.46.20250908.766.data}/purelib/pkscreener/classes/Pktalib.py +36 -36
- {pkscreener-0.46.20250810.756.data → pkscreener-0.46.20250908.766.data}/purelib/pkscreener/classes/PortfolioXRay.py +5 -5
- {pkscreener-0.46.20250810.756.data → pkscreener-0.46.20250908.766.data}/purelib/pkscreener/classes/ScreeningStatistics.py +457 -445
- {pkscreener-0.46.20250810.756.data → pkscreener-0.46.20250908.766.data}/purelib/pkscreener/classes/StockScreener.py +47 -34
- {pkscreener-0.46.20250810.756.data → pkscreener-0.46.20250908.766.data}/purelib/pkscreener/classes/Utility.py +4 -3
- pkscreener-0.46.20250908.766.data/purelib/pkscreener/classes/__init__.py +1 -0
- {pkscreener-0.46.20250810.756.data → pkscreener-0.46.20250908.766.data}/purelib/pkscreener/globals.py +25 -23
- {pkscreener-0.46.20250810.756.data → pkscreener-0.46.20250908.766.data}/purelib/pkscreener/pkscreenerbot.py +24 -21
- {pkscreener-0.46.20250810.756.data → pkscreener-0.46.20250908.766.data}/purelib/pkscreener/pkscreenercli.py +9 -9
- {pkscreener-0.46.20250810.756.data → pkscreener-0.46.20250908.766.data}/purelib/pkscreener/requirements.txt +3 -3
- {pkscreener-0.46.20250810.756.dist-info → pkscreener-0.46.20250908.766.dist-info}/METADATA +8 -8
- pkscreener-0.46.20250908.766.dist-info/RECORD +58 -0
- pkscreener-0.46.20250810.756.data/purelib/pkscreener/classes/__init__.py +0 -1
- pkscreener-0.46.20250810.756.dist-info/RECORD +0 -58
- {pkscreener-0.46.20250810.756.data → pkscreener-0.46.20250908.766.data}/purelib/pkscreener/Disclaimer.txt +0 -0
- {pkscreener-0.46.20250810.756.data → pkscreener-0.46.20250908.766.data}/purelib/pkscreener/LICENSE.txt +0 -0
- {pkscreener-0.46.20250810.756.data → pkscreener-0.46.20250908.766.data}/purelib/pkscreener/LogoWM.txt +0 -0
- {pkscreener-0.46.20250810.756.data → pkscreener-0.46.20250908.766.data}/purelib/pkscreener/classes/ArtTexts.py +0 -0
- {pkscreener-0.46.20250810.756.data → pkscreener-0.46.20250908.766.data}/purelib/pkscreener/classes/Barometer.py +0 -0
- {pkscreener-0.46.20250810.756.data → pkscreener-0.46.20250908.766.data}/purelib/pkscreener/classes/BaseScreeningStatistics.py +0 -0
- {pkscreener-0.46.20250810.756.data → pkscreener-0.46.20250908.766.data}/purelib/pkscreener/classes/Changelog.py +0 -0
- {pkscreener-0.46.20250810.756.data → pkscreener-0.46.20250908.766.data}/purelib/pkscreener/classes/ConsoleMenuUtility.py +0 -0
- {pkscreener-0.46.20250810.756.data → pkscreener-0.46.20250908.766.data}/purelib/pkscreener/classes/GlobalStore.py +0 -0
- {pkscreener-0.46.20250810.756.data → pkscreener-0.46.20250908.766.data}/purelib/pkscreener/classes/MenuOptions.py +0 -0
- {pkscreener-0.46.20250810.756.data → pkscreener-0.46.20250908.766.data}/purelib/pkscreener/classes/Messenger.py +0 -0
- {pkscreener-0.46.20250810.756.data → pkscreener-0.46.20250908.766.data}/purelib/pkscreener/classes/OtaUpdater.py +0 -0
- {pkscreener-0.46.20250810.756.data → pkscreener-0.46.20250908.766.data}/purelib/pkscreener/classes/PKAnalytics.py +0 -0
- {pkscreener-0.46.20250810.756.data → pkscreener-0.46.20250908.766.data}/purelib/pkscreener/classes/PKDataService.py +0 -0
- {pkscreener-0.46.20250810.756.data → pkscreener-0.46.20250908.766.data}/purelib/pkscreener/classes/PKDemoHandler.py +0 -0
- {pkscreener-0.46.20250810.756.data → pkscreener-0.46.20250908.766.data}/purelib/pkscreener/classes/PKPremiumHandler.py +0 -0
- {pkscreener-0.46.20250810.756.data → pkscreener-0.46.20250908.766.data}/purelib/pkscreener/classes/PKScheduledTaskProgress.py +0 -0
- {pkscreener-0.46.20250810.756.data → pkscreener-0.46.20250908.766.data}/purelib/pkscreener/classes/PKScheduler.py +0 -0
- {pkscreener-0.46.20250810.756.data → pkscreener-0.46.20250908.766.data}/purelib/pkscreener/classes/PKSpreadsheets.py +0 -0
- {pkscreener-0.46.20250810.756.data → pkscreener-0.46.20250908.766.data}/purelib/pkscreener/classes/PKTask.py +0 -0
- {pkscreener-0.46.20250810.756.data → pkscreener-0.46.20250908.766.data}/purelib/pkscreener/classes/PKUserRegistration.py +0 -0
- {pkscreener-0.46.20250810.756.data → pkscreener-0.46.20250908.766.data}/purelib/pkscreener/classes/Portfolio.py +0 -0
- {pkscreener-0.46.20250810.756.data → pkscreener-0.46.20250908.766.data}/purelib/pkscreener/classes/StockSentiment.py +0 -0
- {pkscreener-0.46.20250810.756.data → pkscreener-0.46.20250908.766.data}/purelib/pkscreener/classes/UserMenuChoicesHandler.py +0 -0
- {pkscreener-0.46.20250810.756.data → pkscreener-0.46.20250908.766.data}/purelib/pkscreener/classes/WorkflowManager.py +0 -0
- {pkscreener-0.46.20250810.756.data → pkscreener-0.46.20250908.766.data}/purelib/pkscreener/classes/keys.py +0 -0
- {pkscreener-0.46.20250810.756.data → pkscreener-0.46.20250908.766.data}/purelib/pkscreener/courbd.ttf +0 -0
- {pkscreener-0.46.20250810.756.data → pkscreener-0.46.20250908.766.data}/purelib/pkscreener/pkscreener.ini +0 -0
- {pkscreener-0.46.20250810.756.dist-info → pkscreener-0.46.20250908.766.dist-info}/WHEEL +0 -0
- {pkscreener-0.46.20250810.756.dist-info → pkscreener-0.46.20250908.766.dist-info}/entry_points.txt +0 -0
- {pkscreener-0.46.20250810.756.dist-info → pkscreener-0.46.20250908.766.dist-info}/licenses/LICENSE +0 -0
- {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 `
|
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.
|
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.
|
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.
|
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.
|
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.
|
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
|
-
"
|
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
|
-
|
191
|
-
|
192
|
-
|
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 >
|
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',
|
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
|
-
"
|
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
|
-
"
|
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["
|
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["
|
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
|
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["
|
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["
|
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["
|
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["
|
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["
|
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["
|
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["
|
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["
|
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["
|
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["
|
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["
|
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["
|
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["
|
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["
|
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["
|
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["
|
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["
|
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["
|
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["
|
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["
|
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["
|
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["
|
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=["
|
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
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
else:
|
49
|
-
|
50
|
-
|
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
|
-
|
80
|
-
|
81
|
-
|
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.
|
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","
|
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[:, "
|
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%","
|
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","
|
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[:, "
|
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%","
|
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:
|