Investment portfolio charts, search fix, and holding creation fixes
- Add four portfolio charts: allocation donut by holding, allocation donut by asset type, cost basis vs current value bar, return % bar - Fix asset search to use yf.Search() full-text instead of ticker-only lookup — name searches like "vanguard ftse all world" now work - Fix holding creation double-quantity bug: holdings now created with quantity=0 so buy transaction is sole source of quantity/cost basis - Add per-share / total price toggle in Add Holding modal with live calculated equivalent shown as you type - Add ErrorBoundary in AppShell so render errors show a message instead of a blank page - Fix donut charts using || instead of ?? when falling back from current_value to cost_basis_total (0 was not falling through ??) - Allow HoldingCreate.quantity >= 0 (was gt=0) to support zero-init - Fix error display for Pydantic v2 array-of-objects validation errors Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
26e2a055db
commit
cdc1e67321
9 changed files with 424 additions and 70 deletions
|
|
@ -98,19 +98,26 @@ async def fetch_history(symbol: str, days: int = 365) -> list[dict]:
|
|||
def search_yahoo(query: str) -> list[dict]:
|
||||
try:
|
||||
import yfinance as yf
|
||||
ticker = yf.Ticker(query)
|
||||
info = ticker.fast_info
|
||||
price = getattr(info, "last_price", None)
|
||||
if price:
|
||||
return [{
|
||||
"symbol": query.upper(),
|
||||
"name": getattr(info, "long_name", None) or query.upper(),
|
||||
"type": "stock",
|
||||
"currency": (getattr(info, "currency", None) or "USD").upper(),
|
||||
"exchange": getattr(info, "exchange", None),
|
||||
results = yf.Search(query, max_results=10).quotes
|
||||
out = []
|
||||
for r in results:
|
||||
symbol = r.get("symbol")
|
||||
if not symbol:
|
||||
continue
|
||||
quote_type = (r.get("quoteType") or r.get("typeDisp") or "stock").lower()
|
||||
type_map = {"etf": "etf", "equity": "stock", "cryptocurrency": "crypto",
|
||||
"mutualfund": "fund", "bond": "bond"}
|
||||
asset_type = type_map.get(quote_type, "stock")
|
||||
out.append({
|
||||
"symbol": symbol,
|
||||
"name": r.get("longname") or r.get("shortname") or symbol,
|
||||
"type": asset_type,
|
||||
"currency": "USD", # updated on first price sync
|
||||
"exchange": r.get("exchDisp") or r.get("exchange"),
|
||||
"data_source": "yahoo_finance",
|
||||
"data_source_id": None,
|
||||
}]
|
||||
})
|
||||
return out
|
||||
except Exception:
|
||||
pass
|
||||
return []
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue