initial commit

This commit is contained in:
2026-01-31 22:34:57 +09:00
commit f1301de543
875 changed files with 196598 additions and 0 deletions

View File

@@ -0,0 +1,171 @@
# [장내채권] 기본시세 - 장내채권 평균단가조회
# 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()

View File

@@ -0,0 +1,184 @@
# -*- coding: utf-8 -*-
"""
Created on 2025-06-19
"""
import sys
import logging
import pandas as pd
sys.path.extend(['../..', '.']) # kis_auth 파일 경로 추가
import kis_auth as ka
from avg_unit import avg_unit
# 로깅 설정
logging.basicConfig(level=logging.INFO, format='%(levelname)s - %(message)s')
logger = logging.getLogger(__name__)
##############################################################################################
# [장내채권] 기본시세 > 장내채권 평균단가조회 [국내채권-158]
##############################################################################################
# 통합 컬럼 매핑 (모든 output에서 공통 사용)
COLUMN_MAPPING = {
'evlu_dt': '평가일자',
'pdno': '상품번호',
'prdt_type_cd': '상품유형코드',
'kis_unpr': '한국신용평가단가',
'kbp_unpr': '한국채권평가단가',
'nice_evlu_unpr': '한국신용정보평가단가',
'fnp_unpr': '에프앤자산평가단가',
'avg_evlu_unpr': '평균평가단가',
'kis_crdt_grad_text': '한국신용평가신용등급내용',
'kbp_crdt_grad_text': '한국채권평가신용등급내용',
'nice_crdt_grad_text': '한국신용정보신용등급내용',
'fnp_crdt_grad_text': '에프앤자산평가신용등급내용',
'chng_yn': '변경여부',
'kis_erng_rt': '한국신용평가수익율',
'kbp_erng_rt': '한국채권평가수익율',
'nice_evlu_erng_rt': '한국신용정보평가수익율',
'fnp_erng_rt': '에프앤자산평가수익율',
'avg_evlu_erng_rt': '평균평가수익율',
'kis_rf_unpr': '한국신용평가RF단가',
'kbp_rf_unpr': '한국채권평가RF단가',
'nice_evlu_rf_unpr': '한국신용정보평가RF단가',
'avg_evlu_rf_unpr': '평균평가RF단가',
'evlu_dt': '평가일자',
'pdno': '상품번호',
'prdt_type_cd': '상품유형코드',
'kis_evlu_amt': '한국신용평가평가금액',
'kbp_evlu_amt': '한국채권평가평가금액',
'nice_evlu_amt': '한국신용정보평가금액',
'fnp_evlu_amt': '에프앤자산평가평가금액',
'avg_evlu_amt': '평균평가금액',
'chng_yn': '변경여부',
'output3': '응답상세',
'evlu_dt': '평가일자',
'pdno': '상품번호',
'prdt_type_cd': '상품유형코드',
'kis_crcy_cd': '한국신용평가통화코드',
'kis_evlu_unit_pric': '한국신용평가평가단위가격',
'kis_evlu_pric': '한국신용평가평가가격',
'kbp_crcy_cd': '한국채권평가통화코드',
'kbp_evlu_unit_pric': '한국채권평가평가단위가격',
'kbp_evlu_pric': '한국채권평가평가가격',
'nice_crcy_cd': '한국신용정보통화코드',
'nice_evlu_unit_pric': '한국신용정보평가단위가격',
'nice_evlu_pric': '한국신용정보평가가격',
'avg_evlu_unit_pric': '평균평가단위가격',
'avg_evlu_pric': '평균평가가격',
'chng_yn': '변경여부'
}
NUMERIC_COLUMNS = []
def main():
"""
[장내채권] 기본시세
장내채권 평균단가조회[국내주식-158]
장내채권 평균단가조회 테스트 함수`
Parameters:
- inqr_strt_dt (str): 조회시작일자 (일자 ~)
- inqr_end_dt (str): 조회종료일자 (~ 일자)
- pdno (str): 상품번호 (공백: 전체, 특정종목 조회시 : 종목코드)
- prdt_type_cd (str): 상품유형코드 (Unique key(302))
- vrfc_kind_cd (str): 검증종류코드 (Unique key(00))
Returns:
- Tuple[DataFrame, ...]: 장내채권 평균단가조회 결과
Example:
>>> df1, df2, df3 = avg_unit(inqr_strt_dt="20250101", inqr_end_dt="20250131", pdno="KR2033022D33", prdt_type_cd="302", vrfc_kind_cd="00")
"""
try:
# pandas 출력 옵션 설정
pd.set_option('display.max_columns', None) # 모든 컬럼 표시
pd.set_option('display.width', None) # 출력 너비 제한 해제
pd.set_option('display.max_rows', None) # 모든 행 표시
# 토큰 발급
logger.info("토큰 발급 중...")
ka.auth()
logger.info("토큰 발급 완료")
# API 호출
logger.info("API 호출 시작: 장내채권 평균단가조회")
result1, result2, result3 = avg_unit(
inqr_strt_dt="20240101", # 조회시작일자
inqr_end_dt="20250630", # 조회종료일자
pdno="KR103502GA34", # 상품번호
prdt_type_cd="302", # 상품유형코드
vrfc_kind_cd="00", # 검증종류코드
)
# 결과 확인
results = [result1, result2, result3]
if all(result is None or result.empty for result in results):
logger.warning("조회된 데이터가 없습니다.")
return
# output1 결과 처리
logger.info("=== output1 조회 ===")
if not result1.empty:
logger.info("사용 가능한 컬럼: %s", result1.columns.tolist())
# 통합 컬럼명 한글 변환 (필요한 컬럼만 자동 매핑됨)
result1 = result1.rename(columns=COLUMN_MAPPING)
for col in NUMERIC_COLUMNS:
if col in result1.columns:
result1[col] = pd.to_numeric(result1[col], errors='coerce').round(2)
logger.info("output1 결과:")
print(result1)
else:
logger.info("output1 데이터가 없습니다.")
# output2 결과 처리
logger.info("=== output2 조회 ===")
if not result2.empty:
logger.info("사용 가능한 컬럼: %s", result2.columns.tolist())
# 통합 컬럼명 한글 변환 (필요한 컬럼만 자동 매핑됨)
result2 = result2.rename(columns=COLUMN_MAPPING)
for col in NUMERIC_COLUMNS:
if col in result2.columns:
result2[col] = pd.to_numeric(result2[col], errors='coerce').round(2)
logger.info("output2 결과:")
print(result2)
else:
logger.info("output2 데이터가 없습니다.")
# output3 결과 처리
logger.info("=== output3 조회 ===")
if not result3.empty:
logger.info("사용 가능한 컬럼: %s", result3.columns.tolist())
# 통합 컬럼명 한글 변환 (필요한 컬럼만 자동 매핑됨)
result3 = result3.rename(columns=COLUMN_MAPPING)
for col in NUMERIC_COLUMNS:
if col in result3.columns:
result3[col] = pd.to_numeric(result3[col], errors='coerce').round(2)
logger.info("output3 결과:")
print(result3)
else:
logger.info("output3 데이터가 없습니다.")
except Exception as e:
logger.error("에러 발생: %s", str(e))
raise
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,97 @@
"""
Created on 2025-07-09
"""
import logging
import sys
sys.path.extend(['../..', '.'])
import kis_auth as ka
# 로깅 설정
logging.basicConfig(level=logging.INFO, format='%(levelname)s - %(message)s')
logger = logging.getLogger(__name__)
##############################################################################################
# [장내채권] 실시간시세 > 일반채권 실시간호가 [실시간-053]
##############################################################################################
def bond_asking_price(
tr_type: str,
tr_key: str,
) -> tuple[dict, list[str]]:
"""
일반채권 실시간호가[H0BJASP0]
일반채권 실시간호가 API를 통해 실시간 데이터를 구독합니다.
Args:
tr_type (str): [필수] 구독 등록("1") 또는 해제("0") 여부를 나타냅니다.
tr_key (str): [필수] 종목코드. 빈 문자열일 수 없습니다.
Returns:
message (dict): 실시간 데이터 메시지.
columns (list[str]): 응답 데이터의 컬럼 정보.
Raises:
ValueError: tr_key가 빈 문자열인 경우 발생합니다.
Example:
>>> msg, columns = bond_asking_price("1", "005930")
>>> print(msg, columns)
[참고자료]
채권 종목코드 마스터파일은 "KIS포털 - API문서 - 종목정보파일 - 장내채권 - 채권코드" 참고 부탁드립니다.
"""
# 필수 파라미터 검증
if not tr_key:
raise ValueError("tr_key is required and cannot be an empty string")
tr_id = "H0BJASP0"
params = {
"tr_key": tr_key,
}
# 데이터 요청
msg = ka.data_fetch(tr_id, tr_type, params)
# 응답 데이터 컬럼 정보
columns = [
"stnd_iscd",
"stck_cntg_hour",
"askp_ert1",
"bidp_ert1",
"askp1",
"bidp1",
"askp_rsqn1",
"bidp_rsqn1",
"askp_ert2",
"bidp_ert2",
"askp2",
"bidp2",
"askp_rsqn2",
"bidp_rsqn2",
"askp_ert3",
"bidp_ert3",
"askp3",
"bidp3",
"askp_rsqn3",
"bidp_rsqn3",
"askp_ert4",
"bidp_ert4",
"askp4",
"bidp4",
"askp_rsqn4",
"bidp_rsqn4",
"askp_ert5",
"bidp_ert5",
"askp5",
"bidp5",
"askp_rsqn52",
"bidp_rsqn53",
"total_askp_rsqn",
"total_bidp_rsqn",
]
return msg, columns

View File

@@ -0,0 +1,133 @@
"""
Created on 2025-07-09
"""
import logging
import sys
import pandas as pd
sys.path.extend(['../..', '.'])
import kis_auth as ka
from bond_asking_price import bond_asking_price
# 로깅 설정
logging.basicConfig(level=logging.INFO, format='%(levelname)s - %(message)s')
logger = logging.getLogger(__name__)
##############################################################################################
# [장내채권] 실시간시세 > 일반채권 실시간호가 [실시간-053]
##############################################################################################
COLUMN_MAPPING = {
"stnd_iscd": "표준종목코드",
"stck_cntg_hour": "주식체결시간",
"askp_ert1": "매도호가수익률1",
"bidp_ert1": "매수호가수익률1",
"askp1": "매도호가1",
"bidp1": "매수호가1",
"askp_rsqn1": "매도호가잔량1",
"bidp_rsqn1": "매수호가잔량1",
"askp_ert2": "매도호가수익률2",
"bidp_ert2": "매수호가수익률2",
"askp2": "매도호가2",
"bidp2": "매수호가2",
"askp_rsqn2": "매도호가잔량2",
"bidp_rsqn2": "매수호가잔량2",
"askp_ert3": "매도호가수익률3",
"bidp_ert3": "매수호가수익률3",
"askp3": "매도호가3",
"bidp3": "매수호가3",
"askp_rsqn3": "매도호가잔량3",
"bidp_rsqn3": "매수호가잔량3",
"askp_ert4": "매도호가수익률4",
"bidp_ert4": "매수호가수익률4",
"askp4": "매도호가4",
"bidp4": "매수호가4",
"askp_rsqn4": "매도호가잔량4",
"bidp_rsqn4": "매수호가잔량4",
"askp_ert5": "매도호가수익률5",
"bidp_ert5": "매수호가수익률5",
"askp5": "매도호가5",
"bidp5": "매수호가5",
"askp_rsqn52": "매도호가잔량5",
"bidp_rsqn53": "매수호가잔량5",
"total_askp_rsqn": "총매도호가잔량",
"total_bidp_rsqn": "총매수호가잔량"
}
NUMERIC_COLUMNS = [
"매도호가수익률1", "매수호가수익률1", "매도호가1", "매수호가1", "매도호가잔량1", "매수호가잔량1",
"매도호가수익률2", "매수호가수익률2", "매도호가2", "매수호가2", "매도호가잔량2", "매수호가잔량2",
"매도호가수익률3", "매수호가수익률3", "매도호가3", "매수호가3", "매도호가잔량3", "매수호가잔량3",
"매도호가수익률4", "매수호가수익률4", "매도호가4", "매수호가4", "매도호가잔량4", "매수호가잔량4",
"매도호가수익률5", "매수호가수익률5", "매도호가5", "매수호가5", "매도호가잔량5", "매수호가잔량5",
"총매도호가잔량", "총매수호가잔량"
]
def main():
"""
일반채권 실시간호가
일반채권 실시간호가 API입니다.
[참고자료]
채권 종목코드 마스터파일은 "KIS포털 - API문서 - 종목정보파일 - 장내채권 - 채권코드" 참고 부탁드립니다.
[호출 데이터]
헤더와 바디 값을 합쳐 JSON 형태로 전송합니다.
[응답 데이터]
1. 정상 등록 여부 (JSON)
- JSON["body"]["msg1"] - 정상 응답 시, SUBSCRIBE SUCCESS
- JSON["body"]["output"]["iv"] - 실시간 결과 복호화에 필요한 AES256 IV (Initialize Vector)
- JSON["body"]["output"]["key"] - 실시간 결과 복호화에 필요한 AES256 Key
2. 실시간 결과 응답 ( | 로 구분되는 값)
ex) 0|H0STCNT0|004|005930^123929^73100^5^...
- 암호화 유무 : 0 암호화 되지 않은 데이터 / 1 암호화된 데이터
- TR_ID : 등록한 tr_id (ex. H0STCNT0)
- 데이터 건수 : (ex. 001 인 경우 데이터 건수 1건, 004인 경우 데이터 건수 4건)
- 응답 데이터 : 아래 response 데이터 참조 ( ^로 구분됨)
"""
# pandas 출력 옵션 설정
pd.set_option('display.max_columns', None) # 모든 컬럼 표시
pd.set_option('display.width', None) # 출력 너비 제한 해제
pd.set_option('display.max_rows', None) # 모든 행 표시
# 인증 토큰 발급
ka.auth()
ka.auth_ws()
# 인증(auth_ws()) 이후에 선언
kws = ka.KISWebSocket(api_url="/tryitout")
# 조회
kws.subscribe(request=bond_asking_price, data=["KR103502GA34", "KR6095572D81"])
# 결과 표시
def on_result(ws, tr_id: str, result: pd.DataFrame, data_map: dict):
try:
# 컬럼 매핑
result.rename(columns=COLUMN_MAPPING, inplace=True)
# 숫자형 컬럼 변환
for col in NUMERIC_COLUMNS:
if col in result.columns:
result[col] = pd.to_numeric(result[col], errors='coerce')
logging.info("결과:")
print(result)
except Exception as e:
logging.error(f"결과 처리 중 오류: {e}")
logging.error(f"받은 데이터: {result}")
kws.start(on_result=on_result)
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,85 @@
"""
Created on 2025-07-09
"""
import logging
import sys
sys.path.extend(['../..', '.'])
import kis_auth as ka
# 로깅 설정
logging.basicConfig(level=logging.INFO, format='%(levelname)s - %(message)s')
logger = logging.getLogger(__name__)
##############################################################################################
# [장내채권] 실시간시세 > 일반채권 실시간체결가 [실시간-052]
##############################################################################################
def bond_ccnl(
tr_type: str,
tr_key: str,
) -> tuple[dict, list[str]]:
"""
일반채권 실시간체결가[H0BJCNT0] 구독 함수
한국투자증권 웹소켓 API를 통해 일반채권의 실시간 체결가 데이터를 구독합니다.
[참고자료]
채권 종목코드 마스터파일은 "KIS포털 - API문서 - 종목정보파일 - 장내채권 - 채권코드" 참고 부탁드립니다.
Args:
tr_type (str): [필수] 구독 등록("1") 또는 해제("0") 여부
tr_key (str): [필수] 종목코드 (빈 문자열 불가)
Returns:
message (dict): 실시간 데이터 구독 결과 메시지
columns (list[str]): 응답 데이터의 컬럼 정보
Raises:
ValueError: tr_key가 빈 문자열인 경우 발생
Example:
>>> msg, columns = bond_ccnl("1", "005930")
>>> print(msg, columns)
"""
# 필수 파라미터 검증
if not tr_key:
raise ValueError("tr_key는 빈 문자열일 수 없습니다.")
tr_id = "H0BJCNT0"
params = {
"tr_key": tr_key,
}
# 데이터 구독 요청
msg = ka.data_fetch(tr_id, tr_type, params)
# 응답 데이터 컬럼 정보
columns = [
"stnd_iscd", # 표준종목코드
"bond_isnm", # 채권종목명
"stck_cntg_hour", # 주식체결시간
"prdy_vrss_sign", # 전일대비부호
"prdy_vrss", # 전일대비
"prdy_ctrt", # 전일대비율
"stck_prpr", # 현재가
"cntg_vol", # 체결거래량
"stck_oprc", # 시가
"stck_hgpr", # 고가
"stck_lwpr", # 저가
"stck_prdy_clpr", # 전일종가
"bond_cntg_ert", # 현재수익률
"oprc_ert", # 시가수익률
"hgpr_ert", # 고가수익률
"lwpr_ert", # 저가수익률
"acml_vol", # 누적거래량
"prdy_vol", # 전일거래량
"cntg_type_cls_code", # 체결유형코드
]
return msg, columns

View File

