#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ 计算持仓盈亏 """ import requests import json from datetime import datetime # Yahoo Finance API 配置 YAHOO_API_URL = "https://query1.finance.yahoo.com/v8/finance/chart/" # 股票配置(从Notion数据库读取) STOCKS = [ {"symbol": "MSFT", "name": "Microsoft Corporation", "quantity": 1, "cost_basis": 439.00} ] def get_stock_price(symbol): """获取股票实时价格""" try: url = f"{YAHOO_API_URL}{symbol}" params = { "interval": "1d", "range": "1d" } headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36" } response = requests.get(url, params=params, headers=headers, timeout=10) if response.status_code == 200: data = response.json() if "chart" in data and "result" in data["chart"]: result = data["chart"]["result"] if result and len(result) > 0: meta = result[0].get("meta", {}) current_price = meta.get("regularMarketPrice") previous_close = meta.get("chartPreviousClose") if current_price and previous_close: change = current_price - previous_close change_percent = (change / previous_close) * 100 return { "symbol": symbol, "price": current_price, "previous_close": previous_close, "change": change, "change_percent": change_percent, "currency": meta.get("currency", "USD") } return None except Exception as e: print(f"获取 {symbol} 价格失败: {e}") return None def calculate_pnl(): """计算持仓盈亏""" print("=" * 60) print("计算持仓盈亏") print("=" * 60) print(f"日期: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}") print("=" * 60) total_cost = 0 total_market_value = 0 total_pnl = 0 total_pnl_percent = 0 stock_details = [] for stock in STOCKS: symbol = stock["symbol"] name = stock["name"] quantity = stock["quantity"] cost_basis = stock["cost_basis"] # 计算总成本 cost = quantity * cost_basis total_cost += cost # 获取当前价格 price_data = get_stock_price(symbol) if price_data: current_price = price_data["price"] change = price_data["change"] change_percent = price_data["change_percent"] # 计算当前市值 market_value = quantity * current_price total_market_value += market_value # 计算盈亏 pnl = market_value - cost total_pnl += pnl # 计算盈亏百分比 pnl_percent = (pnl / cost) * 100 stock_details.append({ "symbol": symbol, "name": name, "quantity": quantity, "cost_basis": cost_basis, "current_price": current_price, "cost": cost, "market_value": market_value, "pnl": pnl, "pnl_percent": pnl_percent, "change": change, "change_percent": change_percent }) print(f"\n{symbol} - {name}") print(f" 持仓: {quantity}股 @ ${cost_basis}") print(f" 当前价: ${current_price:.2f}") print(f" 总成本: ${cost:.2f}") print(f" 当前市值: ${market_value:.2f}") print(f" 盈亏: ${pnl:+.2f} ({pnl_percent:+.2f}%)") print(f" 日涨跌: ${change:+.2f} ({change_percent:+.2f}%)") else: print(f"\n{symbol} - {name}") print(f" ❌ 无法获取价格数据") # 计算总盈亏百分比 if total_cost > 0: total_pnl_percent = (total_pnl / total_cost) * 100 print("\n" + "=" * 60) print("📊 持仓概览") print("=" * 60) print(f"总持仓数量: {len(STOCKS)} 只股票") print(f"总成本: ${total_cost:.2f}") print(f"当前总市值: ${total_market_value:.2f}") print(f"总盈亏: ${total_pnl:+.2f} ({total_pnl_percent:+.2f}%)") print("=" * 60) return { "date": datetime.now().strftime("%Y-%m-%d %H:%M:%S"), "total_cost": total_cost, "total_market_value": total_market_value, "total_pnl": total_pnl, "total_pnl_percent": total_pnl_percent, "stocks": stock_details } def main(): """主函数""" print("开始计算持仓盈亏...") print() pnl_data = calculate_pnl() if pnl_data["total_cost"] > 0: print("\n✅ 盈亏计算完成") print(f"总盈亏: ${pnl_data['total_pnl']:+.2f} ({pnl_data['total_pnl_percent']:+.2f}%)") else: print("\n❌ 无法计算盈亏") if __name__ == "__main__": main()