# [장내채권] 기본시세 - 장내채권 평균단가조회 # Generated by KIS API Generator (Single API Mode) # -*- coding: utf-8 -*- """ Created on 2025-06-19 """ import logging import time import sys from typing import Optional, Tuple import pandas as pd sys.path.extend(['../..', '.']) import kis_auth as ka # 로깅 설정 logging.basicConfig(level=logging.INFO, format='%(levelname)s - %(message)s') logger = logging.getLogger(__name__) ############################################################################################## # [장내채권] 기본시세 > 장내채권 평균단가조회 [국내채권-158] ############################################################################################## # 상수 정의 API_URL = "/uapi/domestic-bond/v1/quotations/avg-unit" def avg_unit( inqr_strt_dt: str, # 조회시작일자 inqr_end_dt: str, # 조회종료일자 pdno: str, # 상품번호 prdt_type_cd: str, # 상품유형코드 vrfc_kind_cd: str, # 검증종류코드 NK30: str = "", # 연속조회키30 FK100: str = "", # 연속조회검색조건100 dataframe1: Optional[pd.DataFrame] = None, # 누적 데이터프레임 (output1) dataframe2: Optional[pd.DataFrame] = None, # 누적 데이터프레임 (output2) dataframe3: Optional[pd.DataFrame] = None, # 누적 데이터프레임 (output3) tr_cont: str = "", depth: int = 0, max_depth: int = 10 ) -> Tuple[pd.DataFrame, pd.DataFrame, pd.DataFrame]: """ [장내채권] 기본시세 장내채권 평균단가조회[국내주식-158] 장내채권 평균단가조회 API를 호출하여 DataFrame으로 반환합니다. Args: inqr_strt_dt (str): 조회 시작 일자 (예: '20230101') inqr_end_dt (str): 조회 종료 일자 (예: '20230131') pdno (str): 상품번호, 공백: 전체, 특정종목 조회시 : 종목코드 prdt_type_cd (str): 상품유형코드 (예: '302') vrfc_kind_cd (str): 검증종류코드 (예: '00') NK30 (str): 연속조회키30, 공백 허용 FK100 (str): 연속조회검색조건100, 공백 허용 dataframe1 (Optional[pd.DataFrame]): 누적 데이터프레임 (output1) dataframe2 (Optional[pd.DataFrame]): 누적 데이터프레임 (output2) dataframe3 (Optional[pd.DataFrame]): 누적 데이터프레임 (output3) tr_cont (str): 연속 거래 여부 depth (int): 현재 재귀 깊이 max_depth (int): 최대 재귀 깊이 (기본값: 10) Returns: Tuple[pd.DataFrame, pd.DataFrame, pd.DataFrame]: 장내채권 평균단가조회 데이터 Example: >>> df1, df2, df3 = avg_unit( ... inqr_strt_dt='20230101', ... inqr_end_dt='20230131', ... pdno='KR2033022D33', ... prdt_type_cd='302', ... vrfc_kind_cd='00', ... ) >>> print(df1) >>> print(df2) >>> print(df3) """ # 필수 파라미터 검증 if not inqr_strt_dt: logger.error("inqr_strt_dt is required. (e.g. '20230101')") raise ValueError("inqr_strt_dt is required. (e.g. '20230101')") if not inqr_end_dt: logger.error("inqr_end_dt is required. (e.g. '20230131')") raise ValueError("inqr_end_dt is required. (e.g. '20230131')") if not prdt_type_cd: logger.error("prdt_type_cd is required. (e.g. '302')") raise ValueError("prdt_type_cd is required. (e.g. '302')") if not vrfc_kind_cd: logger.error("vrfc_kind_cd is required. (e.g. '00')") raise ValueError("vrfc_kind_cd is required. (e.g. '00')") # 최대 재귀 깊이 체크 if depth >= max_depth: logger.warning("Maximum recursion depth (%d) reached. Stopping further requests.", max_depth) return ( dataframe1 if dataframe1 is not None else pd.DataFrame(), dataframe2 if dataframe2 is not None else pd.DataFrame(), dataframe3 if dataframe3 is not None else pd.DataFrame() ) tr_id = "CTPF2005R" params = { "INQR_STRT_DT": inqr_strt_dt, "INQR_END_DT": inqr_end_dt, "PDNO": pdno, "PRDT_TYPE_CD": prdt_type_cd, "VRFC_KIND_CD": vrfc_kind_cd, "CTX_AREA_NK30": NK30, "CTX_AREA_FK100": FK100, } res = ka._url_fetch(API_URL, tr_id, tr_cont, params) if res.isOK(): # 연속조회 정보 업데이트 tr_cont = res.getHeader().tr_cont NK30 = res.getBody().ctx_area_nk30 FK100 = res.getBody().ctx_area_fk100 # output1 데이터 처리 current_data1 = pd.DataFrame(res.getBody().output1) if dataframe1 is not None: dataframe1 = pd.concat([dataframe1, current_data1], ignore_index=True) else: dataframe1 = current_data1 # output2 데이터 처리 current_data2 = pd.DataFrame(res.getBody().output2) if dataframe2 is not None: dataframe2 = pd.concat([dataframe2, current_data2], ignore_index=True) else: dataframe2 = current_data2 # output3 데이터 처리 current_data3 = pd.DataFrame(res.getBody().output3) if dataframe3 is not None: dataframe3 = pd.concat([dataframe3, current_data3], ignore_index=True) else: dataframe3 = current_data3 if tr_cont in ["M", "F"]: # 다음 페이지 존재 logger.info("Call Next page...") ka.smart_sleep() # 시스템 안정적 운영을 위한 지연 return avg_unit( inqr_strt_dt, inqr_end_dt, pdno, prdt_type_cd, vrfc_kind_cd, NK30, FK100, dataframe1, dataframe2, dataframe3, "N", depth + 1, max_depth ) else: logger.info("Data fetch complete.") return dataframe1, dataframe2, dataframe3 else: logger.error("API call failed: %s - %s", res.getErrorCode(), res.getErrorMessage()) res.printError(API_URL) return pd.DataFrame(), pd.DataFrame(), pd.DataFrame()