@@ -0,0 +1,112 @@
"""
Created on 2025-07-09
"""
import logging
import sys
import pandas as pd
sys.path.extend(['../..', '.'])
import kis_auth as ka
from bond_ccnl import bond_ccnl
# 로깅 설정
logging.basicConfig(level=logging.INFO, format='%(levelname)s - %(message)s')
logger = logging.getLogger(__name__)
##############################################################################################
# [장내채권] 실시간시세 > 일반채권 실시간체결가 [실시간-052]
##############################################################################################
COLUMN_MAPPING = {
"stnd_iscd": "표준종목코드",
"bond_isnm": "채권종목명",
"stck_cntg_hour": "주식체결시간",
"prdy_vrss_sign": "전일대비부호",
"prdy_vrss": "전일대비",
"prdy_ctrt": "전일대비율",
"stck_prpr": "현재가",
"cntg_vol": "체결거래량",
"stck_oprc": "시가",
"stck_hgpr": "고가",
"stck_lwpr": "저가",
"stck_prdy_clpr": "전일종가",
"bond_cntg_ert": "현재수익률",
"oprc_ert": "시가수익률",
"hgpr_ert": "고가수익률",
"lwpr_ert": "저가수익률",
"acml_vol": "누적거래량",
"prdy_vol": "전일거래량",
"cntg_type_cls_code": "체결유형코드"
}
NUMERIC_COLUMNS = [
"전일대비", "전일대비율", "현재가", "체결거래량", "시가", "고가", "저가", "전일종가",
"현재수익률", "시가수익률", "고가수익률", "저가수익률", "누적거래량", "전일거래량"
]
def main():
"""
일반채권 실시간체결가
일반채권 실시간체결가 API입니다.
[호출 데이터]
헤더와 바디 값을 합쳐 JSON 형태로 전송합니다.
[응답 데이터]
1. 정상 등록 여부 (JSON)
- JSON["body"]["msg1"] - 정상 응답 시, SUBSCRIBE SUCCESS
- JSON["body"]["output"]["iv"] - 실시간 결과 복호화에 필요한 AES256 IV (Initialize Vector)
- JSON["body"]["output"]["key"] - 실시간 결과 복호화에 필요한 AES256 Key
2. 실시간 결과 응답 ( | 로 구분되는 값)
ex) 0|H0STCNT0|004|005930^123929^73100^5^...
- 암호화 유무 : 0 암호화 되지 않은 데이터 / 1 암호화된 데이터
- TR_ID : 등록한 tr_id (ex. H0STCNT0)
- 데이터 건수 : (ex. 001 인 경우 데이터 건수 1건, 004인 경우 데이터 건수 4건)
- 응답 데이터 : 아래 response 데이터 참조 ( ^로 구분됨)
[참고자료]
채권 종목코드 마스터파일은 "KIS포털 - API문서 - 종목정보파일 - 장내채권 - 채권코드" 참고 부탁드립니다.
"""
# pandas 출력 옵션 설정
pd.set_option('display.max_columns', None) # 모든 컬럼 표시
pd.set_option('display.width', None) # 출력 너비 제한 해제
pd.set_option('display.max_rows', None) # 모든 행 표시
# 인증 토큰 발급
ka.auth()
ka.auth_ws()
# 인증(auth_ws()) 이후에 선언
kws = ka.KISWebSocket(api_url="/tryitout")
# 조회
kws.subscribe(request=bond_ccnl, data=["KR103502GA34", "KR6095572D81"])
# 결과 표시
def on_result(ws, tr_id: str, result: pd.DataFrame, data_map: dict):
try:
# 컬럼 매핑
result.rename(columns=COLUMN_MAPPING, inplace=True)
# 숫자형 컬럼 변환
for col in NUMERIC_COLUMNS:
if col in result.columns:
result[col] = pd.to_numeric(result[col], errors='coerce')
logging.info("결과:")
print(result)
except Exception as e:
logging.error(f"결과 처리 중 오류: {e}")
logging.error(f"받은 데이터: {result}")
kws.start(on_result=on_result)
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,84 @@
"""
Created on 2025-07-09
"""
import logging
import sys
sys.path.extend(['../..', '.'])
import kis_auth as ka
# 로깅 설정
logging.basicConfig(level=logging.INFO, format='%(levelname)s - %(message)s')
logger = logging.getLogger(__name__)
##############################################################################################
# [장내채권] 실시간시세 > 채권지수 실시간체결가 [실시간-060]
##############################################################################################
def bond_index_ccnl(
tr_type: str,
tr_key: str,
) -> tuple[dict, list[str]]:
"""
채권지수 실시간체결가[H0BICNT0]
채권지수 실시간체결가 API를 통해 실시간 데이터를 구독합니다.
Args:
tr_type (str): [필수] 구독 등록("1") 또는 해제("0") 여부를 나타냅니다.
tr_key (str): [필수] 구독할 종목코드. 빈 문자열이 아니어야 합니다.
Returns:
message (dict): 구독 요청에 대한 응답 메시지.
columns (list[str]): 실시간 데이터의 컬럼 정보.
Raises:
ValueError: tr_key가 빈 문자열인 경우 발생합니다.
Example:
>>> msg, columns = bond_index_ccnl("1", "005930")
>>> print(msg, columns)
[참고자료]
채권 종목코드 마스터파일은 "KIS포털 - API문서 - 종목정보파일 - 장내채권 - 채권코드" 참고 부탁드립니다.
"""
# 필수 파라미터 검증
if not tr_key:
raise ValueError("tr_key is required and cannot be an empty string")
tr_id = "H0BICNT0"
params = {
"tr_key": tr_key,
}
# 데이터 구독 요청
msg = ka.data_fetch(tr_id, tr_type, params)
# 응답 데이터 컬럼 정보
columns = [
"nmix_id", # 지수ID
"stnd_date1", # 기준일자1
"trnm_hour", # 전송시간
"totl_ernn_nmix_oprc", # 총수익지수시가지수
"totl_ernn_nmix_hgpr", # 총수익지수최고가
"totl_ernn_nmix_lwpr", # 총수익지수최저가
"totl_ernn_nmix", # 총수익지수
"prdy_totl_ernn_nmix", # 전일총수익지수
"totl_ernn_nmix_prdy_vrss", # 총수익지수전일대비
"totl_ernn_nmix_prdy_vrss_sign", # 총수익지수전일대비부호
"totl_ernn_nmix_prdy_ctrt", # 총수익지수전일대비율
"clen_prc_nmix", # 순가격지수
"mrkt_prc_nmix", # 시장가격지수
"bond_call_rnvs_nmix", # Call재투자지수
"bond_zero_rnvs_nmix", # Zero재투자지수
"bond_futs_thpr", # 선물이론가격
"bond_avrg_drtn_val", # 평균듀레이션
"bond_avrg_cnvx_val", # 평균컨벡서티
"bond_avrg_ytm_val", # 평균YTM
"bond_avrg_frdl_ytm_val", # 평균선도YTM
]
return msg, columns

View File

@@ -0,0 +1,124 @@
"""
Created on 2025-07-09
"""
import logging
import sys
import pandas as pd
sys.path.extend(['../..', '.'])
import kis_auth as ka
from bond_index_ccnl import bond_index_ccnl
# 로깅 설정
logging.basicConfig(level=logging.INFO, format='%(levelname)s - %(message)s')
logger = logging.getLogger(__name__)
##############################################################################################
# [장내채권] 실시간시세 > 채권지수 실시간체결가 [실시간-060]
##############################################################################################
COLUMN_MAPPING = {
"nmix_id": "지수ID",
"stnd_date1": "기준일자1",
"trnm_hour": "전송시간",
"totl_ernn_nmix_oprc": "총수익지수시가지수",
"totl_ernn_nmix_hgpr": "총수익지수최고가",
"totl_ernn_nmix_lwpr": "총수익지수최저가",
"totl_ernn_nmix": "총수익지수",
"prdy_totl_ernn_nmix": "전일총수익지수",
"totl_ernn_nmix_prdy_vrss": "총수익지수전일대비",
"totl_ernn_nmix_prdy_vrss_sign": "총수익지수전일대비부호",
"totl_ernn_nmix_prdy_ctrt": "총수익지수전일대비율",
"clen_prc_nmix": "순가격지수",
"mrkt_prc_nmix": "시장가격지수",
"bond_call_rnvs_nmix": "Call재투자지수",
"bond_zero_rnvs_nmix": "Zero재투자지수",
"bond_futs_thpr": "선물이론가격",
"bond_avrg_drtn_val": "평균듀레이션",
"bond_avrg_cnvx_val": "평균컨벡서티",
"bond_avrg_ytm_val": "평균YTM",
"bond_avrg_frdl_ytm_val": "평균선도YTM"
}
NUMERIC_COLUMNS = [
"총수익지수시가지수", "총수익지수최고가", "총수익지수최저가", "총수익지수",
"전일총수익지수", "총수익지수전일대비", "총수익지수전일대비율", "순가격지수",
"시장가격지수", "Call재투자지수", "Zero재투자지수", "선물이론가격"]
def main():
"""
채권지수 실시간체결가
채권지수 실시간체결가 API입니다.
[참고자료]
채권 종목코드 마스터파일은 "KIS포털 - API문서 - 종목정보파일 - 장내채권 - 채권코드" 참고 부탁드립니다.
[호출 데이터]
헤더와 바디 값을 합쳐 JSON 형태로 전송합니다.
[응답 데이터]
1. 정상 등록 여부 (JSON)
- JSON["body"]["msg1"] - 정상 응답 시, SUBSCRIBE SUCCESS
- JSON["body"]["output"]["iv"] - 실시간 결과 복호화에 필요한 AES256 IV (Initialize Vector)
- JSON["body"]["output"]["key"] - 실시간 결과 복호화에 필요한 AES256 Key
2. 실시간 결과 응답 ( | 로 구분되는 값)
ex) 0|H0STCNT0|004|005930^123929^73100^5^...
- 암호화 유무 : 0 암호화 되지 않은 데이터 / 1 암호화된 데이터
- TR_ID : 등록한 tr_id (ex. H0STCNT0)
- 데이터 건수 : (ex. 001 인 경우 데이터 건수 1건, 004인 경우 데이터 건수 4건)
- 응답 데이터 : 아래 response 데이터 참조 ( ^로 구분됨)
"""
# pandas 출력 옵션 설정
pd.set_option('display.max_columns', None) # 모든 컬럼 표시
pd.set_option('display.width', None) # 출력 너비 제한 해제
pd.set_option('display.max_rows', None) # 모든 행 표시
# 인증 토큰 발급
ka.auth()
ka.auth_ws()
# 인증(auth_ws()) 이후에 선언
kws = ka.KISWebSocket(api_url="/tryitout")
# 조회
# 한경채권지수: KBPR01, KBPR02, KBPR03, KBPR04
# KIS채권지수: KISR01, MSBI07, KTBL10, MSBI09, MSBI10, CDIX01
# 매경채권지수: MKFR01, MSBI01, MSBI03, MSBI10, CORP01
kws.subscribe(request=bond_index_ccnl, data=[
# 한경채권지수
"KBPR01", "KBPR02", "KBPR03", "KBPR04",
# KIS채권지수
"KISR01", "MSBI07", "KTBL10", "MSBI09", "MSBI10", "CDIX01",
# 매경채권지수
"MKFR01", "MSBI01", "MSBI03", "MSBI10", "CORP01"
])
# 결과 표시
def on_result(ws, tr_id: str, result: pd.DataFrame, data_map: dict):
try:
# 컬럼 매핑
result.rename(columns=COLUMN_MAPPING, inplace=True)
# 숫자형 컬럼 변환
for col in NUMERIC_COLUMNS:
if col in result.columns:
result[col] = pd.to_numeric(result[col], errors='coerce')
logging.info("결과:")
print(result)
except Exception as e:
logging.error(f"결과 처리 중 오류: {e}")
logging.error(f"받은 데이터: {result}")
kws.start(on_result=on_result)
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,112 @@
# [장내채권] 주문/계좌 - 장내채권 매수주문
# Generated by KIS API Generator (Single API Mode)
# -*- coding: utf-8 -*-
"""
Created on 2025-06-20
"""
import logging
from typing import Optional, Tuple
import sys
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__)
##############################################################################################
# [장내채권] 주문/계좌 > 장내채권 매수주문 [국내주식-124]
##############################################################################################
# 상수 정의
API_URL = "/uapi/domestic-bond/v1/trading/buy"
def buy(
cano: str,
acnt_prdt_cd: str,
pdno: str,
ord_qty2: str,
bond_ord_unpr: str,
samt_mket_ptci_yn: str,
bond_rtl_mket_yn: str,
idcr_stfno: str = "",
mgco_aptm_odno: str = "",
ord_svr_dvsn_cd: str = "",
ctac_tlno: str = ""
) -> Optional[pd.DataFrame]:
"""
[장내채권] 주문/계좌
장내채권 매수주문[국내주식-124]
장내채권 매수주문 API를 호출하여 DataFrame으로 반환합니다.
Args:
cano (str): 종합계좌번호 (8자리)
acnt_prdt_cd (str): 계좌상품코드 (2자리)
pdno (str): 상품번호 (12자리)
ord_qty2 (str): 주문수량2 (19자리)
bond_ord_unpr (str): 채권주문단가 (182자리)
samt_mket_ptci_yn (str): 소액시장참여여부 ('Y' or 'N')
bond_rtl_mket_yn (str): 채권소매시장여부 ('Y' or 'N')
idcr_stfno (str, optional): 유치자직원번호 (6자리). Defaults to "".
mgco_aptm_odno (str, optional): 운용사지정주문번호 (12자리). Defaults to "".
ord_svr_dvsn_cd (str, optional): 주문서버구분코드. Defaults to "".
ctac_tlno (str, optional): 연락전화번호. Defaults to "".
Returns:
Optional[pd.DataFrame]: 장내채권 매수주문 데이터
Example:
>>> df = buy(
... cano=trenv.my_acct,
... acnt_prdt_cd=trenv.my_prod,
... pdno="KR1234567890",
... ord_qty2="10",
... bond_ord_unpr="10000",
... samt_mket_ptci_yn="N",
... bond_rtl_mket_yn="Y"
... )
>>> print(df)
"""
tr_id = "TTTC0952U"
params = {
"CANO": cano,
"ACNT_PRDT_CD": acnt_prdt_cd,
"PDNO": pdno,
"ORD_QTY2": ord_qty2,
"BOND_ORD_UNPR": bond_ord_unpr,
"SAMT_MKET_PTCI_YN": samt_mket_ptci_yn,
"BOND_RTL_MKET_YN": bond_rtl_mket_yn,
"IDCR_STFNO": idcr_stfno,
"MGCO_APTM_ODNO": mgco_aptm_odno,
"ORD_SVR_DVSN_CD": ord_svr_dvsn_cd,
"CTAC_TLNO": ctac_tlno,
}
res = ka._url_fetch(api_url=API_URL,
ptr_id=tr_id,
tr_cont="",
params=params,
postFlag=True
)
if res.isOK():
if hasattr(res.getBody(), 'output'):
output_data = res.getBody().output
if not isinstance(output_data, list):
output_data = [output_data]
dataframe = pd.DataFrame(output_data)
else:
dataframe = pd.DataFrame()
logger.info("Data fetch complete.")
return dataframe
else:
logger.error("API call failed: %s - %s", res.getErrorCode(), res.getErrorMessage())
res.printError(API_URL)
return pd.DataFrame()

View File

