监控美股指数
代码如下
import akshare as ak
import pandas as pd
from datetime import datetime, timedelta
import os
import yagmail
def get_price_change(symbol, period):
end_date = datetime.now()
if period == '1m':
start_date = end_date - timedelta(days=30)
elif period == '3m':
start_date = end_date - timedelta(days=90)
elif period == '1y':
start_date = end_date - timedelta(days=365)
elif period == '3y':
start_date = end_date - timedelta(days=3 * 365)
elif period == '5y':
start_date = end_date - timedelta(days=5 * 365)
elif period == '10y':
start_date = end_date - timedelta(days=10 * 365)
elif period == '20y':
start_date = end_date - timedelta(days=20 * 365)
else:
raise ValueError("Invalid period. Choose from '1m', '3m', '1y', '3y', '5y', '10y', '20y'.")
df = ak.index_us_stock_sina(symbol=symbol)
df['date'] = pd.to_datetime(df['date'])
df_filtered = df[(df['date'] >= start_date) & (df['date'] <= end_date)]
df_filtered = df_filtered.sort_values(by='date', ascending=True)
if not df_filtered.empty:
start_price = df_filtered.iloc[0]['close']
end_price = df_filtered.iloc[-1]['close']
price_change = (end_price - start_price) / start_price * 100
return price_change
else:
return None
def calculate_annualized_return(symbol, years):
end_date = datetime.now()
start_date = end_date - timedelta(days=years * 365)
df = ak.index_us_stock_sina(symbol=symbol)
df['date'] = pd.to_datetime(df['date'])
df_filtered = df[(df['date'] >= start_date) & (df['date'] <= end_date)]
df_filtered = df_filtered.sort_values(by='date', ascending=True)
if not df_filtered.empty:
start_price = df_filtered.iloc[0]['close']
end_price = df_filtered.iloc[-1]['close']
annualized_return = ((end_price / start_price) ** (1 / years) - 1) * 100
return annualized_return
else:
return None
def send_email(html_content, today, attachment_path):
try:
# 邮件主题
subject = f"指数涨跌幅及年化收益率报告 ({today})"
# 初始化 yagmail
yag = yagmail.SMTP(user=os.getenv('from_email'), password=os.getenv('password'), host='smtp.qq.com', port=465, smtp_ssl=True)
# 发送邮件
yag.send(to=os.getenv('to_email'), subject=subject, contents=[html_content, yagmail.inline(attachment_path)])
print("邮件发送成功")
except Exception as e:
print(f"邮件发送失败: {e}")
# 定义要监控的指数及其中文名
indices = {
'.NDX': '纳斯达克100指数',
'.IXIC': '纳斯达克综合指数',
'.INX': '标普500指数',
'.DJI': '道琼斯工业平均指数'
}
# 定义要监控的周期
periods = ['1m', '3m', '1y', '3y', '5y', '10y', '20y']
# 创建一个DataFrame来存储结果
results = pd.DataFrame(index=[f"{symbol} ({name})" for symbol, name in indices.items()],
columns=periods + ['5y年化', '10y年化', '20y年化'])
# 计算每个指数在每个周期的涨跌幅
for symbol, name in indices.items():
for period in periods:
change = get_price_change(symbol, period)
results.at[f"{symbol} ({name})", period] = f"{change:.2f}%" if change is not None else "N/A"
# 计算近5年、10年和20年的年化收益率
for years in [5, 10, 20]:
annualized_return = calculate_annualized_return(symbol, years)
results.at[f"{symbol} ({name})", f'{years}y年化'] = f"{annualized_return:.2f}%" if annualized_return is not None else "N/A"
# 将结果保存到Excel文件
excel_path = "index_data.xlsx"
results.to_excel(excel_path, sheet_name="Index Data")
# 生成HTML内容
html_content = results.to_html(classes="table table-striped")
# 获取当前日期
today = datetime.now().strftime("%Y-%m-%d")
# 发送邮件
send_email(html_content, today, excel_path)