-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathScan.py
More file actions
127 lines (116 loc) · 5.35 KB
/
Copy pathScan.py
File metadata and controls
127 lines (116 loc) · 5.35 KB
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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
import Ichimoku
from DataScrape import GetData
from multiprocessing.dummy import Pool as ThreadPool
import itertools
from pick import pick
# for saving files
import os
import pickle
import pandas as pd
from datetime import datetime
# for testing
import time
class Alert(Ichimoku.Analysis):
def __main__(self, period: str = False, interval: str = False):
super().__init__(self.symbol)
self.period = period if period else super().__init__(self.period)
self.interval = interval if interval else super().__init__(self.interval)
def check_conversion(self, data):
if data['tenkan_sen'][-1] > data['kijun_sen'][-1] \
and data['tenkan_sen'][-2] <= data['kijun_sen'][-2]:
return "up"
elif data['tenkan_sen'][-1] < data['kijun_sen'][-1] \
and data['tenkan_sen'][-2] >= data['kijun_sen'][-2]:
return "down"
else:
return False
def check_cloud(self, data):
if data['Close'][-1] > max(data['senkou_span_a'][-1], data['senkou_span_b'][-1]):
return "up"
elif data['Close'][-1] < min(data['senkou_span_a'][-1], data['senkou_span_b'][-1]):
return "down"
else:
return False
def check_rsi(self, data):
# looks for RSI that matches a trending market for pairing with Ichimoku trends
last_entry = round(data['rsi'][-1], 0)
second_last_entry = round(data['rsi'][-2], 0)
increasing = last_entry > second_last_entry
decreasing = last_entry < second_last_entry
four_period = round(data['rsi'][-4:], 0)
four_period_avg = round(four_period.mean(), 0)
# check if the rsi is trending up/down or hit support/resistance and bounced/fell (4 --> 1hr on 15min interval)
if last_entry > four_period_avg and increasing \
or last_entry > 40 and (x < 40 for x in four_period) and increasing:
return "up"
elif last_entry > four_period_avg and decreasing \
or last_entry < 60 and (x > 60 for x in four_period) and decreasing:
return "down"
def check_volume(self, data):
# TODO: subtract first period date and last period date to get difference
# Checks if the volume on the stock is greater than 400,000/day
if interval == "15m":
t = 26
elif interval == "1h":
t = 7
else:
t = 26
t22 = t*22
last_day_vol = data[-t:].Volume.sum() # one day for 15min interval
month_avg = round(data[-t22:].Volume.sum()/22, 0)
if 400000 < month_avg < last_day_vol:
return True
else:
return False
def find_entry(self):
data = super().ichimoku(period=self.period, interval=self.interval)
if data.empty:
pass
else:
if self.check_conversion(data) == "up" \
and self.check_cloud(data) == "up"\
and self.check_rsi(data) == "up"\
and self.check_volume(data):
print("Conversion up and price above cloud!")
print(f"Symbol: {self.symbol}, Period: {self.period}, Interval: {self.interval}")
up = {'Symbol': self.symbol, 'Period': self.period, 'Interval': self.interval, 'Buy/Sell': "BUY"}
return up
elif self.check_conversion(data) == "down" \
and self.check_cloud(data) == "down" \
and self.check_rsi(data) == "down"\
and self.check_volume(data):
print("Conversion down and price below cloud!")
print(f"Symbol: {self.symbol}, Period: {self.period}, Interval: {self.interval}")
down = {'Symbol': self.symbol, 'Period': self.period, 'Interval': self.interval, 'Buy/Sell': "SELL"}
return down
def scan_list(symbol, period=None, interval=None):
return Alert(symbol=symbol, period=period, interval=interval).find_entry()
if __name__ == "__main__":
period, index1 = pick(['6mo', '1mo', '5d', '1d'], 'Select a time period: ')
interval, index2 = pick(['1d', '15m', '5m', '1m'], 'Select an interval: ')
source, index3 = pick(['Nasdaq', 'S&P500'], 'Select the stock list source: ')
entry = {'Symbol': [], 'Period': [], 'Interval': [], 'Buy/Sell': []}
stock_list = GetData(source=str(source)).get_stock_list()
print("Starting to scan for entry points!")
# Pool requests to get data in parallel (much faster)
tp = ThreadPool(50)
entry_list = tp.starmap(scan_list, zip(stock_list, itertools.repeat(period), itertools.repeat(interval)))
tp.close()
tp.join()
for i in entry_list:
if i:
entry["Symbol"].append(i["Symbol"])
entry["Period"].append(i["Period"])
entry["Interval"].append(i["Interval"])
entry["Buy/Sell"].append(i["Buy/Sell"])
# Save results
with open(os.environ['USERPROFILE'] +
"\\PycharmProjects\\Options\\output\\EntryList_" + source + "_"
+ datetime.now().strftime("%m-%d-%Y") + ".p", "wb") as f:
pickle.dump(entry, f)
f.close()
# convert to dataframe and save as csv
df = pd.DataFrame.from_dict(entry)
df.to_csv(os.environ['USERPROFILE'] +
"\\PycharmProjects\\Options\\output\\EntryList_" + source + "_"
+ datetime.now().strftime("%m-%d-%Y") + ".csv")