From cd6e6fa455274c36192331fe42b3406e5ba590a8 Mon Sep 17 00:00:00 2001 From: Manindra de Mel Date: Sat, 3 Jun 2023 18:25:24 +1000 Subject: [PATCH 1/3] Update git ignore --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..71da68f --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.env +AUTH/ From af8c43a3db0773e765e9d144c8991510822fa72c Mon Sep 17 00:00:00 2001 From: Manindra de Mel Date: Sat, 3 Jun 2023 18:36:37 +1000 Subject: [PATCH 2/3] Updated Requirements, added new mail auth implementation, removed old mail_auth, added base credentials --- credentials.json | 15 +++++++++ mail_auth.py | 86 ++++++++++++++++++++++++++++++++++++++++++++++++ main.py | 41 +++++------------------ requirements.txt | 4 +++ 4 files changed, 113 insertions(+), 33 deletions(-) create mode 100644 credentials.json create mode 100644 mail_auth.py diff --git a/credentials.json b/credentials.json new file mode 100644 index 0000000..99abcf6 --- /dev/null +++ b/credentials.json @@ -0,0 +1,15 @@ +{ + "installed": { + "client_id": "YOUR_CLIENT_ID", + "project_id": "YOUR_PROJECT_ID", + "auth_uri": "https://accounts.google.com/o/oauth2/auth", + "token_uri": "https://oauth2.googleapis.com/token", + "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs", + "client_secret": "YOUR_CLIENT_SECRET", + "redirect_uris": [ + "urn:ietf:wg:oauth:2.0:oob", + "http://localhost" + ] + } + } + \ No newline at end of file diff --git a/mail_auth.py b/mail_auth.py new file mode 100644 index 0000000..a605ef3 --- /dev/null +++ b/mail_auth.py @@ -0,0 +1,86 @@ +from google.oauth2.credentials import Credentials +from google_auth_oauthlib.flow import InstalledAppFlow +from google.auth.transport.requests import Request +import os.path +import base64 +from googleapiclient.discovery import build +from googleapiclient.errors import HttpError +from googleapiclient.http import MediaIoBaseDownload +from email.mime.text import MIMEText +import base64 +from googleapiclient.errors import HttpError + + +# If modifying these SCOPES, delete the file token.json. +SCOPES = ['https://www.googleapis.com/auth/gmail.modify'] + +def main(): + """Shows basic usage of the Gmail API. + Lists the user's Gmail labels. + """ + creds = None + # The file token.json stores the user's access and refresh tokens, and is + # created automatically when the authorization flow completes for the first + # time. + if os.path.exists('token.json'): + creds = Credentials.from_authorized_user_file('token.json') + # If there are no (valid) credentials available, let the user log in. + if not creds or not creds.valid: + if creds and creds.expired and creds.refresh_token: + creds.refresh(Request()) + else: + flow = InstalledAppFlow.from_client_secrets_file( + 'credentials.json', SCOPES) + creds = flow.run_local_server(port=0) + # Save the credentials for the next run + with open('token.json', 'w') as token: + token.write(creds.to_json()) + + try: + # Call the Gmail API + service = build('gmail', 'v1', credentials=creds) + # send email here + except Exception as error: + print(f'An error occurred: {error}') + +def create_message(sender, to, subject, message_text): + """Create a message for an email. + + Args: + sender: Email address of the sender. + to: Email address of the receiver. + subject: The subject of the email message. + message_text: The text of the email message. + + Returns: + An object containing a base64url encoded email object. + """ + message = MIMEText(message_text) + message['to'] = to + message['from'] = sender + message['subject'] = subject + return {'raw': base64.urlsafe_b64encode(message.as_string().encode('utf-8')).decode('utf-8')} + +def send_message(service, user_id, message): + """Send an email message. + + Args: + service: Authorized Gmail API service instance. + user_id: User's email address. The special value "me" can be used to indicate the authenticated user. + message: Message to be sent. + + Returns: + Sent Message. + """ + try: + message = (service.users().messages().send(userId=user_id, body=message) + .execute()) + print('Message Id: %s' % message['id']) + return message + except HttpError as error: + print(f'An error occurred: {error}') + + + +if __name__ == '__main__': + main() diff --git a/main.py b/main.py index 1ce002c..d8a636c 100644 --- a/main.py +++ b/main.py @@ -202,43 +202,17 @@ def check_rets(current_stock): mail_content = 0 return mail_content -def mail_alert(mail_content, sleep_time): - # The mail addresses and password - sender_address = 'sender_address' - sender_pass = 'sender_password' - receiver_address = 'receiver_address' - - # Setup MIME - message = MIMEMultipart() - message['From'] = 'Trading Bot' - message['To'] = receiver_address - message['Subject'] = 'HFT Second-Bot' - - # The body and the attachments for the mail - message.attach(MIMEText(mail_content, 'plain')) - - # Create SMTP session for sending the mail - session = smtplib.SMTP('smtp.gmail.com', 587) # use gmail with port - session.starttls() # enable security - - # login with mail_id and password - session.login(sender_address, sender_pass) - text = message.as_string() - session.sendmail(sender_address, receiver_address, text) - session.quit() - time.sleep(sleep_time) - def main(): if api.get_clock().is_open == True: # sends mail when bot starts running mail_content = 'The bot started running on {} at {} UTC'.format(dt.now().strftime('%Y-%m-%d'), dt.now().strftime('%H:%M:%S')) - mail_alert(mail_content, 0) + # mail_alert(mail_content, 0) while True: if api.get_account().pattern_day_trader == True: - mail_alert('Pattern day trading notification, bot is stopping now', 0) + # mail_alert('Pattern day trading notification, bot is stopping now', 0) break tickers = TICKERS @@ -281,7 +255,7 @@ def main(): except: pass mail_content = buy(stock_to_buy) - mail_alert(mail_content, 5) + # mail_alert(mail_content, 5) continue else: @@ -300,7 +274,8 @@ def main(): if any(mail_content_list): for mail in mail_content_list: if mail != 0: - mail_alert(mail, 0) + # mail_alert(mail, 0) + pass else: time.sleep(3) else: @@ -318,7 +293,7 @@ def main(): print('All Ask < LTP') continue mail_content = buy(stock_to_buy) - mail_alert(mail_content, 5) + # mail_alert(mail_content, 5) df = pd.DataFrame() df['First Stock'] = stock_to_buy df.to_csv('FirstTrade.csv') @@ -328,7 +303,7 @@ def main(): continue else: mail_content = 'The market is closed now' - mail_alert(mail_content, 0) + # mail_alert(mail_content, 0) break except Exception as e: print(e) @@ -337,7 +312,7 @@ def main(): if api.get_clock().is_open == False: # sends mail when bot starts running mail_content = 'The bot stopped running on {} at {} UTC'.format(dt.now().strftime('%Y-%m-%d'), dt.now().strftime('%H:%M:%S')) - mail_alert(mail_content, 0) + # mail_alert(mail_content, 0) if __name__ == '__main__': main() diff --git a/requirements.txt b/requirements.txt index 6955fa9..87fdaa3 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,7 @@ alpaca_trade_api==2.0.0 pandas==1.4.1 numpy==1.22.3 +google-api-python-client==2.88.0 +google-auth==2.19.1 +google-auth-httplib2==0.1.0 +google-auth-oauthlib==1.0.0 From b92abbf862192062141a4df0349aca2d92ec801f Mon Sep 17 00:00:00 2001 From: Manindra de Mel Date: Sat, 3 Jun 2023 18:45:06 +1000 Subject: [PATCH 3/3] Integrated new code with main --- .gitignore | 1 + main.py | 40 +++++++++++++++++++++++++++------------- 2 files changed, 28 insertions(+), 13 deletions(-) diff --git a/.gitignore b/.gitignore index 71da68f..cc40766 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ .env AUTH/ +credentials.json \ No newline at end of file diff --git a/main.py b/main.py index d8a636c..a6611dd 100644 --- a/main.py +++ b/main.py @@ -1,19 +1,16 @@ import pandas as pd -import datetime from datetime import datetime as dt from pytz import timezone import time - +import mail_auth as mail import alpaca_trade_api as alpaca import json -import smtplib -from email.mime.multipart import MIMEMultipart -from email.mime.text import MIMEText - from datetime import timedelta import os.path +from requests import HTTPError + key = json.loads(open('AUTH/auth.txt', 'r').read()) api = alpaca.REST(key['APCA-API-KEY-ID'], key['APCA-API-SECRET-KEY'], base_url='https://api.alpaca.markets', api_version = 'v2') tickers = open('AUTH/Tickers.txt', 'r').read() @@ -202,17 +199,34 @@ def check_rets(current_stock): mail_content = 0 return mail_content +def alert_user(message): + try: + to = "reciever_email" + from_ = "sender_email" + subject = "ALERT" + # Creating the message + message_to_send = mail.create_message(from_, to, subject, message) + + # Sending the message + result = mail.send_message("me", message_to_send) + print('Message sent') + return result + + except HTTPError as error: + print(f'An error occurred: {error}') + + def main(): if api.get_clock().is_open == True: # sends mail when bot starts running mail_content = 'The bot started running on {} at {} UTC'.format(dt.now().strftime('%Y-%m-%d'), dt.now().strftime('%H:%M:%S')) - # mail_alert(mail_content, 0) + alert_user(mail_content) while True: if api.get_account().pattern_day_trader == True: - # mail_alert('Pattern day trading notification, bot is stopping now', 0) + alert_user('Pattern day trading notification, bot is stopping now') break tickers = TICKERS @@ -255,7 +269,7 @@ def main(): except: pass mail_content = buy(stock_to_buy) - # mail_alert(mail_content, 5) + alert_user(mail_content) continue else: @@ -274,7 +288,7 @@ def main(): if any(mail_content_list): for mail in mail_content_list: if mail != 0: - # mail_alert(mail, 0) + alert_user(mail) pass else: time.sleep(3) @@ -293,7 +307,7 @@ def main(): print('All Ask < LTP') continue mail_content = buy(stock_to_buy) - # mail_alert(mail_content, 5) + alert_user(mail_content) df = pd.DataFrame() df['First Stock'] = stock_to_buy df.to_csv('FirstTrade.csv') @@ -303,7 +317,7 @@ def main(): continue else: mail_content = 'The market is closed now' - # mail_alert(mail_content, 0) + alert_user(mail_content) break except Exception as e: print(e) @@ -312,7 +326,7 @@ def main(): if api.get_clock().is_open == False: # sends mail when bot starts running mail_content = 'The bot stopped running on {} at {} UTC'.format(dt.now().strftime('%Y-%m-%d'), dt.now().strftime('%H:%M:%S')) - # mail_alert(mail_content, 0) + alert_user(mail_content) if __name__ == '__main__': main()