Skip to content

Commit

Permalink
v1.38 - Nifty Prediction using AI model
Browse files Browse the repository at this point in the history
* Prediction Model Notebooks and FIles added
* Model downloader implemented
* Fetcher, Utility and UI updated
* Changelog updated
* Requirements and buildscript updated to fix talib/numpy version error
* TF model changed from pickle to keras loading
* Fixed ML Model downloading
* ML Models and scaler updated
* TF Warnings silenced
pranjal-joshi committed Sep 25, 2022

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
1 parent 7e83078 commit 41d8d9e
Showing 13 changed files with 979 additions and 13 deletions.
4 changes: 3 additions & 1 deletion .github/workflows/workflow-build-matrix.yml
Original file line number Diff line number Diff line change
@@ -58,6 +58,7 @@ jobs:
cd /home/runner/work/Screeni-py/Screeni-py/
python -m pip install --upgrade pip
pip install -r requirements.txt
pip install ta-lib==0.4.24
TEST_BUILD: |
/home/runner/work/Screeni-py/Screeni-py/dist/screenipy.bin --testbuild
exit $?
@@ -73,6 +74,7 @@ jobs:
brew install ta-lib
python -m pip install --upgrade pip
pip install -r requirements.txt
pip install ta-lib==0.4.24
TEST_BUILD: |
/Users/runner/work/Screeni-py/Screeni-py/dist/screenipy.run --testbuild
exit $?
@@ -140,4 +142,4 @@ jobs:
release_name: Screenipy - v${{ steps.get_version.outputs.VERSION }}
body: |
${{ steps.read_release.outputs.RELEASE_BODY }}
overwrite: true
overwrite: true
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -5,6 +5,7 @@ test/*.ini
__pycache__/
.vscode/
*.xlsx
*.pkl
stock*.pkl
results*.pkl
*.spec
.DS_Store
7 changes: 5 additions & 2 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
numpy==1.21.0 # Installed as dependency for yfinance, scipy, matplotlib, pandas
appdirs
cachecontrol
contextlib2
@@ -22,6 +23,9 @@ tabulate
yfinance
alive-progress==1.6.2
Pillow
scikit-learn==1.1.1
tensorflow==2.9.2
joblib
altgraph # Installed as dependency for pyinstaller
atomicwrites # Installed as dependency for pytest
attrs # Installed as dependency for pytest
@@ -36,7 +40,6 @@ iniconfig # Installed as dependency for pytest
lxml # Installed as dependency for yfinance
msgpack # Installed as dependency for cachecontrol
multitasking # Installed as dependency for yfinance
numpy==1.21.0 # Installed as dependency for yfinance, scipy, matplotlib, pandas
packaging # Installed as dependency for pytest
pandas==1.3.5 # Installed as dependency for yfinance
pefile # Installed as dependency for pyinstaller
@@ -53,4 +56,4 @@ setuptools # Installed as dependency for pyinstaller
six # Installed as dependency for cycler, nsetools, packaging, retrying, python-dateutil, html5lib
toml # Installed as dependency for pep517, pytest
urllib3 # Installed as dependency for requests
webencodings # Installed as dependency for html5lib
webencodings # Installed as dependency for html5lib
5 changes: 4 additions & 1 deletion src/classes/Changelog.py
Original file line number Diff line number Diff line change
@@ -7,7 +7,7 @@

from classes.ColorText import colorText

VERSION = "1.37"
VERSION = "1.38"

changelog = colorText.BOLD + '[ChangeLog]\n' + colorText.END + colorText.BLUE + '''
[1.00 - Beta]
@@ -174,5 +174,8 @@
[1.37]
1. New Chart Pattern -> Buy at Trendline : Try Option 7 > 5
[1.38]
1. Added AI based predictions for Nifty closing on next day : Select Index for Screening > N
--- END ---
''' + colorText.END
12 changes: 12 additions & 0 deletions src/classes/Fetcher.py
Original file line number Diff line number Diff line change
@@ -133,6 +133,18 @@ def fetchStockData(self, stockCode, period, duration, proxyServer, screenResults
colorText.END, end='\r', flush=True)
return data

# Get Daily Nifty 50 Index:
def fetchLatestNiftyDaily(self):
data = yf.download(
tickers="^NSEI",
period='1d',
interval='1d',
progress=False,
timeout=10
)
data = data.iloc[-1]
return data

# Load stockCodes from the watchlist.xlsx
def fetchWatchlist(self):
createTemplate = False
23 changes: 23 additions & 0 deletions src/classes/Screener.py
Original file line number Diff line number Diff line change
@@ -10,12 +10,16 @@
import numpy as np
import pandas as pd
import talib
import joblib
import keras
import classes.Utility as Utility
from sklearn.preprocessing import StandardScaler
from scipy.signal import argrelextrema
from scipy.stats import linregress
from classes.ColorText import colorText
from classes.SuppressOutput import SuppressOutput


# Exception for newly listed stocks with candle nos < daysToLookback
class StockDataNotAdequate(Exception):
pass
@@ -556,6 +560,25 @@ def validateVCP(self, data, screenDict, saveDict, stockName=None, window=3, perc
print(traceback.format_exc())
return False

def getNiftyPrediction(self, data, proxyServer):
import warnings
warnings.filterwarnings("ignore")
model, pkl = Utility.tools.getNiftyModel(proxyServer=proxyServer)
with SuppressOutput(suppress_stderr=True, suppress_stdout=True):
data = data[pkl['columns']]
data = pkl['scaler'].transform([data])
pred = model.predict(data)[0]
if pred > 0.5:
out = colorText.BOLD + colorText.FAIL + "BEARISH" + colorText.END + colorText.BOLD
sug = "Hold your Shorts!"
else:
out = colorText.BOLD + colorText.GREEN + "BULLISH" + colorText.END + colorText.BOLD
sug = "Stay Long!"
if not Utility.tools.isClosingHour():
print(colorText.BOLD + colorText.WARN + "Note: The AI prediction should be executed After 3 PM or Near to Closing time as the Prediction Accuracy is based on the Closing price!" + colorText.END)
print(colorText.BOLD + colorText.BLUE + "\n" + "[+] Nifty AI Prediction -> " + colorText.END + colorText.BOLD + "Market may Close {} next day! {}".format(out, sug) + colorText.END)
return pred

'''
# Find out trend for days to lookback
def validateVCP(data, screenDict, saveDict, daysToLookback=ConfigManager.daysToLookback, stockName=None):
58 changes: 58 additions & 0 deletions src/classes/Utility.py
Original file line number Diff line number Diff line change
@@ -5,13 +5,18 @@
* Description : Class for managing misc and utility methods
'''

from decimal import DivisionByZero
from genericpath import isfile
import os
import sys
import platform
import datetime
import pytz
import pickle
import requests
import time
import joblib
import keras
import pandas as pd
from alive_progress import alive_bar
from tabulate import tabulate
@@ -95,6 +100,12 @@ def isTradingTime():
closeTime = curr.replace(hour=15, minute=30)
return ((openTime <= curr <= closeTime) and (0 <= curr.weekday() <= 4))

def isClosingHour():
curr = datetime.datetime.now(pytz.timezone('Asia/Kolkata'))
openTime = curr.replace(hour=15, minute=00)
closeTime = curr.replace(hour=15, minute=30)
return ((openTime <= curr <= closeTime) and (0 <= curr.weekday() <= 4))

def saveStockData(stockDict, configManager, loadCount):
curr = datetime.datetime.now(pytz.timezone('Asia/Kolkata'))
openTime = curr.replace(hour=9, minute=15)
@@ -277,3 +288,50 @@ def getProgressbarStyle():
bar = 'classic2'
spinner = 'dots_recur'
return bar, spinner

def getNiftyModel(proxyServer=None):
files = ['nifty_model.h5', 'nifty_model.pkl']
urls = [
"https://raw.github.com/pranjal-joshi/Screeni-py/new-features/src/ml/nifty_model.h5",
"https://raw.github.com/pranjal-joshi/Screeni-py/new-features/src/ml/nifty_model.pkl"
]
if os.path.isfile(files[0]) and os.path.isfile(files[1]):
file_age = (time.time() - os.path.getmtime(files[0]))/604800
if file_age > 1:
download = True
os.remove(files[0])
os.remove(files[1])
else:
download = False
else:
download = True
if download:
for file_url in urls:
if proxyServer is not None:
resp = requests.get(file_url, stream=True, proxies={'https':proxyServer})
else:
resp = requests.get(file_url, stream=True)
if resp.status_code == 200:
print(colorText.BOLD + colorText.GREEN +
"[+] Downloading AI model for Nifty predictions, Please Wait.." + colorText.END)
try:
chunksize = 1024*1024*1
filesize = int(int(resp.headers.get('content-length'))/chunksize)
filesize = 1 if not filesize else filesize
bar, spinner = tools.getProgressbarStyle()
f = open(file_url.split('/')[-1], 'wb')
dl = 0
with alive_bar(filesize, bar=bar, spinner=spinner, manual=True) as progressbar:
for data in resp.iter_content(chunk_size=chunksize):
dl += 1
f.write(data)
progressbar(dl/filesize)
if dl >= filesize:
progressbar(1.0)
f.close()
except Exception as e:
print("[!] Download Error - " + str(e))
time.sleep(3)
model = keras.models.load_model(files[0])
pkl = joblib.load(files[1])
return model, pkl
Binary file added src/ml/best_model_0.7438acc.h5
Binary file not shown.
Loading

0 comments on commit 41d8d9e

Please sign in to comment.