diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..cc40766 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +.env +AUTH/ +credentials.json \ No newline at end of file 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..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,43 +199,34 @@ 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')) +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 - # Create SMTP session for sending the mail - session = smtplib.SMTP('smtp.gmail.com', 587) # use gmail with port - session.starttls() # enable security + except HTTPError as error: + print(f'An error occurred: {error}') - # 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) + 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 @@ -281,7 +269,7 @@ def main(): except: pass mail_content = buy(stock_to_buy) - mail_alert(mail_content, 5) + alert_user(mail_content) continue else: @@ -300,7 +288,8 @@ 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) else: @@ -318,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') @@ -328,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) @@ -337,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() 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