rmi-backend/app/analyzer/portfolio.py

65 lines
1.9 KiB
Python

"""
Portfolio aggregator: calculates total value and 24h change from holdings.
"""
def build_portfolio(holdings: list) -> dict:
"""
Aggregate token holdings into a portfolio summary.
Args:
holdings: Raw list from get_wallet_holdings()
Returns:
{
"tokens": [...enriched tokens with usd_value, qty],
"total_value": float,
"change_24h_usd": float,
"change_24h_pct": float,
"token_count": int,
}
"""
tokens = []
total_value = 0.0
total_value_yesterday = 0.0
for item in holdings:
price = float(item.get("price") or 0)
qty_raw = item.get("remainQty") or "0"
qty = float(qty_raw) if qty_raw else 0.0
change_24h = float(item.get("percentChange24h") or 0)
usd_value = price * qty
if usd_value < 0.01:
continue # skip dust
usd_value_yesterday = usd_value / (1 + change_24h / 100) if change_24h != -100 else usd_value
total_value += usd_value
total_value_yesterday += usd_value_yesterday
tokens.append(
{
"symbol": item.get("symbol", "?"),
"name": item.get("name", "?"),
"contractAddress": item.get("contractAddress", ""),
"qty": qty,
"price": price,
"usd_value": usd_value,
"change_24h_pct": change_24h,
"risk_level": item.get("riskLevel", "UNKNOWN"),
}
)
tokens.sort(key=lambda t: t["usd_value"], reverse=True)
change_24h_usd = total_value - total_value_yesterday
change_24h_pct = (change_24h_usd / total_value_yesterday * 100) if total_value_yesterday > 0 else 0.0
return {
"tokens": tokens,
"total_value": total_value,
"change_24h_usd": change_24h_usd,
"change_24h_pct": change_24h_pct,
"token_count": len(tokens),
}