Skip to content

Commit

Permalink
Merge pull request #3 from pranjal-joshi/CandlePatterns
Browse files Browse the repository at this point in the history
Candlestick Pattern Recognition - Feature Added - PR Merged.
  • Loading branch information
pranjal-joshi authored Apr 19, 2021
2 parents f1091c3 + e415fd8 commit e870464
Show file tree
Hide file tree
Showing 3 changed files with 124 additions and 17 deletions.
95 changes: 95 additions & 0 deletions CandlePatterns.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
'''
* Project : Screenipy
* Author : Pranjal Joshi
* Created : 11/04/2021
* Description : Class for analyzing candle-stick patterns
'''

import pandas as pd
import talib
from ColorText import colorText

class CandlePatterns:
def __init__(self):
pass

# Find candle-stick patterns
# Arrange if statements with max priority from top to bottom
def findPattern(self, data, dict, saveDict):
data = data.head(4)
data = data[::-1]

check = talib.CDLMORNINGSTAR(data['Open'], data['High'], data['Low'], data['Close'])
if(check.tail(1).item() != 0):
dict['Pattern'] = colorText.BOLD + colorText.GREEN + 'Morning Star' + colorText.END
saveDict['Pattern'] = 'Morning Star'
return True

check = talib.CDLEVENINGSTAR(data['Open'], data['High'], data['Low'], data['Close'])
if(check.tail(1).item() != 0):
dict['Pattern'] = colorText.BOLD + colorText.FAIL + 'Evening Star' + colorText.END
saveDict['Pattern'] = 'Evening Star'
return True

check = talib.CDL3LINESTRIKE(data['Open'], data['High'], data['Low'], data['Close'])
if(check.tail(1).item() != 0):
if(check.tail(1).item() > 0):
dict['Pattern'] = colorText.BOLD + colorText.GREEN + '3 Line Strike' + colorText.END
else:
dict['Pattern'] = colorText.BOLD + colorText.FAIL + '3 Line Strike' + colorText.END
saveDict['Pattern'] = '3 Line Strike'
return True

check = talib.CDL3BLACKCROWS(data['Open'], data['High'], data['Low'], data['Close'])
if(check.tail(1).item() != 0):
dict['Pattern'] = colorText.BOLD + colorText.FAIL + '3 Black Crows' + colorText.END
saveDict['Pattern'] = '3 Black Crows'
return True

check = talib.CDL3OUTSIDE(data['Open'], data['High'], data['Low'], data['Close'])
if(check.tail(1).item() != 0):
if(check.tail(1).item() > 0):
dict['Pattern'] = colorText.BOLD + colorText.GREEN + '3 Outside Up' + colorText.END
saveDict['Pattern'] = '3 Outside Up'
else:
dict['Pattern'] = colorText.BOLD + colorText.FAIL + '3 Outside Down' + colorText.END
saveDict['Pattern'] = '3 Outside Down'
return True

check = talib.CDL3WHITESOLDIERS(data['Open'], data['High'], data['Low'], data['Close'])
if(check.tail(1).item() != 0):
dict['Pattern'] = colorText.BOLD + colorText.GREEN + '3 White Soldiers' + colorText.END
saveDict['Pattern'] = '3 White Soldiers'
return True

check = talib.CDLENGULFING(data['Open'], data['High'], data['Low'], data['Close'])
if(check.tail(1).item() != 0):
if(check.tail(1).item() > 0):
dict['Pattern'] = colorText.BOLD + colorText.GREEN + 'Bullish Engulfing' + colorText.END
saveDict['Pattern'] = 'Bullish Engulfing'
else:
dict['Pattern'] = colorText.BOLD + colorText.FAIL + 'Bearish Engulfing' + colorText.END
saveDict['Pattern'] = 'Bearish Engulfing'
return True

check = talib.CDLHAMMER(data['Open'], data['High'], data['Low'], data['Close'])
if(check.tail(1).item() != 0):
dict['Pattern'] = colorText.BOLD + colorText.GREEN + 'Hammer' + colorText.END
saveDict['Pattern'] = 'Hammer'
return True

check = talib.CDLINVERTEDHAMMER(data['Open'], data['High'], data['Low'], data['Close'])
if(check.tail(1).item() != 0):
dict['Pattern'] = colorText.BOLD + colorText.FAIL + 'Inverted Hammer' + colorText.END
saveDict['Pattern'] = 'Inverted Hammer'
return True


check = talib.CDLDOJI(data['Open'], data['High'], data['Low'], data['Close'])
if(check.tail(1).item() != 0):
dict['Pattern'] = colorText.BOLD + 'Doji' + colorText.END
saveDict['Pattern'] = 'Doji'
return True
dict['Pattern'] = ''
saveDict['Pattern'] = ''
return False
17 changes: 17 additions & 0 deletions ColorText.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
'''
* Project : Screenipy
* Author : Pranjal Joshi
* Created : 11/04/2021
* Description : Class for terminal text decoration
'''

