<!DOCTYPE html>
In [68]:
#!pip3 install fix_yahoo_finance
#!pip3 install pandas_datareader
from IPython.core.display import display, HTML
display(HTML("<style>.container { width:100% !important; }</style>"))
# ___library_import_statements___
import pandas as pd
# for pandas_datareader, otherwise it might have issues
pd.core.common.is_list_like = pd.api.types.is_list_like
import pandas_datareader.data as web
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import datetime
import time
#yahoo API data source correction
import fix_yahoo_finance as yahoo_finance
yahoo_finance.pdr_override()
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
In [69]:
# ___variables___
ticker = 'VZ'
start_time = datetime.datetime(2017, 10, 1)
#end_time = datetime.datetime(2019, 1, 20)
end_time = datetime.datetime.now().date().isoformat() # today
In [70]:
# yahoo gives only daily historical data
connected = False
while not connected:
try:
ticker_df = web.get_data_yahoo(ticker, start=start_time, end=end_time)
connected = True
print('connected to yahoo')
except Exception as e:
print("type error: " + str(e))
time.sleep( 5 )
pass
# use numerical integer index instead of date
ticker_df = ticker_df.reset_index()
print(ticker_df.head(5))
In [71]:
# discrete dataset
x_data = ticker_df.index.tolist() # the index will be our x axis, not date
y_data = ticker_df['High']
# x values for the polynomial fit, 200 points
x = np.linspace(0, max(ticker_df.index.tolist()), max(ticker_df.index.tolist()) + 1)
# polynomial fit of degree xxx
pol = np.polyfit(x_data, y_data, 15)
y_pol = np.polyval(pol, x)
# ___ plotting ___
plt.figure(figsize=(20, 10), dpi= 120, facecolor='w', edgecolor='k')
# plot stock data
plt.plot(x_data, y_data, 'o', markersize=3.5, color='grey', alpha=0.7)
# plot polynomial fit
plt.plot(x, y_pol, '-', markersize=1.0, color='black', alpha=0.9)
plt.legend(['stock data', 'polynomial fit'])
plt.show()
In [72]:
data = y_pol
# ___ detection of local minimums and maximums ___
min_max = np.diff(np.sign(np.diff(data))).nonzero()[0] + 1 # local min & max
l_min = (np.diff(np.sign(np.diff(data))) > 0).nonzero()[0] + 1 # local min
l_max = (np.diff(np.sign(np.diff(data))) < 0).nonzero()[0] + 1 # local max
# +1 due to the fact that diff reduces the original index number
# plot
plt.figure(figsize=(20, 5))
plt.plot(x, data, color='grey')
plt.plot(x[l_min], data[l_min], "o", label="min", color='r') # minima
plt.plot(x[l_max], data[l_max], "o", label="max", color='b') # maxima
plt.title('Local minima and maxima')
plt.show()
In [73]:
print('corresponding HIGH values for suspected indices: ')
print(ticker_df.High.iloc[l_max])
#extend the suspected x range:
delta = 5 # how many ticks to the left and to the right from local maximum on x axis
dict_i = dict()
for element in l_max:
l_bound = element - delta # lower bound
u_bound = element + delta # upper bound
x_range = range(l_bound, u_bound + 1)
y_loc_list = list()
for x_element in x_range:
y_loc_list.append(ticker_df.High.iloc[x_element])
#print(y_loc_list)
dict_i[element] = y_loc_list
print('DICTIONARY for l_max: ', dict_i)
In [79]:
y_delta = 0.05 # percentage distance between average highs
threshold = max(ticker_df['High']) * 0.90 # setting threshold lower than the global high
y_dict = dict()
maxi = list()
suspected_tops = list()
for key in dict_i.keys():
mn = sum(dict_i[key])/len(dict_i[key])
maxi.append(max(dict_i[key]))
l_y = mn * (1.0 - y_delta)
u_y = mn * (1.0 + y_delta)
y_dict[key] = [l_y, u_y, mn]
print('SCREENING FOR DOUBLE TOP:')
for key_i in y_dict.keys():
for key_j in y_dict.keys():
if (key_i != key_j) and (y_dict[key_i][2] > threshold):
if (y_dict[key_i][2] < y_dict[key_j][1]) and (y_dict[key_i][2] > y_dict[key_j][0]):
print('----------------------- ')
print('--- Topping pattern found for x index pair: ', key_i, ',', key_j)
suspected_tops.append(key_i)
print('----------------------- ')
else:
print('Not found yet')
In [82]:
print(y_dict)
# ___ plotting ___
plt.figure(figsize=(20, 10), dpi= 120, facecolor='w', edgecolor='k')
# plot stock data
plt.plot(x_data, y_data, 'o', markersize=3.5, color='grey', alpha=0.7)
# plot polynomial fit
plt.plot(x, y_pol, '-', markersize=1.0, color='black', alpha=0.9)
plt.legend(['stock data', 'polynomial fit'])
for position in suspected_tops:
plt.axvline(x=position)
plt.axhline(threshold)
plt.show()
Sources:
https://towardsdatascience.com/basic-time-series-analysis-and-trading-strategy-with-bitcoin-price-data-1a8f1a30f11
https://www.learndatasci.com/tutorials/python-finance-part-yahoo-finance-api-pandas-matplotlib/
https://github.com/Crypto-toolbox/pandas-technical-indicators/blob/master/technical_indicators.py
https://stackoverflow.com/questions/4624970/finding-local-maxima-minima-with-numpy-in-a-1d-numpy-array
https://www.youtube.com/watch?v=970im6yAmhE
https://stackoverflow.com/questions/24988448/how-to-draw-vertical-lines-on-a-given-plot-in-matplotlib