@@ -0,0 +1,114 @@
# -*- coding: utf-8 -*-
"""
Created on 2025-06-20
"""
import sys
import logging
import pandas as pd
sys.path.extend(['../..', '.']) # kis_auth 파일 경로 추가
import kis_auth as ka
from buy import buy
# 로깅 설정
logging.basicConfig(level=logging.INFO, format='%(levelname)s - %(message)s')
logger = logging.getLogger(__name__)
##############################################################################################
# [장내채권] 주문/계좌 > 장내채권 매수주문 [국내주식-124]
##############################################################################################
COLUMN_MAPPING = {
'KRX_FWDG_ORD_ORGNO': '한국거래소전송주문조직번호',
'ODNO': '주문번호',
'ORD_TMD': '주문시각'
}
NUMERIC_COLUMNS = []
def main():
"""
[장내채권] 주문/계좌`
장내채권 매수주문[국내주식-124]
장내채권 매수주문 테스트 함수
Parameters:
cano (str): 종합계좌번호 (8자리)
acnt_prdt_cd (str): 계좌상품코드 (2자리)
pdno (str): 상품번호 (12자리)
ord_qty2 (str): 주문수량2 (19자리)
bond_ord_unpr (str): 채권주문단가 (182자리)
samt_mket_ptci_yn (str): 소액시장참여여부 ('Y' or 'N')
bond_rtl_mket_yn (str): 채권소매시장여부 ('Y' or 'N')
idcr_stfno (str, optional): 유치자직원번호 (6자리). Defaults to "".
mgco_aptm_odno (str, optional): 운용사지정주문번호 (12자리). Defaults to "".
Returns:
- DataFrame: 장내채권 매수주문 결과
Example:
>>> df = main()
>>> print(df)
"""
try:
# pandas 출력 옵션 설정
pd.set_option('display.max_columns', None) # 모든 컬럼 표시
pd.set_option('display.width', None) # 출력 너비 제한 해제
pd.set_option('display.max_rows', None) # 모든 행 표시
# 토큰 발급
logger.info("토큰 발급 중...")
ka.auth()
logger.info("토큰 발급 완료")
# kis_auth 모듈에서 계좌 정보 가져오기
trenv = ka.getTREnv()
# API 호출
logger.info("API 호출 시작: 장내채권 매수주문")
result = buy(
cano=trenv.my_acct, # 종합계좌번호
acnt_prdt_cd=trenv.my_prod, # 계좌상품코드
pdno="KR6095572D81", # 상품번호
ord_qty2="10", # 주문수량
bond_ord_unpr="9900", # 채권주문단가
samt_mket_ptci_yn="N", # 소액시장참여여부
bond_rtl_mket_yn="N", # 채권소매시장여부
idcr_stfno="", # 유치자직원번호
mgco_aptm_odno="", # 운용사지정주문번호
ord_svr_dvsn_cd="0", # 주문서버구분코드
ctac_tlno="", # 연락전화번호
)
if result is None or result.empty:
logger.warning("조회된 데이터가 없습니다.")
return
# 컬럼명 출력
logger.info("사용 가능한 컬럼 목록:")
logger.info(result.columns.tolist())
# 한글 컬럼명으로 변환
result = result.rename(columns=COLUMN_MAPPING)
# 숫자형 컬럼 변환
for col in NUMERIC_COLUMNS:
if col in result.columns:
result[col] = pd.to_numeric(result[col], errors='coerce')
# 결과 출력
logger.info("=== 장내채권 매수주문 결과 ===")
logger.info("조회된 데이터 건수: %d", len(result))
print(result)
except Exception as e:
logger.error("에러 발생: %s", str(e))
raise
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,123 @@
# -*- coding: utf-8 -*-
"""
Created on 2025-06-19
"""
import logging
import sys
import pandas as pd
sys.path.extend(['../..', '.']) # kis_auth 파일 경로 추가
import kis_auth as ka
from inquire_asking_price import inquire_asking_price
# 로깅 설정
logging.basicConfig(level=logging.INFO, format='%(levelname)s - %(message)s')
logger = logging.getLogger(__name__)
##############################################################################################
# [장내채권] 기본시세 > 장내채권현재가(호가) [국내주식-132]
##############################################################################################
COLUMN_MAPPING = {
'aspr_acpt_hour': '호가 접수 시간',
'bond_askp1': '채권 매도호가1',
'bond_askp2': '채권 매도호가2',
'bond_askp3': '채권 매도호가3',
'bond_askp4': '채권 매도호가4',
'bond_askp5': '채권 매도호가5',
'bond_bidp1': '채권 매수호가1',
'bond_bidp2': '채권 매수호가2',
'bond_bidp3': '채권 매수호가3',
'bond_bidp4': '채권 매수호가4',
'bond_bidp5': '채권 매수호가5',
'askp_rsqn1': '매도호가 잔량1',
'askp_rsqn2': '매도호가 잔량2',
'askp_rsqn3': '매도호가 잔량3',
'askp_rsqn4': '매도호가 잔량4',
'askp_rsqn5': '매도호가 잔량5',
'bidp_rsqn1': '매수호가 잔량1',
'bidp_rsqn2': '매수호가 잔량2',
'bidp_rsqn3': '매수호가 잔량3',
'bidp_rsqn4': '매수호가 잔량4',
'bidp_rsqn5': '매수호가 잔량5',
'total_askp_rsqn': '총 매도호가 잔량',
'total_bidp_rsqn': '총 매수호가 잔량',
'ntby_aspr_rsqn': '순매수 호가 잔량',
'seln_ernn_rate1': '매도 수익 비율1',
'seln_ernn_rate2': '매도 수익 비율2',
'seln_ernn_rate3': '매도 수익 비율3',
'seln_ernn_rate4': '매도 수익 비율4',
'seln_ernn_rate5': '매도 수익 비율5',
'shnu_ernn_rate1': '매수2 수익 비율1',
'shnu_ernn_rate2': '매수2 수익 비율2',
'shnu_ernn_rate3': '매수2 수익 비율3',
'shnu_ernn_rate4': '매수2 수익 비율4',
'shnu_ernn_rate5': '매수2 수익 비율5'
}
NUMERIC_COLUMNS = []
def main():
"""
[장내채권] 기본시세
장내채권현재가(호가)[국내주식-132]
장내채권현재가(호가) 테스트 함수
Parameters:
- fid_cond_mrkt_div_code (str): 시장 분류 코드 (B 입력)
- fid_input_iscd (str): 채권종목코드
Returns:
- DataFrame: 장내채권현재가(호가) 결과
Example:
>>> df = inquire_asking_price(fid_cond_mrkt_div_code="B", fid_input_iscd="KR2033022D33")
"""
try:
# pandas 출력 옵션 설정
pd.set_option('display.max_columns', None) # 모든 컬럼 표시
pd.set_option('display.width', None) # 출력 너비 제한 해제
pd.set_option('display.max_rows', None) # 모든 행 표시
# 토큰 발급
logger.info("토큰 발급 중...")
ka.auth()
logger.info("토큰 발급 완료")
# API 호출
logger.info("API 호출 시작: 장내채권현재가(호가)")
result = inquire_asking_price(
fid_cond_mrkt_div_code="B", # 시장 분류 코드
fid_input_iscd="KR2033022D33", # 채권종목코드
)
if result is None or result.empty:
logger.warning("조회된 데이터가 없습니다.")
return
# 컬럼명 출력
logger.info("사용 가능한 컬럼 목록:")
logger.info(result.columns.tolist())
# 한글 컬럼명으로 변환
result = result.rename(columns=COLUMN_MAPPING)
# 숫자형 컬럼 변환
for col in NUMERIC_COLUMNS:
if col in result.columns:
result[col] = pd.to_numeric(result[col], errors='coerce')
# 결과 출력
logger.info("=== 장내채권현재가(호가) 결과 ===")
logger.info("조회된 데이터 건수: %d", len(result))
print(result)
except Exception as e:
logger.error("에러 발생: %s", str(e))
raise
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,116 @@
# [장내채권] 기본시세 - 장내채권현재가(호가)
# Generated by KIS API Generator (Single API Mode)
# -*- coding: utf-8 -*-
"""
Created on 2025-06-19
"""
import logging
import time
from typing import Optional, Tuple
import sys
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__)
##############################################################################################
# [장내채권] 기본시세 > 장내채권현재가(호가) [국내주식-132]
##############################################################################################
# 상수 정의
API_URL = "/uapi/domestic-bond/v1/quotations/inquire-asking-price"
def inquire_asking_price(
fid_cond_mrkt_div_code: str, # 시장 분류 코드
fid_input_iscd: str, # 채권종목코드
tr_cont: str = "", # 연속 거래 여부
dataframe: Optional[pd.DataFrame] = None, # 누적 데이터프레임
depth: int = 0, # 현재 재귀 깊이
max_depth: int = 10 # 최대 재귀 깊이
) -> Optional[pd.DataFrame]:
"""
[장내채권] 기본시세
장내채권현재가(호가)[국내주식-132]
장내채권현재가(호가) API를 호출하여 DataFrame으로 반환합니다.
Args:
fid_cond_mrkt_div_code (str): 시장 분류 코드 (B 입력)
fid_input_iscd (str): 채권종목코드 (ex KR2033022D33)
tr_cont (str): 연속 거래 여부 (기본값: "")
dataframe (Optional[pd.DataFrame]): 누적 데이터프레임 (기본값: None)
depth (int): 현재 재귀 깊이 (기본값: 0)
max_depth (int): 최대 재귀 깊이 (기본값: 10)
Returns:
Optional[pd.DataFrame]: 장내채권현재가(호가) 데이터
Example:
>>> df = inquire_asking_price(fid_cond_mrkt_div_code="B", fid_input_iscd="KR2033022D33")
>>> print(df)
"""
# 필수 파라미터 검증
if not fid_cond_mrkt_div_code:
logger.error("fid_cond_mrkt_div_code is required. (e.g. 'B')")
raise ValueError("fid_cond_mrkt_div_code is required. (e.g. 'B')")
if not fid_input_iscd:
logger.error("fid_input_iscd is required. (e.g. 'KR2033022D33')")
raise ValueError("fid_input_iscd is required. (e.g. 'KR2033022D33')")
# 최대 재귀 깊이 체크
if depth >= max_depth:
logger.warning("Maximum recursion depth (%d) reached. Stopping further requests.", max_depth)
return dataframe if dataframe is not None else pd.DataFrame()
tr_id = "FHKBJ773401C0"
params = {
"FID_COND_MRKT_DIV_CODE": fid_cond_mrkt_div_code,
"FID_INPUT_ISCD": fid_input_iscd,
}
# API 호출
res = ka._url_fetch(API_URL, tr_id, tr_cont, params)
if res.isOK():
# 응답 데이터 처리
if hasattr(res.getBody(), 'output'):
output_data = res.getBody().output
if not isinstance(output_data, list):
output_data = [output_data]
current_data = pd.DataFrame(output_data)
else:
current_data = pd.DataFrame()
# 데이터프레임 병합
if dataframe is not None:
dataframe = pd.concat([dataframe, current_data], ignore_index=True)
else:
dataframe = current_data
# 연속 거래 여부 확인
tr_cont = res.getHeader().tr_cont
if tr_cont == "M":
logger.info("Calling next page...")
ka.smart_sleep()
return inquire_asking_price(
fid_cond_mrkt_div_code,
fid_input_iscd,
"N", dataframe, depth + 1, max_depth
)
else:
logger.info("Data fetch complete.")
return dataframe
else:
# API 에러 처리
logger.error("API call failed: %s - %s", res.getErrorCode(), res.getErrorMessage())
res.printError(API_URL)
return pd.DataFrame()

View File

@@ -0,0 +1,111 @@
# -*- coding: utf-8 -*-
"""
Created on 2025-06-20
"""
import sys
import logging
import pandas as pd
sys.path.extend(['../..', '.']) # kis_auth 파일 경로 추가
import kis_auth as ka
from inquire_balance import inquire_balance
# 로깅 설정
logging.basicConfig(level=logging.INFO, format='%(levelname)s - %(message)s')
logger = logging.getLogger(__name__)
##############################################################################################
# [장내채권] 주문/계좌 > 장내채권 잔고조회 [국내주식-198]
##############################################################################################
COLUMN_MAPPING = {
'pdno': '상품번호',
'buy_dt': '매수일자',
'buy_sqno': '매수일련번호',
'cblc_qty': '잔고수량',
'agrx_qty': '종합과세수량',
'sprx_qty': '분리과세수량',
'exdt': '만기일',
'buy_erng_rt': '매수수익율',
'buy_unpr': '매수단가',
'buy_amt': '매수금액',
'ord_psbl_qty': '주문가능수량'
}
NUMERIC_COLUMNS = []
def main():
"""
[장내채권] 주문/계좌
장내채권 잔고조회[국내주식-198]
장내채권 잔고조회 테스트 함수
Parameters:
- cano (str): 종합계좌번호 ()
- acnt_prdt_cd (str): 계좌상품코드 ()
- inqr_cndt (str): 조회조건 (00: 전체, 01: 상품번호단위)
- pdno (str): 상품번호 (공백)
- buy_dt (str): 매수일자 (공백)
Returns:
- DataFrame: 장내채권 잔고조회 결과
Example:
>>> df = inquire_balance(cano=trenv.my_acct, acnt_prdt_cd=trenv.my_prod, inqr_cndt="00", pdno="", buy_dt="")
"""
try:
# pandas 출력 옵션 설정
pd.set_option('display.max_columns', None) # 모든 컬럼 표시
pd.set_option('display.width', None) # 출력 너비 제한 해제
pd.set_option('display.max_rows', None) # 모든 행 표시
# 토큰 발급
logger.info("토큰 발급 중...")
ka.auth()
logger.info("토큰 발급 완료")
# kis_auth 모듈에서 계좌 정보 가져오기
trenv = ka.getTREnv()
# API 호출
logger.info("API 호출 시작: 장내채권 잔고조회")
result = inquire_balance(
cano=trenv.my_acct, # 종합계좌번호
acnt_prdt_cd=trenv.my_prod, # 계좌상품코드
inqr_cndt="00", # 조회조건
pdno="", # 상품번호
buy_dt="", # 매수일자
)
if result is None or result.empty:
logger.warning("조회된 데이터가 없습니다.")
return
# 컬럼명 출력
logger.info("사용 가능한 컬럼 목록:")
logger.info(result.columns.tolist())
# 한글 컬럼명으로 변환
result = result.rename(columns=COLUMN_MAPPING)
# 숫자형 컬럼 변환
for col in NUMERIC_COLUMNS:
if col in result.columns:
result[col] = pd.to_numeric(result[col], errors='coerce')
# 결과 출력
logger.info("=== 장내채권 잔고조회 결과 ===")
logger.info("조회된 데이터 건수: %d", len(result))
print(result)
except Exception as e:
logger.error("에러 발생: %s", str(e))
raise
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,147 @@
# [장내채권] 주문/계좌 - 장내채권 잔고조회
# Generated by KIS API Generator (Single API Mode)
# -*- coding: utf-8 -*-
"""
Created on 2025-06-20
"""
import logging
import time
from typing import Optional
import sys
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__)
##############################################################################################
# [장내채권] 주문/계좌 > 장내채권 잔고조회 [국내주식-198]
##############################################################################################
# 상수 정의
API_URL = "/uapi/domestic-bond/v1/trading/inquire-balance"
def inquire_balance(
cano: str, # 종합계좌번호
acnt_prdt_cd: str, # 계좌상품코드
inqr_cndt: str, # 조회조건
pdno: str, # 상품번호
buy_dt: str, # 매수일자
FK200: str = "", # 연속조회검색조건200
NK200: str = "", # 연속조회키200
tr_cont: str = "", # 연속 거래 여부
dataframe: Optional[pd.DataFrame] = None, # 누적 데이터프레임
depth: int = 0, # 현재 재귀 깊이
max_depth: int = 10 # 최대 재귀 깊이
) -> Optional[pd.DataFrame]:
"""
[장내채권] 주문/계좌
장내채권 잔고조회[국내주식-198]
장내채권 잔고조회 API를 호출하여 DataFrame으로 반환합니다.
Args:
cano (str): 종합계좌번호
acnt_prdt_cd (str): 계좌상품코드
inqr_cndt (str): 조회조건 (00: 전체, 01: 상품번호단위)
pdno (str): 상품번호 (공백 허용)
buy_dt (str): 매수일자 (공백 허용)
FK200 (str): 연속조회검색조건200
NK200 (str): 연속조회키200
tr_cont (str): 연속 거래 여부 (기본값: "")
dataframe (Optional[pd.DataFrame]): 누적 데이터프레임
depth (int): 현재 재귀 깊이
max_depth (int): 최대 재귀 깊이 (기본값: 10)
Returns:
Optional[pd.DataFrame]: 장내채권 잔고조회 데이터
Example:
>>> df = inquire_balance(
... cano=trenv.my_acct,
... acnt_prdt_cd=trenv.my_prod,
... inqr_cndt='00',
... pdno='',
... buy_dt='',
... )
>>> print(df)
"""
# 로깅 설정
logger = logging.getLogger(__name__)
# 필수 파라미터 검증
if not cano:
logger.error("cano is required. (e.g. '12345678')")
raise ValueError("cano is required. (e.g. '12345678')")
if not acnt_prdt_cd:
logger.error("acnt_prdt_cd is required. (e.g. '01')")
raise ValueError("acnt_prdt_cd is required. (e.g. '01')")
if not inqr_cndt:
logger.error("inqr_cndt is required. (e.g. '00')")
raise ValueError("inqr_cndt is required. (e.g. '00')")
# 최대 재귀 깊이 체크
if depth >= max_depth:
logger.warning("Maximum recursion depth (%d) reached. Stopping further requests.", max_depth)
return dataframe if dataframe is not None else pd.DataFrame()
tr_id = "CTSC8407R"
params = {
"CANO": cano,
"ACNT_PRDT_CD": acnt_prdt_cd,
"INQR_CNDT": inqr_cndt,
"PDNO": pdno,
"BUY_DT": buy_dt,
"CTX_AREA_FK200": FK200,
"CTX_AREA_NK200": NK200,
}
# API 호출
res = ka._url_fetch(API_URL, tr_id, tr_cont, params)
if res.isOK():
if hasattr(res.getBody(), 'output'):
output_data = res.getBody().output
if not isinstance(output_data, list):
output_data = [output_data]
current_data = pd.DataFrame(output_data)
else:
current_data = pd.DataFrame()
if dataframe is not None:
dataframe = pd.concat([dataframe, current_data], ignore_index=True)
else:
dataframe = current_data
tr_cont = res.getHeader().tr_cont
NK200 = res.getBody().ctx_area_nk200
FK200 = res.getBody().ctx_area_fk200
if tr_cont == "M":
logger.info("Calling next page...")
ka.smart_sleep()
return inquire_balance(
cano,
acnt_prdt_cd,
inqr_cndt,
pdno,
buy_dt,
FK200,
NK200,
"N", dataframe, depth + 1, max_depth
)
else:
logger.info("Data fetch complete.")
return dataframe
else:
logger.error("API call failed: %s - %s", res.getErrorCode(), res.getErrorMessage())
res.printError(API_URL)
return pd.DataFrame()

View File

@@ -0,0 +1,99 @@
# -*- coding: utf-8 -*-
"""
Created on 2025-06-19
"""
import sys
import logging
import pandas as pd
sys.path.extend(['../..', '.']) # kis_auth 파일 경로 추가
import kis_auth as ka
from inquire_ccnl import inquire_ccnl
# 로깅 설정
logging.basicConfig(level=logging.INFO, format='%(levelname)s - %(message)s')
logger = logging.getLogger(__name__)
##############################################################################################
# [장내채권] 기본시세 > 장내채권현재가(체결) [국내주식-201]
##############################################################################################
COLUMN_MAPPING = {
'output1': '응답상세',
'stck_cntg_hour': '주식 체결 시간',
'bond_prpr': '채권 현재가',
'bond_prdy_vrss': '채권 전일 대비',
'prdy_vrss_sign': '전일 대비 부호',
'prdy_ctrt': '전일 대비율',
'cntg_vol': '체결 거래량',
'acml_vol': '누적 거래량'
}
NUMERIC_COLUMNS = []
def main():
"""
[장내채권] 기본시세
장내채권현재가(체결)[국내주식-201]
장내채권현재가(체결) 테스트 함수
Parameters:
- fid_cond_mrkt_div_code (str): 조건시장분류코드 (B (업종코드))
- fid_input_iscd (str): 입력종목코드 (채권종목코드(ex KR2033022D33))
Returns:
- DataFrame: 장내채권현재가(체결) 결과
Example:
>>> df = inquire_ccnl(fid_cond_mrkt_div_code="B", fid_input_iscd="KR2033022D33")
"""
try:
# pandas 출력 옵션 설정
pd.set_option('display.max_columns', None) # 모든 컬럼 표시
pd.set_option('display.width', None) # 출력 너비 제한 해제
pd.set_option('display.max_rows', None) # 모든 행 표시
# 토큰 발급
logger.info("토큰 발급 중...")
ka.auth()
logger.info("토큰 발급 완료")
# API 호출
logger.info("API 호출 시작: 장내채권현재가(체결)")
result = inquire_ccnl(
fid_cond_mrkt_div_code="B", # 조건시장분류코드
fid_input_iscd="KR103502GA34", # 입력종목코드
)
if result is None or result.empty:
logger.warning("조회된 데이터가 없습니다.")
return
# 컬럼명 출력
logger.info("사용 가능한 컬럼 목록:")
logger.info(result.columns.tolist())
# 한글 컬럼명으로 변환
result = result.rename(columns=COLUMN_MAPPING)
# 숫자형 컬럼 변환s
for col in NUMERIC_COLUMNS:
if col in result.columns:
result[col] = pd.to_numeric(result[col], errors='coerce')
# 결과 출력
logger.info("=== 장내채권현재가(체결) 결과 ===")
logger.info("조회된 데이터 건수: %d", len(result))
print(result)
except Exception as e:
logger.error("에러 발생: %s", str(e))
raise
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,117 @@
# [장내채권] 기본시세 - 장내채권현재가(체결)
# Generated by KIS API Generator (Single API Mode)
# -*- coding: utf-8 -*-
"""
Created on 2025-06-19
"""
import logging
import sys
import time
from typing import Optional
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__)
##############################################################################################
# [장내채권] 기본시세 > 장내채권현재가(체결) [국내주식-201]
##############################################################################################
# 상수 정의
API_URL = "/uapi/domestic-bond/v1/quotations/inquire-ccnl"
def inquire_ccnl(
fid_cond_mrkt_div_code: str, # 조건시장분류코드
fid_input_iscd: str, # 입력종목코드
tr_cont: str = "", # 연속 거래 여부
dataframe: Optional[pd.DataFrame] = None, # 누적 데이터프레임
depth: int = 0, # 현재 재귀 깊이
max_depth: int = 10 # 최대 재귀 깊이
) -> Optional[pd.DataFrame]:
"""
[장내채권] 기본시세
장내채권현재가(체결)[국내주식-201]
장내채권현재가(체결) API를 호출하여 DataFrame으로 반환합니다.
Args:
fid_cond_mrkt_div_code (str): 조건시장분류코드 (예: 'B')
fid_input_iscd (str): 입력종목코드 (예: 'KR2033022D33')
tr_cont (str): 연속 거래 여부 (기본값: "")
dataframe (Optional[pd.DataFrame]): 누적 데이터프레임 (기본값: None)
depth (int): 현재 재귀 깊이 (기본값: 0)
max_depth (int): 최대 재귀 깊이 (기본값: 10)
Returns:
Optional[pd.DataFrame]: 장내채권현재가(체결) 데이터
Example:
>>> df = inquire_ccnl('B', 'KR2033022D33')
>>> print(df)
"""
# 필수 파라미터 검증
if not fid_cond_mrkt_div_code:
logger.error("fid_cond_mrkt_div_code is required. (e.g. 'B')")
raise ValueError("fid_cond_mrkt_div_code is required. (e.g. 'B')")
if not fid_input_iscd:
logger.error("fid_input_iscd is required. (e.g. 'KR2033022D33')")
raise ValueError("fid_input_iscd is required. (e.g. 'KR2033022D33')")
# 최대 재귀 깊이 체크
if depth >= max_depth:
logger.warning("Maximum recursion depth (%d) reached. Stopping further requests.", max_depth)
return dataframe if dataframe is not None else pd.DataFrame()
tr_id = "FHKBJ773403C0"
# API 요청 파라미터 설정
params = {
"FID_COND_MRKT_DIV_CODE": fid_cond_mrkt_div_code,
"FID_INPUT_ISCD": fid_input_iscd,
}
# API 호출
res = ka._url_fetch(API_URL, tr_id, tr_cont, params)
# API 응답 처리
if res.isOK():
if hasattr(res.getBody(), 'output'):
output_data = res.getBody().output
if not isinstance(output_data, list):
output_data = [output_data]
current_data = pd.DataFrame(output_data)
else:
current_data = pd.DataFrame()
# 데이터프레임 병합
if dataframe is not None:
dataframe = pd.concat([dataframe, current_data], ignore_index=True)
else:
dataframe = current_data
# 연속 거래 여부 확인
tr_cont = res.getHeader().tr_cont
if tr_cont == "M":
logger.info("Calling next page...")
ka.smart_sleep()
return inquire_ccnl(
fid_cond_mrkt_div_code,
fid_input_iscd,
"N", dataframe, depth + 1, max_depth
)
else:
logger.info("Data fetch complete.")
return dataframe
else:
logger.error("API call failed: %s - %s", res.getErrorCode(), res.getErrorMessage())
res.printError(API_URL)
return pd.DataFrame()

View File

@@ -0,0 +1,156 @@
# -*- coding: utf-8 -*-
"""
Created on 2025-06-20
"""
import sys
import logging
import pandas as pd
sys.path.extend(['../..', '.']) # kis_auth 파일 경로 추가
import kis_auth as ka
from inquire_daily_ccld import inquire_daily_ccld
# 로깅 설정
logging.basicConfig(level=logging.INFO, format='%(levelname)s - %(message)s')
logger = logging.getLogger(__name__)
##############################################################################################
# [장내채권] 주문/계좌 > 장내채권 일별체결조회 [국내주식-127]
##############################################################################################
# 통합 컬럼 매핑 (모든 output에서 공통 사용)
COLUMN_MAPPING = {
'tot_ord_qty': '총주문수량',
'tot_ccld_qty_smtl': '총체결수량합계',
'tot_bond_ccld_avg_unpr': '총채권체결평균단가',
'tot_ccld_amt_smtl': '총체결금액합계',
'ord_dt': '주문일자',
'odno': '주문번호',
'orgn_odno': '원주문번호',
'ord_dvsn_name': '주문구분명',
'sll_buy_dvsn_cd_name': '매도매수구분코드명',
'shtn_pdno': '단축상품번호',
'prdt_abrv_name': '상품약어명',
'ord_qty': '주문수량',
'bond_ord_unpr': '채권주문단가',
'ord_tmd': '주문시각',
'tot_ccld_qty': '총체결수량',
'bond_avg_unpr': '채권평균단가',
'tot_ccld_amt': '총체결금액',
'loan_dt': '대출일자',
'buy_dt': '매수일자',
'samt_mket_ptci_yn_name': '소액시장참여여부명',
'sprx_psbl_yn_ifom': '분리과세가능여부알림',
'ord_mdia_dvsn_name': '주문매체구분묭',
'sll_buy_dvsn_cd': '매도매수구분코드',
'nccs_qty': '미체결수량',
'ord_gno_brno': '주문채번지점번호'
}
NUMERIC_COLUMNS = []
def main():
"""
[장내채권] 주문/계좌
장내채권 주문체결내역[국내주식-127]
장내채권 주문체결내역 테스트 함수
Parameters:
- cano (str): 종합계좌번호 (종합계좌번호)
- acnt_prdt_cd (str): 계좌상품코드 (계좌상품코드)
- inqr_strt_dt (str): 조회시작일자 (일자 ~ (1주일 이내))
- inqr_end_dt (str): 조회종료일자 (~ 일자 (조회 당일))
- sll_buy_dvsn_cd (str): 매도매수구분코드 (%(전체), 01(매도), 02(매수))
- sort_sqn_dvsn (str): 정렬순서구분 (01(주문순서), 02(주문역순))
- pdno (str): 상품번호 ()
- nccs_yn (str): 미체결여부 (N(전체), C(체결), Y(미체결))
Returns:
- Tuple[DataFrame, ...]: 장내채권 주문체결내역 결과
Example:
>>> df1, df2 = inquire_daily_ccld(cano=trenv.my_acct, acnt_prdt_cd=trenv.my_prod, inqr_strt_dt="20250601", inqr_end_dt="20250630", sll_buy_dvsn_cd="%", sort_sqn_dvsn="01", pdno="", nccs_yn="N", ctx_area_nk200="", ctx_area_fk200="")
"""
try:
# pandas 출력 옵션 설정
pd.set_option('display.max_columns', None) # 모든 컬럼 표시
pd.set_option('display.width', None) # 출력 너비 제한 해제
pd.set_option('display.max_rows', None) # 모든 행 표시
# 토큰 발급
logger.info("토큰 발급 중...")
ka.auth()
logger.info("토큰 발급 완료")
# kis_auth 모듈에서 계좌 정보 가져오기
trenv = ka.getTREnv()
# API 호출
logger.info("API 호출 시작: 장내채권 주문체결내역")
result1, result2 = inquire_daily_ccld(
cano=trenv.my_acct, # 종합계좌번호
acnt_prdt_cd=trenv.my_prod, # 계좌상품코드
inqr_strt_dt="20250601", # 조회시작일자
inqr_end_dt="20250630", # 조회종료일자
sll_buy_dvsn_cd="%", # 매도매수구분코드
sort_sqn_dvsn="01", # 정렬순서구분
pdno="", # 상품번호
nccs_yn="N", # 미체결여부
ctx_area_nk200="", # 연속조회키200
ctx_area_fk200="", # 연속조회검색조건200
)
# 결과 확인
results = [result1, result2]
if all(result is None or result.empty for result in results):
logger.warning("조회된 데이터가 없습니다.")
return
# output1 결과 처리
logger.info("=== output1 조회 ===")
if not result1.empty:
logger.info("사용 가능한 컬럼: %s", result1.columns.tolist())
# 통합 컬럼명 한글 변환 (필요한 컬럼만 자동 매핑됨)
result1 = result1.rename(columns=COLUMN_MAPPING)
# 숫자형 컬럼 변환s
for col in NUMERIC_COLUMNS:
if col in result1.columns:
result1[col] = pd.to_numeric(result1[col], errors='coerce')
logger.info("output1 결과:")
print(result1)
else:
logger.info("output1 데이터가 없습니다.")
# output2 결과 처리
logger.info("=== output2 조회 ===")
if not result2.empty:
logger.info("사용 가능한 컬럼: %s", result2.columns.tolist())
# 통합 컬럼명 한글 변환 (필요한 컬럼만 자동 매핑됨)
result2 = result2.rename(columns=COLUMN_MAPPING)
# 숫자형 컬럼 변환s
for col in NUMERIC_COLUMNS:
if col in result2.columns:
result2[col] = pd.to_numeric(result2[col], errors='coerce')
logger.info("output2 결과:")
print(result2)
else:
logger.info("output2 데이터가 없습니다.")
except Exception as e:
logger.error("에러 발생: %s", str(e))
raise
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,202 @@
# [장내채권] 주문/계좌 - 장내채권 주문체결내역
# Generated by KIS API Generator (Single API Mode)
# -*- coding: utf-8 -*-
"""
Created on 2025-06-20
"""
import logging
import time
from typing import Optional, Tuple
import sys
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__)
##############################################################################################
# [장내채권] 주문/계좌 > 장내채권 일별체결조회 [국내주식-127]
##############################################################################################
# 상수 정의
API_URL = "/uapi/domestic-bond/v1/trading/inquire-daily-ccld"
def inquire_daily_ccld(
cano: str, # 종합계좌번호
acnt_prdt_cd: str, # 계좌상품코드
inqr_strt_dt: str, # 조회시작일자
inqr_end_dt: str, # 조회종료일자
sll_buy_dvsn_cd: str, # 매도매수구분코드
sort_sqn_dvsn: str, # 정렬순서구분
pdno: str, # 상품번호
nccs_yn: str, # 미체결여부
ctx_area_nk200: str, # 연속조회키200
ctx_area_fk200: str, # 연속조회검색조건200
dataframe1: Optional[pd.DataFrame] = None, # 누적 데이터프레임 (output1)
dataframe2: Optional[pd.DataFrame] = None, # 누적 데이터프레임 (output2)
tr_cont: str = "",
depth: int = 0,
max_depth: int = 10
) -> Tuple[pd.DataFrame, pd.DataFrame]:
"""
[장내채권] 주문/계좌
장내채권 주문체결내역[국내주식-127]
장내채권 주문체결내역 API를 호출하여 DataFrame으로 반환합니다.
Args:
cano (str): 종합계좌번호
acnt_prdt_cd (str): 계좌상품코드
inqr_strt_dt (str): 조회시작일자 (1주일 이내)
inqr_end_dt (str): 조회종료일자 (조회 당일)
sll_buy_dvsn_cd (str): 매도매수구분코드 (%(전체), 01(매도), 02(매수))
sort_sqn_dvsn (str): 정렬순서구분 (01(주문순서), 02(주문역순))
pdno (str): 상품번호
nccs_yn (str): 미체결여부 (N(전체), C(체결), Y(미체결))
ctx_area_nk200 (str): 연속조회키200
ctx_area_fk200 (str): 연속조회검색조건200
dataframe1 (Optional[pd.DataFrame]): 누적 데이터프레임 (output1)
dataframe2 (Optional[pd.DataFrame]): 누적 데이터프레임 (output2)
tr_cont (str): 연속 거래 여부
depth (int): 현재 재귀 깊이
max_depth (int): 최대 재귀 깊이 (기본값: 10)
Returns:
Tuple[pd.DataFrame, pd.DataFrame]: 장내채권 주문체결내역 데이터
Example:
>>> df1, df2 = inquire_daily_ccld(
... cano=trenv.my_acct,
... acnt_prdt_cd=trenv.my_prod,
... inqr_strt_dt='20230101',
... inqr_end_dt='20230107',
... sll_buy_dvsn_cd='01',
... sort_sqn_dvsn='01',
... pdno='000000000001',
... nccs_yn='N',
... ctx_area_nk200='',
... ctx_area_fk200=''
... )
>>> print(df1)
>>> print(df2)
"""
# 필수 파라미터 검증
if not cano:
logger.error("cano is required. (e.g. '12345678')")
raise ValueError("cano is required. (e.g. '12345678')")
if not acnt_prdt_cd:
logger.error("acnt_prdt_cd is required. (e.g. '01')")
raise ValueError("acnt_prdt_cd is required. (e.g. '01')")
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. '20230107')")
raise ValueError("inqr_end_dt is required. (e.g. '20230107')")
if not sll_buy_dvsn_cd in ["%", "01", "02"]:
logger.error("sll_buy_dvsn_cd is required. (e.g. '01')")
raise ValueError("sll_buy_dvsn_cd is required. (e.g. '01')")
if not sort_sqn_dvsn in ["01", "02"]:
logger.error("sort_sqn_dvsn is required. (e.g. '01')")
raise ValueError("sort_sqn_dvsn is required. (e.g. '01')")
if not nccs_yn in ["N", "C", "Y"]:
logger.error("nccs_yn is required. (e.g. 'N')")
raise ValueError("nccs_yn is required. (e.g. 'N')")
# 최대 재귀 깊이 체크
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()
tr_id = "CTSC8013R"
params = {
"CANO": cano,
"ACNT_PRDT_CD": acnt_prdt_cd,
"INQR_STRT_DT": inqr_strt_dt,
"INQR_END_DT": inqr_end_dt,
"SLL_BUY_DVSN_CD": sll_buy_dvsn_cd,
"SORT_SQN_DVSN": sort_sqn_dvsn,
"PDNO": pdno,
"NCCS_YN": nccs_yn,
"CTX_AREA_NK200": ctx_area_nk200,
"CTX_AREA_FK200": ctx_area_fk200,
}
res = ka._url_fetch(API_URL, tr_id, tr_cont, params)
if res.isOK():
# output1 처리
if hasattr(res.getBody(), 'output1'):
output_data = res.getBody().output1
if output_data:
# output1은 단일 객체, output2는 배열일 수 있음
if isinstance(output_data, list):
current_data1 = pd.DataFrame(output_data)
else:
# 단일 객체인 경우 리스트로 감싸서 DataFrame 생성
current_data1 = pd.DataFrame([output_data])
if dataframe1 is not None:
dataframe1 = pd.concat([dataframe1, current_data1], ignore_index=True)
else:
dataframe1 = current_data1
else:
if dataframe1 is None:
dataframe1 = pd.DataFrame()
else:
if dataframe1 is None:
dataframe1 = pd.DataFrame()
# output2 처리
if hasattr(res.getBody(), 'output2'):
output_data = res.getBody().output2
if output_data:
# output1은 단일 객체, output2는 배열일 수 있음
if isinstance(output_data, list):
current_data2 = pd.DataFrame(output_data)
else:
# 단일 객체인 경우 리스트로 감싸서 DataFrame 생성
current_data2 = pd.DataFrame([output_data])
if dataframe2 is not None:
dataframe2 = pd.concat([dataframe2, current_data2], ignore_index=True)
else:
dataframe2 = current_data2
else:
if dataframe2 is None:
dataframe2 = pd.DataFrame()
else:
if dataframe2 is None:
dataframe2 = pd.DataFrame()
tr_cont = res.getHeader().tr_cont
ctx_area_nk200 = res.getBody().ctx_area_nk200
ctx_area_fk200 = res.getBody().ctx_area_fk200
if tr_cont in ["M", "F"]:
logger.info("Calling next page...")
ka.smart_sleep()
return inquire_daily_ccld(
cano,
acnt_prdt_cd,
inqr_strt_dt,
inqr_end_dt,
sll_buy_dvsn_cd,
sort_sqn_dvsn,
pdno,
nccs_yn,
ctx_area_nk200,
ctx_area_fk200,
"N", dataframe1, dataframe2, depth + 1, max_depth
)
else:
logger.info("Data fetch complete.")
return dataframe1, dataframe2
else:
logger.error("API call failed: %s - %s", res.getErrorCode(), res.getErrorMessage())
res.printError(API_URL)
return pd.DataFrame(), pd.DataFrame()

View File

