diff --git a/src/classes/Changelog.py b/src/classes/Changelog.py
index 4fc00db..0c667aa 100644
--- a/src/classes/Changelog.py
+++ b/src/classes/Changelog.py
@@ -7,7 +7,7 @@
from classes.ColorText import colorText
-VERSION = "2.18"
+VERSION = "2.19"
changelog = colorText.BOLD + '[ChangeLog]\n' + colorText.END + colorText.BLUE + '''
[1.00 - Beta]
@@ -281,4 +281,8 @@
[2.18]
1. Critical backtest bug fixed (dropna axis-1 removed from results)
2. Clear stock cached data button added
+
+[2.19]
+1. New Index (Group of Indices) `16 > Sectoral Indices` added
+
''' + colorText.END
diff --git a/src/classes/Fetcher.py b/src/classes/Fetcher.py
index 2a17647..a6891ad 100644
--- a/src/classes/Fetcher.py
+++ b/src/classes/Fetcher.py
@@ -36,6 +36,50 @@ def __init__(self, configManager):
self.configManager = configManager
pass
+ def getAllNiftyIndices(self) -> dict:
+ return {
+ "^NSEI": "NIFTY 50",
+ "^NSMIDCP": "NIFTY NEXT 50",
+ "^CNX100": "NIFTY 100",
+ "^CNX200": "NIFTY 200",
+ "^CNX500": "NIFTY 500",
+ "^NSEMDCP50": "NIFTY MIDCAP 50",
+ "NIFTY_MIDCAP_100.NS": "NIFTY MIDCAP 100",
+ "^CNXSC": "NIFTY SMALLCAP 100",
+ "^INDIAVIX": "INDIA VIX",
+ "NIFTYMIDCAP150.NS": "NIFTY MIDCAP 150",
+ "NIFTYSMLCAP50.NS": "NIFTY SMALLCAP 50",
+ "NIFTYSMLCAP250.NS": "NIFTY SMALLCAP 250",
+ "NIFTYMIDSML400.NS": "NIFTY MIDSMALLCAP 400",
+ "NIFTY500_MULTICAP.NS": "NIFTY500 MULTICAP 50:25:25",
+ "NIFTY_LARGEMID250.NS": "NIFTY LARGEMIDCAP 250",
+ "NIFTY_MID_SELECT.NS": "NIFTY MIDCAP SELECT",
+ "NIFTY_TOTAL_MKT.NS": "NIFTY TOTAL MARKET",
+ "NIFTY_MICROCAP250.NS": "NIFTY MICROCAP 250",
+ "^NSEBANK": "NIFTY BANK",
+ "^CNXAUTO": "NIFTY AUTO",
+ "NIFTY_FIN_SERVICE.NS": "NIFTY FINANCIAL SERVICES",
+ "^CNXFMCG": "NIFTY FMCG",
+ "^CNXIT": "NIFTY IT",
+ "^CNXMEDIA": "NIFTY MEDIA",
+ "^CNXMETAL": "NIFTY METAL",
+ "^CNXPHARMA": "NIFTY PHARMA",
+ "^CNXPSUBANK": "NIFTY PSU BANK",
+ "^CNXREALTY": "NIFTY REALTY",
+ "NIFTY_HEALTHCARE.NS": "NIFTY HEALTHCARE INDEX",
+ "NIFTY_CONSR_DURBL.NS": "NIFTY CONSUMER DURABLES",
+ "NIFTY_OIL_AND_GAS.NS": "NIFTY OIL & GAS",
+ "NIFTYALPHA50.NS": "NIFTY ALPHA 50",
+ "^CNXCMDT": "NIFTY COMMODITIES",
+ "NIFTY_CPSE.NS": "NIFTY CPSE",
+ "^CNXENERGY": "NIFTY ENERGY",
+ "^CNXINFRA": "NIFTY INFRASTRUCTURE",
+ "^CNXMNC": "NIFTY MNC",
+ "^CNXPSE": "NIFTY PSE",
+ "^CNXSERVICE": "NIFTY SERVICES SECTOR",
+ "NIFTY100_ESG.NS": "NIFTY100 ESG SECTOR LEADERS",
+ }
+
def _getBacktestDate(self, backtest):
try:
end = backtest + datetime.timedelta(days=1)
@@ -80,6 +124,8 @@ def fetchCodes(self, tickerOption,proxyServer=None):
return list(pd.read_csv(url)['SYMBOL'].values)
if tickerOption == 15:
return ["MMM", "ABT", "ABBV", "ABMD", "ACN", "ATVI", "ADBE", "AMD", "AAP", "AES", "AFL", "A", "APD", "AKAM", "ALK", "ALB", "ARE", "ALXN", "ALGN", "ALLE", "AGN", "ADS", "LNT", "ALL", "GOOGL", "GOOG", "MO", "AMZN", "AMCR", "AEE", "AAL", "AEP", "AXP", "AIG", "AMT", "AWK", "AMP", "ABC", "AME", "AMGN", "APH", "ADI", "ANSS", "ANTM", "AON", "AOS", "APA", "AIV", "AAPL", "AMAT", "APTV", "ADM", "ARNC", "ANET", "AJG", "AIZ", "ATO", "T", "ADSK", "ADP", "AZO", "AVB", "AVY", "BKR", "BLL", "BAC", "BK", "BAX", "BDX", "BRK.B", "BBY", "BIIB", "BLK", "BA", "BKNG", "BWA", "BXP", "BSX", "BMY", "AVGO", "BR", "BF.B", "CHRW", "COG", "CDNS", "CPB", "COF", "CPRI", "CAH", "KMX", "CCL", "CAT", "CBOE", "CBRE", "CDW", "CE", "CNC", "CNP", "CTL", "CERN", "CF", "SCHW", "CHTR", "CVX", "CMG", "CB", "CHD", "CI", "XEC", "CINF", "CTAS", "CSCO", "C", "CFG", "CTXS", "CLX", "CME", "CMS", "KO", "CTSH", "CL", "CMCSA", "CMA", "CAG", "CXO", "COP", "ED", "STZ", "COO", "CPRT", "GLW", "CTVA", "COST", "COTY", "CCI", "CSX", "CMI", "CVS", "DHI", "DHR", "DRI", "DVA", "DE", "DAL", "XRAY", "DVN", "FANG", "DLR", "DFS", "DISCA", "DISCK", "DISH", "DG", "DLTR", "D", "DOV", "DOW", "DTE", "DUK", "DRE", "DD", "DXC", "ETFC", "EMN", "ETN", "EBAY", "ECL", "EIX", "EW", "EA", "EMR", "ETR", "EOG", "EFX", "EQIX", "EQR", "ESS", "EL", "EVRG", "ES", "RE", "EXC", "EXPE", "EXPD", "EXR", "XOM", "FFIV", "FB", "FAST", "FRT", "FDX", "FIS", "FITB", "FE", "FRC", "FISV", "FLT", "FLIR", "FLS", "FMC", "F", "FTNT", "FTV", "FBHS", "FOXA", "FOX", "BEN", "FCX", "GPS", "GRMN", "IT", "GD", "GE", "GIS", "GM", "GPC", "GILD", "GL", "GPN", "GS", "GWW", "HRB", "HAL", "HBI", "HOG", "HIG", "HAS", "HCA", "PEAK", "HP", "HSIC", "HSY", "HES", "HPE", "HLT", "HFC", "HOLX", "HD", "HON", "HRL", "HST", "HPQ", "HUM", "HBAN", "HII", "IEX", "IDXX", "INFO", "ITW", "ILMN", "IR", "INTC", "ICE", "IBM", "INCY", "IP", "IPG", "IFF", "INTU", "ISRG", "IVZ", "IPGP", "IQV", "IRM", "JKHY", "J", "JBHT", "SJM", "JNJ", "JCI", "JPM", "JNPR", "KSU", "K", "KEY", "KEYS", "KMB", "KIM", "KMI", "KLAC", "KSS", "KHC", "KR", "LB", "LHX", "LH", "LRCX", "LW", "LVS", "LEG", "LDOS", "LEN", "LLY", "LNC", "LIN", "LYV", "LKQ", "LMT", "L", "LOW", "LYB", "MTB", "M", "MRO", "MPC", "MKTX", "MAR", "MMC", "MLM", "MAS", "MA", "MKC", "MXIM", "MCD", "MCK", "MDT", "MRK", "MET", "MTD", "MGM", "MCHP", "MU", "MSFT", "MAA", "MHK", "TAP", "MDLZ", "MNST", "MCO", "MS", "MOS", "MSI", "MSCI", "MYL", "NDAQ", "NOV", "NTAP", "NFLX", "NWL", "NEM", "NWSA", "NWS", "NEE", "NLSN", "NKE", "NI", "NBL", "JWN", "NSC", "NTRS", "NOC", "NLOK", "NCLH", "NRG", "NUE", "NVDA", "NVR", "ORLY", "OXY", "ODFL", "OMC", "OKE", "ORCL", "PCAR", "PKG", "PH", "PAYX", "PYPL", "PNR", "PBCT", "PEP", "PKI", "PRGO", "PFE", "PM", "PSX", "PNW", "PXD", "PNC", "PPG", "PPL", "PFG", "PG", "PGR", "PLD", "PRU", "PEG", "PSA", "PHM", "PVH", "QRVO", "PWR", "QCOM", "DGX", "RL", "RJF", "RTN", "O", "REG", "REGN", "RF", "RSG", "RMD", "RHI", "ROK", "ROL", "ROP", "ROST", "RCL", "SPGI", "CRM", "SBAC", "SLB", "STX", "SEE", "SRE", "NOW", "SHW", "SPG", "SWKS", "SLG", "SNA", "SO", "LUV", "SWK", "SBUX", "STT", "STE", "SYK", "SIVB", "SYF", "SNPS", "SYY", "TMUS", "TROW", "TTWO", "TPR", "TGT", "TEL", "FTI", "TFX", "TXN", "TXT", "TMO", "TIF", "TJX", "TSCO", "TDG", "TRV", "TFC", "TWTR", "TSN", "UDR", "ULTA", "USB", "UAA", "UA", "UNP", "UAL", "UNH", "UPS", "URI", "UTX", "UHS", "UNM", "VFC", "VLO", "VAR", "VTR", "VRSN", "VRSK", "VZ", "VRTX", "VIAC", "V", "VNO", "VMC", "WRB", "WAB", "WMT", "WBA", "DIS", "WM", "WAT", "WEC", "WCG", "WFC", "WELL", "WDC", "WU", "WRK", "WY", "WHR", "WMB", "WLTW", "WYNN", "XEL", "XRX", "XLNX", "XYL", "YUM", "ZBRA", "ZBH", "ZION", "ZTS"]
+ if tickerOption == 16:
+ return self.getAllNiftyIndices()
tickerMapping = {
1: "https://archives.nseindia.com/content/indices/ind_nifty50list.csv",
2: "https://archives.nseindia.com/content/indices/ind_niftynext50list.csv",
@@ -133,6 +179,8 @@ def fetchStockCodes(self, tickerOption, proxyServer=None):
print(colorText.BOLD +
"[+] Getting Stock Codes From NSE... ", end='')
listStockCodes = self.fetchCodes(tickerOption,proxyServer=proxyServer)
+ if type(listStockCodes) == dict:
+ listStockCodes = list(listStockCodes.keys())
if len(listStockCodes) > 10:
print(colorText.GREEN + ("=> Done! Fetched %d stock codes." %
len(listStockCodes)) + colorText.END)
@@ -162,7 +210,7 @@ def fetchStockData(self, stockCode, period, duration, proxyServer, screenResults
dateDict = None
with SuppressOutput(suppress_stdout=True, suppress_stderr=True):
append_exchange = ".NS"
- if tickerOption == 15:
+ if tickerOption == 15 or tickerOption == 16:
append_exchange = ""
data = yf.download(
tickers=stockCode + append_exchange,
diff --git a/src/classes/ParallelProcessing.py b/src/classes/ParallelProcessing.py
index 9ce8d7b..0d2f487 100644
--- a/src/classes/ParallelProcessing.py
+++ b/src/classes/ParallelProcessing.py
@@ -18,6 +18,7 @@
import classes.Fetcher as Fetcher
import classes.Screener as Screener
import classes.Utility as Utility
+from copy import deepcopy
from classes.CandlePatterns import CandlePatterns
from classes.ColorText import colorText
from classes.SuppressOutput import SuppressOutput
@@ -124,11 +125,18 @@ def screenStocks(self, tickerOption, executeOption, reversalOption, maLength, da
with self.screenCounter.get_lock():
self.screenCounter.value += 1
if not processedData.empty:
+ urlStock = None
+ if tickerOption == 16:
+ urlStock = deepcopy(stock).replace('^','').replace('.NS','')
+ stock = fetcher.getAllNiftyIndices()[stock]
+ stock = stock.replace('^','').replace('.NS','')
+ urlStock = stock.replace('&','_') if urlStock is None else urlStock.replace('&','_')
screeningDictionary['Stock'] = colorText.BOLD + \
- colorText.BLUE + f'\x1B]8;;https://in.tradingview.com/chart?symbol=NSE%3A{stock}\x1B\\{stock}\x1B]8;;\x1B\\' + colorText.END if tickerOption != 15 \
+ colorText.BLUE + f'\x1B]8;;https://in.tradingview.com/chart?symbol=NSE%3A{urlStock}\x1B\\{stock}\x1B]8;;\x1B\\' + colorText.END if tickerOption < 15 \
else colorText.BOLD + \
- colorText.BLUE + f'\x1B]8;;https://in.tradingview.com/chart?symbol={stock}\x1B\\{stock}\x1B]8;;\x1B\\' + colorText.END
+ colorText.BLUE + f'\x1B]8;;https://in.tradingview.com/chart?symbol={urlStock}\x1B\\{stock}\x1B]8;;\x1B\\' + colorText.END
saveDictionary['Stock'] = stock
+
consolidationValue = screener.validateConsolidation(
processedData, screeningDictionary, saveDictionary, percentage=configManager.consolidationPercentage)
isMaReversal = screener.validateMovingAverages(
diff --git a/src/release.md b/src/release.md
index b3ea26f..6e9a481 100644
--- a/src/release.md
+++ b/src/release.md
@@ -7,11 +7,11 @@ Screeni-py is now on **YouTube** for additional help! - Thank You for your suppo
⚠️ **Executable files (.exe, .bin and .run) are now DEPRECATED! Please Switch to Docker**
-1. **Backtesting Reports** Added for Screening Patterns to Develope and Test Strategies!
-2. **Position Size Calculator** tab added for Better and Quick Risk Management!
-3. **Lorentzian Classification** (by @jdehorty) added for enhanced accuracy for your trades - - Try `Option > 6 > 7` 🤯
-4. **Artificial Intelligence v3 for Nifty 50 Prediction** - Predict Next day Gap-up/down using Nifty, Gold and Crude prices! - Try `Select Index for Screening > N`
-5. **US S&P 500** Index added for scanning US markets.
+1. **NSE Indices** added to find Sectoral opportunities - Try Index `16 > Sectoral Indices`
+2. **Backtesting Reports** Added for Screening Patterns to Develope and Test Strategies!
+3. **Position Size Calculator** tab added for Better and Quick Risk Management!
+4. **Lorentzian Classification** (invented by Justin Dehorty) added for enhanced accuracy for your trades - - Try `Option > 6 > 7` 🤯
+5. **Artificial Intelligence v3 for Nifty 50 Prediction** - Predict Next day Gap-up/down using Nifty, Gold and Crude prices! - Try `Select Index for Screening > N`
6. **Search Similar Stocks** Added using Vector Similarity search - Try `Search Similar Stocks`.
7. New Screener **Buy at Trendline** added for Swing/Mid/Long term traders - Try `Option > 7 > 5`.
diff --git a/src/screenipy.py b/src/screenipy.py
index 61a161b..a7f02c9 100644
--- a/src/screenipy.py
+++ b/src/screenipy.py
@@ -98,7 +98,7 @@ def initExecution():
4 > Nifty 200 5 > Nifty 500 6 > Nifty Smallcap 50
7 > Nifty Smallcap 100 8 > Nifty Smallcap 250 9 > Nifty Midcap 50
10 > Nifty Midcap 100 11 > Nifty Midcap 150 13 > Newly Listed (IPOs in last 2 Year)
- 14 > F&O Stocks Only 15 > US S&P 500
+ 14 > F&O Stocks Only 15 > US S&P 500 16 > Sectoral Indices (NSE)
Enter > All Stocks (default) ''' + colorText.END
)
try:
@@ -112,7 +112,7 @@ def initExecution():
tickerOption = tickerOption.upper()
else:
tickerOption = int(tickerOption)
- if(tickerOption < 0 or tickerOption > 15):
+ if(tickerOption < 0 or tickerOption > 16):
raise ValueError
elif tickerOption == 13:
newlyListedOnly = True
@@ -292,8 +292,7 @@ def main(testing=False, testBuild=False, downloadOnly=False, execute_inputs:list
"[+] Press any key to Exit!" + colorText.END)
sys.exit(0)
- print(tickerOption)
- if tickerOption == 'W' or tickerOption == 'N' or tickerOption == 'E' or tickerOption == 'S' or (tickerOption >= 0 and tickerOption < 16):
+ if tickerOption == 'W' or tickerOption == 'N' or tickerOption == 'E' or tickerOption == 'S' or (tickerOption >= 0 and tickerOption < 17):
configManager.getConfig(ConfigManager.parser)
try:
if tickerOption == 'W':
diff --git a/src/streamlit_app.py b/src/streamlit_app.py
index d244688..ea52b9b 100644
--- a/src/streamlit_app.py
+++ b/src/streamlit_app.py
@@ -13,6 +13,7 @@
from math import floor
import classes.ConfigManager as ConfigManager
import classes.Utility as Utility
+import classes.Fetcher as Fetcher
st.set_page_config(layout="wide", page_title="Screeni-py", page_icon="📈")
@@ -62,9 +63,19 @@ def show_df_as_result_table():
type='secondary',
use_container_width=True
)
- if execute_inputs[0] != '15':
+ if int(execute_inputs[0]) < 15:
df.index = df.index.map(lambda x: "https://in.tradingview.com/chart?symbol=NSE%3A" + x)
df.index = df.index.map(lambda x: f'{x.split("%3A")[-1]}')
+ elif execute_inputs[0] == '16':
+ try:
+ fetcher = Fetcher.tools(configManager=ConfigManager.tools())
+ url_dict_reversed = {key.replace('^','').replace('.NS',''): value for key, value in fetcher.getAllNiftyIndices().items()}
+ url_dict_reversed = {v: k for k, v in url_dict_reversed.items()}
+ df.index = df.index.map(lambda x: "https://in.tradingview.com/chart?symbol=NSE%3A" + url_dict_reversed[x])
+ url_dict_reversed = {v: k for k, v in url_dict_reversed.items()}
+ df.index = df.index.map(lambda x: f'{url_dict_reversed[x.split("%3A")[-1]]}')
+ except KeyError:
+ pass
else:
df.index = df.index.map(lambda x: "https://in.tradingview.com/chart?symbol=" + x)
df.index = df.index.map(lambda x: f'{x.split("=")[-1]}')
@@ -310,7 +321,8 @@ def get_extra_inputs(tickerOption, executeOption, c_index=None, c_criteria=None,
'11 > Nifty Midcap 150',
'13 > Newly Listed (IPOs in last 2 Year)',
'14 > F&O Stocks Only',
- '15 > US S&P 500'
+ '15 > US S&P 500',
+ '16 > Sectoral Indices (NSE)'
]
list_criteria = [