From d830e8231bb205abfeca36b8abb5a655594f2faf Mon Sep 17 00:00:00 2001 From: sashaTribe <53623386+sashaTribe@users.noreply.github.com> Date: Fri, 13 Oct 2023 12:44:07 +0100 Subject: [PATCH 1/4] My historical_stock file Holds scripts to calculate weekly averages and compare to the latest stock price as well as being able to communicate with IFTTT. --- historical_stock.py | 108 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 historical_stock.py diff --git a/historical_stock.py b/historical_stock.py new file mode 100644 index 0000000..dc74b8d --- /dev/null +++ b/historical_stock.py @@ -0,0 +1,108 @@ +import requests +import json + + +def get_data_request(ticker): + """ + This function fetches the api based on what company the ticker + presents. + Afterwards it gets the dictionary that has all the records of daily + prices per day. + Then, it makes sure to only take 5 records and returns the final dictionary. + """ + url = f"https://www.alphavantage.co/query?function=TIME_SERIES_DAILY& + symbol={ticker}&outputsize=compact&apikey=demoY22ZX8DF9C8MCNWW" + response_for_historical = requests.get(url) + if response_for_historical.status_code == 200: + data = response_for_historical.json() + main_dict = data['Time Series (Daily)'] + finalized_dict = finalize_dict(main_dict) + return finalized_dict + else: + print("Did not fetch data properly, ", + response_for_historical.status_code) + + + +def store_weekly_avgs(ticker_list): + """ + This function calculates the weekly average of a given + dataset then assigns it to its related symbol (company) + in form of a dictionary. + """ + week_avgs = [] + for ticker in ticker_list: + dataset = get_data_request(ticker) + week_avgs.append(calc_weekly_average(dataset)) + return {k: v for k, v in zip(ticker_list, week_avgs)} + + +def finalize_dict(dict): + """ + This function returns the first 5 items of the given + dictionary for its weekly calculation. + The reason 5 is because the stock market is only open + on weekdays. + """ + first_five_items = {k: dict[k] for k in list(dict)[:5]} + return first_five_items + +def return_open_val(given_dict): + # returns the open price of a given dictionary + return float(given_dict['1. open']) + +def calc_weekly_average(given_dict): + # calculates the weekly average of a given dictionary + total = 0 + for key, value in given_dict.items(): + total += return_open_val(value) + return total/5 + +def latest_stock_lt_week_avg(stock_price, weekly_average): + """ + This function returns True if the latest stock price is less + than it's weekly average. + """ + if stock_price < weekly_average: + return True + +def main(): + """ + The main function triggers the functions above then + communicates with IFTTT by posting a request to trigger + an email to the assigned Gmail accounts with the IFTTT + """ + api_key = "nmSjoGFt5z5ExJ4bLUMBcr0JozQykoHC2TB5dUNdUT4" # my api key for authentication + event_name = "stock_update" # needed for my IFTTT trigger + url = f"https://maker.ifttt.com/trigger/{event_name}/with/key/{api_key}" # the api + + TICKER_LIST = ["AAPL","TSLA","MSFT","GOOGL","NKE"] # symbol list stakeholder queried + weekly_avgs = store_weekly_avgs(TICKER_LIST) + json_file = "real_time_stock_data" # name of json file + recent_stock_prices = [] + + try: + with open(json_file, 'r') as f: + data = json.load(f) + for key,value in data.items(): + recent_stock_prices.append([value][0]) + for i in range(len(weekly_avgs)): + if latest_stock_lt_week_avg(recent_stock_prices[i],weekly_avgs[i]): + message = f"The stock price for {key} are less than + the stock's weekly average. Buy more stocks now!!!" + data = { + 'Value1':message + } + response = requests.post(url, json=data) + if response.status_code == 200: + print("Email sent!") + else: + print("Failed to send email.") + print("And yes, there has been a drop of prices") + + except FileNotFoundError: + print(f"The file '{json_file}' was not found.") + except json.JSONDecodeError: + print(f"The file '{json_file}' is not a valid JSON file.") + + From 7d836bf0de9c4734c75ea1450118f37a5fb77871 Mon Sep 17 00:00:00 2001 From: sashaTribe <53623386+sashaTribe@users.noreply.github.com> Date: Fri, 13 Oct 2023 12:55:13 +0100 Subject: [PATCH 2/4] Real Time Stock Prices file upload This script contains functions that fetches data from the APIs, calculates differences, and communicates with my IFTTT --- real_time_stock_prices.py | 148 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 148 insertions(+) create mode 100644 real_time_stock_prices.py diff --git a/real_time_stock_prices.py b/real_time_stock_prices.py new file mode 100644 index 0000000..abc0f24 --- /dev/null +++ b/real_time_stock_prices.py @@ -0,0 +1,148 @@ +import requests +import json + +def get_dataset(ticker): + """ + A function that fetches an api based on ticker value (sybmbol of company) whic + then returns a dictionary data structure + """ + print("Running dataset") + response_for_realtime = requests.get(f"https://www.alphavantage.co/query?function=TIME_SERIES_INTRADAY&symbol={ticker}&interval=1min&outputsize=compact&apikey=O3KE4N17RB5IPQOD") + if response_for_realtime.status_code == 200: + data = response_for_realtime.json() + print(data) + return data + + else: + print("Error getting the request needed: ", response_for_realtime.status_code) + +def get_main_data(dict): + """ + A simple function that returns data belonging to the key 'Time Series (1min) + """ + print("Getting main data") + return dict['Time Series (1min)'] + +def get_datasets(ticker_list): + """ + A function that takes in a list of tickers and calls the + function 'get_dataset()' and stores each dataset on to a list + then returns it. + """ + print("Running datasets") + datasets = [] + for ticker in ticker_list: + temp_data = (get_dataset(ticker)) + datasets.append(get_main_data(temp_data)) + return datasets + +def store_stock_price(stock_pair,new_price): + """ + A functions that updates the prices. + This function would be called when there has been an update on the prices. + """ + stock_pair.pop(0) + stock_pair.append(new_price) + return stock_pair + +def has_price_decreased(pair_of_stock_prices): + """ + This function checks if the new stock price is below £0.25. + The function will return True. + This is called from the main function. + """ + if float(pair_of_stock_prices[1]) < (float(pair_of_stock_prices[0]) - 0.25): + return True + + +def generate_stock_queue(dict): + """ + This function generates a pair of stock prices. + It acts as a queue where when you push one price, then + push the most recent price on the list. + It then converts to GBP which is what the stakeholder wants. + """ + new_stock_pair = [] + latest_data_dict = list(dict.items()) + newest_price = latest_data_dict[0][1]['1. open'] + second_newest_price = latest_data_dict[1][1]['1. open'] + new_stock_pair.append(convert_usd_to_gbp(newest_price)) + new_stock_pair.append(convert_usd_to_gbp(second_newest_price)) + return new_stock_pair + +def get_all_stock_pairs(datasets): + """ + This function iterates each dataset to generate a stock pair + for each company. + It returns a two-dimensional array. + """ + two_d_array_stock = [] + for dataset in datasets: + two_d_array_stock.append(generate_stock_queue(dataset)) + return two_d_array_stock + + +def return_open_val(given_dict): + # returns the open price for a given dataset + return float(given_dict['1. open']) + + + +def convert_usd_to_gbp(price_to_convert): + # a simple function to convert USD to GBP + return price_to_convert/1.23 + +def main(): + """ + The main calls all the functions above and communicates with the IFTTT so it can email + any updates about the stocks when triggered. + """ + api_key = "nmSjoGFt5z5ExJ4bLUMBcr0JozQykoHC2TB5dUNdUT4" + event_name = "stock_update" + url = f"https://maker.ifttt.com/trigger/{event_name}/with/key/{api_key}" + + real_time_stock_data = "real_time_data.json" + + TICKER_LIST = ["AAPL","TSLA","MSFT","GOOGL","NKE"] + stock_datasets = [] + stock_pairs = [] + stock_datasets = get_datasets(TICKER_LIST) + + for dict in stock_datasets: + stock_pairs.append(generate_stock_queue(dict)) + full_data_dict = {k: v for k, v in zip(TICKER_LIST, stock_pairs)} + + with open(real_time_stock_data, 'w') as f: + json.dump(full_data_dict, f, indent=4) + + for key,value in full_data_dict.items(): + print(key, ':', value) + if has_price_decreased(value): + message = f"The stock price for {key} has dropped by at least £0.25GBP. Buy more stocks now!!!" + data = { + 'Value1':message + } + response = requests.post(url, json=data) + if response.status_code == 200: + print("Email sent!") + else: + print("Failed to send email.") + print("Yes there has been a drop of prices") + else: + data = { + 'Value1':'No updates on the stocks', + } + response = requests.post(url, json=data) + if response.status_code == 200: + print("Email sent!") + else: + print("Failed to send email.") + print("No decrease") + + +main() + + + + + From f9f225fb515a27cf356345508abc57b7fb01882d Mon Sep 17 00:00:00 2001 From: sashaTribe <53623386+sashaTribe@users.noreply.github.com> Date: Mon, 23 Oct 2023 14:07:23 +0100 Subject: [PATCH 3/4] Update historical_stock.py deleted api --- historical_stock.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/historical_stock.py b/historical_stock.py index dc74b8d..538bcf7 100644 --- a/historical_stock.py +++ b/historical_stock.py @@ -11,7 +11,7 @@ def get_data_request(ticker): Then, it makes sure to only take 5 records and returns the final dictionary. """ url = f"https://www.alphavantage.co/query?function=TIME_SERIES_DAILY& - symbol={ticker}&outputsize=compact&apikey=demoY22ZX8DF9C8MCNWW" + symbol={ticker}&outputsize=compact&apikey=demo{api-key}" response_for_historical = requests.get(url) if response_for_historical.status_code == 200: data = response_for_historical.json() From b61256c6b4f7ae35eb819bd3ca4626ea3df85e76 Mon Sep 17 00:00:00 2001 From: sashaTribe <53623386+sashaTribe@users.noreply.github.com> Date: Mon, 23 Oct 2023 14:08:15 +0100 Subject: [PATCH 4/4] Update real_time_stock_prices.py deleted api key --- real_time_stock_prices.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/real_time_stock_prices.py b/real_time_stock_prices.py index abc0f24..9911946 100644 --- a/real_time_stock_prices.py +++ b/real_time_stock_prices.py @@ -7,7 +7,7 @@ def get_dataset(ticker): then returns a dictionary data structure """ print("Running dataset") - response_for_realtime = requests.get(f"https://www.alphavantage.co/query?function=TIME_SERIES_INTRADAY&symbol={ticker}&interval=1min&outputsize=compact&apikey=O3KE4N17RB5IPQOD") + response_for_realtime = requests.get(f"https://www.alphavantage.co/query?function=TIME_SERIES_INTRADAY&symbol={ticker}&interval=1min&outputsize=compact&apikey={api-key}") if response_for_realtime.status_code == 200: data = response_for_realtime.json() print(data) @@ -97,7 +97,7 @@ def main(): The main calls all the functions above and communicates with the IFTTT so it can email any updates about the stocks when triggered. """ - api_key = "nmSjoGFt5z5ExJ4bLUMBcr0JozQykoHC2TB5dUNdUT4" + api_key = "api" event_name = "stock_update" url = f"https://maker.ifttt.com/trigger/{event_name}/with/key/{api_key}"