-
Notifications
You must be signed in to change notification settings - Fork 0
/
technical_analysis.py
304 lines (236 loc) · 10.3 KB
/
technical_analysis.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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
import yfinance as yf
import pandas as pd
import tkinter as tk
from matplotlib.figure import Figure
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from mpl_finance import candlestick_ohlc
import matplotlib.dates as mpl_dates
import numpy as np
def calculate_bollinger_bands(ticker):
# Fetch data from Yahoo Finance
data = yf.download(ticker, period='1y')
# Calculate Bollinger Bands
data['SMA'] = data['Close'].rolling(window=20).mean()
data['STD'] = data['Close'].rolling(window=20).std()
data['Upper'] = data['SMA'] + 2 * data['STD']
data['Lower'] = data['SMA'] - 2 * data['STD']
# Identify buy and sell positions
data['Buy'] = data['Close'] > data['Upper']
data['Sell'] = data['Close'] < data['Lower']
return data
def calculate_head_and_shoulders(ticker):
# Fetch data from Yahoo Finance
data = yf.download(ticker, period='1y')
# Find potential head and shoulders pattern
pattern = np.where(
(data['Close'].shift(-2) < data['Close'].shift(-1)) &
(data['Close'].shift(-2) < data['Close']) &
(data['Close'].shift(2) < data['Close'].shift(1)) &
(data['Close'].shift(2) < data['Close'])
)
return data, pattern
def calculate_double_top_and_bottom(ticker):
# Fetch data from Yahoo Finance
data = yf.download(ticker, period='1y')
# Find potential double top and double bottom patterns
double_top_pattern = np.where(
(data['High'].shift(-1) < data['High']) &
(data['High'].shift(1) < data['High']) &
(data['Low'].shift(-1) > data['Low']) &
(data['Low'].shift(1) > data['Low'])
)
double_bottom_pattern = np.where(
(data['High'].shift(-1) < data['High']) &
(data['High'].shift(1) < data['High']) &
(data['Low'].shift(-1) > data['Low']) &
(data['Low'].shift(1) > data['Low'])
)
return data, double_top_pattern, double_bottom_pattern
def calculate_triangles(ticker):
# Fetch data from Yahoo Finance
data = yf.download(ticker, period='1y')
# Find potential ascending, descending, and symmetrical triangles
ascending_triangle = np.where(
(data['High'].shift(-2) < data['High'].shift(-1)) &
(data['High'].shift(-2) < data['High']) &
(data['Low'].shift(-2) < data['Low'].shift(-1)) &
(data['Low'].shift(-2) < data['Low'])
)
descending_triangle = np.where(
(data['High'].shift(-2) > data['High'].shift(-1)) &
(data['High'].shift(-2) > data['High']) &
(data['Low'].shift(-2) > data['Low'].shift(-1)) &
(data['Low'].shift(-2) > data['Low'])
)
symmetrical_triangle = np.where(
((data['High'].shift(-2) < data['High'].shift(-1)) & (data['High'].shift(-2) < data['High']) &
(data['Low'].shift(-2) > data['Low'].shift(-1)) & (data['Low'].shift(-2) < data['Low'])) |
((data['High'].shift(-2) > data['High'].shift(-1)) & (data['High'].shift(-2) > data['High']) &
(data['Low'].shift(-2) < data['Low'].shift(-1)) & (data['Low'].shift(-2) > data['Low']))
)
return data, ascending_triangle, descending_triangle, symmetrical_triangle
def calculate_flags_and_pennants(ticker):
# Fetch data from Yahoo Finance
data = yf.download(ticker, period='1y')
# Find potential flag and pennant patterns
flags = np.where(
(data['Close'].shift(-1) > data['Close']) &
(data['Close'].shift(1) > data['Close']) &
(data['High'].shift(-1) > data['High']) &
(data['High'].shift(1) > data['High']) &
(data['Low'].shift(-1) < data['Low']) &
(data['Low'].shift(1) < data['Low'])
)
pennants = np.where(
(data['Close'].shift(-1) < data['Close']) &
(data['Close'].shift(1) < data['Close']) &
(data['High'].shift(-1) > data['High']) &
(data['High'].shift(1) > data['High']) &
(data['Low'].shift(-1) < data['Low']) &
(data['Low'].shift(1) < data['Low'])
)
return data, flags, pennants
def calculate_cup_and_handle(ticker):
# Fetch data from Yahoo Finance
data = yf.download(ticker, period='1y')
# Find potential cup and handle pattern
pattern = np.where(
(data['Close'] > data['Close'].shift(-1)) &
(data['Close'].shift(-1) > data['Close'].shift(-2)) &
(data['Close'].shift(-2) > data['Close'].shift(-3)) &
(data['Close'].shift(-3) > data['Close'].shift(-4)) &
(data['Close'].shift(-4) < data['Close'].shift(-5))
)
return data, pattern
def calculate_wedges(ticker):
# Fetch data from Yahoo Finance
data = yf.download(ticker, period='1y')
# Find potential ascending and descending wedges
ascending_wedge = np.where(
(data['High'].shift(-2) < data['High'].shift(-1)) &
(data['High'].shift(-2) < data['High']) &
(data['Low'].shift(-2) < data['Low'].shift(-1)) &
(data['Low'].shift(-2) < data['Low'])
)
descending_wedge = np.where(
(data['High'].shift(-2) > data['High'].shift(-1)) &
(data['High'].shift(-2) > data['High']) &
(data['Low'].shift(-2) > data['Low'].shift(-1)) &
(data['Low'].shift(-2) > data['Low'])
)
return data, ascending_wedge, descending_wedge
def calculate_gaps(ticker):
# Fetch data from Yahoo Finance
data = yf.download(ticker, period='1y')
# Calculate price differences between consecutive days
price_diff = data['Close'].diff()
# Find potential gap patterns
breakaway_gaps = np.where((price_diff > 0) & (price_diff.shift(-1) > 0))
exhaustion_gaps = np.where((price_diff < 0) & (price_diff.shift(-1) < 0))
runaway_gaps = np.where((price_diff > 0) & (price_diff.shift(-1) < 0))
return data, breakaway_gaps, exhaustion_gaps, runaway_gaps
def plot_pattern(data, pattern):
# Create a new window for the plot
window = tk.Toplevel()
window.title('Pattern Analysis')
# Create a Figure and set its size
figure = Figure(figsize=(8, 6), dpi=100)
# Create a subplot within the Figure
subplot = figure.add_subplot(111)
# Plot the stock prices
candlestick_ohlc(subplot, data[['Date', 'Open', 'High', 'Low', 'Close']].values, width=0.6,
colorup='green', colordown='red')
subplot.xaxis.set_major_formatter(mpl_dates.DateFormatter('%Y-%m-%d'))
subplot.xaxis.set_major_locator(mpl_dates.DayLocator())
# Highlight the pattern on the plot
subplot.plot(data.iloc[pattern]['Date'], data.iloc[pattern]['Close'], 'bo', markersize=8)
# Add labels and title to the plot
subplot.set_xlabel('Date')
subplot.set_ylabel('Price')
subplot.set_title('Pattern Analysis')
# Rotate the x-axis tick labels for better visibility
figure.autofmt_xdate()
# Create a canvas for the Figure
canvas = FigureCanvasTkAgg(figure, master=window)
canvas.draw()
# Add the canvas to the window
canvas.get_tk_widget().pack()
def analyze_stock():
ticker = entry.get()
pattern = pattern_var.get()
if pattern == 'Bollinger Bands':
# Perform Bollinger Bands analysis
data = calculate_bollinger_bands(ticker)
# Plot the Bollinger Bands
plot_bollinger_bands(data)
elif pattern == 'Head and Shoulders':
# Perform Head and Shoulders pattern analysis
data, pattern = calculate_head_and_shoulders(ticker)
# Plot the pattern
plot_pattern(data, pattern)
elif pattern == 'Double Top and Double Bottom':
# Perform Double Top and Double Bottom pattern analysis
data, double_top_pattern, double_bottom_pattern = calculate_double_top_and_bottom(ticker)
# Plot the patterns
plot_pattern(data, double_top_pattern)
plot_pattern(data, double_bottom_pattern)
elif pattern == 'Triangles':
# Perform Triangles pattern analysis
data, ascending_triangle, descending_triangle, symmetrical_triangle = calculate_triangles(ticker)
# Plot the patterns
plot_pattern(data, ascending_triangle)
plot_pattern(data, descending_triangle)
plot_pattern(data, symmetrical_triangle)
elif pattern == 'Flags and Pennants':
# Perform Flags and Pennants pattern analysis
data, flags, pennants = calculate_flags_and_pennants(ticker)
# Plot the patterns
plot_pattern(data, flags)
plot_pattern(data, pennants)
elif pattern == 'Cup and Handle':
# Perform Cup and Handle pattern analysis
data, pattern = calculate_cup_and_handle(ticker)
# Plot the pattern
plot_pattern(data, pattern)
elif pattern == 'Wedges':
# Perform Wedges pattern analysis
data, ascending_wedge, descending_wedge = calculate_wedges(ticker)
# Plot the patterns
plot_pattern(data, ascending_wedge)
plot_pattern(data, descending_wedge)
elif pattern == 'Gaps':
# Perform Gaps pattern analysis
data, breakaway_gaps, exhaustion_gaps, runaway_gaps = calculate_gaps(ticker)
# Plot the patterns
plot_pattern(data, breakaway_gaps)
plot_pattern(data, exhaustion_gaps)
plot_pattern(data, runaway_gaps)
# Create the main window
window = tk.Tk()
window.title('Stock Analysis Tool')
window.geometry('300x300')
# Create a label and an entry for the stock ticker
label = tk.Label(window, text='Enter Stock Ticker:')
label.pack()
entry = tk.Entry(window)
entry.pack()
# Create a dropdown menu for pattern selection
pattern_var = tk.StringVar(window)
pattern_var.set('Bollinger Bands')
pattern_label = tk.Label(window, text='Select Pattern:')
pattern_label.pack()
pattern_menu = tk.OptionMenu(window, pattern_var,
'Bollinger Bands',
'Head and Shoulders',
'Double Top and Double Bottom',
'Triangles',
'Flags and Pennants',
'Cup and Handle',
'Wedges',
'Gaps')
pattern_menu.pack()
# Create a button to analyze the stock
button = tk.Button(window, text='Analyze', command=analyze_stock)
button.pack()
# Start the main GUI loop
tk.mainloop()