-
Notifications
You must be signed in to change notification settings - Fork 16
Dev - Volha #9
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
Vuictorovna
wants to merge
8
commits into
alexnaylor99:main
Choose a base branch
from
Vuictorovna:dev
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Dev - Volha #9
Changes from all commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
76ec388
Implement real-time stock price monitoring with Alpha Vantage API
Vuictorovna 7b90b6b
Add webhook applets
Vuictorovna 4eb935b
Fix webhook message
Vuictorovna e30878b
Improve webhook message
Vuictorovna 86b34d2
Add check if price is less than the 7-day average
Vuictorovna deac398
Add requirements.txt
Vuictorovna 5c0cd44
Add README.md
Vuictorovna c37f35a
Add code comments
Vuictorovna File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| venv/ | ||
|
|
||
| .env | ||
|
|
||
| __pycache__ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,40 +1,50 @@ | ||
| # API-Stock-Signalling | ||
| ###### NOTE: this is a project to practice your Python industry skills. Please upload your solutions by opening a new branch to the main. All files that are instantly merged to the main will be deleted. | ||
| ## Overview | ||
| A small consultancy who is currently delivering client work for a major bank wants to monitor the prices for the following stocks: Tesla, Apple, Microsoft, Google, and Nike. Once the stock falls below a certain price, they want to be immediately notified so that they can purchase more stocks. | ||
| ## Goal | ||
| Write a real time Python application that monitors the prices then notifies the user when the price of any of these stocks falls by at least £0.25 GBP. The user should also be notified if today's price is less than the 7-day average of that stock price. | ||
| ## Brief | ||
| To do this, the client has recommended using a popular automation website called IFTTT: https://ifttt.com/. They are willing to use a different provider or solution (use those consultancy skills!) if you believe there is a better option. | ||
| #### IFTTT Applet | ||
|
|
||
| IFTTT stands for “If This Then That” and it’s an automation platform that allows you to connect different apps and services together. An applet is a connection between two or more apps or devices that enables you to do something that those services couldn’t do on their own. Applets consists of two parts triggers and actions. Triggers tell an applet to start, and actions are the end result of an applet run. To use an applet, you’ll need to create a free IFTTT account and connect your apps and devices to IFTTT so that they can talk to each other. | ||
|
|
||
| #### Proposed Workflow | ||
| - Write a script that returns the stock prices. This will involve making an API request. | ||
| - Set up a IFTTT account and applet. This will be accessible via the mobile app which allows you to trigger the webhook service provided by IFTTT. | ||
| - You will need to configure the 'webhooks' service to receive web requests. You can find more details here: https://ifttt.com/maker_webhooks. | ||
| - From here you can write an application that utilises the requests package to make POST and GET requests. | ||
| - Think of what aspects or components of your proposed solution needs to be tested and what would these tests look like and attempt to implement such tests. | ||
|
|
||
| ## Main Considerations | ||
| - Choose an automation approach. Are you planning on using IFTTT or another workflow? | ||
| - What API are you going to use? You can use this as a starting point: https://github.com/public-apis/public-apis | ||
| - Remember, this is a proposed workflow. If you believe you have a more efficient approach please reach out to the Academy Team. | ||
| #### Requirements Gathering | ||
| The start to any project is to make sure you have clear and well-defined requirements for your project. Most projects start with a vague idea of what the stakeholder wants, and as a consultant, we will never have as much knowledge about their problem/business context as they do. Therefore, we need to get as much information out of them as possible, as they will subconsciously assume that we know everything. For this project, Alex Naylor will be the stakeholder. | ||
|
|
||
| If you don't know the answer to any question then you should always ask - NEVER ASSUME. This will only risk the accuracy of your work and end up having to do everything all over again if you wrongly assume. | ||
|
|
||
| Questions to ask yourself constantly throughout the project are: | ||
|
|
||
| - What is the purpose of this project, why does the stakeholder want this and what is the desired outcome of the project? | ||
| - Is there any extra info that the stakeholder could tell you to help tailor the project to what they want? | ||
|
|
||
| ## Assessment | ||
| For the assessment, you will have a 15 minute technical interview. This will consist of a strict 5 minute presentation on your technical solution. There is no need to create slides for this but you may want to demo your code. For the second half of the session, you will be asked technical questions related to the project. You will be assessed on: | ||
| - Project Complexity | ||
| - Brief Completness i.e. have you managed to meet the client brief? | ||
| - Coding Standards | ||
|
|
||
| Good Luck! | ||
|
|
||
| This Python application monitors real-time stock prices and notifies users when specific conditions are met: | ||
|
|
||
| 1. When the stock price falls by at least $0.25 USD. | ||
| 2. When today's stock price is less than the 7-day average. | ||
|
|
||
| ## Prerequisites | ||
|
|
||
| - Python 3.x | ||
| - An API key from Financial Modeling Prep (FMP) | ||
| - IFTTT account and key for notifications | ||
|
|
||
| ## Getting Started | ||
|
|
||
| ### Step 1: Get Your FMP API Key | ||
|
|
||
| 1. Visit [Financial Modeling Prep](https://site.financialmodelingprep.com) website. | ||
| 2. Sign up for an account and generate your API key. | ||
|
|
||
| ### Step 2: Set Up Your `.env` File | ||
|
|
||
| 1. Create a new file in the root directory of your project and name it `.env`. | ||
| 2. Open `.env` and add the following lines: | ||
|
|
||
| ``` | ||
| API_KEY=Your_FMP_API_Key_Here | ||
| WEBHOOK_KEY=Your_IFTTT_Key_Here | ||
| ``` | ||
|
|
||
| ### Step 3: Get Your IFTTT Key | ||
|
|
||
| 1. Visit the [IFTTT website](https://ifttt.com/) and create an account if you don't have one. | ||
| 2. Generate your IFTTT key. | ||
|
|
||
| ### Step 4: Create an IFTTT Applet | ||
|
|
||
| 1. Log in to your IFTTT account. | ||
| 2. Create a new applet. | ||
| 3. Set the event name to `stock_price_fell`. | ||
| 4. Configure the applet to receive notifications when this event is triggered. | ||
|
|
||
| ### Step 5: Install Required Python Packages | ||
|
|
||
| If you haven't done so already, install the required Python packages by running: | ||
|
|
||
| ```bash | ||
| pip install -r requirements.txt | ||
|
|
||
| ``` |
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Great:
Areas for Improvement:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,102 @@ | ||
| import requests | ||
| import time | ||
| from json.decoder import JSONDecodeError | ||
| import os | ||
| from dotenv import load_dotenv | ||
| from webhook import send_price_drop, send_avg_price_drop | ||
|
|
||
|
|
||
| load_dotenv() | ||
|
|
||
|
|
||
| class StockInfo: | ||
| def __init__(self, symbol): | ||
| self.symbol = symbol | ||
| self.current_price = None | ||
| self.previous_price = None | ||
|
|
||
| # Update the current and previous stock prices | ||
| def update_price(self, new_price): | ||
| self.previous_price = self.current_price | ||
| self.current_price = new_price | ||
|
|
||
| # Check if the stock price has fallen by at least $0.25 GBP and send alert | ||
| def check_price_fall(self): | ||
| if self.current_price and self.previous_price: | ||
| if self.current_price < self.previous_price - 0.25: | ||
| print( | ||
| f"ALERT: {self.symbol} has fallen by at least £0.25 GBP. Current price is ${self.current_price}. Time to buy!" | ||
| ) | ||
| send_price_drop( | ||
| "stock_price_fell", | ||
| self.symbol, | ||
| self.current_price, | ||
| self.previous_price, | ||
| ) | ||
|
|
||
| # Check if current stock price is below its 7-day average and send alert | ||
| def check_below_seven_day_avg(self, daily_avg): | ||
| if self.current_price < daily_avg: | ||
| print( | ||
| f"ALERT: {self.symbol}'s current price of ${self.current_price} is below the 7-day average of ${daily_avg}. Consider buying!" | ||
| ) | ||
| send_avg_price_drop( | ||
| "stock_price_fell", | ||
| self.symbol, | ||
| self.current_price, | ||
| daily_avg, | ||
| ) | ||
|
|
||
|
|
||
| # Fetch current stock price from FMP API | ||
| def get_stock_price(symbol, api_token): | ||
| url = f"https://financialmodelingprep.com/api/v3/quote/{symbol}?apikey={api_token}" | ||
| response = requests.get(url) | ||
| if response.status_code == 200: | ||
| try: | ||
| data = response.json() | ||
| return float(data[0]["price"]) | ||
| except (JSONDecodeError, KeyError): | ||
| print(f"Failed to get price data for {symbol}.") | ||
| return None | ||
|
|
||
|
|
||
| # Fetch 7-day average stock price from FMP API | ||
| def get_daily_average_price(symbol, api_token): | ||
| url = f"https://financialmodelingprep.com/api/v3/historical-price-full/{symbol}?timeseries=7&apikey={api_token}" | ||
| response = requests.get(url) | ||
| if response.status_code == 200: | ||
| try: | ||
| data = response.json()["historical"] | ||
| prices = [day["close"] for day in data] | ||
| return sum(prices) / len(prices) | ||
| except (JSONDecodeError, KeyError): | ||
| print(f"Failed to get historical data for {symbol}.") | ||
| return None | ||
|
|
||
|
|
||
| if __name__ == "__main__": | ||
| api_token = os.getenv("API_KEY") | ||
|
|
||
| # List of stocks to be monitored | ||
| monitored_stocks = [ | ||
| StockInfo("TSLA"), | ||
| StockInfo("AAPL"), | ||
| StockInfo("MSFT"), | ||
| StockInfo("GOOGL"), | ||
| StockInfo("NKE"), | ||
| ] | ||
|
|
||
| # Main loop for monitoring stock prices | ||
| while True: | ||
| for stock_info in monitored_stocks: | ||
| new_price = get_stock_price(stock_info.symbol, api_token) | ||
|
|
||
| if new_price is not None: | ||
| stock_info.update_price(new_price) | ||
| stock_info.check_price_fall() | ||
|
|
||
| daily_avg = get_daily_average_price(stock_info.symbol, api_token) | ||
| stock_info.check_below_seven_day_avg(daily_avg) | ||
|
|
||
| time.sleep(60 * 5) # Sleep for 5 minutes |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| requests | ||
| python-dotenv |
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Great:
Areas for Improvement:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| import requests | ||
|
|
||
| import os | ||
| from dotenv import load_dotenv | ||
|
|
||
|
|
||
| load_dotenv() | ||
|
|
||
|
|
||
| # Function to send a webhook to IFTTT | ||
| def send_ifttt_webhook(event, message): | ||
| webhook_key = os.getenv("WEBHOOK_KEY") | ||
| url = f"https://maker.ifttt.com/trigger/{event}/with/key/{webhook_key}" | ||
| payload = { | ||
| "value1": message, | ||
| "value2": "", | ||
| "value3": "", | ||
| } | ||
| response = requests.post(url, json=payload) | ||
|
|
||
|
|
||
| # Function to send a price drop alert | ||
| def send_price_drop(event, symbol, current_price, previous_price): | ||
| message = f"ALERT: The stock {symbol} has fallen. Previous Price: ${previous_price:.2f}. Current Price: ${current_price:.2f}. Consider buying now!" | ||
| send_ifttt_webhook(event, message) | ||
|
|
||
|
|
||
| # Function to send an alert when the price is below the 7-day average | ||
| def send_avg_price_drop(event, symbol, current_price, daily_avg): | ||
| message = f"ALERT: {symbol}'s current price of ${current_price:.2f} is below the 7-day average of ${daily_avg:.2f}. Consider buying!" | ||
| send_ifttt_webhook(event, message) |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great readme! A step-by-step guide for the stakeholders to ensure the application runs smoothly and that they can receive the IFTTT alerts. Very helpful!