""" Korea Investment API Adapter 기존 코드와의 호환성을 위한 어댑터 기존: from app.services.korea_investment_api import korea_investment_api 새 구조: app.trading.모듈로 분리 이 파일은 기존 코드가 수정 없이 동작하도록 보장합니다. """ from typing import Dict, Any, Optional import logging from app.trading.kis_client import kis_client, real_market_client from app.trading.order_manager import order_manager from app.trading.market_data import market_data_provider logger = logging.getLogger(__name__) class KoreaInvestmentAPIAdapter: """기존 API 인터페이스 어댑터 (Backward Compatibility)""" def __init__(self): self.client = kis_client self.order_mgr = order_manager self.market_data = market_data_provider # 기존 속성 노출 self.base_url = self.client.base_url self.app_key = self.client.app_key self.app_secret = self.client.app_secret self.account_number = self.client.account_number self.access_token = self.client.access_token self.token_expires_at = self.client.token_expires_at @classmethod def for_real_market_data(cls) -> "KoreaInvestmentAPIAdapter": """실계좌 시세조회 전용""" instance = cls() instance.client = real_market_client instance.market_data = market_data_provider # real_client 사용 return instance # ── 주문 관련 (위임) ──────────────────────────────────────────── async def place_order(self, stock_code: str, order_type: str, quantity: int, price: Optional[float] = None): return await self.order_mgr.place_order(stock_code, order_type, quantity, price) async def cancel_order(self, order_id: str, quantity: int): return await self.order_mgr.cancel_order(order_id, quantity) async def get_balance(self): return await self.order_mgr.get_balance() async def place_overseas_order(self, symbol: str, order_type: str, quantity: int, price: float, exchange_code: str = "NASD"): return await self.order_mgr.place_overseas_order(symbol, order_type, quantity, price, exchange_code) async def get_overseas_balance(self): return await self.order_mgr.get_overseas_balance() # ── 시세/차트 관련 (위임) ───────────────────────────────────── async def get_current_price(self, stock_code: str): return await self.market_data.get_current_price(stock_code) async def get_daily_chart(self, stock_code: str, period: str = "D", limit: int = 240): return await self.market_data.get_daily_chart(stock_code, period, limit) async def get_minute_chart(self, stock_code: str, ref_time: str = "", include_past: bool = True): return await self.market_data.get_minute_chart(stock_code, ref_time, include_past) async def get_overseas_price(self, symbol: str, exchange_code: str = "NASD"): return await self.market_data.get_overseas_price(symbol, exchange_code) async def get_orderbook(self, stock_code: str): return await self.market_data.get_orderbook(stock_code) async def get_volume_rank(self, market: str = "J"): return await self.market_data.get_volume_rank(market) async def get_stock_list(self, market: str = "J"): return await self.market_data.get_volume_rank(market) # ── 기타 (호환성) ─────────────────────────────────────────────── async def _get_access_token(self): """Deprecated: 직접 호출 불필요 (client가 자동 관리)""" return await self.client.get_access_token() async def _make_request(self, method: str, endpoint: str, tr_id: str, extra_headers: Optional[Dict] = None, **kwargs): """Deprecated: 직접 request 호출""" return await self.client.request(method, endpoint, tr_id, extra_headers, **kwargs) def get_monitor_stats(self): """API 통계 (향후 monitoring.py로 이동 예정)""" return {"message": "Monitoring moved to trading.monitoring module"} # 싱글톤 인스턴스 - 기존 코드에서 그대로 사용 가능 korea_investment_api = KoreaInvestmentAPIAdapter() try: real_market_api = KoreaInvestmentAPIAdapter.for_real_market_data() except Exception: real_market_api = None # Backward compatibility alias KoreaInvestmentAPI = KoreaInvestmentAPIAdapter