from __future__ import annotations import logging from typing import Any from app.agents.tools.types import ToolResult logger = logging.getLogger(__name__) async def get_stock_price(params: dict[str, Any]) -> ToolResult: """종목 OHLCV 데이터를 pykrx로 조회한다.""" from pykrx import stock as pykrx_stock ticker = params.get("ticker", "") start_date = params.get("start_date", "") end_date = params.get("end_date", "") if not all([ticker, start_date, end_date]): return ToolResult(data="Error: ticker, start_date, end_date 모두 필수입니다.") try: df = pykrx_stock.get_market_ohlcv_by_date(start_date, end_date, ticker) if df.empty: return ToolResult(data=f"데이터 없음: {ticker} ({start_date}~{end_date})") records = df.reset_index().to_dict(orient="records") return ToolResult( data={"ticker": ticker, "period": f"{start_date}~{end_date}", "ohlcv": records} ) except Exception as e: logger.exception("get_stock_price failed for %s", ticker) return ToolResult(data=f"Error: {e}") async def get_financial_statements(params: dict[str, Any]) -> ToolResult: """종목의 재무제표 데이터를 pykrx로 조회한다.""" from pykrx import stock as pykrx_stock ticker = params.get("ticker", "") year = params.get("year", "") if not all([ticker, year]): return ToolResult(data="Error: ticker, year 모두 필수입니다.") try: # pykrx 기본 재무 데이터: BPS, PER, PBR, EPS, DIV, DPS start_date = f"{year}0101" end_date = f"{year}1231" df = pykrx_stock.get_market_fundamental_by_date(start_date, end_date, ticker) if df.empty: return ToolResult(data=f"재무 데이터 없음: {ticker} ({year})") # 연말 기준 최신 데이터 latest = df.iloc[-1].to_dict() return ToolResult( data={"ticker": ticker, "year": year, "fundamentals": latest} ) except Exception as e: logger.exception("get_financial_statements failed for %s", ticker) return ToolResult(data=f"Error: {e}") async def get_market_metrics(params: dict[str, Any]) -> ToolResult: """종목의 시가총액, PER, PBR 등 시장 지표를 조회한다.""" from pykrx import stock as pykrx_stock ticker = params.get("ticker", "") date = params.get("date", "") if not all([ticker, date]): return ToolResult(data="Error: ticker, date 모두 필수입니다.") try: # 시가총액 cap_df = pykrx_stock.get_market_cap_by_date(date, date, ticker) # 밸류에이션 fund_df = pykrx_stock.get_market_fundamental_by_date(date, date, ticker) result: dict[str, Any] = {"ticker": ticker, "date": date} if not cap_df.empty: result["market_cap"] = cap_df.iloc[-1].to_dict() if not fund_df.empty: result["valuation"] = fund_df.iloc[-1].to_dict() if len(result) == 2: return ToolResult(data=f"시장 지표 없음: {ticker} ({date})") return ToolResult(data=result) except Exception as e: logger.exception("get_market_metrics failed for %s", ticker) return ToolResult(data=f"Error: {e}") async def get_market_index(params: dict[str, Any]) -> ToolResult: """KOSPI/KOSDAQ 지수 데이터를 조회한다.""" from pykrx import stock as pykrx_stock index_code = params.get("index_code", "1001") # 기본: 코스피 start_date = params.get("start_date", "") end_date = params.get("end_date", "") if not all([start_date, end_date]): return ToolResult(data="Error: start_date, end_date 모두 필수입니다.") try: df = pykrx_stock.get_index_ohlcv_by_date(start_date, end_date, index_code) if df.empty: return ToolResult(data=f"지수 데이터 없음: {index_code} ({start_date}~{end_date})") records = df.reset_index().to_dict(orient="records") return ToolResult( data={ "index_code": index_code, "period": f"{start_date}~{end_date}", "ohlcv": records, } ) except Exception as e: logger.exception("get_market_index failed for %s", index_code) return ToolResult(data=f"Error: {e}")