153 lines
4.6 KiB
Python
153 lines
4.6 KiB
Python
|
|
#!/usr/bin/env python3
|
|||
|
|
"""
|
|||
|
|
更新美股持仓数据库 - 批量更新
|
|||
|
|
"""
|
|||
|
|
|
|||
|
|
import requests
|
|||
|
|
import json
|
|||
|
|
from datetime import datetime
|
|||
|
|
|
|||
|
|
# Notion API 配置
|
|||
|
|
NOTION_API_KEY = "ntn_c43902219395mirQBetIfYoww1qKCAF14GBRUQeDee29o2"
|
|||
|
|
DATABASE_ID = "2fb105ad-7873-8175-bbbd-e5b87cf101d9"
|
|||
|
|
|
|||
|
|
# 持仓数据
|
|||
|
|
positions = [
|
|||
|
|
{"symbol": "BND", "shares": 6.7219, "cost": 501.83},
|
|||
|
|
{"symbol": "SGOV", "shares": 33.7072, "cost": 3380.48},
|
|||
|
|
{"symbol": "VOO", "shares": 3.1963, "cost": 1969.46}
|
|||
|
|
]
|
|||
|
|
|
|||
|
|
# 当前价格(从搜索结果获取)
|
|||
|
|
current_prices = {
|
|||
|
|
"BND": 74.22,
|
|||
|
|
"SGOV": 100.44,
|
|||
|
|
"VOO": 636.09
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
def get_current_price(symbol):
|
|||
|
|
"""获取当前价格"""
|
|||
|
|
return current_prices.get(symbol, 0)
|
|||
|
|
|
|||
|
|
def calculate_pnl(shares, cost, current_price):
|
|||
|
|
"""计算盈亏"""
|
|||
|
|
market_value = shares * current_price
|
|||
|
|
total_cost = cost
|
|||
|
|
pnl_amount = market_value - total_cost
|
|||
|
|
pnl_percent = (pnl_amount / total_cost * 100) if total_cost > 0 else 0
|
|||
|
|
return market_value, total_cost, pnl_amount, pnl_percent
|
|||
|
|
|
|||
|
|
def update_notion_page(page_id, symbol, shares, cost, current_price, market_value, pnl_amount, pnl_percent):
|
|||
|
|
"""更新Notion页面"""
|
|||
|
|
url = f"https://api.notion.com/v1/pages/{page_id}"
|
|||
|
|
|
|||
|
|
headers = {
|
|||
|
|
"Authorization": f"Bearer {NOTION_API_KEY}",
|
|||
|
|
"Content-Type": "application/json",
|
|||
|
|
"Notion-Version": "2022-06-28"
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# 获取当前时间(UTC+8)
|
|||
|
|
now = datetime.utcnow()
|
|||
|
|
date_str = now.strftime("%Y-%m-%d %H:%M")
|
|||
|
|
|
|||
|
|
data = {
|
|||
|
|
"properties": {
|
|||
|
|
"股票代码": {"title": [{"text": {"content": symbol}}]},
|
|||
|
|
"持仓数量": {"number": shares},
|
|||
|
|
"买入成本": {"number": cost},
|
|||
|
|
"当前价格": {"number": current_price},
|
|||
|
|
"总成本": {"number": cost},
|
|||
|
|
"当前市值": {"number": market_value},
|
|||
|
|
"盈亏金额": {"number": round(pnl_amount, 2)},
|
|||
|
|
"盈亏百分比": {"number": round(pnl_percent, 2)},
|
|||
|
|
"最后更新": {"date": {"start": date_str}}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
response = requests.patch(url, headers=headers, json=data)
|
|||
|
|
return response.status_code == 200
|
|||
|
|
|
|||
|
|
def find_page_by_symbol(symbol):
|
|||
|
|
"""根据股票代码查找页面ID"""
|
|||
|
|
url = "https://api.notion.com/v1/databases/" + DATABASE_ID + "/query"
|
|||
|
|
|
|||
|
|
headers = {
|
|||
|
|
"Authorization": f"Bearer {NOTION_API_KEY}",
|
|||
|
|
"Content-Type": "application/json",
|
|||
|
|
"Notion-Version": "2022-06-28"
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
data = {
|
|||
|
|
"filter": {
|
|||
|
|
"property": "股票代码",
|
|||
|
|
"title": {
|
|||
|
|
"equals": symbol
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
response = requests.post(url, headers=headers, json=data)
|
|||
|
|
|
|||
|
|
if response.status_code == 200:
|
|||
|
|
results = response.json().get("results", [])
|
|||
|
|
if results:
|
|||
|
|
return results[0]["id"]
|
|||
|
|
return None
|
|||
|
|
|
|||
|
|
def main():
|
|||
|
|
print("开始更新美股持仓数据库...")
|
|||
|
|
print("=" * 50)
|
|||
|
|
|
|||
|
|
total_market_value = 0
|
|||
|
|
total_cost = 0
|
|||
|
|
total_pnl = 0
|
|||
|
|
|
|||
|
|
for position in positions:
|
|||
|
|
symbol = position["symbol"]
|
|||
|
|
shares = position["shares"]
|
|||
|
|
cost = position["cost"]
|
|||
|
|
|
|||
|
|
print(f"\n处理 {symbol}...")
|
|||
|
|
|
|||
|
|
# 获取当前价格
|
|||
|
|
current_price = get_current_price(symbol)
|
|||
|
|
print(f" 当前价格: ${current_price:.2f}")
|
|||
|
|
|
|||
|
|
# 计算盈亏
|
|||
|
|
market_value, total_cost_val, pnl_amount, pnl_percent = calculate_pnl(shares, cost, current_price)
|
|||
|
|
print(f" 持仓数量: {shares}")
|
|||
|
|
print(f" 成本: ${cost:.2f}")
|
|||
|
|
print(f" 市值: ${market_value:.2f}")
|
|||
|
|
print(f" 盈亏: ${pnl_amount:.2f} ({pnl_percent:.2f}%)")
|
|||
|
|
|
|||
|
|
# 查找页面ID
|
|||
|
|
page_id = find_page_by_symbol(symbol)
|
|||
|
|
|
|||
|
|
if page_id:
|
|||
|
|
# 更新现有页面
|
|||
|
|
success = update_notion_page(page_id, symbol, shares, cost, current_price, market_value, pnl_amount, pnl_percent)
|
|||
|
|
if success:
|
|||
|
|
print(f" ✅ Notion页面更新成功")
|
|||
|
|
else:
|
|||
|
|
print(f" ❌ Notion页面更新失败")
|
|||
|
|
else:
|
|||
|
|
print(f" ⚠️ 未找到 {symbol} 的持仓记录")
|
|||
|
|
|
|||
|
|
# 累计数据
|
|||
|
|
total_market_value += market_value
|
|||
|
|
total_cost += total_cost_val
|
|||
|
|
total_pnl += pnl_amount
|
|||
|
|
|
|||
|
|
# 总计
|
|||
|
|
print("\n" + "=" * 50)
|
|||
|
|
print("总计:")
|
|||
|
|
print(f" 总市值: ${total_market_value:.2f}")
|
|||
|
|
print(f" 总成本: ${total_cost:.2f}")
|
|||
|
|
print(f" 总盈亏: ${total_pnl:.2f} ({total_pnl/total_cost*100:.2f}%)")
|
|||
|
|
print("=" * 50)
|
|||
|
|
print("更新完成!")
|
|||
|
|
|
|||
|
|
if __name__ == "__main__":
|
|||
|
|
main()
|