Files
server-configs/calculate-pnl.py
2026-02-13 22:24:27 +08:00

171 lines
5.3 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/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()