# Decoration Class
class colorText:
HEAD = '\033[95m'
BLUE = '\033[94m'
GREEN = '\033[92m'
WARN = '\033[93m'
FAIL = '\033[91m'
END = '\033[0m'
BOLD = '\033[1m'
UNDR = '\033[4m'
29 changes: 12 additions & 17 deletions screenipy.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/usr/bin/python3

# Pyinstaller compile: pyinstaller --onefile --icon=icon.ico screenipy.py --hidden-import cmath
# Pyinstaller compile: pyinstaller --onefile --icon=icon.ico screenipy.py --hidden-import cmath --hidden-import talib.stream

import os
import sys
Expand All @@ -17,21 +17,12 @@
import datetime
import math
import random
from CandlePatterns import CandlePatterns
from ColorText import colorText

# Try Fixing bug with this symbol
TEST_STKCODE = "HAPPSTMNDS"

# Decoration Class
class colorText:
HEAD = '\033[95m'
BLUE = '\033[94m'
GREEN = '\033[92m'
WARN = '\033[93m'
FAIL = '\033[91m'
END = '\033[0m'
BOLD = '\033[1m'
UNDR = '\033[4m'

# Constants
DEBUG = False
VERSION = "1.03"
Expand Down Expand Up @@ -81,12 +72,14 @@ class colorText:
[1.03]
1. Result excel file will not be overwritten now. Each result file will be saved with timestamp.
2. Mino bug-fixes.
2. Candlestick pattern recognition added
3. Mino bug-fixes.
--- END ---
''' + colorText.END

nse = Nse()
candlePatterns = CandlePatterns()
np.seterr(divide='ignore', invalid='ignore')
parser = configparser.ConfigParser()
screenCounter = 1
Expand Down Expand Up @@ -156,7 +149,6 @@ def fetchStockData(stockCode):
)
sys.stdout.write("\r\033[K")
try:
#print(colorText.BOLD + colorText.GREEN + ("[%d%%] Fetching data & Analyzing %s..." % (int(screenCounter/len(listStockCodes)*100), stockCode)) + colorText.END, end='')
print(colorText.BOLD + colorText.GREEN + ("[%d%%] Screened %d, Found %d. Fetching data & Analyzing %s..." % (int(screenCounter/len(listStockCodes)*100), screenCounter, len(screenResults), stockCode)) + colorText.END, end='')
except ZeroDivisionError:
pass
Expand Down Expand Up @@ -480,11 +472,14 @@ def checkForUpdate():
sys.exit(0)
if executeOption > 0 and executeOption < 5:
getConfig(parser)
'''
# Disabled after implementation of CandlePatterns class
try:
daysForInsideBar = int(input(colorText.BOLD + colorText.WARN + '\n[+] Enter days to look back for formation of Inside Bar (Optimal = 3 to 4): '))
print('')
except:
pass
'''
fetchStockCodes()
print(colorText.BOLD + colorText.WARN + "[+] Starting Stock Screening.. Press Ctrl+C to stop!\n")
for stock in listStockCodes:
Expand All @@ -499,22 +494,22 @@ def checkForUpdate():
isVolumeHigh = validateVolume(processedData, screeningDictionary, saveDictionary, volumeRatio=volumeRatio)
isBreaking = findBreakout(processedData, screeningDictionary, saveDictionary, daysToLookback=daysToLookback)
isLtpValid = validateLTP(fullData, screeningDictionary, saveDictionary, minLTP=minLTP, maxLTP=maxLTP)
isInsideBar = validateInsideBar(processedData, screeningDictionary, saveDictionary, daysToLookback=daysForInsideBar)
#isInsideBar = validateInsideBar(processedData, screeningDictionary, saveDictionary, daysToLookback=daysForInsideBar)
isCandlePattern = candlePatterns.findPattern(processedData, screeningDictionary, saveDictionary)
if (executeOption == 1 or executeOption == 2) and isBreaking and isVolumeHigh and isLtpValid:
screenResults = screenResults.append(screeningDictionary,ignore_index=True)
saveResults = saveResults.append(saveDictionary, ignore_index=True)
if (executeOption == 1 or executeOption == 3) and (consolidationValue <= consolidationPercentage and consolidationValue != 0) and isLtpValid:
screenResults = screenResults.append(screeningDictionary,ignore_index=True)
saveResults = saveResults.append(saveDictionary, ignore_index=True)
if executeOption == 4 and isLtpValid and isInsideBar:
if executeOption == 4 and isLtpValid and isCandlePattern:
screenResults = screenResults.append(screeningDictionary,ignore_index=True)
saveResults = saveResults.append(saveDictionary, ignore_index=True)
except KeyboardInterrupt:
print(colorText.BOLD + colorText.FAIL + "\n[+] Script terminated by the user." + colorText.END)
break
except Exception as e:
print(colorText.FAIL + ("[+] Exception Occured while Screening %s! Skipping this stock.." % stock) + colorText.END)
print(e)
screenResults.sort_values(by=['Stock'], ascending=True, inplace=True)
saveResults.sort_values(by=['Stock'], ascending=True, inplace=True)
print(tabulate(screenResults, headers='keys', tablefmt='psql'))
Expand Down

0 comments on commit e870464

Please sign in to comment.