一个监控ETF收益并发邮件的脚本
import pandas as pd
import akshare as ak
import yagmail
from datetime import datetime, timedelta
# QQ 邮箱配置
QQ_EMAIL = "xx@qq.com" # 发件人邮箱
QQ_PASSWORD ="xx" # 发件人邮箱密码或授权码
TO_EMAIL = "xx@qq.com" # 收件人邮箱
# ETF代码与名称的映射
etf_names = {
'510300': '300ETF',
'159915': '创业板',
'513050': '中概互联网ETF',
'159941': '纳指ETF',
'518880': '黄金ETF',
'511090': '30年国债ETF',
'512890': '红利低波'
}
# 获取ETF数据的函数
def fetch_etf_data(symbol="510300"):
# 使用 akshare 的 fund_etf_hist_em 接口获取 ETF 数据
df = ak.fund_etf_hist_em(symbol=symbol, period="daily", adjust='qfq')
# 转换日期格式
df['日期'] = pd.to_datetime(df['日期']) # 假设日期列名为 '日期'
df.set_index('日期', inplace=True)
# 重命名列以符合标准格式
df.rename(columns={
'开盘': 'Open',
'最高': 'High',
'最低': 'Low',
'收盘': 'Close',
'成交量': 'Volume'
}, inplace=True)
return df
# 计算收益率
def calculate_return(df, period):
if period == '1w':
start_date = datetime.now() - timedelta(days=7)
elif period == '1m':
start_date = datetime.now() - timedelta(days=30)
elif period == '1y':
start_date = datetime.now() - timedelta(days=365)
elif period == '3y':
start_date = datetime.now() - timedelta(days=365*3)
else:
raise ValueError("Invalid period")
start_date = start_date.strftime('%Y-%m-%d')
end_date = datetime.now().strftime('%Y-%m-%d')
start_price = df.loc[start_date:end_date, 'Close'].iloc[0]
end_price = df.loc[start_date:end_date, 'Close'].iloc[-1]
return (end_price - start_price) / start_price
# 获取所有ETF的收益率
def get_etf_returns(etf_list):
etf_returns = []
for symbol in etf_list:
df = fetch_etf_data(symbol)
returns = {
'1w': calculate_return(df, '1w'),
'1m': calculate_return(df, '1m'),
'1y': calculate_return(df, '1y'),
'3y': calculate_return(df, '3y')
}
etf_returns.append((symbol, etf_names[symbol], returns))
return etf_returns
# 按照最近一个月的收益率排序
def sort_etfs_by_1m_return(etf_returns):
return sorted(etf_returns, key=lambda x: x[2]['1m'], reverse=True)
# 发送邮件
def send_email(etf_returns, today):
try:
# 邮件主题
subject = f"ETF监控率报告 ({today})"
# 邮件正文内容
text_content = f"""
日期: {today}
以下是今日ETF的收益率分析(按近一个月收益率排序):
"""
for symbol, name, returns in etf_returns:
text_content += f"\n{symbol} ({name})\n"
text_content += f"近一周收益率: {returns['1w']:.2%}\n"
text_content += f"近一个月收益率: {returns['1m']:.2%}\n"
text_content += f"近一年收益率: {returns['1y']:.2%}\n"
text_content += f"近三年收益率: {returns['3y']:.2%}\n"
# 初始化 yagmail
yag = yagmail.SMTP(user=QQ_EMAIL, password=QQ_PASSWORD, host='smtp.qq.com', port=465, smtp_ssl=True)
# 发送邮件
yag.send(to=TO_EMAIL, subject=subject, contents=[text_content])
print("邮件发送成功")
except Exception as e:
print(f"邮件发送失败: {e}")
# 主函数
def main():
# 获取当前日期
today = datetime.now().strftime("%Y-%m-%d")
# ETF列表
etf_list = ['510300', '159915', '513050', '159941', '518880','512890']
# 获取所有ETF的收益率
etf_returns = get_etf_returns(etf_list)
# 按照最近一个月的收益率排序
etf_returns_sorted = sort_etfs_by_1m_return(etf_returns)
# 发送邮件
send_email(etf_returns_sorted, today)
# 运行主函数
if __name__ == "__main__":
main()