#!/usr/bin/env python3 """ 每日投资报告 - 用户表: 代码 + 持仓数量 + 持仓成本(每股成本价) - 自动计算: 总成本 = 持仓成本 × 持仓数量 """ from datetime import datetime USER_DB_ID = "2fb105ad78738175bbbde5b87cf101d9" NOTION_TOKEN = "ntn_c43902219395mirQBetIfYoww1qKCAF14GBRUQeDee29o2" def get_user_holdings(): import requests url = f"https://api.notion.com/v1/databases/{USER_DB_ID}/query" headers = { "Authorization": f"Bearer {NOTION_TOKEN}", "Content-Type": "application/json", "Notion-Version": "2022-06-28" } response = requests.post(url, headers=headers, json={}, timeout=30) if response.status_code == 200: data = response.json() holdings = [] for item in data.get("results", []): props = item.get("properties", {}) code = "" titles = props.get("股票代码", {}).get("title", []) if titles: code = titles[0].get("plain_text", "").upper() shares = props.get("持仓数量", {}).get("number", 0) or 0 cost_per_share = props.get("持仓成本", {}).get("number", 0) or 0 if code and shares > 0: total_cost = round(shares * cost_per_share, 2) holdings.append({ "code": code, "shares": shares, "cost_per_share": cost_per_share, "total_cost": total_cost }) return holdings return [] def get_us_price(code): import yfinance as yf import time time.sleep(3) # 避免限流 try: ticker = yf.Ticker(code) hist = ticker.history(period="1d") if len(hist) > 0: return round(hist['Close'].iloc[-1], 2) except: pass return None def main(): import requests import yfinance as yf print(f"\n{'='*85}") print(f"📊 每日投资报告") print(f"更新时间: {datetime.now().strftime('%Y-%m-%d %H:%M')}") print(f"{'='*85}\n") print("[1] 从用户表读取...") holdings = get_user_holdings() if not holdings: print("❌ 无法获取数据\n") return print(f"\n[2] 获取股价...") prices = {} for h in holdings: code = h["code"] price = get_us_price(code) if price: prices[code] = price print(f" {code}: ${price}") else: print(f" {code}: 获取失败") print(f"\n{'='*85}") print("📊 持仓盈亏") print(f"{'='*85}\n") print(f"{'代码':<10} {'股数':<10} {'每股成本':<12} {'总成本':<12} {'当前价':<12} {'市值':<12} {'盈亏':<18}") print("-" * 100) total_cost = 0 total_value = 0 for h in holdings: code = h["code"] shares = h["shares"] cost_per = h["cost_per_share"] cost = h["total_cost"] price = prices.get(code) if price: value = round(shares * price, 2) else: value = 0 pnl = round(value - cost, 2) pnl_pct = round((pnl / cost * 100), 2) if cost > 0 else 0 total_cost += cost total_value += value price_str = f"${price:.2f}" if price else "❌" cost_str = f"${cost:.2f}" if cost else "❌" value_str = f"${value:.2f}" if value else "❌" emoji = "🟢" if pnl >= 0 else "🔴" pnl_str = f"{emoji}${pnl:+.2f} ({pnl_pct:+.2f}%)" cost_per_str = f"${cost_per:.2f}" if cost_per else "❌" print(f"{code:<10} {shares:<10.2f} {cost_per_str:<12} {cost_str:<12} {price_str:<12} {value_str:<12} {pnl_str:<18}") print("-" * 100) total_pnl = round(total_value - total_cost, 2) total_pnl_pct = round((total_pnl / total_cost * 100), 2) if total_cost > 0 else 0 total_emoji = "🟢" if total_pnl >= 0 else "🔴" print(f"{'合计':<10} {'':<10} {'':<12} ${total_cost:<11.2f} {'':<12} ${total_value:<11.2f} {total_emoji}${total_pnl:+.2f} ({total_pnl_pct:+.2f}%)") print(f"\n{'='*85}") print("💡 成本规则: 总成本 = 每股成本价(持仓成本) × 持仓数量") print(f"{'='*85}") if __name__ == "__main__": main()