@@ -0,0 +1,95 @@
# -*- coding: utf-8 -*-
"""
Created on 2025-06-19
"""
import sys
import logging
import pandas as pd
sys.path.extend(['../..', '.']) # kis_auth 파일 경로 추가
import kis_auth as ka
from inquire_daily_itemchartprice import inquire_daily_itemchartprice
# 로깅 설정
logging.basicConfig(level=logging.INFO, format='%(levelname)s - %(message)s')
logger = logging.getLogger(__name__)
##############################################################################################
# [장내채권] 기본시세 > 장내채권 기간별시세(일) [국내주식-159]
##############################################################################################
COLUMN_MAPPING = {
'stck_bsop_date': '주식영업일자',
'bond_oprc': '채권시가2',
'bond_hgpr': '채권고가',
'bond_lwpr': '채권저가',
'bond_prpr': '채권현재가',
'acml_vol': '누적거래량'
}
NUMERIC_COLUMNS = []
def main():
"""
[장내채권] 기본시세
장내채권 기간별시세(일)[국내주식-159]
장내채권 기간별시세(일) 테스트 함수
Parameters:
- fid_cond_mrkt_div_code (str): 조건 시장 구분 코드 (Unique key(B))
- fid_input_iscd (str): 입력 종목코드 (채권종목코드)
Returns:
- DataFrame: 장내채권 기간별시세(일) 결과
Example:
>>> df = inquire_daily_itemchartprice(fid_cond_mrkt_div_code="B", fid_input_iscd="KR2033022D33")
"""
try:
# pandas 출력 옵션 설정
pd.set_option('display.max_columns', None) # 모든 컬럼 표시
pd.set_option('display.width', None) # 출력 너비 제한 해제
pd.set_option('display.max_rows', None) # 모든 행 표시
# 토큰 발급
logger.info("토큰 발급 중...")
ka.auth()
logger.info("토큰 발급 완료")
# API 호출
logger.info("API 호출 시작: 장내채권 기간별시세(일)")
result = inquire_daily_itemchartprice(
fid_cond_mrkt_div_code="B", # 조건 시장 구분 코드
fid_input_iscd="KR103502GA34", # 입력 종목코드
)
if result is None or result.empty:
logger.warning("조회된 데이터가 없습니다.")
return
# 컬럼명 출력
logger.info("사용 가능한 컬럼 목록:")
logger.info(result.columns.tolist())
# 한글 컬럼명으로 변환
result = result.rename(columns=COLUMN_MAPPING)
# 숫자형 컬럼 변환
for col in NUMERIC_COLUMNS:
if col in result.columns:
result[col] = pd.to_numeric(result[col], errors='coerce')
# 결과 출력
logger.info("=== 장내채권 기간별시세(일) 결과 ===")
logger.info("조회된 데이터 건수: %d", len(result))
print(result)
except Exception as e:
logger.error("에러 발생: %s", str(e))
raise
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,114 @@
# [장내채권] 기본시세 - 장내채권 기간별시세(일)
# Generated by KIS API Generator (Single API Mode)
# -*- coding: utf-8 -*-
"""
Created on 2025-06-19
"""
import logging
import time
from typing import Optional, Tuple
import sys
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__)
##############################################################################################
# [장내채권] 기본시세 > 장내채권 기간별시세(일) [국내주식-159]
##############################################################################################
# 상수 정의
API_URL = "/uapi/domestic-bond/v1/quotations/inquire-daily-itemchartprice"
def inquire_daily_itemchartprice(
fid_cond_mrkt_div_code: str, # 조건 시장 구분 코드
fid_input_iscd: str, # 입력 종목코드
tr_cont: str = "", # 연속 거래 여부
dataframe: Optional[pd.DataFrame] = None, # 누적 데이터프레임
depth: int = 0, # 현재 재귀 깊이
max_depth: int = 10 # 최대 재귀 깊이
) -> Optional[pd.DataFrame]:
"""
[장내채권] 기본시세
장내채권 기간별시세(일)[국내주식-159]
장내채권 기간별시세(일) API를 호출하여 DataFrame으로 반환합니다.
Args:
fid_cond_mrkt_div_code (str): 조건 시장 구분 코드 (필수)
fid_input_iscd (str): 입력 종목코드 (필수)
tr_cont (str): 연속 거래 여부 (기본값: "")
dataframe (Optional[pd.DataFrame]): 누적 데이터프레임 (기본값: None)
depth (int): 현재 재귀 깊이 (기본값: 0)
max_depth (int): 최대 재귀 깊이 (기본값: 10)
Returns:
Optional[pd.DataFrame]: 장내채권 기간별시세(일) 데이터
Example:
>>> df = inquire_daily_itemchartprice("B", "KR2033022D33")
>>> print(df)
"""
# 필수 파라미터 검증
if not fid_cond_mrkt_div_code:
logger.error("fid_cond_mrkt_div_code is required. (e.g. 'B')")
raise ValueError("fid_cond_mrkt_div_code is required. (e.g. 'B')")
if not fid_input_iscd:
logger.error("fid_input_iscd is required. (e.g. 'KR2033022D33')")
raise ValueError("fid_input_iscd is required. (e.g. 'KR2033022D33')")
# 최대 재귀 깊이 체크
if depth >= max_depth:
logger.warning("Maximum recursion depth (%d) reached. Stopping further requests.", max_depth)
return dataframe if dataframe is not None else pd.DataFrame()
tr_id = "FHKBJ773701C0"
params = {
"FID_COND_MRKT_DIV_CODE": fid_cond_mrkt_div_code,
"FID_INPUT_ISCD": fid_input_iscd,
}
# API 호출
res = ka._url_fetch(API_URL, tr_id, tr_cont, params)
if res.isOK():
if hasattr(res.getBody(), 'output'):
output_data = res.getBody().output
if not isinstance(output_data, list):
output_data = [output_data]
current_data = pd.DataFrame(output_data)
else:
current_data = pd.DataFrame()
# 데이터프레임 병합
if dataframe is not None:
dataframe = pd.concat([dataframe, current_data], ignore_index=True)
else:
dataframe = current_data
# 연속 거래 여부 확인
tr_cont = res.getHeader().tr_cont
if tr_cont == "M":
logger.info("Calling next page...")
ka.smart_sleep()
return inquire_daily_itemchartprice(
fid_cond_mrkt_div_code,
fid_input_iscd,
"N", dataframe, depth + 1, max_depth
)
else:
logger.info("Data fetch complete.")
return dataframe
else:
logger.error("API call failed: %s - %s", res.getErrorCode(), res.getErrorMessage())
res.printError(API_URL)
return pd.DataFrame()

View File

@@ -0,0 +1,99 @@
# -*- coding: utf-8 -*-
"""
Created on 2025-06-19
"""
import sys
import logging
import pandas as pd
sys.path.extend(['../..', '.']) # kis_auth 파일 경로 추가
import kis_auth as ka
from inquire_daily_price import inquire_daily_price
# 로깅 설정
logging.basicConfig(level=logging.INFO, format='%(levelname)s - %(message)s')
logger = logging.getLogger(__name__)
##############################################################################################
# [장내채권] 기본시세 > 장내채권현재가(일별) [국내주식-202]
##############################################################################################
COLUMN_MAPPING = {
'output1': '응답상세',
'stck_bsop_date': '주식영업일자',
'bond_prpr': '채권현재가',
'bond_prdy_vrss': '채권전일대비',
'prdy_vrss_sign': '전일대비부호',
'prdy_ctrt': '전일대비율',
'acml_vol': '누적거래량',
'bond_oprc': '채권시가2',
'bond_hgpr': '채권고가',
'bond_lwpr': '채권저가'
}
NUMERIC_COLUMNS = []
def main():
"""
[장내채권] 기본시세
장내채권현재가(일별)[국내주식-202]
장내채권현재가(일별) 테스트 함수
Parameters:
- fid_cond_mrkt_div_code (str): 조건시장분류코드 (B (업종코드))
- fid_input_iscd (str): 입력종목코드 (채권종목코드(ex KR2033022D33))
Returns:
- DataFrame: 장내채권현재가(일별) 결과
Example:
>>> df = inquire_daily_price(fid_cond_mrkt_div_code="B", fid_input_iscd="KR2033022D33")
"""
try:
# pandas 출력 옵션 설정
pd.set_option('display.max_columns', None) # 모든 컬럼 표시
pd.set_option('display.width', None) # 출력 너비 제한 해제
pd.set_option('display.max_rows', None) # 모든 행 표시
# 토큰 발급
logger.info("토큰 발급 중...")
ka.auth()
logger.info("토큰 발급 완료")
# API 호출
logger.info("API 호출 시작: 장내채권현재가(일별)")
result = inquire_daily_price(
fid_cond_mrkt_div_code="B", # 조건시장분류코드
fid_input_iscd="KR6095572D81", # 입력종목코드
)
if result is None or result.empty:
logger.warning("조회된 데이터가 없습니다.")
return
# 컬럼명 출력
logger.info("사용 가능한 컬럼 목록:")
logger.info(result.columns.tolist())
# 한글 컬럼명으로 변환
result = result.rename(columns=COLUMN_MAPPING)
# 숫자형 컬럼 변환
for col in NUMERIC_COLUMNS:
if col in result.columns:
result[col] = pd.to_numeric(result[col], errors='coerce')
# 결과 출력
logger.info("=== 장내채권현재가(일별) 결과 ===")
logger.info("조회된 데이터 건수: %d", len(result))
print(result)
except Exception as e:
logger.error("에러 발생: %s", str(e))
raise
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,119 @@
# [장내채권] 기본시세 - 장내채권현재가(일별)
# Generated by KIS API Generator (Single API Mode)
# -*- coding: utf-8 -*-
"""
Created on 2025-06-19
"""
import logging
import sys
import time
from typing import Optional
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__)
##############################################################################################
# [장내채권] 기본시세 > 장내채권현재가(일별) [국내주식-202]
##############################################################################################
# 상수 정의
API_URL = "/uapi/domestic-bond/v1/quotations/inquire-daily-price"
def inquire_daily_price(
fid_cond_mrkt_div_code: str, # 조건시장분류코드
fid_input_iscd: str, # 입력종목코드
tr_cont: str = "", # 연속 거래 여부
dataframe: Optional[pd.DataFrame] = None, # 누적 데이터프레임
depth: int = 0, # 현재 재귀 깊이
max_depth: int = 10 # 최대 재귀 깊이
) -> Optional[pd.DataFrame]:
"""
[장내채권] 기본시세
장내채권현재가(일별)[국내주식-202]
장내채권현재가(일별) API를 호출하여 DataFrame으로 반환합니다.
Args:
fid_cond_mrkt_div_code (str): 조건시장분류코드 (예: 'B')
fid_input_iscd (str): 입력종목코드 (예: 'KR2033022D33')
tr_cont (str): 연속 거래 여부 (기본값: "")
dataframe (Optional[pd.DataFrame]): 누적 데이터프레임 (기본값: None)
depth (int): 현재 재귀 깊이 (기본값: 0)
max_depth (int): 최대 재귀 깊이 (기본값: 10)
Returns:
Optional[pd.DataFrame]: 장내채권현재가(일별) 데이터
Example:
>>> df = inquire_daily_price('B', 'KR2033022D33')
>>> print(df)
"""
# 로깅 설정
logger = logging.getLogger(__name__)
# 필수 파라미터 검증
if not fid_cond_mrkt_div_code:
logger.error("fid_cond_mrkt_div_code is required. (e.g. 'B')")
raise ValueError("fid_cond_mrkt_div_code is required. (e.g. 'B')")
if not fid_input_iscd:
logger.error("fid_input_iscd is required. (e.g. 'KR2033022D33')")
raise ValueError("fid_input_iscd is required. (e.g. 'KR2033022D33')")
# 최대 재귀 깊이 체크
if depth >= max_depth:
logger.warning("Maximum recursion depth (%d) reached. Stopping further requests.", max_depth)
return dataframe if dataframe is not None else pd.DataFrame()
tr_id = "FHKBJ773404C0"
params = {
"FID_COND_MRKT_DIV_CODE": fid_cond_mrkt_div_code,
"FID_INPUT_ISCD": fid_input_iscd,
}
# API 호출
res = ka._url_fetch(API_URL, tr_id, tr_cont, params)
if res.isOK():
# 응답 데이터 처리
if hasattr(res.getBody(), 'output'):
output_data = res.getBody().output
if not isinstance(output_data, list):
output_data = [output_data]
current_data = pd.DataFrame(output_data)
else:
current_data = pd.DataFrame()
# 데이터프레임 병합
if dataframe is not None:
dataframe = pd.concat([dataframe, current_data], ignore_index=True)
else:
dataframe = current_data
# 연속 거래 여부 확인
tr_cont = res.getHeader().tr_cont
if tr_cont == "M":
logger.info("Calling next page...")
ka.smart_sleep()
return inquire_daily_price(
fid_cond_mrkt_div_code,
fid_input_iscd,
"N", dataframe, depth + 1, max_depth
)
else:
logger.info("Data fetch complete.")
return dataframe
else:
# API 에러 처리
logger.error("API call failed: %s - %s", res.getErrorCode(), res.getErrorMessage())
res.printError(API_URL)
return pd.DataFrame()

View File

@@ -0,0 +1,107 @@
# -*- coding: utf-8 -*-
"""
Created on 2025-06-19
"""
import sys
import logging
import pandas as pd
sys.path.extend(['../..', '.']) # kis_auth 파일 경로 추가
import kis_auth as ka
from inquire_price import inquire_price
# 로깅 설정
logging.basicConfig(level=logging.INFO, format='%(levelname)s - %(message)s')
logger = logging.getLogger(__name__)
##############################################################################################
# [장내채권] 기본시세 > 장내채권현재가(시세) [국내주식-200]
##############################################################################################
COLUMN_MAPPING = {
'stnd_iscd': '표준종목코드',
'hts_kor_isnm': 'HTS한글종목명',
'bond_prpr': '채권현재가',
'prdy_vrss_sign': '전일대비부호',
'bond_prdy_vrss': '채권전일대비',
'prdy_ctrt': '전일대비율',
'acml_vol': '누적거래량',
'bond_prdy_clpr': '채권전일종가',
'bond_oprc': '채권시가2',
'bond_hgpr': '채권고가',
'bond_lwpr': '채권저가',
'ernn_rate': '수익비율',
'oprc_ert': '시가2수익률',
'hgpr_ert': '최고가수익률',
'lwpr_ert': '최저가수익률',
'bond_mxpr': '채권상한가',
'bond_llam': '채권하한가'
}
NUMERIC_COLUMNS = []
def main():
"""
[장내채권] 기본시세
장내채권현재가(시세)[국내주식-200]
장내채권현재가(시세) 테스트 함수
Parameters:
- fid_cond_mrkt_div_code (str): 조건시장분류코드 (B (업종코드))
- fid_input_iscd (str): 입력종목코드 (채권종목코드(ex KR2033022D33))
Returns:
- DataFrame: 장내채권현재가(시세) 결과
Example:
>>> df = inquire_price(fid_cond_mrkt_div_code="B", fid_input_iscd="KR2033022D33")
"""
try:
# pandas 출력 옵션 설정
pd.set_option('display.max_columns', None) # 모든 컬럼 표시
pd.set_option('display.width', None) # 출력 너비 제한 해제
pd.set_option('display.max_rows', None) # 모든 행 표시
# 토큰 발급
logger.info("토큰 발급 중...")
ka.auth()
logger.info("토큰 발급 완료")
# API 호출
logger.info("API 호출 시작: 장내채권현재가(시세)")
result = inquire_price(
fid_cond_mrkt_div_code="B", # 조건시장분류코드
fid_input_iscd="KR2033022D33", # 입력종목코드
)
if result is None or result.empty:
logger.warning("조회된 데이터가 없습니다.")
return
# 컬럼명 출력
logger.info("사용 가능한 컬럼 목록:")
logger.info(result.columns.tolist())
# 한글 컬럼명으로 변환
result = result.rename(columns=COLUMN_MAPPING)
# 숫자형 컬럼 변환
for col in NUMERIC_COLUMNS:
if col in result.columns:
result[col] = pd.to_numeric(result[col], errors='coerce')
# 결과 출력
logger.info("=== 장내채권현재가(시세) 결과 ===")
logger.info("조회된 데이터 건수: %d", len(result))
print(result)
except Exception as e:
logger.error("에러 발생: %s", str(e))
raise
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,114 @@
# [장내채권] 기본시세 - 장내채권현재가(시세)
# Generated by KIS API Generator (Single API Mode)
# -*- coding: utf-8 -*-
"""
Created on 2025-06-19
"""
import logging
import sys
import time
from typing import Optional
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__)
##############################################################################################
# [장내채권] 기본시세 > 장내채권현재가(시세) [국내주식-200]
##############################################################################################
# 상수 정의
API_URL = "/uapi/domestic-bond/v1/quotations/inquire-price"
def inquire_price(
fid_cond_mrkt_div_code: str, # 조건시장분류코드
fid_input_iscd: str, # 입력종목코드
tr_cont: str = "", # 연속 거래 여부
dataframe: Optional[pd.DataFrame] = None, # 누적 데이터프레임
depth: int = 0, # 현재 재귀 깊이
max_depth: int = 10 # 최대 재귀 깊이
) -> Optional[pd.DataFrame]:
"""
[장내채권] 기본시세
장내채권현재가(시세)[국내주식-200]
장내채권현재가(시세) API를 호출하여 DataFrame으로 반환합니다.
Args:
fid_cond_mrkt_div_code (str): 조건시장분류코드 (예: 'B')
fid_input_iscd (str): 입력종목코드 (예: 'KR2033022D33')
tr_cont (str): 연속 거래 여부 (기본값: "")
dataframe (Optional[pd.DataFrame]): 누적 데이터프레임 (기본값: None)
depth (int): 현재 재귀 깊이 (기본값: 0)
max_depth (int): 최대 재귀 깊이 (기본값: 10)
Returns:
Optional[pd.DataFrame]: 장내채권현재가(시세) 데이터
Example:
>>> df = inquire_price('B', 'KR2033022D33')
>>> print(df)
"""
# 필수 파라미터 검증
if not fid_cond_mrkt_div_code:
logger.error("fid_cond_mrkt_div_code is required. (e.g. 'B')")
raise ValueError("fid_cond_mrkt_div_code is required. (e.g. 'B')")
if not fid_input_iscd:
logger.error("fid_input_iscd is required. (e.g. 'KR2033022D33')")
raise ValueError("fid_input_iscd is required. (e.g. 'KR2033022D33')")
# 최대 재귀 깊이 체크
if depth >= max_depth:
logger.warning("Maximum recursion depth (%d) reached. Stopping further requests.", max_depth)
return dataframe if dataframe is not None else pd.DataFrame()
tr_id = "FHKBJ773400C0"
params = {
"FID_COND_MRKT_DIV_CODE": fid_cond_mrkt_div_code,
"FID_INPUT_ISCD": fid_input_iscd,
}
# API 호출
res = ka._url_fetch(API_URL, tr_id, tr_cont, params)
if res.isOK():
if hasattr(res.getBody(), 'output'):
output_data = res.getBody().output
if not isinstance(output_data, list):
output_data = [output_data]
current_data = pd.DataFrame(output_data)
else:
current_data = pd.DataFrame()
# 데이터프레임 병합
if dataframe is not None:
dataframe = pd.concat([dataframe, current_data], ignore_index=True)
else:
dataframe = current_data
# 연속 거래 여부 확인
tr_cont = res.getHeader().tr_cont
if tr_cont == "M":
logger.info("Calling next page...")
ka.smart_sleep()
return inquire_price(
fid_cond_mrkt_div_code,
fid_input_iscd,
"N", dataframe, depth + 1, max_depth
)
else:
logger.info("Data fetch complete.")
return dataframe
else:
logger.error("API call failed: %s - %s", res.getErrorCode(), res.getErrorMessage())
res.printError(API_URL)
return pd.DataFrame()

