forked from SamPom100/UnusualVolumeDetector
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmarket_scanner.py
105 lines (88 loc) · 3.41 KB
/
market_scanner.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
import os
import time
import yfinance as yf
import dateutil.relativedelta
from datetime import date
import datetime
import numpy as np
import sys
from stocklist import NasdaqController
from tqdm import tqdm
from joblib import Parallel, delayed, parallel_backend
import multiprocessing
###########################
# THIS IS THE MAIN SCRIPT #
###########################
# Change variables to your liking then run the script
MONTH_CUTTOFF = 5
DAY_CUTTOFF = 3
STD_CUTTOFF = 9
class mainObj:
def __init__(self):
pass
def getData(self, ticker):
global MONTH_CUTOFF
currentDate = datetime.date.today() + datetime.timedelta(days=1)
pastDate = currentDate - \
dateutil.relativedelta.relativedelta(months=MONTH_CUTTOFF)
sys.stdout = open(os.devnull, "w")
data = yf.download(ticker, pastDate, currentDate)
sys.stdout = sys.__stdout__
return data[["Volume"]]
def find_anomalies(self, data):
global STD_CUTTOFF
indexs = []
outliers = []
data_std = np.std(data['Volume'])
data_mean = np.mean(data['Volume'])
anomaly_cut_off = data_std * STD_CUTTOFF
upper_limit = data_mean + anomaly_cut_off
data.reset_index(level=0, inplace=True)
for i in range(len(data)):
temp = data['Volume'].iloc[i]
if temp > upper_limit:
indexs.append(str(data['Date'].iloc[i])[:-9])
outliers.append(temp)
d = {'Dates': indexs, 'Volume': outliers}
return d
def customPrint(self, d, tick):
print("\n\n\n******* " + tick.upper() + " *******")
print("Ticker is: "+tick.upper())
for i in range(len(d['Dates'])):
str1 = str(d['Dates'][i])
str2 = str(d['Volume'][i])
print(str1 + " - " + str2)
print("*********************\n\n\n")
def days_between(self, d1, d2):
d1 = datetime.datetime.strptime(d1, "%Y-%m-%d")
d2 = datetime.datetime.strptime(d2, "%Y-%m-%d")
return abs((d2 - d1).days)
def parallel_wrapper(self, x, currentDate, positive_scans):
global DAY_CUTTOFF
d = (self.find_anomalies(self.getData(x)))
if d['Dates']:
for i in range(len(d['Dates'])):
if self.days_between(str(currentDate)[:-9], str(d['Dates'][i])) <= DAY_CUTTOFF:
self.customPrint(d, x)
stonk = dict()
stonk['Ticker'] = x
stonk['TargetDate'] = d['Dates'][0]
stonk['TargetVolume'] = str(
'{:,.2f}'.format(d['Volume'][0]))[:-3]
positive_scans.append(stonk)
def main_func(self):
StocksController = NasdaqController(True)
list_of_tickers = StocksController.getList()
currentDate = datetime.datetime.strptime(
date.today().strftime("%Y-%m-%d"), "%Y-%m-%d")
start_time = time.time()
manager = multiprocessing.Manager()
positive_scans = manager.list()
with parallel_backend('loky', n_jobs=multiprocessing.cpu_count()):
Parallel()(delayed(self.parallel_wrapper)(x, currentDate, positive_scans)
for x in tqdm(list_of_tickers))
print("\n\n\n\n--- this took %s seconds to run ---" %
(time.time() - start_time))
return positive_scans
if __name__ == '__main__':
mainObj().main_func()