Skip to content

Commit e4bb79a

Browse files
committed
Add _fetch_missing_prices method and expand MergedPortfolioService test coverage
- Introduce `_fetch_missing_prices` to query and update current prices for stocks without pricing data using the KIS API. - Ensure proper handling for cases without holdings or zero quantity stocks. - Add extensive test coverage for `_fetch_missing_prices`, including successful updates, API errors, and skip logic for already priced stocks. - Expand tests for MergedPortfolioService methods to include integration scenarios and edge cases.
1 parent 4f18cce commit e4bb79a

File tree

2 files changed

+683
-0
lines changed

2 files changed

+683
-0
lines changed

app/services/merged_portfolio_service.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,36 @@ async def _apply_manual_holdings(
256256
)
257257
)
258258

259+
async def _fetch_missing_prices(
260+
self,
261+
merged: dict[str, MergedHolding],
262+
market_type: MarketType,
263+
kis_client: KISClient,
264+
) -> None:
265+
"""현재가가 없는 종목들의 현재가를 KIS API로 조회"""
266+
tickers_without_price = [
267+
ticker
268+
for ticker, holding in merged.items()
269+
if holding.current_price == 0 and holding.total_quantity > 0
270+
]
271+
272+
if not tickers_without_price:
273+
return
274+
275+
for ticker in tickers_without_price:
276+
try:
277+
if market_type == MarketType.KR:
278+
df = await kis_client.inquire_price(ticker)
279+
if not df.empty:
280+
merged[ticker].current_price = float(df.iloc[0]["close"])
281+
else:
282+
# 해외주식의 경우 별도 API 필요 (추후 구현)
283+
pass
284+
except Exception as exc:
285+
logger.warning(
286+
"Failed to fetch price for %s: %s", ticker, exc
287+
)
288+
259289
def _finalize_holdings(self, merged: dict[str, MergedHolding]) -> None:
260290
for holding in merged.values():
261291
holding.total_quantity = sum(
@@ -323,6 +353,15 @@ async def _build_merged_portfolio(
323353
kis_stocks = await self._fetch_kis_holdings(kis_client, market_type)
324354
self._apply_kis_holdings(merged, kis_stocks, market_type)
325355
await self._apply_manual_holdings(merged, user_id, market_type)
356+
357+
# 수동 등록 종목만 있는 경우 (KIS에 없는 종목) 현재가 조회
358+
# total_quantity를 먼저 계산해야 함
359+
for holding in merged.values():
360+
holding.total_quantity = sum(
361+
int(item.quantity) for item in holding.holdings
362+
)
363+
await self._fetch_missing_prices(merged, market_type, kis_client)
364+
326365
self._finalize_holdings(merged)
327366
await self._attach_analysis_and_settings(merged)
328367

0 commit comments

Comments
 (0)