Files
auto-stock/backend/app/services/korea_investment_api_adapter.py

107 lines
4.5 KiB
Python

"""
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