View File

@@ -0,0 +1,104 @@
# -*- coding: utf-8 -*-
"""
Created on 2025-06-20
"""
import sys
import logging
import pandas as pd
sys.path.extend(['../..', '.']) # kis_auth 파일 경로 추가
import kis_auth as ka
from inquire_psbl_order import inquire_psbl_order
# 로깅 설정
logging.basicConfig(level=logging.INFO, format='%(levelname)s - %(message)s')
logger = logging.getLogger(__name__)
##############################################################################################
# [장내채권] 주문/계좌 > 장내채권 매수가능조회 [국내주식-199]
##############################################################################################
COLUMN_MAPPING = {
'ord_psbl_cash': '주문가능현금',
'ord_psbl_sbst': '주문가능대용',
'ruse_psbl_amt': '재사용가능금액',
'bond_ord_unpr2': '채권주문단가2',
'buy_psbl_amt': '매수가능금액',
'buy_psbl_qty': '매수가능수량',
'cma_evlu_amt': 'CMA평가금액'
}
NUMERIC_COLUMNS = []
def main():
"""
[장내채권] 주문/계좌
장내채권 매수가능조회[국내주식-199]
장내채권 매수가능조회 테스트 함수
Parameters:
- cano (str): 종합계좌번호
- acnt_prdt_cd (str): 계좌상품코드
- pdno (str): 채권종목코드(ex KR2033022D33)
- bond_ord_unpr (str): 채권주문단가
Returns:
- DataFrame: 장내채권 매수가능조회 결과
Example:
>>> df = inquire_psbl_order(cano=trenv.my_acct, acnt_prdt_cd=trenv.my_prod, pdno="KR2033022D33", bond_ord_unpr="1000")
"""
try:
# pandas 출력 옵션 설정
pd.set_option('display.max_columns', None) # 모든 컬럼 표시
pd.set_option('display.width', None) # 출력 너비 제한 해제
pd.set_option('display.max_rows', None) # 모든 행 표시
# 토큰 발급
logger.info("토큰 발급 중...")
ka.auth()
logger.info("토큰 발급 완료")
# kis_auth 모듈에서 계좌 정보 가져오기
trenv = ka.getTREnv()
# API 호출
logger.info("API 호출 시작: 장내채권 매수가능조회")
result = inquire_psbl_order(
cano=trenv.my_acct, # 종합계좌번호
acnt_prdt_cd=trenv.my_prod, # 계좌상품코드
pdno="KR2033022D33", # 채권종목코드(ex KR2033022D33)
bond_ord_unpr="1000", # 채권주문단가
)
if result is None or result.empty:
logger.warning("조회된 데이터가 없습니다.")
return
# 컬럼명 출력
logger.info("사용 가능한 컬럼 목록:")
logger.info(result.columns.tolist())
# 한글 컬럼명으로 변환
result = result.rename(columns=COLUMN_MAPPING)
# 숫자형 컬럼 변환
for col in NUMERIC_COLUMNS:
if col in result.columns:
result[col] = pd.to_numeric(result[col], errors='coerce')
# 결과 출력
logger.info("=== 장내채권 매수가능조회 결과 ===")
logger.info("조회된 데이터 건수: %d", len(result))
print(result)
except Exception as e:
logger.error("에러 발생: %s", str(e))
raise
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,132 @@
# [장내채권] 주문/계좌 - 장내채권 매수가능조회
# Generated by KIS API Generator (Single API Mode)
# -*- coding: utf-8 -*-
"""
Created on 2025-06-20
"""
import logging
import sys
import time
from typing import Optional
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__)
##############################################################################################
# [장내채권] 주문/계좌 > 장내채권 매수가능조회 [국내주식-199]
##############################################################################################
# 상수 정의
API_URL = "/uapi/domestic-bond/v1/trading/inquire-psbl-order"
def inquire_psbl_order(
cano: str, # 종합계좌번호
acnt_prdt_cd: str, # 계좌상품코드
pdno: str, # 상품번호
bond_ord_unpr: str, # 채권주문단가
tr_cont: str = "", # 연속 거래 여부
dataframe: Optional[pd.DataFrame] = None, # 누적 데이터프레임
depth: int = 0, # 현재 재귀 깊이
max_depth: int = 10 # 최대 재귀 깊이
) -> Optional[pd.DataFrame]:
"""
[장내채권] 주문/계좌
장내채권 매수가능조회[국내주식-199]
장내채권 매수가능조회 API를 호출하여 DataFrame으로 반환합니다.
Args:
cano (str): 종합계좌번호 (필수)
acnt_prdt_cd (str): 계좌상품코드 (필수)
pdno (str): 채권종목코드(ex KR2033022D33)
bond_ord_unpr (str): 채권주문단가 (필수)
tr_cont (str): 연속 거래 여부 (기본값: "")
dataframe (Optional[pd.DataFrame]): 누적 데이터프레임
depth (int): 현재 재귀 깊이
max_depth (int): 최대 재귀 깊이 (기본값: 10)
Returns:
Optional[pd.DataFrame]: 장내채권 매수가능조회 데이터
Example:
>>> df = inquire_psbl_order("12345678", "01", "KR2033022D33", "1000")
>>> print(df)
"""
# 필수 파라미터 검증
if not cano:
logger.error("cano is required. (e.g. '1234567890')")
raise ValueError("cano is required. (e.g. '1234567890')")
if not acnt_prdt_cd:
logger.error("acnt_prdt_cd is required. (e.g. '01')")
raise ValueError("acnt_prdt_cd is required. (e.g. '01')")
if not pdno:
logger.error("pdno is required. (e.g. 'KR2033022D33')")
raise ValueError("pdno is required. (e.g. 'KR2033022D33')")
if not bond_ord_unpr:
logger.error("bond_ord_unpr is required. (e.g. '1000')")
raise ValueError("bond_ord_unpr is required. (e.g. '1000')")
# 최대 재귀 깊이 체크
if depth >= max_depth:
logger.warning("Maximum recursion depth (%d) reached. Stopping further requests.", max_depth)
return dataframe if dataframe is not None else pd.DataFrame()
tr_id = "TTTC8910R"
params = {
"CANO": cano,
"ACNT_PRDT_CD": acnt_prdt_cd,
"PDNO": pdno,
"BOND_ORD_UNPR": bond_ord_unpr,
}
# API 호출
res = ka._url_fetch(API_URL, tr_id, tr_cont, params)
if res.isOK():
# 응답 데이터 처리
if hasattr(res.getBody(), 'output'):
output_data = res.getBody().output
if not isinstance(output_data, list):
output_data = [output_data]
current_data = pd.DataFrame(output_data)
else:
current_data = pd.DataFrame()
# 데이터프레임 병합
if dataframe is not None:
dataframe = pd.concat([dataframe, current_data], ignore_index=True)
else:
dataframe = current_data
# 연속 거래 여부 확인
tr_cont = res.getHeader().tr_cont
if tr_cont == "M":
logger.info("Calling next page...")
ka.smart_sleep()
return inquire_psbl_order(
cano,
acnt_prdt_cd,
pdno,
bond_ord_unpr,
"N", dataframe, depth + 1, max_depth
)
else:
logger.info("Data fetch complete.")
return dataframe
else:
# API 에러 처리
logger.error("API call failed: %s - %s", res.getErrorCode(), res.getErrorMessage())
res.printError(API_URL)
return pd.DataFrame()

View File

@@ -0,0 +1,114 @@
# -*- coding: utf-8 -*-
"""
Created on 2025-06-20
"""
import sys
import logging
import pandas as pd
sys.path.extend(['../..', '.']) # kis_auth 파일 경로 추가
import kis_auth as ka
from inquire_psbl_rvsecncl import inquire_psbl_rvsecncl
# 로깅 설정
logging.basicConfig(level=logging.INFO, format='%(levelname)s - %(message)s')
logger = logging.getLogger(__name__)
##############################################################################################
# [장내채권] 주문/계좌 > 채권정정취소가능주문조회 [국내주식-126]
##############################################################################################
COLUMN_MAPPING = {
'odno': '주문번호',
'pdno': '상품번호',
'rvse_cncl_dvsn_name': '정정취소구분명',
'ord_qty': '주문수량',
'bond_ord_unpr': '채권주문단가',
'ord_tmd': '주문시각',
'tot_ccld_qty': '총체결수량',
'tot_ccld_amt': '총체결금액',
'ord_psbl_qty': '주문가능수량',
'orgn_odno': '원주문번호',
'sll_buy_dvsn_cd': '매도매수구분코드',
'ord_dvsn_cd': '주문구분코드',
'mgco_aptm_odno': '운용사지정주문번호',
'samt_mket_ptci_yn': '소액시장참여여부'
}
NUMERIC_COLUMNS = []
def main():
"""
[장내채권] 주문/계좌
채권정정취소가능주문조회[국내주식-126]
채권정정취소가능주문조회 테스트 함수
Parameters:
- cano (str): 종합계좌번호 ()
- acnt_prdt_cd (str): 계좌상품코드 ()
- ord_dt (str): 주문일자 ()
- odno (str): 주문번호 ()
- ctx_area_fk200 (str): 연속조회검색조건200 ()
- ctx_area_nk200 (str): 연속조회키200 ()
Returns:
- DataFrame: 채권정정취소가능주문조회 결과
Example:
>>> df = inquire_psbl_rvsecncl(cano=trenv.my_acct, acnt_prdt_cd=trenv.my_prod, ord_dt="20250601", odno="", ctx_area_fk200="", ctx_area_nk200="")
"""
try:
# pandas 출력 옵션 설정
pd.set_option('display.max_columns', None) # 모든 컬럼 표시
pd.set_option('display.width', None) # 출력 너비 제한 해제
pd.set_option('display.max_rows', None) # 모든 행 표시
# 토큰 발급
logger.info("토큰 발급 중...")
ka.auth()
logger.info("토큰 발급 완료")
# kis_auth 모듈에서 계좌 정보 가져오기
trenv = ka.getTREnv()
# API 호출
logger.info("API 호출 시작: 채권정정취소가능주문조회")
result = inquire_psbl_rvsecncl(
cano=trenv.my_acct, # 종합계좌번호
acnt_prdt_cd=trenv.my_prod, # 계좌상품코드
ord_dt="", # 주문일자
odno="", # 주문번호
ctx_area_fk200="", # 연속조회검색조건200
ctx_area_nk200="", # 연속조회키200
)
if result is None or result.empty:
logger.warning("조회된 데이터가 없습니다.")
return
# 컬럼명 출력
logger.info("사용 가능한 컬럼 목록:")
logger.info(result.columns.tolist())
# 한글 컬럼명으로 변환
result = result.rename(columns=COLUMN_MAPPING)
# 숫자형 컬럼 변환
for col in NUMERIC_COLUMNS:
if col in result.columns:
result[col] = pd.to_numeric(result[col], errors='coerce')
# 결과 출력
logger.info("=== 채권정정취소가능주문조회 결과 ===")
logger.info("조회된 데이터 건수: %d", len(result))
print(result)
except Exception as e:
logger.error("에러 발생: %s", str(e))
raise
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,136 @@
# [장내채권] 주문/계좌 - 채권정정취소가능주문조회
# Generated by KIS API Generator (Single API Mode)
# -*- coding: utf-8 -*-
"""
Created on 2025-06-20
"""
import logging
import time
from typing import Optional
import sys
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__)
##############################################################################################
# [장내채권] 주문/계좌 > 채권정정취소가능주문조회 [국내주식-126]
##############################################################################################
# 상수 정의
API_URL = "/uapi/domestic-bond/v1/trading/inquire-psbl-rvsecncl"
def inquire_psbl_rvsecncl(
cano: str, # 종합계좌번호
acnt_prdt_cd: str, # 계좌상품코드
ord_dt: str, # 주문일자
odno: str, # 주문번호
ctx_area_fk200: str, # 연속조회검색조건200
ctx_area_nk200: str, # 연속조회키200
tr_cont: str = "", # 연속 거래 여부
dataframe: Optional[pd.DataFrame] = None, # 누적 데이터프레임
depth: int = 0, # 현재 재귀 깊이
max_depth: int = 10 # 최대 재귀 깊이
) -> Optional[pd.DataFrame]:
"""
[장내채권] 주문/계좌
채권정정취소가능주문조회[국내주식-126]
채권정정취소가능주문조회 API를 호출하여 DataFrame으로 반환합니다.
Args:
cano (str): 종합계좌번호 (예: '12345678')
acnt_prdt_cd (str): 계좌상품코드 (예: '01')
ord_dt (str): 주문일자 (예: '20230101')
odno (str): 주문번호 (예: '0000000001')
ctx_area_fk200 (str): 연속조회검색조건200 (예: '조건값')
ctx_area_nk200 (str): 연속조회키200 (예: '키값')
tr_cont (str): 연속 거래 여부 (기본값: "")
dataframe (Optional[pd.DataFrame]): 누적 데이터프레임
depth (int): 현재 재귀 깊이
max_depth (int): 최대 재귀 깊이 (기본값: 10)
Returns:
Optional[pd.DataFrame]: 채권정정취소가능주문조회 데이터
Example:
>>> df = inquire_psbl_rvsecncl(
... cano=trenv.my_acct,
... acnt_prdt_cd=trenv.my_prod,
... ord_dt='20230101',
... odno='0000000001',
... ctx_area_fk200='조건값',
... ctx_area_nk200='키값'
... )
>>> print(df)
"""
# 필수 파라미터 검증
if not cano:
logger.error("cano is required. (e.g. '12345678')")
raise ValueError("cano is required. (e.g. '12345678')")
if not acnt_prdt_cd:
logger.error("acnt_prdt_cd is required. (e.g. '01')")
raise ValueError("acnt_prdt_cd is required. (e.g. '01')")
# 최대 재귀 깊이 체크
if depth >= max_depth:
logger.warning("Maximum recursion depth (%d) reached. Stopping further requests.", max_depth)
return dataframe if dataframe is not None else pd.DataFrame()
tr_id = "CTSC8035R"
params = {
"CANO": cano,
"ACNT_PRDT_CD": acnt_prdt_cd,
"ORD_DT": ord_dt,
"ODNO": odno,
"CTX_AREA_FK200": ctx_area_fk200,
"CTX_AREA_NK200": ctx_area_nk200,
}
res = ka._url_fetch(API_URL, tr_id, tr_cont, params)
if res.isOK():
if hasattr(res.getBody(), 'output'):
output_data = res.getBody().output
if not isinstance(output_data, list):
output_data = [output_data]
current_data = pd.DataFrame(output_data)
else:
current_data = pd.DataFrame()
if dataframe is not None:
dataframe = pd.concat([dataframe, current_data], ignore_index=True)
else:
dataframe = current_data
tr_cont = res.getHeader().tr_cont
ctx_area_nk200 = res.getBody().ctx_area_nk200
ctx_area_fk200 = res.getBody().ctx_area_fk200
if tr_cont == "M":
logger.info("Calling next page...")
ka.smart_sleep()
return inquire_psbl_rvsecncl(
cano,
acnt_prdt_cd,
ord_dt,
odno,
ctx_area_fk200,
ctx_area_nk200,
"N", dataframe, depth + 1, max_depth
)
else:
logger.info("Data fetch complete.")
return dataframe
else:
logger.error("API call failed: %s - %s", res.getErrorCode(), res.getErrorMessage())
res.printError(API_URL)
return pd.DataFrame()

View File

