diff --git a/stock/app/holdings_intel.py b/stock/app/holdings_intel.py new file mode 100644 index 0000000..a8bc58d --- /dev/null +++ b/stock/app/holdings_intel.py @@ -0,0 +1,37 @@ +"""보유종목 인텔리전스 — 순수연산 중심 (advisory). KIS 실주문 미사용.""" +from __future__ import annotations +import datetime as dt +from typing import Any, Optional + +from . import db +from . import price_fetcher + + +def _krx_tickers() -> set: + """krx_master에 존재하는 ticker 집합 (KRX 판별용).""" + with db._conn() as conn: + try: + rows = conn.execute("SELECT ticker FROM krx_master").fetchall() + except Exception: + return set() + return {r["ticker"] for r in rows} + + +def get_holdings() -> list[dict]: + """portfolio + 현재가 + pnl_rate + is_krx.""" + items = db.get_all_portfolio() + tickers = [it["ticker"] for it in items] + prices = price_fetcher.get_current_prices(tickers) if tickers else {} + krx = _krx_tickers() + out = [] + for it in items: + cur = prices.get(it["ticker"]) + avg = it["avg_price"] + pnl = ((cur - avg) / avg * 100.0) if (cur and avg) else None + out.append({ + **it, + "current_price": cur, + "pnl_rate": pnl, + "is_krx": it["ticker"] in krx, + }) + return out diff --git a/stock/app/test_holdings_intel.py b/stock/app/test_holdings_intel.py new file mode 100644 index 0000000..c104abe --- /dev/null +++ b/stock/app/test_holdings_intel.py @@ -0,0 +1,17 @@ +from app import holdings_intel as hi + +def test_get_holdings_merges_price_and_pnl(monkeypatch): + monkeypatch.setattr(hi.db, "get_all_portfolio", lambda: [ + {"id": 1, "broker": "kis", "ticker": "005930", "name": "삼성전자", + "quantity": 10, "avg_price": 70000, "purchase_price": 70000}, + {"id": 2, "broker": "kis", "ticker": "AAPL", "name": "Apple", + "quantity": 5, "avg_price": 200, "purchase_price": 200}, + ]) + monkeypatch.setattr(hi.price_fetcher, "get_current_prices", + lambda tickers: {"005930": 77000}) # AAPL 미조회(비KRX) + monkeypatch.setattr(hi, "_krx_tickers", lambda: {"005930"}) + hs = hi.get_holdings() + s = {h["ticker"]: h for h in hs} + assert s["005930"]["is_krx"] is True + assert round(s["005930"]["pnl_rate"], 1) == 10.0 # (77000-70000)/70000 + assert s["AAPL"]["is_krx"] is False # KRX 외