监控有溢价的ETF发邮件
import akshare as ak
import pandas as pd
import numpy as np
import os
import yagmail
from datetime import datetime
def fetch_qdii_data():
"""
从集思录获取T+0 QDII数据
"""
try:
qdii_data = ak.qdii_e_index_jsl()
return qdii_data
except Exception as e:
print(f"获取数据失败: {e}")
return None
def clean_data(data):
"""
清洗数据,处理非数值占位符
"""
if data is None:
return None
# 替换 '-' 为 NaN
data = data.replace('-', np.nan)
# 转换数据类型
data['现价'] = pd.to_numeric(data['现价'], errors='coerce')
data['T-1溢价率'] = pd.to_numeric(data['T-1溢价率'].str.strip('%'), errors='coerce')
return data
def filter_and_monitor_premium_rate(data, threshold=1):
"""
保留LOF和ETF基金,将LOF放在前面,ETF放在后面,并监控溢价率高于阈值的基金
"""
if data is None:
print("数据为空,无法进行监控。")
return None
# 筛选出溢价率高于阈值的基金
high_premium_funds = data[data['T-1溢价率'] > threshold]
# 分离LOF和ETF基金
lof_funds = high_premium_funds[high_premium_funds['名称'].str.contains("LOF")]
etf_funds = high_premium_funds[~high_premium_funds['名称'].str.contains("LOF")]
# 将LOF和ETF基金合并,LOF在前,ETF在后
result = pd.concat([lof_funds, etf_funds], ignore_index=True)
return result
def send_email(index_results, today):
"""
发送邮件功能
"""
try:
# 邮箱配置
from_email = os.getenv("from_email") # 发件人邮箱
password = os.getenv("password") # 发件人邮箱密码或授权码
to_email = os.getenv("to_email") # 收件人邮箱
# 邮件主题
subject = f"溢价率高于1%的基金报告 ({today})"
# 邮件正文内容
text_content = f"日期: {today}\n\n"
text_content += "以下为溢价率高于1%的基金信息:\n\n"
for idx, row in index_results.iterrows():
text_content += f"基金代码: {row['代码']}\n"
text_content += f"基金名称: {row['名称']}\n"
text_content += f"现价: {row['现价']}\n"
text_content += f"T-1溢价率: {row['T-1溢价率']}%\n"
text_content+='\n'
# 发送邮件
yag = yagmail.SMTP(user=from_email, password=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():
print("开始获取QDII数据...")
qdii_data = fetch_qdii_data()
if qdii_data is not None:
print("清洗数据...")
cleaned_data = clean_data(qdii_data)
if cleaned_data is not None:
print("过滤并监控溢价率...")
high_premium_funds = filter_and_monitor_premium_rate(cleaned_data, threshold=1)
if high_premium_funds is not None and not high_premium_funds.empty:
print(f"发现溢价率高于1%的基金,详情如下:")
print(high_premium_funds[['代码', '名称', '现价', 'T-1溢价率', '涨幅']])
# 发送邮件
today = datetime.now().strftime("%Y-%m-%d")
send_email(high_premium_funds, today)
else:
print("当前没有溢价率高于1%且可申购的基金。")
else:
print("数据清洗失败,请检查数据格式。")
else:
print("未获取到数据,请检查接口或网络连接。")
if __name__ == "__main__":
main()