@@ -0,0 +1,176 @@
# -*- coding: utf-8 -*-
"""
Created on 2025-06-19
"""
import sys
import logging
import pandas as pd
sys.path.extend(['../..', '.']) # kis_auth 파일 경로 추가
import kis_auth as ka
from issue_info import issue_info
# 로깅 설정
logging.basicConfig(level=logging.INFO, format='%(levelname)s - %(message)s')
logger = logging.getLogger(__name__)
##############################################################################################
# [장내채권] 기본시세 > 장내채권 발행정보 [국내주식-156]
##############################################################################################
COLUMN_MAPPING = {
'pdno': '상품번호',
'prdt_type_cd': '상품유형코드',
'prdt_name': '상품명',
'prdt_eng_name': '상품영문명',
'ivst_heed_prdt_yn': '투자유의상품여부',
'exts_yn': '연장여부',
'bond_clsf_cd': '채권분류코드',
'bond_clsf_kor_name': '채권분류한글명',
'papr': '액면가',
'int_mned_dvsn_cd': '이자월말구분코드',
'rvnu_shap_cd': '매출형태코드',
'issu_amt': '발행금액',
'lstg_rmnd': '상장잔액',
'int_dfrm_mcnt': '이자지급개월수',
'bond_int_dfrm_mthd_cd': '채권이자지급방법코드',
'splt_rdpt_rcnt': '분할상환횟수',
'prca_dfmt_term_mcnt': '원금거치기간개월수',
'int_anap_dvsn_cd': '이자선후급구분코드',
'bond_rght_dvsn_cd': '채권권리구분코드',
'prdt_pclc_text': '상품특성내용',
'prdt_abrv_name': '상품약어명',
'prdt_eng_abrv_name': '상품영문약어명',
'sprx_psbl_yn': '분리과세가능여부',
'pbff_pplc_ofrg_mthd_cd': '공모사모모집방법코드',
'cmco_cd': '주간사코드',
'issu_istt_cd': '발행기관코드',
'issu_istt_name': '발행기관명',
'pnia_dfrm_agcy_istt_cd': '원리금지급대행기관코드',
'dsct_ec_rt': '할인할증율',
'srfc_inrt': '표면이율',
'expd_rdpt_rt': '만기상환율',
'expd_asrc_erng_rt': '만기보장수익율',
'bond_grte_istt_name': '채권보증기관명',
'int_dfrm_day_type_cd': '이자지급일유형코드',
'ksd_int_calc_unit_cd': '증권예탁결제원이자계산단위코드',
'int_wunt_uder_prcs_dvsn_cd': '이자원화단위미만처리구분코드',
'rvnu_dt': '매출일자',
'issu_dt': '발행일자',
'lstg_dt': '상장일자',
'expd_dt': '만기일자',
'rdpt_dt': '상환일자',
'sbst_pric': '대용가격',
'rgbf_int_dfrm_dt': '직전이자지급일자',
'nxtm_int_dfrm_dt': '차기이자지급일자',
'frst_int_dfrm_dt': '최초이자지급일자',
'ecis_pric': '행사가격',
'rght_stck_std_pdno': '권리주식표준상품번호',
'ecis_opng_dt': '행사개시일자',
'ecis_end_dt': '행사종료일자',
'bond_rvnu_mthd_cd': '채권매출방법코드',
'oprt_stfno': '조작직원번호',
'oprt_stff_name': '조작직원명',
'rgbf_int_dfrm_wday': '직전이자지급요일',
'nxtm_int_dfrm_wday': '차기이자지급요일',
'kis_crdt_grad_text': '한국신용평가신용등급내용',
'kbp_crdt_grad_text': '한국채권평가신용등급내용',
'nice_crdt_grad_text': '한국신용정보신용등급내용',
'fnp_crdt_grad_text': '에프앤자산평가신용등급내용',
'dpsi_psbl_yn': '예탁가능여부',
'pnia_int_calc_unpr': '원리금이자계산단가',
'prcm_idx_bond_yn': '물가지수채권여부',
'expd_exts_srdp_rcnt': '만기연장분할상환횟수',
'expd_exts_srdp_rt': '만기연장분할상환율',
'loan_psbl_yn': '대출가능여부',
'grte_dvsn_cd': '보증구분코드',
'fnrr_rank_dvsn_cd': '선후순위구분코드',
'krx_lstg_abol_dvsn_cd': '한국거래소상장폐지구분코드',
'asst_rqdi_dvsn_cd': '자산유동화구분코드',
'opcb_dvsn_cd': '옵션부사채구분코드',
'crfd_item_yn': '크라우드펀딩종목여부',
'crfd_item_rstc_cclc_dt': '크라우드펀딩종목제한해지일자',
'bond_nmpr_unit_pric': '채권호가단위가격',
'ivst_heed_bond_dvsn_name': '투자유의채권구분명',
'add_erng_rt': '추가수익율',
'add_erng_rt_aply_dt': '추가수익율적용일자',
'bond_tr_stop_dvsn_cd': '채권거래정지구분코드',
'ivst_heed_bond_dvsn_cd': '투자유의채권구분코드',
'pclr_cndt_text': '특이조건내용',
'hbbd_yn': '하이브리드채권여부',
'cdtl_cptl_scty_type_cd': '조건부자본증권유형코드',
'elec_scty_yn': '전자증권여부',
'sq1_clop_ecis_opng_dt': '1차콜옵션행사개시일자',
'frst_erlm_stfno': '최초등록직원번호',
'frst_erlm_dt': '최초등록일자',
'frst_erlm_tmd': '최초등록시각',
'tlg_rcvg_dtl_dtime': '전문수신상세일시'
}
NUMERIC_COLUMNS = []
def main():
"""
[장내채권] 기본시세
장내채권 발행정보[국내주식-156]
장내채권 발행정보 테스트 함수
Parameters:
- pdno (str): 사용자권한정보 (채권 종목번호(ex. KR6449111CB8))
- prdt_type_cd (str): 거래소코드 (Unique key(302))
Returns:
- DataFrame: 장내채권 발행정보 결과
Example:
>>> df = issue_info(pdno="KR6449111CB8", prdt_type_cd="302")
"""
try:
# pandas 출력 옵션 설정
pd.set_option('display.max_columns', None) # 모든 컬럼 표시
pd.set_option('display.width', None) # 출력 너비 제한 해제
pd.set_option('display.max_rows', None) # 모든 행 표시
# 토큰 발급
logger.info("토큰 발급 중...")
ka.auth()
logger.info("토큰 발급 완료")
# API 호출
logger.info("API 호출 시작: 장내채권 발행정보")
result = issue_info(
pdno="KR6449111CB8", # 사용자권한정보
prdt_type_cd="302", # 거래소코드
)
if result is None or result.empty:
logger.warning("조회된 데이터가 없습니다.")
return
# 컬럼명 출력
logger.info("사용 가능한 컬럼 목록:")
logger.info(result.columns.tolist())
# 한글 컬럼명으로 변환
result = result.rename(columns=COLUMN_MAPPING)
# 숫자형 컬럼 변환
for col in NUMERIC_COLUMNS:
if col in result.columns:
result[col] = pd.to_numeric(result[col], errors='coerce')
# 결과 출력
logger.info("=== 장내채권 발행정보 결과 ===")
logger.info("조회된 데이터 건수: %d", len(result))
print(result)
except Exception as e:
logger.error("에러 발생: %s", str(e))
raise
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,121 @@
# [장내채권] 기본시세 - 장내채권 발행정보
# Generated by KIS API Generator (Single API Mode)
# -*- coding: utf-8 -*-
"""
Created on 2025-06-19
"""
import logging
import time
from typing import Optional
import sys
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__)
##############################################################################################
# [장내채권] 기본시세 > 장내채권 발행정보 [국내주식-156]
##############################################################################################
# 상수 정의
API_URL = "/uapi/domestic-bond/v1/quotations/issue-info"
def issue_info(
pdno: str, # 사용자권한정보
prdt_type_cd: str, # 거래소코드
tr_cont: str = "", # 연속 거래 여부
dataframe: Optional[pd.DataFrame] = None, # 누적 데이터프레임
depth: int = 0, # 현재 재귀 깊이
max_depth: int = 10 # 최대 재귀 깊이
) -> Optional[pd.DataFrame]:
"""
[장내채권] 기본시세
장내채권 발행정보[국내주식-156]
장내채권 발행정보 API를 호출하여 DataFrame으로 반환합니다.
Args:
pdno (str): 채권 종목번호(ex. KR6449111CB8)
prdt_type_cd (str): Unique key(302)
tr_cont (str): 연속 거래 여부
dataframe (Optional[pd.DataFrame]): 누적 데이터프레임
depth (int): 현재 재귀 깊이
max_depth (int): 최대 재귀 깊이 (기본값: 10)
Returns:
Optional[pd.DataFrame]: 장내채권 발행정보 데이터
Example:
>>> df = issue_info("KR6449111CB8", "302")
>>> print(df)
"""
# 로깅 설정
logger = logging.getLogger(__name__)
# 필수 파라미터 검증
if not pdno:
logger.error("pdno is required. (e.g. 'KR6449111CB8')")
raise ValueError("pdno is required. (e.g. 'KR6449111CB8')")
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 depth >= max_depth:
logger.warning("Maximum recursion depth (%d) reached. Stopping further requests.", max_depth)
return dataframe if dataframe is not None else pd.DataFrame()
# API 호출 URL 및 거래 ID 설정
tr_id = "CTPF1101R"
# 요청 파라미터 설정
params = {
"PDNO": pdno,
"PRDT_TYPE_CD": prdt_type_cd,
}
# API 호출
res = ka._url_fetch(API_URL, tr_id, tr_cont, params)
# API 호출 성공 여부 확인
if res.isOK():
# 응답 데이터 처리
if hasattr(res.getBody(), 'output'):
output_data = res.getBody().output
if not isinstance(output_data, list):
output_data = [output_data]
current_data = pd.DataFrame(output_data)
else:
current_data = pd.DataFrame()
# 데이터프레임 병합
if dataframe is not None:
dataframe = pd.concat([dataframe, current_data], ignore_index=True)
else:
dataframe = current_data
# 연속 거래 여부 확인
tr_cont = res.getHeader().tr_cont
if tr_cont == "M":
logger.info("Calling next page...")
ka.smart_sleep()
return issue_info(
pdno,
prdt_type_cd,
"N", dataframe, depth + 1, max_depth
)
else:
logger.info("Data fetch complete.")
return dataframe
else:
# API 호출 실패 시 에러 로그 출력
logger.error("API call failed: %s - %s", res.getErrorCode(), res.getErrorMessage())
res.printError(API_URL)
return pd.DataFrame()

View File

@@ -0,0 +1,115 @@
# -*- coding: utf-8 -*-
"""
Created on 2025-06-20
"""
import sys
import logging
import pandas as pd
sys.path.extend(['../..', '.']) # kis_auth 파일 경로 추가
import kis_auth as ka
from order_rvsecncl import order_rvsecncl
# 로깅 설정
logging.basicConfig(level=logging.INFO, format='%(levelname)s - %(message)s')
logger = logging.getLogger(__name__)
##############################################################################################
# [장내채권] 주문/계좌 > 장내채권 정정취소주문 [국내주식-125]
##############################################################################################
COLUMN_MAPPING = {
'KRX_FWDG_ORD_ORGNO': '한국거래소전송주문조직번호',
'ODNO': '주문번호',
'ORD_TMD': '주문시각'
}
NUMERIC_COLUMNS = []
def main():
"""
[장내채권] 주문/계좌
장내채권 정정취소주문[국내주식-125]
장내채권 정정취소주문 테스트 함수
Parameters:
cano (str): 종합계좌번호
acnt_prdt_cd (str): 계좌상품코드
pdno (str): 상품번호
orgn_odno (str): 원주문번호
ord_qty2 (str): 주문수량2
bond_ord_unpr (str): 채권주문단가
qty_all_ord_yn (str): 잔량전부주문여부
rvse_cncl_dvsn_cd (str): 정정취소구분코드
mgco_aptm_odno (str): 운용사지정주문번호
ord_svr_dvsn_cd (str): 주문서버구분코드
ctac_tlno (str): 연락전화번호
Returns:
- DataFrame: 장내채권 정정취소주문 결과
Example:
>>> df = main()
>>> print(df)
"""
try:
# pandas 출력 옵션 설정
pd.set_option('display.max_columns', None) # 모든 컬럼 표시
pd.set_option('display.width', None) # 출력 너비 제한 해제
pd.set_option('display.max_rows', None) # 모든 행 표시
# 토큰 발급
logger.info("토큰 발급 중...")
ka.auth()
logger.info("토큰 발급 완료")
# kis_auth 모듈에서 계좌 정보 가져오기
trenv = ka.getTREnv()
# API 호출
logger.info("API 호출 시작: 장내채권 정정취소주문")
result = order_rvsecncl(
cano=trenv.my_acct,
acnt_prdt_cd=trenv.my_prod,
pdno="KR6095572D81",
orgn_odno="0004357900", # 실제 테스트 시 유효한 원주문번호로 변경해야 합니다.
ord_qty2="1", # 정정/취소 수량
bond_ord_unpr="10470", # 정정 단가
qty_all_ord_yn="Y", # 잔량 전부 주문 여부
rvse_cncl_dvsn_cd="01", # 01: 정정, 02: 취소
mgco_aptm_odno="",
ord_svr_dvsn_cd="0",
ctac_tlno="",
)
if result is None or result.empty:
logger.warning("조회된 데이터가 없습니다.")
return
# 컬럼명 출력
logger.info("사용 가능한 컬럼 목록:")
logger.info(result.columns.tolist())
# 한글 컬럼명으로 변환
result = result.rename(columns=COLUMN_MAPPING)
# 숫자형 컬럼 변환
for col in NUMERIC_COLUMNS:
if col in result.columns:
result[col] = pd.to_numeric(result[col], errors='coerce')
# 결과 출력
logger.info("=== 장내채권 정정취소주문 결과 ===")
logger.info("조회된 데이터 건수: %d", len(result))
print(result)
except Exception as e:
logger.error("에러 발생: %s", str(e))
raise
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,113 @@
# [장내채권] 주문/계좌 - 장내채권 정정취소주문
# Generated by KIS API Generator (Single API Mode)
# -*- coding: utf-8 -*-
"""
Created on 2025-06-20
"""
import logging
from typing import Optional
import sys
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__)
##############################################################################################
# [장내채권] 주문/계좌 > 장내채권 정정취소주문 [국내주식-125]
##############################################################################################
# 상수 정의
API_URL = "/uapi/domestic-bond/v1/trading/order-rvsecncl"
def order_rvsecncl(
cano: str,
acnt_prdt_cd: str,
pdno: str,
orgn_odno: str,
ord_qty2: str,
bond_ord_unpr: str,
qty_all_ord_yn: str,
rvse_cncl_dvsn_cd: str,
mgco_aptm_odno: str = "",
ord_svr_dvsn_cd: str = "0",
ctac_tlno: str = ""
) -> Optional[pd.DataFrame]:
"""
[장내채권] 주문/계좌
장내채권 정정취소주문[국내주식-125]
장내채권 정정취소주문 API를 호출하여 DataFrame으로 반환합니다.
Args:
cano (str): 종합계좌번호
acnt_prdt_cd (str): 계좌상품코드
pdno (str): 상품번호
orgn_odno (str): 원주문번호
ord_qty2 (str): 주문수량2
bond_ord_unpr (str): 채권주문단가
qty_all_ord_yn (str): 잔량전부주문여부
rvse_cncl_dvsn_cd (str): 정정취소구분코드
mgco_aptm_odno (str, optional): 운용사지정주문번호. Defaults to "".
ord_svr_dvsn_cd (str, optional): 주문서버구분코드. Defaults to "0".
ctac_tlno (str, optional): 연락전화번호. Defaults to "".
Returns:
Optional[pd.DataFrame]: 장내채권 정정취소주문 데이터
Example:
>>> df = order_rvsecncl(
... cano=trenv.my_acct,
... acnt_prdt_cd=trenv.my_prod,
... pdno="KR6095572D81",
... orgn_odno="0000015402",
... ord_qty2="2",
... bond_ord_unpr="10460",
... qty_all_ord_yn="Y",
... rvse_cncl_dvsn_cd="01"
... )
>>> print(df)
"""
tr_id = "TTTC0953U"
params = {
"CANO": cano,
"ACNT_PRDT_CD": acnt_prdt_cd,
"PDNO": pdno,
"ORGN_ODNO": orgn_odno,
"ORD_QTY2": ord_qty2,
"BOND_ORD_UNPR": bond_ord_unpr,
"QTY_ALL_ORD_YN": qty_all_ord_yn,
"RVSE_CNCL_DVSN_CD": rvse_cncl_dvsn_cd,
"MGCO_APTM_ODNO": mgco_aptm_odno,
"ORD_SVR_DVSN_CD": ord_svr_dvsn_cd,
"CTAC_TLNO": ctac_tlno
}
res = ka._url_fetch(api_url=API_URL,
ptr_id=tr_id,
tr_cont="",
params=params,
postFlag=True
)
if res.isOK():
if hasattr(res.getBody(), 'output'):
output_data = res.getBody().output
if not isinstance(output_data, list):
output_data = [output_data]
dataframe = pd.DataFrame(output_data)
else:
dataframe = pd.DataFrame()
logger.info("Data fetch complete.")
return dataframe
else:
logger.error("API call failed: %s - %s", res.getErrorCode(), res.getErrorMessage())
res.printError(API_URL)
return pd.DataFrame()

View File

