python 量化交易,將處理完的數(shù)據(jù),自動(dòng)發(fā)送至郵箱——量化03
自動(dòng)發(fā)送郵件代碼
import?pandas?as?pd import?smtplib from?email.mime.text?import?MIMEText from?email.mime.multipart?import?MIMEMultipart from?email.mime.base?import?MIMEBase from?email?import?encoders from?email.header?import?Header from?email.utils?import?formataddr import?sqlite3 from?datetime?import?datetime,?timedelta,?time #?批量自動(dòng)化給訂閱用戶發(fā)送郵件 #?查詢并提取場(chǎng)內(nèi)基金網(wǎng)格交易數(shù)據(jù)表'fund_grid_trading'近20分鐘生成的內(nèi)容,保存為pd def?get_recent_data(table_name): ????#?連接數(shù)據(jù)庫 ????conn?=?sqlite3.connect(r'D:\wenjian\python\smart\data\my_data.db') ????c?=?conn.cursor() ????#?獲取當(dāng)前時(shí)間和20分鐘前的時(shí)間 ????now?=?datetime.now() ????twenty_minutes_ago?=?now?-?timedelta(minutes=20) ????#?查詢最近20分鐘的數(shù)據(jù) ????query?=?f"SELECT?*?FROM?{table_name}?WHERE?時(shí)間?BETWEEN???AND??" ????results?=?pd.read_sql_query(query,?conn,?params=(twenty_minutes_ago.strftime('%Y-%m-%d?%H:%M'),?now.strftime('%Y-%m-%d?%H:%M'))) ????#?關(guān)閉數(shù)據(jù)庫連接 ????conn.close() ????return?results def?send_email(receiver,?table_name,?file_path1=None,?file_path2=None): ????#?郵件發(fā)送方的信息 ????sender?=?'電子郵箱'???#?與下方的SMTP保持一致——smtp_obj?=?smtplib.SMTP_SSL('smtp.exmail.qq.com',?465) ????password?=?'客戶端密碼' ????#?郵件主題和內(nèi)容 ????subject?=?'微信公眾號(hào)“余漢波”的訂閱郵件' ????#?獲取當(dāng)前時(shí)間的時(shí)間部分 ????current_time?=?datetime.now().time() ????#?根據(jù)條件設(shè)置郵件內(nèi)容 ????if?table_name?==?'fund_grid_trading': ????????content?=?'場(chǎng)內(nèi)基金網(wǎng)格交易策略' ????elif?table_name?==?'trade_func': ????????if?time(10,?0)?<?current_time?<?time(11,?0): ????????????content?=?'A股、港股和場(chǎng)內(nèi)基金交易策略' ????????elif?time(21,?0)?<?current_time?<?time(22,?0): ????????????content?=?'美股交易策略' ????????else: ????????????content?=?'微信公眾號(hào)“余漢波”的訂閱郵件' ????else: ????????content?=?'微信公眾號(hào)“余漢波”的訂閱郵件' ????#?創(chuàng)建郵件對(duì)象 ????message?=?MIMEMultipart() ????message['From']?=?formataddr((Header(sender,?'utf-8').encode(),?sender)) ????message['To']?=?formataddr((Header(receiver,?'utf-8').encode(),?receiver)) ????message['Subject']?=?Header(subject,?'utf-8') ????filtered_data?=?get_recent_data(table_name) ????#?檢查結(jié)果是否為空 ????if?filtered_data.empty: ????????print('結(jié)果為空,不發(fā)送郵件') ????????return ????html?=?filtered_data.to_html(index=False) ????#?添加郵件正文 ????#?message.attach(MIMEText(content,?'plain',?'utf-8')) ????message.attach(MIMEText(content?+?html,?'html')) ????#?添加附件1 ????if?file_path1?is?not?None: ????????with?open(file_path1,?'rb')?as?f: ????????????attachment?=?MIMEBase('application',?'octet-stream') ????????????attachment.set_payload(f.read()) ????????????encoders.encode_base64(attachment) ????????????attachment.add_header('Content-Disposition',?'attachment',?filename=('utf-8',?'',?file_path1.split('\\')[-1])) ????????????message.attach(attachment) ????#?添加附件2 ????if?file_path2?is?not?None: ????????with?open(file_path2,?'rb')?as?f: ????????????attachment?=?MIMEBase('application',?'octet-stream') ????????????attachment.set_payload(f.read()) ????????????encoders.encode_base64(attachment) ????????????attachment.add_header('Content-Disposition',?'attachment',?filename=('utf-8',?'',?file_path2.split('\\')[-1])) ????????????message.attach(attachment) ????#?發(fā)送郵件,若切換郵箱需要修改SMTP ????try: ????????smtp_obj?=?smtplib.SMTP_SSL('smtp.exmail.qq.com',?465) ????????smtp_obj.login(sender,?password) ????????smtp_obj.sendmail(sender,?receiver,?message.as_string()) ????????print('郵件發(fā)送成功') ????except?smtplib.SMTPException?as?e: ????????print('郵件發(fā)送失敗:',?e) #?讀取excel表格中的郵箱地址,參數(shù)有三個(gè),第1個(gè)是郵箱的表,第2和第3是附件,可以省略。 def?send_emails_from_excel(sheet_name,?table_name,?file_path1=None,?file_path2=None): ????#?讀取Excel文件 ????df?=?pd.read_excel(r'D:\wenjian\python\smart\data\sub_user.xlsx',?sheet_name=sheet_name) ????#?獲取郵箱列數(shù)據(jù) ????emails?=?df['郵箱'] ????#?循環(huán)發(fā)送郵件并打印 ????for?receiver?in?emails: ????????send_email(receiver,?table_name,?file_path1,?file_path2) if?__name__?==?'__main__': ????#?print(get_recent_data('fund_grid_trading')) ????send_emails_from_excel('一般',?'fund_grid_trading')
代碼說明
代碼有三個(gè)自定義函數(shù):
get_recent_data(table_name):查詢并提取近20分鐘生成的內(nèi)容,保存為 pd,參數(shù)為數(shù)據(jù)庫的表名稱。
send_email(receiver, table_name, file_path1=None, file_path2=None):讀取 excel 表中的郵箱地址,將函數(shù) get_recent_data(table_name)生成的 pd 轉(zhuǎn)成 html,并發(fā)送。參數(shù)有 4 個(gè),第一個(gè)參數(shù)是下面函數(shù)的函數(shù),不用理它;第二個(gè)參數(shù)是數(shù)據(jù)庫的表名稱;第三和第四個(gè)參數(shù)都為增加的附件,若沒有附件不用理它,默認(rèn)為沒有。
send_emails_from_excel(sheet_name, table_name, file_path1=None, file_path2=None):讀取excel表格中的郵箱地址,參數(shù)有4個(gè),第1個(gè)是郵箱的表,第2是數(shù)據(jù)庫表的名稱,第3和第4是附件,可以省略。
需修改的代碼
conn = sqlite3.connect(r'D:\wenjian\python\smart\data\my_data.db'):改成你的數(shù)據(jù)庫的路徑,進(jìn)行連接。
twenty_minutes_ago = now - timedelta(minutes=20):修改發(fā)送的條件,比如這里是發(fā)送近 20 分鐘獲取數(shù)據(jù)的內(nèi)容。
sender = '電子郵箱':修改成發(fā)件人郵箱地址。
password = '客戶端密碼':修改成發(fā)件人的客戶端密碼,注意并不是登陸密碼,是 SMTP 客戶端上面的密碼。
根據(jù)條件設(shè)置郵件內(nèi)容:這部分是判斷數(shù)據(jù)表的條件,滿足不同的條件發(fā)送不同的內(nèi)容,看自己的需求要不要這部分內(nèi)容。
smtp_obj = smtplib.SMTP_SSL('smtp.exmail.qq.com', 465):修改郵箱對(duì)應(yīng)的 SMTP 服務(wù)器。
df = pd.read_excel(r'D:\wenjian\python\smart\data\sub_user.xlsx', sheet_name=sheet_name):修改接收方的郵箱,這里是存在放在 excel 中,需要修改路徑。
send_emails_from_excel('一般', 'fund_grid_trading'):修改“一般”的 excel 路徑的表,修改 'fund_grid_trading'需要發(fā)送數(shù)據(jù)庫數(shù)據(jù)的表名稱。若需發(fā)送附件,在括號(hào)中直接增加附件的路徑,最多支持 2 個(gè)附件;若要發(fā)送多個(gè)附件,需對(duì)函數(shù) send_email(receiver, table_name, file_path1=None, file_path2=None)進(jìn)行增加。