@@ -0,0 +1,171 @@
# -*- coding: utf-8 -*-
"""
Created on 2025-06-19
"""
import sys
import logging
import pandas as pd
sys.path.extend(['../..', '.']) # kis_auth 파일 경로 추가
import kis_auth as ka
from search_bond_info import search_bond_info
# 로깅 설정
logging.basicConfig(level=logging.INFO, format='%(levelname)s - %(message)s')
logger = logging.getLogger(__name__)
##############################################################################################
# [장내채권] 기본시세 > 장내채권 기본조회 [국내주식-129]
##############################################################################################
COLUMN_MAPPING = {
'pdno': '상품번호',
'prdt_type_cd': '상품유형코드',
'ksd_bond_item_name': '증권예탁결제원채권종목명',
'ksd_bond_item_eng_name': '증권예탁결제원채권종목영문명',
'ksd_bond_lstg_type_cd': '증권예탁결제원채권상장유형코드',
'ksd_ofrg_dvsn_cd': '증권예탁결제원모집구분코드',
'ksd_bond_int_dfrm_dvsn_cd': '증권예탁결제원채권이자지급구분',
'issu_dt': '발행일자',
'rdpt_dt': '상환일자',
'rvnu_dt': '매출일자',
'iso_crcy_cd': '통화코드',
'mdwy_rdpt_dt': '중도상환일자',
'ksd_rcvg_bond_dsct_rt': '증권예탁결제원수신채권할인율',
'ksd_rcvg_bond_srfc_inrt': '증권예탁결제원수신채권표면이율',
'bond_expd_rdpt_rt': '채권만기상환율',
'ksd_prca_rdpt_mthd_cd': '증권예탁결제원원금상환방법코드',
'int_caltm_mcnt': '이자계산기간개월수',
'ksd_int_calc_unit_cd': '증권예탁결제원이자계산단위코드',
'uval_cut_dvsn_cd': '절상절사구분코드',
'uval_cut_dcpt_dgit': '절상절사소수점자릿수',
'ksd_dydv_caltm_aply_dvsn_cd': '증권예탁결제원일할계산기간적용',
'dydv_calc_dcnt': '일할계산일수',
'bond_expd_asrc_erng_rt': '채권만기보장수익율',
'padf_plac_hdof_name': '원리금지급장소본점명',
'lstg_dt': '상장일자',
'lstg_abol_dt': '상장폐지일자',
'ksd_bond_issu_mthd_cd': '증권예탁결제원채권발행방법코드',
'laps_indf_yn': '경과이자지급여부',
'ksd_lhdy_pnia_dfrm_mthd_cd': '증권예탁결제원공휴일원리금지급',
'frst_int_dfrm_dt': '최초이자지급일자',
'ksd_prcm_lnkg_gvbd_yn': '증권예탁결제원물가연동국고채여',
'dpsi_end_dt': '예탁종료일자',
'dpsi_strt_dt': '예탁시작일자',
'dpsi_psbl_yn': '예탁가능여부',
'atyp_rdpt_bond_erlm_yn': '비정형상환채권등록여부',
'dshn_occr_yn': '부도발생여부',
'expd_exts_yn': '만기연장여부',
'pclr_ptcr_text': '특이사항내용',
'dpsi_psbl_excp_stat_cd': '예탁가능예외상태코드',
'expd_exts_srdp_rcnt': '만기연장분할상환횟수',
'expd_exts_srdp_rt': '만기연장분할상환율',
'expd_rdpt_rt': '만기상환율',
'expd_asrc_erng_rt': '만기보장수익율',
'bond_int_dfrm_mthd_cd': '채권이자지급방법코드',
'int_dfrm_day_type_cd': '이자지급일유형코드',
'prca_dfmt_term_mcnt': '원금거치기간개월수',
'splt_rdpt_rcnt': '분할상환횟수',
'rgbf_int_dfrm_dt': '직전이자지급일자',
'nxtm_int_dfrm_dt': '차기이자지급일자',
'sprx_psbl_yn': '분리과세가능여부',
'ictx_rt_dvsn_cd': '소득세율구분코드',
'bond_clsf_cd': '채권분류코드',
'bond_clsf_kor_name': '채권분류한글명',
'int_mned_dvsn_cd': '이자월말구분코드',
'pnia_int_calc_unpr': '원리금이자계산단가',
'frn_intr': 'FRN금리',
'aply_day_prcm_idx_lnkg_cefc': '적용일물가지수연동계수',
'ksd_expd_dydv_calc_bass_cd': '증권예탁결제원만기일할계산기준',
'expd_dydv_calc_dcnt': '만기일할계산일수',
'ksd_cbbw_dvsn_cd': '증권예탁결제원신종사채구분코드',
'crfd_item_yn': '크라우드펀딩종목여부',
'pnia_bank_ofdy_dfrm_mthd_cd': '원리금은행휴무일지급방법코드',
'qib_yn': 'QIB여부',
'qib_cclc_dt': 'QIB해지일자',
'csbd_yn': '영구채여부',
'csbd_cclc_dt': '영구채해지일자',
'ksd_opcb_yn': '증권예탁결제원옵션부사채여부',
'ksd_sodn_yn': '증권예탁결제원후순위채권여부',
'ksd_rqdi_scty_yn': '증권예탁결제원유동화증권여부',
'elec_scty_yn': '전자증권여부',
'rght_ecis_mbdy_dvsn_cd': '권리행사주체구분코드',
'int_rkng_mthd_dvsn_cd': '이자산정방법구분코드',
'ofrg_dvsn_cd': '모집구분코드',
'ksd_tot_issu_amt': '증권예탁결제원총발행금액',
'next_indf_chk_ecls_yn': '다음이자지급체크제외여부',
'ksd_bond_intr_dvsn_cd': '증권예탁결제원채권금리구분코드',
'ksd_inrt_aply_dvsn_cd': '증권예탁결제원이율적용구분코드',
'krx_issu_istt_cd': 'KRX발행기관코드',
'ksd_indf_frqc_uder_calc_cd': '증권예탁결제원이자지급주기미만',
'ksd_indf_frqc_uder_calc_dcnt': '증권예탁결제원이자지급주기미만',
'tlg_rcvg_dtl_dtime': '전문수신상세일시'
}
NUMERIC_COLUMNS = []
def main():
"""
[장내채권] 기본시세
장내채권 기본조회[국내주식-129]
장내채권 기본조회 테스트 함수
Parameters:
- pdno (str): 상품번호 (상품번호)
- prdt_type_cd (str): 상품유형코드 (Unique key(302))
Returns:
- DataFrame: 장내채권 기본조회 결과
Example:
>>> df = search_bond_info(pdno="", prdt_type_cd="302")
"""
try:
# pandas 출력 옵션 설정
pd.set_option('display.max_columns', None) # 모든 컬럼 표시
pd.set_option('display.width', None) # 출력 너비 제한 해제
pd.set_option('display.max_rows', None) # 모든 행 표시
# 토큰 발급
logger.info("토큰 발급 중...")
ka.auth()
logger.info("토큰 발급 완료")
# API 호출
logger.info("API 호출 시작: 장내채권 기본조회")
result = search_bond_info(
pdno="KR103502GA34", # 상품번호
prdt_type_cd="302", # 상품유형코드
)
if result is None or result.empty:
logger.warning("조회된 데이터가 없습니다.")
return
# 컬럼명 출력
logger.info("사용 가능한 컬럼 목록:")
logger.info(result.columns.tolist())
# 한글 컬럼명으로 변환
result = result.rename(columns=COLUMN_MAPPING)
# 숫자형 컬럼 변환
for col in NUMERIC_COLUMNS:
if col in result.columns:
result[col] = pd.to_numeric(result[col], errors='coerce')
# 결과 출력
logger.info("=== 장내채권 기본조회 결과 ===")
logger.info("조회된 데이터 건수: %d", len(result))
print(result)
except Exception as e:
logger.error("에러 발생: %s", str(e))
raise
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,115 @@
# [장내채권] 기본시세 - 장내채권 기본조회
# Generated by KIS API Generator (Single API Mode)
# -*- coding: utf-8 -*-
"""
Created on 2025-06-19
"""
import logging
import time
from typing import Optional
import sys
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__)
##############################################################################################
# [장내채권] 기본시세 > 장내채권 기본조회 [국내주식-129]
##############################################################################################
# 상수 정의
API_URL = "/uapi/domestic-bond/v1/quotations/search-bond-info"
def search_bond_info(
pdno: str, # 상품번호
prdt_type_cd: str, # 상품유형코드
tr_cont: str = "", # 연속 거래 여부
dataframe: Optional[pd.DataFrame] = None, # 누적 데이터프레임
depth: int = 0, # 현재 재귀 깊이
max_depth: int = 10 # 최대 재귀 깊이
) -> Optional[pd.DataFrame]:
"""
[장내채권] 기본시세
장내채권 기본조회[국내주식-129]
장내채권 기본조회 API를 호출하여 DataFrame으로 반환합니다.
Args:
pdno (str): 상품번호 (필수)
prdt_type_cd (str): 상품유형코드 (필수)
tr_cont (str): 연속 거래 여부 (기본값: "")
dataframe (Optional[pd.DataFrame]): 누적 데이터프레임
depth (int): 현재 재귀 깊이
max_depth (int): 최대 재귀 깊이 (기본값: 10)
Returns:
Optional[pd.DataFrame]: 장내채권 기본조회 데이터
Example:
>>> df = search_bond_info("KR2033022D33", "302")
>>> print(df)
"""
# 로깅 설정
logger = logging.getLogger(__name__)
# 필수 파라미터 검증
if not pdno:
logger.error("pdno is required. (e.g. 'KR2033022D33')")
raise ValueError("pdno is required. (e.g. 'KR2033022D33')")
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 depth >= max_depth:
logger.warning("Maximum recursion depth (%d) reached. Stopping further requests.", max_depth)
return dataframe if dataframe is not None else pd.DataFrame()
tr_id = "CTPF1114R"
params = {
"PDNO": pdno,
"PRDT_TYPE_CD": prdt_type_cd,
}
# API 호출
res = ka._url_fetch(API_URL, tr_id, tr_cont, params)
if res.isOK():
if hasattr(res.getBody(), 'output'):
output_data = res.getBody().output
if not isinstance(output_data, list):
output_data = [output_data]
current_data = pd.DataFrame(output_data)
else:
current_data = pd.DataFrame()
if dataframe is not None:
dataframe = pd.concat([dataframe, current_data], ignore_index=True)
else:
dataframe = current_data
tr_cont = res.getHeader().tr_cont
if tr_cont == "M":
logger.info("Calling next page...")
ka.smart_sleep()
return search_bond_info(
pdno,
prdt_type_cd,
"N", dataframe, depth + 1, max_depth
)
else:
logger.info("Data fetch complete.")
return dataframe
else:
logger.error("API call failed: %s - %s", res.getErrorCode(), res.getErrorMessage())
res.printError(API_URL)
return pd.DataFrame()

View File

@@ -0,0 +1,124 @@
# -*- coding: utf-8 -*-
"""
Created on 2025-06-20
"""
import sys
import logging
import pandas as pd
sys.path.extend(['../..', '.']) # kis_auth 파일 경로 추가
import kis_auth as ka
from sell import sell
# 로깅 설정
logging.basicConfig(level=logging.INFO, format='%(levelname)s - %(message)s')
logger = logging.getLogger(__name__)
##############################################################################################
# [장내채권] 주문/계좌 > 장내채권 매도주문 [국내주식-123]
##############################################################################################
COLUMN_MAPPING = {
'KRX_FWDG_ORD_ORGNO': '한국거래소전송주문조직번호',
'ODNO': '주문번호',
'ORD_TMD': '주문시각'
}
NUMERIC_COLUMNS = []
def main():
"""
[장내채권] 주문/계좌
장내채권 매도주문[국내주식-123]
장내채권 매도주문 테스트 함수
Parameters:
cano (str): 종합계좌번호
acnt_prdt_cd (str): 계좌상품코드
ord_dvsn (str): 주문구분
pdno (str): 상품번호
ord_qty2 (str): 주문수량2
bond_ord_unpr (str): 채권주문단가
sprx_yn (str): 분리과세여부
buy_dt (str): 매수일자
buy_seq (str): 매수순번
samt_mket_ptci_yn (str): 소액시장참여여부
sll_agco_opps_sll_yn (str): 매도대행사반대매도여부
bond_rtl_mket_yn (str): 채권소매시장여부
mgco_aptm_odno (str): 운용사지정주문번호
ord_svr_dvsn_cd (str): 주문서버구분코드
ctac_tlno (str): 연락전화번호
Returns:
- DataFrame: 장내채권 매도주문 결과
Example:
>>> df = main()
>>> print(df)
"""
try:
# pandas 출력 옵션 설정
pd.set_option('display.max_columns', None) # 모든 컬럼 표시
pd.set_option('display.width', None) # 출력 너비 제한 해제
pd.set_option('display.max_rows', None) # 모든 행 표시
# 토큰 발급
logger.info("토큰 발급 중...")
ka.auth()
logger.info("토큰 발급 완료")
# kis_auth 모듈에서 계좌 정보 가져오기
trenv = ka.getTREnv()
# API 호출
logger.info("API 호출 시작: 장내채권 매도주문")
result = sell(
cano=trenv.my_acct, # 종합계좌번호
acnt_prdt_cd=trenv.my_prod, # 계좌상품코드
ord_dvsn="01", # 주문구분
pdno="KR6095572D81", # 상품번호
ord_qty2="1", # 주문수량
bond_ord_unpr="10000.0", # 채권주문단가
sprx_yn="N", # 분리과세여부
buy_dt="", # 매수일자
buy_seq="", # 매수순번
samt_mket_ptci_yn="N", # 소액시장참여여부
sll_agco_opps_sll_yn="N", # 매도대행사반대매도여부
bond_rtl_mket_yn="N", # 채권소매시장여부
mgco_aptm_odno="", # 운용사지정주문번호
ord_svr_dvsn_cd="0", # 주문서버구분코드
ctac_tlno="", # 연락전화번호
)
if result is None or result.empty:
logger.warning("조회된 데이터가 없습니다.")
return
# 컬럼명 출력
logger.info("사용 가능한 컬럼 목록:")
logger.info(result.columns.tolist())
# 한글 컬럼명으로 변환
result = result.rename(columns=COLUMN_MAPPING)
# 숫자형 컬럼 변환
for col in NUMERIC_COLUMNS:
if col in result.columns:
result[col] = pd.to_numeric(result[col], errors='coerce')
# 결과 출력
logger.info("=== 장내채권 매도주문 결과 ===")
logger.info("조회된 데이터 건수: %d", len(result))
print(result)
except Exception as e:
logger.error("에러 발생: %s", str(e))
raise
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,127 @@
# [장내채권] 주문/계좌 - 장내채권 매도주문
# Generated by KIS API Generator (Single API Mode)
# -*- coding: utf-8 -*-
"""
Created on 2025-06-20
"""
import logging
from typing import Optional
import sys
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__)
##############################################################################################
# [장내채권] 주문/계좌 > 장내채권 매도주문 [국내주식-123]
##############################################################################################
# 상수 정의
API_URL = "/uapi/domestic-bond/v1/trading/sell"
def sell(
cano: str,
acnt_prdt_cd: str,
ord_dvsn: str,
pdno: str,
ord_qty2: str,
bond_ord_unpr: str,
sprx_yn: str,
samt_mket_ptci_yn: str,
sll_agco_opps_sll_yn: str,
bond_rtl_mket_yn: str,
buy_dt: str = "",
buy_seq: str = "",
mgco_aptm_odno: str = "",
ord_svr_dvsn_cd: str = "0",
ctac_tlno: str = ""
) -> Optional[pd.DataFrame]:
"""
[장내채권] 주문/계좌
장내채권 매도주문[국내주식-123]
장내채권 매도주문 API를 호출하여 DataFrame으로 반환합니다.
Args:
cano (str): 종합계좌번호
acnt_prdt_cd (str): 계좌상품코드
ord_dvsn (str): 주문구분
pdno (str): 상품번호
ord_qty2 (str): 주문수량2
bond_ord_unpr (str): 채권주문단가
sprx_yn (str): 분리과세여부
samt_mket_ptci_yn (str): 소액시장참여여부
sll_agco_opps_sll_yn (str): 매도대행사반대매도여부
bond_rtl_mket_yn (str): 채권소매시장여부
buy_dt (str, optional): 매수일자. Defaults to "".
buy_seq (str, optional): 매수순번. Defaults to "".
mgco_aptm_odno (str, optional): 운용사지정주문번호. Defaults to "".
ord_svr_dvsn_cd (str, optional): 주문서버구분코드. Defaults to "0".
ctac_tlno (str, optional): 연락전화번호. Defaults to "".
Returns:
Optional[pd.DataFrame]: 장내채권 매도주문 데이터
Example:
>>> df = sell(
... cano=trenv.my_acct,
... acnt_prdt_cd=trenv.my_prod,
... ord_dvsn="01",
... pdno="KR6095572D81",
... ord_qty2="1",
... bond_ord_unpr="10000.0",
... sprx_yn="N",
... samt_mket_ptci_yn="N",
... sll_agco_opps_sll_yn="N",
... bond_rtl_mket_yn="N"
... )
>>> print(df)
"""
tr_id = "TTTC0958U"
params = {
"CANO": cano,
"ACNT_PRDT_CD": acnt_prdt_cd,
"ORD_DVSN": ord_dvsn,
"PDNO": pdno,
"ORD_QTY2": ord_qty2,
"BOND_ORD_UNPR": bond_ord_unpr,
"SPRX_YN": sprx_yn,
"BUY_DT": buy_dt,
"BUY_SEQ": buy_seq,
"SAMT_MKET_PTCI_YN": samt_mket_ptci_yn,
"SLL_AGCO_OPPS_SLL_YN": sll_agco_opps_sll_yn,
"BOND_RTL_MKET_YN": bond_rtl_mket_yn,
"MGCO_APTM_ODNO": mgco_aptm_odno,
"ORD_SVR_DVSN_CD": ord_svr_dvsn_cd,
"CTAC_TLNO": ctac_tlno
}
res = ka._url_fetch(api_url=API_URL,
ptr_id=tr_id,
tr_cont="",
params=params,
postFlag=True
)
if res.isOK():
if hasattr(res.getBody(), 'output'):
output_data = res.getBody().output
if not isinstance(output_data, list):
output_data = [output_data]
dataframe = pd.DataFrame(output_data)
else:
dataframe = pd.DataFrame()
logger.info("Data fetch complete.")
return dataframe
else:
logger.error("API call failed: %s - %s", res.getErrorCode(), res.getErrorMessage())
res.printError(API_URL)
return pd.DataFrame()