initial commit

This commit is contained in:
2026-02-04 00:16:34 +09:00
commit ae11528dd9
867 changed files with 209640 additions and 0 deletions

View File

@@ -0,0 +1,116 @@
"""
Created on 20250601
"""
import logging
import sys
import pandas as pd
sys.path.extend(['../..', '.'])
import kis_auth as ka
from commodity_futures_realtime_conclusion import commodity_futures_realtime_conclusion
# 로깅 설정
logging.basicConfig(level=logging.INFO)
##############################################################################################
# [국내선물옵션] 실시간시세 > 상품선물 실시간체결가[실시간-022]
##############################################################################################
COLUMN_MAPPING = {
"futs_shrn_iscd": "선물 단축 종목코드",
"bsop_hour": "영업 시간",
"futs_prdy_vrss": "선물 전일 대비",
"prdy_vrss_sign": "전일 대비 부호",
"futs_prdy_ctrt": "선물 전일 대비율",
"futs_prpr": "선물 현재가",
"futs_oprc": "선물 시가2",
"futs_hgpr": "선물 최고가",
"futs_lwpr": "선물 최저가",
"last_cnqn": "최종 거래량",
"acml_vol": "누적 거래량",
"acml_tr_pbmn": "누적 거래 대금",
"hts_thpr": "HTS 이론가",
"mrkt_basis": "시장 베이시스",
"dprt": "괴리율",
"nmsc_fctn_stpl_prc": "근월물 약정가",
"fmsc_fctn_stpl_prc": "원월물 약정가",
"spead_prc": "스프레드1",
"hts_otst_stpl_qty": "HTS 미결제 약정 수량",
"otst_stpl_qty_icdc": "미결제 약정 수량 증감",
"oprc_hour": "시가 시간",
"oprc_vrss_prpr_sign": "시가2 대비 현재가 부호",
"oprc_vrss_nmix_prpr": "시가 대비 지수 현재가",
"hgpr_hour": "최고가 시간",
"hgpr_vrss_prpr_sign": "최고가 대비 현재가 부호",
"hgpr_vrss_nmix_prpr": "최고가 대비 지수 현재가",
"lwpr_hour": "최저가 시간",
"lwpr_vrss_prpr_sign": "최저가 대비 현재가 부호",
"lwpr_vrss_nmix_prpr": "최저가 대비 지수 현재가",
"shnu_rate": "매수2 비율",
"cttr": "체결강도",
"esdg": "괴리도",
"otst_stpl_rgbf_qty_icdc": "미결제 약정 직전 수량 증감",
"thpr_basis": "이론 베이시스",
"futs_askp1": "선물 매도호가1",
"futs_bidp1": "선물 매수호가1",
"askp_rsqn1": "매도호가 잔량1",
"bidp_rsqn1": "매수호가 잔량1",
"seln_cntg_csnu": "매도 체결 건수",
"shnu_cntg_csnu": "매수 체결 건수",
"ntby_cntg_csnu": "순매수 체결 건수",
"seln_cntg_smtn": "총 매도 수량",
"shnu_cntg_smtn": "총 매수 수량",
"total_askp_rsqn": "총 매도호가 잔량",
"total_bidp_rsqn": "총 매수호가 잔량",
"prdy_vol_vrss_acml_vol_rate": "전일 거래량 대비 등락율",
"dscs_bltr_acml_qty": "협의 대량 거래량",
"dynm_mxpr": "실시간상한가",
"dynm_llam": "실시간하한가",
"dynm_prc_limt_yn": "실시간가격제한구분"
}
NUMERIC_COLUMNS = []
def main():
"""
상품선물 실시간체결가
Returns:
None
"""
# 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=commodity_futures_realtime_conclusion, data=["165W09"])
# 결과 표시
def on_result(ws, tr_id: str, result: pd.DataFrame, data_map: dict):
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').round(2)
logging.info("결과:")
print(result)
kws.start(on_result=on_result)
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,108 @@
"""
Created on 20250601
"""
import logging
import sys
sys.path.extend(['../..', '.'])
import kis_auth as ka
# 로깅 설정
logging.basicConfig(level=logging.INFO)
##############################################################################################
# [국내선물옵션] 실시간시세 > 상품선물 실시간체결가[실시간-022]
##############################################################################################
def commodity_futures_realtime_conclusion(
tr_type: str,
tr_key: str,
) -> (dict, list[str]):
"""
상품선물 실시간체결가 API입니다.
실시간 웹소켓 연결을 통해 상품선물의 실시간 체결가 정보를 수신할 수 있습니다.
현재가, 시고저가, 체결량, 누적거래량, 이론가, 베이시스, 괴리율 등의 상세 정보를 제공합니다.
매도/매수 호가, 체결 건수, 미결제 약정 수량 등의 선물거래 필수 정보를 포함합니다.
Args:
tr_type (str): [필수] 구독 등록/해제 여부 (ex. "1": 구독, "2": 해제)
tr_key (str): [필수] 종목코드 (ex. 101S12)
Returns:
message (str): 메시지 데이터
Example:
>>> msg, columns = commodity_futures_realtime_conclusion("1", "101S12")
>>> print(msg, columns)
"""
# 필수 파라미터 검증
if tr_type == "":
raise ValueError("tr_type is empty")
if tr_key == "":
raise ValueError("tr_key is required")
tr_id = "H0CFCNT0"
params = {
"tr_key": tr_key,
}
msg = ka.data_fetch(tr_id, tr_type, params)
columns = [
"futs_shrn_iscd",
"bsop_hour",
"futs_prdy_vrss",
"prdy_vrss_sign",
"futs_prdy_ctrt",
"futs_prpr",
"futs_oprc",
"futs_hgpr",
"futs_lwpr",
"last_cnqn",
"acml_vol",
"acml_tr_pbmn",
"hts_thpr",
"mrkt_basis",
"dprt",
"nmsc_fctn_stpl_prc",
"fmsc_fctn_stpl_prc",
"spead_prc",
"hts_otst_stpl_qty",
"otst_stpl_qty_icdc",
"oprc_hour",
"oprc_vrss_prpr_sign",
"oprc_vrss_nmix_prpr",
"hgpr_hour",
"hgpr_vrss_prpr_sign",
"hgpr_vrss_nmix_prpr",
"lwpr_hour",
"lwpr_vrss_prpr_sign",
"lwpr_vrss_nmix_prpr",
"shnu_rate",
"cttr",
"esdg",
"otst_stpl_rgbf_qty_icdc",
"thpr_basis",
"futs_askp1",
"futs_bidp1",
"askp_rsqn1",
"bidp_rsqn1",
"seln_cntg_csnu",
"shnu_cntg_csnu",
"ntby_cntg_csnu",
"seln_cntg_smtn",
"shnu_cntg_smtn",
"total_askp_rsqn",
"total_bidp_rsqn",
"prdy_vol_vrss_acml_vol_rate",
"dscs_bltr_acml_qty",
"dynm_mxpr",
"dynm_llam",
"dynm_prc_limt_yn"
]
return msg, columns

View File

@@ -0,0 +1,104 @@
"""
Created on 20250601
"""
import logging
import sys
import pandas as pd
sys.path.extend(['../..', '.'])
import kis_auth as ka
from commodity_futures_realtime_quote import commodity_futures_realtime_quote
# 로깅 설정
logging.basicConfig(level=logging.INFO)
##############################################################################################
# [국내선물옵션] 실시간시세 > 상품선물 실시간호가[실시간-023]
##############################################################################################
COLUMN_MAPPING = {
"futs_shrn_iscd": "선물 단축 종목코드",
"bsop_hour": "영업 시간",
"futs_askp1": "선물 매도호가1",
"futs_askp2": "선물 매도호가2",
"futs_askp3": "선물 매도호가3",
"futs_askp4": "선물 매도호가4",
"futs_askp5": "선물 매도호가5",
"futs_bidp1": "선물 매수호가1",
"futs_bidp2": "선물 매수호가2",
"futs_bidp3": "선물 매수호가3",
"futs_bidp4": "선물 매수호가4",
"futs_bidp5": "선물 매수호가5",
"askp_csnu1": "매도호가 건수1",
"askp_csnu2": "매도호가 건수2",
"askp_csnu3": "매도호가 건수3",
"askp_csnu4": "매도호가 건수4",
"askp_csnu5": "매도호가 건수5",
"bidp_csnu1": "매수호가 건수1",
"bidp_csnu2": "매수호가 건수2",
"bidp_csnu3": "매수호가 건수3",
"bidp_csnu4": "매수호가 건수4",
"bidp_csnu5": "매수호가 건수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_csnu": "총 매도호가 건수",
"total_bidp_csnu": "총 매수호가 건수",
"total_askp_rsqn": "총 매도호가 잔량",
"total_bidp_rsqn": "총 매수호가 잔량",
"total_askp_rsqn_icdc": "총 매도호가 잔량 증감",
"total_bidp_rsqn_icdc": "총 매수호가 잔량 증감"
}
NUMERIC_COLUMNS = []
def main():
"""
상품선물 실시간호가
Returns:
None
"""
# 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=commodity_futures_realtime_quote, data=["165W09"])
# 결과 표시
def on_result(ws, tr_id: str, result: pd.DataFrame, data_map: dict):
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').round(2)
logging.info("결과:")
print(result)
kws.start(on_result=on_result)
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,96 @@
"""
Created on 20250601
"""
import logging
import sys
sys.path.extend(['../..', '.'])
import kis_auth as ka
# 로깅 설정
logging.basicConfig(level=logging.INFO)
##############################################################################################
# [국내선물옵션] 실시간시세 > 상품선물 실시간호가[실시간-023]
##############################################################################################
def commodity_futures_realtime_quote(
tr_type: str,
tr_key: str,
) -> (dict, list[str]):
"""
상품선물 실시간호가 API입니다.
실시간 웹소켓 연결을 통해 상품선물 매도/매수 호가 정보를 실시간으로 수신할 수 있습니다.
실전계좌만 지원되며, 모의투자는 지원하지 않습니다.
선물옵션 호가 데이터는 0.2초 필터링 옵션이 적용됩니다.
Args:
tr_type (str): [필수] 구독 등록/해제 여부 (ex. "1": 구독, "2": 해제)
tr_key (str): [필수] 종목코드 (ex. 101S12)
Returns:
message (str): 메시지 데이터
Example:
>>> msg, columns = commodity_futures_realtime_quote("1", "101S12")
>>> print(msg, columns)
"""
# 필수 파라미터 검증
if tr_type == "":
raise ValueError("tr_type is required")
if tr_key == "":
raise ValueError("tr_key is required")
tr_id = "H0CFASP0"
params = {
"tr_key": tr_key,
}
msg = ka.data_fetch(tr_id, tr_type, params)
columns = [
"futs_shrn_iscd",
"bsop_hour",
"futs_askp1",
"futs_askp2",
"futs_askp3",
"futs_askp4",
"futs_askp5",
"futs_bidp1",
"futs_bidp2",
"futs_bidp3",
"futs_bidp4",
"futs_bidp5",
"askp_csnu1",
"askp_csnu2",
"askp_csnu3",
"askp_csnu4",
"askp_csnu5",
"bidp_csnu1",
"bidp_csnu2",
"bidp_csnu3",
"bidp_csnu4",
"bidp_csnu5",
"askp_rsqn1",
"askp_rsqn2",
"askp_rsqn3",
"askp_rsqn4",
"askp_rsqn5",
"bidp_rsqn1",
"bidp_rsqn2",
"bidp_rsqn3",
"bidp_rsqn4",
"bidp_rsqn5",
"total_askp_csnu",
"total_bidp_csnu",
"total_askp_rsqn",
"total_bidp_rsqn",
"total_askp_rsqn_icdc",
"total_bidp_rsqn_icdc"
]
return msg, columns

View File

@@ -0,0 +1,130 @@
"""
Created on 20250601
"""
import sys
import logging
import pandas as pd
sys.path.extend(['../..', '.'])
import kis_auth as ka
from display_board_callput import display_board_callput
# 로깅 설정
logging.basicConfig(level=logging.INFO)
##############################################################################################
# [국내선물옵션] 기본시세 > 국내옵션전광판_콜풋[국내선물-022]
##############################################################################################
# 컬럼명 한글 변환 및 데이터 출력
COLUMN_MAPPING = {
'acpr': '행사가',
'unch_prpr': '환산 현재가',
'optn_shrn_iscd': '옵션 단축 종목코드',
'optn_prpr': '옵션 현재가',
'optn_prdy_vrss': '옵션 전일 대비',
'prdy_vrss_sign': '전일 대비 부호',
'optn_prdy_ctrt': '옵션 전일 대비율',
'optn_bidp': '옵션 매수호가',
'optn_askp': '옵션 매도호가',
'tmvl_val': '시간가치 값',
'nmix_sdpr': '지수 기준가',
'acml_vol': '누적 거래량',
'seln_rsqn': '매도 잔량',
'shnu_rsqn': '매수2 잔량',
'acml_tr_pbmn': '누적 거래 대금',
'hts_otst_stpl_qty': 'HTS 미결제 약정 수량',
'otst_stpl_qty_icdc': '미결제 약정 수량 증감',
'delta_val': '델타 값',
'gama': '감마',
'vega': '베가',
'theta': '세타',
'rho': '로우',
'hts_ints_vltl': 'HTS 내재 변동성',
'invl_val': '내재가치 값',
'esdg': '괴리도',
'dprt': '괴리율',
'hist_vltl': '역사적 변동성',
'hts_thpr': 'HTS 이론가',
'optn_oprc': '옵션 시가2',
'optn_hgpr': '옵션 최고가',
'optn_lwpr': '옵션 최저가',
'optn_mxpr': '옵션 상한가',
'optn_llam': '옵션 하한가',
'atm_cls_name': 'ATM 구분 명',
'rgbf_vrss_icdc': '직전 대비 증감',
'total_askp_rsqn': '총 매도호가 잔량',
'total_bidp_rsqn': '총 매수호가 잔량',
'futs_antc_cnpr': '선물예상체결가',
'futs_antc_cntg_vrss': '선물예상체결대비',
'antc_cntg_vrss_sign': '예상 체결 대비 부호',
'antc_cntg_prdy_ctrt': '예상 체결 전일 대비율',
}
NUMERIC_COLUMNS = []
def main():
"""
국내옵션전광판_콜풋 조회 테스트 함수
이 함수는 국내옵션전광판_콜풋 API를 호출하여 결과를 출력합니다.
Returns:
None
"""
# pandas 출력 옵션 설정
pd.set_option('display.max_columns', None) # 모든 컬럼 표시
pd.set_option('display.width', None) # 출력 너비 제한 해제
pd.set_option('display.max_rows', None) # 모든 행 표시
# 인증 토큰 발급
ka.auth()
# Case1 테스트
logging.info("=== Case1 테스트 ===")
try:
result1, result2 = display_board_callput(
fid_cond_mrkt_div_code="O",
fid_cond_scr_div_code="20503",
fid_mrkt_cls_code="CO",
fid_mtrt_cnt="202508",
fid_mrkt_cls_code1="PO"
)
except ValueError as e:
logging.error("에러 발생: %s" % str(e))
return
# Output1 처리
logging.info("=== Output1 결과 ===")
logging.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)
logging.info("결과:")
print(result1)
# Output2 처리
logging.info("=== Output2 결과 ===")
logging.info("사용 가능한 컬럼: %s", result2.columns.tolist())
result2 = result2.rename(columns=COLUMN_MAPPING)
# 숫자형 컬럼 소수점 둘째자리까지 표시 (메타데이터에 number 자료형 없음)
for col in NUMERIC_COLUMNS:
if col in result2.columns:
result2[col] = pd.to_numeric(result2[col], errors='coerce').round(2)
logging.info("결과:")
print(result2)
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,91 @@
"""
Created on 20250601
"""
import sys
from typing import Tuple
import logging
import pandas as pd
sys.path.extend(['../..', '.'])
import kis_auth as ka
# 로깅 설정
logging.basicConfig(level=logging.INFO)
##############################################################################################
# [국내선물옵션] 기본시세 > 국내옵션전광판_콜풋[국내선물-022]
##############################################################################################
# 상수 정의
API_URL = "/uapi/domestic-futureoption/v1/quotations/display-board-callput"
def display_board_callput(
fid_cond_mrkt_div_code: str, # [필수] 조건 시장 분류 코드 (ex. O: 옵션)
fid_cond_scr_div_code: str, # [필수] 조건 화면 분류 코드 (ex. 20503)
fid_mrkt_cls_code: str, # [필수] 시장 구분 코드 (ex. CO: 콜옵션)
fid_mtrt_cnt: str, # [필수] 만기 수 (ex. 202508)
fid_mrkt_cls_code1: str, # [필수] 시장 구분 코드 (ex. PO: 풋옵션)
fid_cond_mrkt_cls_code: str = "" # 조건 시장 구분 코드
) -> Tuple[pd.DataFrame, pd.DataFrame]:
"""
국내옵션전광판_콜풋 API입니다.
한국투자 HTS(eFriend Plus) > [0503] 선물옵션 종합시세() 화면의 "중앙" 기능을 API로 개발한 사항으로, 해당 화면을 참고하시면 기능을 이해하기 쉽습니다.
※ output1, output2 각각 100건까지만 확인이 가능합니다. (FY25년도 서비스 개선 예정)
※ 조회시간이 긴 API인 점 참고 부탁드리며, 잦은 호출을 삼가해주시기 바랍니다. (1초당 최대 1건 권장)
Args:
fid_cond_mrkt_div_code (str): [필수] 조건 시장 분류 코드 (ex. O: 옵션)
fid_cond_scr_div_code (str): [필수] 조건 화면 분류 코드 (ex. 20503)
fid_mrkt_cls_code (str): [필수] 시장 구분 코드 (ex. CO: 콜옵션)
fid_mtrt_cnt (str): [필수] 만기 수 (ex. 202508)
fid_mrkt_cls_code1 (str): [필수] 시장 구분 코드 (ex. PO: 풋옵션)
fid_cond_mrkt_cls_code (str): 조건 시장 구분 코드
Returns:
Tuple[pd.DataFrame, pd.DataFrame]: (output1 DataFrame, output2 DataFrame)
Example:
>>> df1, df2 = display_board_callput("O", "20503", "CO", "202508", "PO")
>>> print(df1)
>>> print(df2)
"""
# 필수 파라미터 검증
if fid_cond_mrkt_div_code == "":
raise ValueError("fid_cond_mrkt_div_code is required (e.g. 'O')")
if fid_cond_scr_div_code == "":
raise ValueError("fid_cond_scr_div_code is required (e.g. '20503')")
if fid_mrkt_cls_code == "":
raise ValueError("fid_mrkt_cls_code is required (e.g. 'CO')")
if fid_mtrt_cnt == "":
raise ValueError("fid_mtrt_cnt is required (e.g. '202508')")
if fid_mrkt_cls_code1 == "":
raise ValueError("fid_mrkt_cls_code1 is required (e.g. 'PO')")
tr_id = "FHPIF05030100"
params = {
"FID_COND_MRKT_DIV_CODE": fid_cond_mrkt_div_code,
"FID_COND_SCR_DIV_CODE": fid_cond_scr_div_code,
"FID_MRKT_CLS_CODE": fid_mrkt_cls_code,
"FID_MTRT_CNT": fid_mtrt_cnt,
"FID_MRKT_CLS_CODE1": fid_mrkt_cls_code1,
"FID_COND_MRKT_CLS_CODE": fid_cond_mrkt_cls_code
}
res = ka._url_fetch(API_URL, tr_id, "", params)
if res.isOK():
output1_df = pd.DataFrame(res.getBody().output1)
output2_df = pd.DataFrame(res.getBody().output2)
return output1_df, output2_df
else:
res.printError(url=API_URL)
return pd.DataFrame(), pd.DataFrame()

View File

@@ -0,0 +1,91 @@
"""
Created on 20250112
"""
import sys
import logging
import pandas as pd
sys.path.extend(['../..', '.'])
import kis_auth as ka
from display_board_futures import display_board_futures
# 로깅 설정
logging.basicConfig(level=logging.INFO)
##############################################################################################
# [국내선물옵션] 기본시세 > 국내옵션전광판_선물[국내선물-023]
##############################################################################################
COLUMN_MAPPING = {
'futs_shrn_iscd': '선물 단축 종목코드',
'hts_kor_isnm': 'HTS 한글 종목명',
'futs_prpr': '선물 현재가',
'futs_prdy_vrss': '선물 전일 대비',
'prdy_vrss_sign': '전일 대비 부호',
'futs_prdy_ctrt': '선물 전일 대비율',
'hts_thpr': 'HTS 이론가',
'acml_vol': '누적 거래량',
'futs_askp': '선물 매도호가',
'futs_bidp': '선물 매수호가',
'hts_otst_stpl_qty': 'HTS 미결제 약정 수량',
'futs_hgpr': '선물 최고가',
'futs_lwpr': '선물 최저가',
'hts_rmnn_dynu': 'HTS 잔존 일수',
'total_askp_rsqn': '총 매도호가 잔량',
'total_bidp_rsqn': '총 매수호가 잔량',
'futs_antc_cnpr': '선물예상체결가',
'futs_antc_cntg_vrss': '선물예상체결대비',
'antc_cntg_vrss_sign': '예상 체결 대비 부호',
'antc_cntg_prdy_ctrt': '예상 체결 전일 대비율'
}
NUMERIC_COLUMNS = []
def main():
"""
국내선물옵션 선물전광판 조회 테스트 함수
이 함수는 국내선물옵션 선물전광판 API를 호출하여 결과를 출력합니다.
Returns:
None
"""
# pandas 출력 옵션 설정
pd.set_option('display.max_columns', None) # 모든 컬럼 표시
pd.set_option('display.width', None) # 출력 너비 제한 해제
pd.set_option('display.max_rows', None) # 모든 행 표시
# 인증 토큰 발급
ka.auth()
# case1 테스트
logging.info("=== case1 테스트 ===")
try:
result = display_board_futures(
fid_cond_mrkt_div_code="F",
fid_cond_scr_div_code="20503",
fid_cond_mrkt_cls_code="MKI"
)
except ValueError as e:
logging.error("에러 발생: %s", str(e))
return
logging.info("사용 가능한 컬럼: %s", result.columns.tolist())
# 컬럼명 한글 변환
result = result.rename(columns=COLUMN_MAPPING)
# 숫자형 컬럼 소수점 표시 (메타데이터에 number 자료형이 명시된 컬럼 없음)
for col in NUMERIC_COLUMNS:
if col in result.columns:
result[col] = pd.to_numeric(result[col], errors='coerce').round(2)
logging.info("결과:")
print(result)
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,69 @@
"""
Created on 20250112
"""
import sys
import logging
import pandas as pd
sys.path.extend(['../..', '.'])
import kis_auth as ka
# 로깅 설정
logging.basicConfig(level=logging.INFO)
##############################################################################################
# [국내선물옵션] 기본시세 > 국내옵션전광판_선물[국내선물-023]
##############################################################################################
# 상수 정의
API_URL = "/uapi/domestic-futureoption/v1/quotations/display-board-futures"
def display_board_futures(
fid_cond_mrkt_div_code: str, # 조건 시장 분류 코드
fid_cond_scr_div_code: str, # 조건 화면 분류 코드
fid_cond_mrkt_cls_code: str # 조건 시장 구분 코드
) -> pd.DataFrame:
"""
국내옵션전광판_선물 API입니다.
한국투자 HTS(eFriend Plus) > [0503] 선물옵션 종합시세() 화면의 "하단" 기능을 API로 개발한 사항입니다.
Args:
fid_cond_mrkt_div_code (str): [필수] 조건 시장 분류 코드 (ex. F)
fid_cond_scr_div_code (str): [필수] 조건 화면 분류 코드 (ex. 20503)
fid_cond_mrkt_cls_code (str): [필수] 조건 시장 구분 코드 (ex. MKI)
Returns:
pd.DataFrame: 국내선물옵션 선물전광판 데이터
Example:
>>> df = display_board_futures("F", "20503", "MKI")
>>> print(df)
"""
# 필수 파라미터 검증
if fid_cond_mrkt_div_code == "":
raise ValueError("fid_cond_mrkt_div_code is required (e.g. 'F')")
if fid_cond_scr_div_code == "":
raise ValueError("fid_cond_scr_div_code is required (e.g. '20503')")
if fid_cond_mrkt_cls_code == "":
raise ValueError("fid_cond_mrkt_cls_code is required (e.g. 'MKI')")
tr_id = "FHPIF05030200"
params = {
"FID_COND_MRKT_DIV_CODE": fid_cond_mrkt_div_code,
"FID_COND_SCR_DIV_CODE": fid_cond_scr_div_code,
"FID_COND_MRKT_CLS_CODE": fid_cond_mrkt_cls_code
}
res = ka._url_fetch(API_URL, tr_id, "", params)
if res.isOK():
return pd.DataFrame(res.getBody().output)
else:
res.printError(url=API_URL)
return pd.DataFrame()

View File

@@ -0,0 +1,71 @@
"""
Created on 20250601
"""
import sys
import logging
import pandas as pd
sys.path.extend(['../..', '.'])
import kis_auth as ka
from display_board_option_list import display_board_option_list
# 로깅 설정
logging.basicConfig(level=logging.INFO)
##############################################################################################
# [국내선물옵션] 기본시세 > 국내옵션전광판_옵션월물리스트[국내선물-020]
##############################################################################################
COLUMN_MAPPING = {
'mtrt_yymm_code': '만기 년월 코드',
'mtrt_yymm': '만기 년월'
}
NUMERIC_COLUMNS = []
def main():
"""
국내옵션전광판_옵션월물리스트 조회 테스트 함수
이 함수는 국내옵션전광판_옵션월물리스트 API를 호출하여 결과를 출력합니다.
Returns:
None
"""
# pandas 출력 옵션 설정
pd.set_option('display.max_columns', None) # 모든 컬럼 표시
pd.set_option('display.width', None) # 출력 너비 제한 해제
pd.set_option('display.max_rows', None) # 모든 행 표시
# 인증 토큰 발급
ka.auth()
# case1 조회
logging.info("=== case1 조회 ===")
try:
result = display_board_option_list(fid_cond_scr_div_code="509")
except ValueError as e:
logging.error("에러 발생: %s" % str(e))
return
logging.info("사용 가능한 컬럼: %s", result.columns.tolist())
# 컬럼명 한글 변환 및 데이터 출력
result = result.rename(columns=COLUMN_MAPPING)
# 숫자형 컬럼 소수점 둘째자리까지 표시 (메타데이터에 number 자료형이 명시된 필드가 없음)
for col in NUMERIC_COLUMNS:
if col in result.columns:
result[col] = pd.to_numeric(result[col], errors='coerce').round(2)
logging.info("결과:")
print(result)
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,63 @@
"""
Created on 20250601
"""
import sys
import logging
import pandas as pd
sys.path.extend(['../..', '.'])
import kis_auth as ka
# 로깅 설정
logging.basicConfig(level=logging.INFO)
##############################################################################################
# [국내선물옵션] 기본시세 > 국내옵션전광판_옵션월물리스트[국내선물-020]
##############################################################################################
# 상수 정의
API_URL = "/uapi/domestic-futureoption/v1/quotations/display-board-option-list"
def display_board_option_list(
fid_cond_scr_div_code: str,
fid_cond_mrkt_div_code: str = "",
fid_cond_mrkt_cls_code: str = ""
) -> pd.DataFrame:
"""
국내옵션전광판_옵션월물리스트 API입니다.
한국투자 HTS(eFriend Plus) > [0503] 선물옵션 종합시세() 화면의 "월물리스트 목록 확인" 기능을 API로 개발한 사항입니다.
Args:
fid_cond_scr_div_code (str): [필수] 조건 화면 분류 코드 (ex. 509)
fid_cond_mrkt_div_code (str): 조건 시장 분류 코드
fid_cond_mrkt_cls_code (str): 조건 시장 구분 코드
Returns:
pd.DataFrame: 국내옵션전광판_옵션월물리스트 데이터
Example:
>>> df = display_board_option_list(fid_cond_scr_div_code="509")
>>> print(df)
"""
if fid_cond_scr_div_code == "":
raise ValueError("fid_cond_scr_div_code is required (e.g. '509')")
tr_id = "FHPIO056104C0"
params = {
"FID_COND_SCR_DIV_CODE": fid_cond_scr_div_code,
"FID_COND_MRKT_DIV_CODE": fid_cond_mrkt_div_code,
"FID_COND_MRKT_CLS_CODE": fid_cond_mrkt_cls_code
}
res = ka._url_fetch(API_URL, tr_id, "", params)
if res.isOK():
current_data = pd.DataFrame(res.getBody().output)
return current_data
else:
res.printError(url=API_URL)
return pd.DataFrame()

View File

@@ -0,0 +1,96 @@
"""
Created on 20250601
"""
import sys
import logging
import pandas as pd
sys.path.extend(['../..', '.'])
import kis_auth as ka
from display_board_top import display_board_top
# 로깅 설정
logging.basicConfig(level=logging.INFO)
##############################################################################################
# [국내선물옵션] 기본시세 > 국내선물 기초자산 시세[국내선물-021]
##############################################################################################
COLUMN_MAPPING = {
'unas_prpr': '기초자산 현재가',
'unas_prdy_vrss': '기초자산 전일 대비',
'unas_prdy_vrss_sign': '기초자산 전일 대비 부호',
'unas_prdy_ctrt': '기초자산 전일 대비율',
'unas_acml_vol': '기초자산 누적 거래량',
'hts_kor_isnm': 'HTS 한글 종목명',
'futs_prpr': '선물 현재가',
'futs_prdy_vrss': '선물 전일 대비',
'prdy_vrss_sign': '전일 대비 부호',
'futs_prdy_ctrt': '선물 전일 대비율',
'hts_rmnn_dynu': 'HTS 잔존 일수'
}
NUMERIC_COLUMNS = []
def main():
"""
국내선물 기초자산 시세 조회 테스트 함수
이 함수는 국내선물 기초자산 시세 API를 호출하여 결과를 출력합니다.
Returns:
None
"""
# pandas 출력 옵션 설정
pd.set_option('display.max_columns', None) # 모든 컬럼 표시
pd.set_option('display.width', None) # 출력 너비 제한 해제
pd.set_option('display.max_rows', None) # 모든 행 표시
# 인증 토큰 발급
ka.auth()
logging.info("=== 국내선물 기초자산 시세 조회 ===")
try:
output1, output2 = display_board_top(fid_cond_mrkt_div_code="F", fid_input_iscd="101W09")
except ValueError as e:
logging.error("에러 발생: %s" % str(e))
return
# output1 처리
logging.info("=== output1 결과 ===")
logging.info("사용 가능한 컬럼: %s", output1.columns.tolist())
# 컬럼명 한글 변환
output1 = output1.rename(columns=COLUMN_MAPPING)
# 숫자형 컬럼 소수점 둘째자리까지 표시
for col in NUMERIC_COLUMNS:
if col in output1.columns:
output1[col] = pd.to_numeric(output1[col], errors='coerce').round(2)
logging.info("결과:")
print(output1)
# output2 처리
logging.info("=== output2 결과 ===")
logging.info("사용 가능한 컬럼: %s", output2.columns.tolist())
# 컬럼명 한글 변환
output2 = output2.rename(columns=COLUMN_MAPPING)
# 숫자형 컬럼 소수점 둘째자리까지 표시
for col in NUMERIC_COLUMNS:
if col in output2.columns:
output2[col] = pd.to_numeric(output2[col], errors='coerce').round(2)
logging.info("결과:")
print(output2)
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,79 @@
"""
Created on 20250601
"""
import sys
import logging
from typing import Tuple
import pandas as pd
sys.path.extend(['../..', '.'])
import kis_auth as ka
# 로깅 설정
logging.basicConfig(level=logging.INFO)
##############################################################################################
# [국내선물옵션] 기본시세 > 국내선물 기초자산 시세[국내선물-021]
##############################################################################################
# 상수 정의
API_URL = "/uapi/domestic-futureoption/v1/quotations/display-board-top"
def display_board_top(
fid_cond_mrkt_div_code: str, # [필수] 조건 시장 분류 코드 (ex. F)
fid_input_iscd: str, # [필수] 입력 종목코드 (ex. 101V06)
fid_cond_mrkt_div_code1: str = "", # 조건 시장 분류 코드
fid_cond_scr_div_code: str = "", # 조건 화면 분류 코드
fid_mtrt_cnt: str = "", # 만기 수
fid_cond_mrkt_cls_code: str = "" # 조건 시장 구분 코드
) -> Tuple[pd.DataFrame, pd.DataFrame]:
"""
국내선물 기초자산 시세 API입니다.
한국투자 HTS(eFriend Plus) > [0503] 선물옵션 종합시세() 화면의 "상단 바" 기능을 API로 개발한 사항입니다.
Args:
fid_cond_mrkt_div_code (str): [필수] 조건 시장 분류 코드 (ex. F)
fid_input_iscd (str): [필수] 입력 종목코드 (ex. 101V06)
fid_cond_mrkt_div_code1 (str): 조건 시장 분류 코드
fid_cond_scr_div_code (str): 조건 화면 분류 코드
fid_mtrt_cnt (str): 만기 수
fid_cond_mrkt_cls_code (str): 조건 시장 구분 코드
Returns:
Tuple[pd.DataFrame, pd.DataFrame]: (output1, output2) 데이터프레임 튜플
Example:
>>> output1, output2 = display_board_top(fid_cond_mrkt_div_code="F", fid_input_iscd="101W09")
>>> print(output1)
>>> print(output2)
"""
if fid_cond_mrkt_div_code == "":
raise ValueError("fid_cond_mrkt_div_code is required (e.g. 'F')")
if fid_input_iscd == "":
raise ValueError("fid_input_iscd is required (e.g. '101W09')")
tr_id = "FHPIF05030000"
params = {
"FID_COND_MRKT_DIV_CODE": fid_cond_mrkt_div_code,
"FID_INPUT_ISCD": fid_input_iscd,
"FID_COND_MRKT_DIV_CODE1": fid_cond_mrkt_div_code1,
"FID_COND_SCR_DIV_CODE": fid_cond_scr_div_code,
"FID_MTRT_CNT": fid_mtrt_cnt,
"FID_COND_MRKT_CLS_CODE": fid_cond_mrkt_cls_code
}
res = ka._url_fetch(API_URL, tr_id, "", params)
if res.isOK():
output1 = pd.DataFrame(res.getBody().output1, index=[0])
output2 = pd.DataFrame(res.getBody().output2)
return output1, output2
else:
res.printError(url=API_URL)
return pd.DataFrame(), pd.DataFrame()

View File

@@ -0,0 +1,92 @@
"""
Created on 20250601
"""
import sys
import logging
import pandas as pd
sys.path.extend(['../..', '.'])
import kis_auth as ka
from exp_price_trend import exp_price_trend
# 로깅 설정
logging.basicConfig(level=logging.INFO)
##############################################################################################
# [국내선물옵션] 기본시세 > 선물옵션 일중예상체결추이[국내선물-018]
##############################################################################################
COLUMN_MAPPING = {
'hts_kor_isnm': '영업 시간',
'futs_antc_cnpr': '업종 지수 현재가',
'antc_cntg_vrss_sign': '업종 지수 전일 대비',
'futs_antc_cntg_vrss': '전일 대비 부호',
'antc_cntg_prdy_ctrt': '업종 지수 전일 대비율',
'futs_sdpr': '누적 거래 대금',
'stck_cntg_hour': '주식체결시간',
'futs_antc_cnpr': '선물예상체결가',
'antc_cntg_vrss_sign': '예상체결대비부호',
'futs_antc_cntg_vrss': '선물예상체결대비',
'antc_cntg_prdy_ctrt': '예상체결전일대비율'
}
NUMERIC_COLUMNS = []
def main():
"""
선물옵션 일중예상체결추이 조회 테스트 함수
이 함수는 선물옵션 일중예상체결추이 API를 호출하여 결과를 출력합니다.
Returns:
None
"""
# pandas 출력 옵션 설정
pd.set_option('display.max_columns', None) # 모든 컬럼 표시
pd.set_option('display.width', None) # 출력 너비 제한 해제
pd.set_option('display.max_rows', None) # 모든 행 표시
# 인증 토큰 발급
ka.auth()
# case1 조회
logging.info("=== case1 조회 ===")
try:
result1, result2 = exp_price_trend(fid_input_iscd="101W09", fid_cond_mrkt_div_code="F")
except ValueError as e:
logging.error("에러 발생: %s" % str(e))
return
# output1 결과 처리
logging.info("사용 가능한 컬럼 (output1): %s", result1.columns.tolist())
# 컬럼명 한글 변환 및 데이터 출력 (output1)
result1 = result1.rename(columns=COLUMN_MAPPING)
# 숫자형 컬럼 소수점 둘째자리까지 표시 (output1)
for col in NUMERIC_COLUMNS:
if col in result1.columns:
result1[col] = pd.to_numeric(result1[col], errors='coerce').round(2)
logging.info("결과 (output1):")
print(result1)
# output2 결과 처리
logging.info("사용 가능한 컬럼 (output2): %s", result2.columns.tolist())
# 컬럼명 한글 변환 및 데이터 출력 (output2)
result2 = result2.rename(columns=COLUMN_MAPPING)
# 숫자형 컬럼 소수점 둘째자리까지 표시 (output2)
for col in NUMERIC_COLUMNS:
if col in result2.columns:
result2[col] = pd.to_numeric(result2[col], errors='coerce').round(2)
logging.info("결과 (output2):")
print(result2)
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,70 @@
"""
Created on 20250601
"""
import sys
import logging
from typing import Tuple
import pandas as pd
sys.path.extend(['../..', '.'])
import kis_auth as ka
# 로깅 설정
logging.basicConfig(level=logging.INFO)
##############################################################################################
# [국내선물옵션] 기본시세 > 선물옵션 일중예상체결추이[국내선물-018]
##############################################################################################
# 상수 정의
API_URL = "/uapi/domestic-futureoption/v1/quotations/exp-price-trend"
def exp_price_trend(
fid_input_iscd: str, # [필수] 입력 종목코드 (ex. 101V06)
fid_cond_mrkt_div_code: str # [필수] 조건 시장 분류 코드 (ex. F)
) -> Tuple[pd.DataFrame, pd.DataFrame]:
"""
선물옵션 일중예상체결추이 API입니다.
한국투자 HTS(eFriend Plus) > [0548] 선물옵션 예상체결추이 화면의 기능을 API로 개발한 사항입니다.
Args:
fid_input_iscd (str): [필수] 입력 종목코드 (ex. 101V06)
fid_cond_mrkt_div_code (str): [필수] 조건 시장 분류 코드 (ex. F)
Returns:
Tuple[pd.DataFrame, pd.DataFrame]: (output1, output2) 데이터프레임 튜플
Example:
>>> df1, df2 = exp_price_trend(fid_input_iscd="101W09", fid_cond_mrkt_div_code="F")
>>> print(df1)
>>> print(df2)
"""
if fid_input_iscd == "":
raise ValueError("fid_input_iscd is required (e.g. '101W09')")
if fid_cond_mrkt_div_code == "":
raise ValueError("fid_cond_mrkt_div_code is required (e.g. 'F')")
tr_id = "FHPIF05110100" # 선물옵션 일중예상체결추이
params = {
"FID_INPUT_ISCD": fid_input_iscd, # 입력 종목코드
"FID_COND_MRKT_DIV_CODE": fid_cond_mrkt_div_code # 조건 시장 분류 코드
}
res = ka._url_fetch(API_URL, tr_id, "", params)
if res.isOK():
# output1은 object 타입이므로 단일 행 DataFrame
output1_data = pd.DataFrame([res.getBody().output1])
# output2는 array 타입이므로 여러 행 DataFrame
output2_data = pd.DataFrame(res.getBody().output2)
return output1_data, output2_data
else:
res.printError(url=API_URL)
return pd.DataFrame(), pd.DataFrame()

View File

@@ -0,0 +1,89 @@
"""
Created on 20250601
"""
import logging
import sys
import pandas as pd
sys.path.extend(['../..', '.'])
import kis_auth as ka
from fuopt_ccnl_notice import fuopt_ccnl_notice
# 로깅 설정
logging.basicConfig(level=logging.INFO)
##############################################################################################
# [국내선물옵션] 실시간시세 > 선물옵션 실시간체결통보[실시간-012]
##############################################################################################
COLUMN_MAPPING = {
"cust_id": "고객 ID",
"acnt_no": "계좌번호",
"oder_no": "주문번호",
"ooder_no": "원주문번호",
"seln_byov_cls": "매도매수구분",
"rctf_cls": "정정구분",
"oder_kind2": "주문종류2",
"stck_shrn_iscd": "주식 단축 종목코드",
"cntg_qty": "체결 수량",
"cntg_unpr": "체결단가",
"stck_cntg_hour": "주식 체결 시간",
"rfus_yn": "거부여부",
"cntg_yn": "체결여부",
"acpt_yn": "접수여부",
"brnc_no": "지점번호",
"oder_qty": "주문수량",
"acnt_name": "계좌명",
"cntg_isnm": "체결종목명",
"oder_cond": "주문조건",
"ord_grp": "주문그룹ID",
"ord_grpseq": "주문그룹SEQ",
"order_prc": "주문가격"
}
NUMERIC_COLUMNS = []
def main():
"""
선물옵션 실시간체결통보
Returns:
None
"""
# 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()
trenv = ka.getTREnv()
# 인증(auth_ws()) 이후에 선언
kws = ka.KISWebSocket(api_url="/tryitout")
# 조회
kws.subscribe(request=fuopt_ccnl_notice, data=[trenv.my_htsid])
# 결과 표시
def on_result(ws, tr_id: str, result: pd.DataFrame, data_map: dict):
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').round(2)
logging.info("결과:")
print(result)
kws.start(on_result=on_result)
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,81 @@
"""
Created on 20250601
"""
import logging
import sys
from typing import Optional, Tuple
import pandas as pd
sys.path.extend(['../..', '.'])
import kis_auth as ka
# 로깅 설정
logging.basicConfig(level=logging.INFO)
##############################################################################################
# [국내선물옵션] 실시간시세 > 선물옵션 실시간체결통보[실시간-012]
##############################################################################################
def fuopt_ccnl_notice(
tr_type: str,
tr_key: str,
):
"""
선물옵션 실시간체결통보 API입니다.
실시간 웹소켓 연결을 통해 선물옵션 거래의 실시간 체결 통보를 수신할 수 있습니다.
주문접수, 체결, 정정, 취소 등의 거래 상태 변화를 실시간으로 통보받을 수 있습니다.
고객ID, 계좌번호, 주문번호, 체결수량, 체결단가 등의 상세 거래 정보를 포함합니다.
실전계좌와 모의투자 모두 지원됩니다.
Args:
tr_type (str): [필수] 구독 등록/해제 여부 (ex. "1": 구독, "2": 해제)
tr_key (str): [필수] 코드 (ex. dttest11)
Returns:
message (str): 메시지 데이터
Example:
>>> msg, columns = fuopt_ccnl_notice("1", trenv.my_htsid)
>>> print(msg, columns)
"""
# 필수 파라미터 검증
if tr_key == "":
raise ValueError("tr_key is required")
tr_id = "H0IFCNI0"
params = {
"tr_key": tr_key,
}
msg = ka.data_fetch(tr_id, tr_type, params)
columns = [
"cust_id",
"acnt_no",
"oder_no",
"ooder_no",
"seln_byov_cls",
"rctf_cls",
"oder_kind2",
"stck_shrn_iscd",
"cntg_qty",
"cntg_unpr",
"stck_cntg_hour",
"rfus_yn",
"cntg_yn",
"acpt_yn",
"brnc_no",
"oder_qty",
"acnt_name",
"cntg_isnm",
"oder_cond",
"ord_grp",
"ord_grpseq",
"order_prc"
]
return msg, columns

View File

@@ -0,0 +1,74 @@
"""
Created on 20250601
"""
import logging
import sys
import pandas as pd
sys.path.extend(['../..', '.'])
import kis_auth as ka
from futures_exp_ccnl import futures_exp_ccnl
# 로깅 설정
logging.basicConfig(level=logging.INFO)
##############################################################################################
# [국내선물옵션] 실시간시세 > 주식선물 실시간예상체결 [실시간-031]
##############################################################################################
COLUMN_MAPPING = {
"futs_shrn_iscd": "선물단축종목코드",
"bsop_hour": "영업시간",
"antc_cnpr": "예상체결가",
"antc_cntg_vrss": "예상체결대비",
"antc_cntg_vrss_sign": "예상체결대비부호",
"antc_cntg_prdy_ctrt": "예상체결전일대비율",
"antc_mkop_cls_code": "예상장운영구분코드",
"antc_cnqn": "예상체결수량"
}
NUMERIC_COLUMNS = []
def main():
"""
[국내선물옵션] 실시간시세 > 주식선물 실시간예상체결 [실시간-031]
Returns:
None
"""
# 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=futures_exp_ccnl, data=["111W07"])
# 결과 표시
def on_result(ws, tr_id: str, result: pd.DataFrame, data_map: dict):
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').round(2)
logging.info("결과:")
print(result)
kws.start(on_result=on_result)
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,64 @@
"""
Created on 20250601
"""
import logging
import sys
sys.path.extend(['../..', '.'])
import kis_auth as ka
# 로깅 설정
logging.basicConfig(level=logging.INFO)
##############################################################################################
# [국내선물옵션] 실시간시세 > 주식선물 실시간예상체결 [실시간-031]
##############################################################################################
def futures_exp_ccnl(
tr_type: str,
tr_key: str,
) -> (dict, list[str]):
"""
[국내선물옵션] 실시간시세 > 주식선물 실시간예상체결 [실시간-031]
Args:
tr_type (str): [필수] 등록/해제
tr_key (str): [필수] 종목코드
Returns:
message (dict): 메시지 데이터
columns (list[str]): 컬럼 정보
Example:
>>> msg, columns = futures_exp_ccnl("1", "111W07")
>>> print(msg, columns)
"""
# 필수 파라미터 검증
if tr_type == "":
raise ValueError("tr_type is required")
if tr_key == "":
raise ValueError("tr_key is required")
tr_id = "H0ZFANC0"
params = {
"tr_key": tr_key,
}
msg = ka.data_fetch(tr_id, tr_type, params)
columns = [
"futs_shrn_iscd",
"bsop_hour",
"antc_cnpr",
"antc_cntg_vrss",
"antc_cntg_vrss_sign",
"antc_cntg_prdy_ctrt",
"antc_mkop_cls_code",
"antc_cnqn"
]
return msg, columns

View File

@@ -0,0 +1,116 @@
"""
Created on 20250601
"""
import logging
import sys
import pandas as pd
sys.path.extend(['../..', '.'])
import kis_auth as ka
from index_futures_realtime_conclusion import index_futures_realtime_conclusion
# 로깅 설정
logging.basicConfig(level=logging.INFO)
##############################################################################################
# [국내선물옵션] 실시간시세 > 지수선물 실시간체결가[실시간-010]
##############################################################################################
COLUMN_MAPPING = {
"futs_shrn_iscd": "선물 단축 종목코드",
"bsop_hour": "영업 시간",
"futs_prdy_vrss": "선물 전일 대비",
"prdy_vrss_sign": "전일 대비 부호",
"futs_prdy_ctrt": "선물 전일 대비율",
"futs_prpr": "선물 현재가",
"futs_oprc": "선물 시가2",
"futs_hgpr": "선물 최고가",
"futs_lwpr": "선물 최저가",
"last_cnqn": "최종 거래량",
"acml_vol": "누적 거래량",
"acml_tr_pbmn": "누적 거래 대금",
"hts_thpr": "HTS 이론가",
"mrkt_basis": "시장 베이시스",
"dprt": "괴리율",
"nmsc_fctn_stpl_prc": "근월물 약정가",
"fmsc_fctn_stpl_prc": "원월물 약정가",
"spead_prc": "스프레드1",
"hts_otst_stpl_qty": "HTS 미결제 약정 수량",
"otst_stpl_qty_icdc": "미결제 약정 수량 증감",
"oprc_hour": "시가 시간",
"oprc_vrss_prpr_sign": "시가2 대비 현재가 부호",
"oprc_vrss_nmix_prpr": "시가 대비 지수 현재가",
"hgpr_hour": "최고가 시간",
"hgpr_vrss_prpr_sign": "최고가 대비 현재가 부호",
"hgpr_vrss_nmix_prpr": "최고가 대비 지수 현재가",
"lwpr_hour": "최저가 시간",
"lwpr_vrss_prpr_sign": "최저가 대비 현재가 부호",
"lwpr_vrss_nmix_prpr": "최저가 대비 지수 현재가",
"shnu_rate": "매수2 비율",
"cttr": "체결강도",
"esdg": "괴리도",
"otst_stpl_rgbf_qty_icdc": "미결제 약정 직전 수량 증감",
"thpr_basis": "이론 베이시스",
"futs_askp1": "선물 매도호가1",
"futs_bidp1": "선물 매수호가1",
"askp_rsqn1": "매도호가 잔량1",
"bidp_rsqn1": "매수호가 잔량1",
"seln_cntg_csnu": "매도 체결 건수",
"shnu_cntg_csnu": "매수 체결 건수",
"ntby_cntg_csnu": "순매수 체결 건수",
"seln_cntg_smtn": "총 매도 수량",
"shnu_cntg_smtn": "총 매수 수량",
"total_askp_rsqn": "총 매도호가 잔량",
"total_bidp_rsqn": "총 매수호가 잔량",
"prdy_vol_vrss_acml_vol_rate": "전일 거래량 대비 등락율",
"dscs_bltr_acml_qty": "협의 대량 거래량",
"dynm_mxpr": "실시간상한가",
"dynm_llam": "실시간하한가",
"dynm_prc_limt_yn": "실시간가격제한구분"
}
NUMERIC_COLUMNS = []
def main():
"""
지수선물 실시간체결가
Returns:
None
"""
# 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=index_futures_realtime_conclusion, data=["101W09"])
# 결과 표시
def on_result(ws, tr_id: str, result: pd.DataFrame, data_map: dict):
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').round(2)
logging.info("결과:")
print(result)
kws.start(on_result=on_result)
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,109 @@
"""
Created on 20250601
"""
import logging
import sys
sys.path.extend(['../..', '.'])
import kis_auth as ka
# 로깅 설정
logging.basicConfig(level=logging.INFO)
##############################################################################################
# [국내선물옵션] 실시간시세 > 지수선물 실시간체결가[실시간-010]
##############################################################################################
def index_futures_realtime_conclusion(
tr_type: str,
tr_key: str,
) -> (dict, list[str]):
"""
지수선물 실시간체결가 API입니다.
실시간 웹소켓 연결을 통해 지수선물의 실시간 체결가 정보를 수신할 수 있습니다.
현재가, 시고저가, 체결량, 누적거래량, 이론가, 베이시스, 괴리율 등의 상세 정보를 제공합니다.
매도/매수 호가, 체결 건수, 미결제 약정 수량 등의 선물거래 필수 정보를 포함합니다.
실전계좌만 지원되며 모의투자는 미지원됩니다.
Args:
tr_type (str): [필수] 구독 등록/해제 여부 (ex. "1": 구독, "2": 해제)
tr_key (str): [필수] 코드 (ex. 101S12)
Returns:
message (str): 메시지 데이터
Example:
>>> msg, columns = index_futures_realtime_conclusion("1", "101S12")
>>> print(msg, columns)
"""
# 필수 파라미터 검증
if tr_type == "":
raise ValueError("tr_type is required")
if tr_key == "":
raise ValueError("tr_key is required")
tr_id = "H0IFCNT0"
params = {
"tr_key": tr_key,
}
msg = ka.data_fetch(tr_id, tr_type, params)
columns = [
"futs_shrn_iscd",
"bsop_hour",
"futs_prdy_vrss",
"prdy_vrss_sign",
"futs_prdy_ctrt",
"futs_prpr",
"futs_oprc",
"futs_hgpr",
"futs_lwpr",
"last_cnqn",
"acml_vol",
"acml_tr_pbmn",
"hts_thpr",
"mrkt_basis",
"dprt",
"nmsc_fctn_stpl_prc",
"fmsc_fctn_stpl_prc",
"spead_prc",
"hts_otst_stpl_qty",
"otst_stpl_qty_icdc",
"oprc_hour",
"oprc_vrss_prpr_sign",
"oprc_vrss_nmix_prpr",
"hgpr_hour",
"hgpr_vrss_prpr_sign",
"hgpr_vrss_nmix_prpr",
"lwpr_hour",
"lwpr_vrss_prpr_sign",
"lwpr_vrss_nmix_prpr",
"shnu_rate",
"cttr",
"esdg",
"otst_stpl_rgbf_qty_icdc",
"thpr_basis",
"futs_askp1",
"futs_bidp1",
"askp_rsqn1",
"bidp_rsqn1",
"seln_cntg_csnu",
"shnu_cntg_csnu",
"ntby_cntg_csnu",
"seln_cntg_smtn",
"shnu_cntg_smtn",
"total_askp_rsqn",
"total_bidp_rsqn",
"prdy_vol_vrss_acml_vol_rate",
"dscs_bltr_acml_qty",
"dynm_mxpr",
"dynm_llam",
"dynm_prc_limt_yn"
]
return msg, columns

View File

@@ -0,0 +1,104 @@
"""
Created on 20250601
"""
import logging
import sys
import pandas as pd
sys.path.extend(['../..', '.'])
import kis_auth as ka
from index_futures_realtime_quote import index_futures_realtime_quote
# 로깅 설정
logging.basicConfig(level=logging.INFO)
##############################################################################################
# [국내선물옵션] 실시간시세 > 지수선물 실시간호가[실시간-011]
##############################################################################################
COLUMN_MAPPING = {
"futs_shrn_iscd": "선물 단축 종목코드",
"bsop_hour": "영업 시간",
"futs_askp1": "선물 매도호가1",
"futs_askp2": "선물 매도호가2",
"futs_askp3": "선물 매도호가3",
"futs_askp4": "선물 매도호가4",
"futs_askp5": "선물 매도호가5",
"futs_bidp1": "선물 매수호가1",
"futs_bidp2": "선물 매수호가2",
"futs_bidp3": "선물 매수호가3",
"futs_bidp4": "선물 매수호가4",
"futs_bidp5": "선물 매수호가5",
"askp_csnu1": "매도호가 건수1",
"askp_csnu2": "매도호가 건수2",
"askp_csnu3": "매도호가 건수3",
"askp_csnu4": "매도호가 건수4",
"askp_csnu5": "매도호가 건수5",
"bidp_csnu1": "매수호가 건수1",
"bidp_csnu2": "매수호가 건수2",
"bidp_csnu3": "매수호가 건수3",
"bidp_csnu4": "매수호가 건수4",
"bidp_csnu5": "매수호가 건수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_csnu": "총 매도호가 건수",
"total_bidp_csnu": "총 매수호가 건수",
"total_askp_rsqn": "총 매도호가 잔량",
"total_bidp_rsqn": "총 매수호가 잔량",
"total_askp_rsqn_icdc": "총 매도호가 잔량 증감",
"total_bidp_rsqn_icdc": "총 매수호가 잔량 증감"
}
NUMERIC_COLUMNS = []
def main():
"""
지수선물 실시간호가
Returns:
None
"""
# 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=index_futures_realtime_quote, data=["101W09"])
# 결과 표시
def on_result(ws, tr_id: str, result: pd.DataFrame, data_map: dict):
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').round(2)
logging.info("결과:")
print(result)
kws.start(on_result=on_result)
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,97 @@
"""
Created on 20250601
"""
import logging
import sys
sys.path.extend(['../..', '.'])
import kis_auth as ka
# 로깅 설정
logging.basicConfig(level=logging.INFO)
##############################################################################################
# [국내선물옵션] 실시간시세 > 지수선물 실시간호가[실시간-011]
##############################################################################################
def index_futures_realtime_quote(
tr_type: str,
tr_key: str,
) -> (dict, list[str]):
"""
지수선물 실시간호가 API입니다.
실시간 웹소켓 연결을 통해 지수선물의 실시간 호가 정보를 수신할 수 있습니다.
매도/매수 호가 1~5단계, 호가 건수, 호가 잔량 등의 상세 정보를 제공합니다.
선물옵션 호가 데이터는 0.2초 필터링 옵션이 적용됩니다.
실전계좌만 지원되며 모의투자는 미지원됩니다.
Args:
tr_type (str): [필수] 구독 등록/해제 여부 (ex. "1": 구독, "2": 해제)
tr_key (str): [필수] 코드 (ex. 101S12)
Returns:
message (str): 메시지 데이터
Example:
>>> msg, columns = index_futures_realtime_quote("1", "101S12")
>>> print(msg, columns)
"""
# 필수 파라미터 검증
if tr_type == "":
raise ValueError("tr_type is required")
if tr_key == "":
raise ValueError("tr_key is required")
tr_id = "H0IFASP0"
params = {
"tr_key": tr_key,
}
msg = ka.data_fetch(tr_id, tr_type, params)
columns = [
"futs_shrn_iscd",
"bsop_hour",
"futs_askp1",
"futs_askp2",
"futs_askp3",
"futs_askp4",
"futs_askp5",
"futs_bidp1",
"futs_bidp2",
"futs_bidp3",
"futs_bidp4",
"futs_bidp5",
"askp_csnu1",
"askp_csnu2",
"askp_csnu3",
"askp_csnu4",
"askp_csnu5",
"bidp_csnu1",
"bidp_csnu2",
"bidp_csnu3",
"bidp_csnu4",
"bidp_csnu5",
"askp_rsqn1",
"askp_rsqn2",
"askp_rsqn3",
"askp_rsqn4",
"askp_rsqn5",
"bidp_rsqn1",
"bidp_rsqn2",
"bidp_rsqn3",
"bidp_rsqn4",
"bidp_rsqn5",
"total_askp_csnu",
"total_bidp_csnu",
"total_askp_rsqn",
"total_bidp_rsqn",
"total_askp_rsqn_icdc",
"total_bidp_rsqn_icdc"
]
return msg, columns

View File

@@ -0,0 +1,124 @@
"""
Created on 20250601
"""
import logging
import sys
import pandas as pd
sys.path.extend(['../..', '.'])
import kis_auth as ka
from index_option_realtime_conclusion import index_option_realtime_conclusion
# 로깅 설정
logging.basicConfig(level=logging.INFO)
##############################################################################################
# [국내선물옵션] 실시간시세 > 지수옵션 실시간체결가[실시간-014]
##############################################################################################
COLUMN_MAPPING = {
"optn_shrn_iscd": "옵션 단축 종목코드",
"bsop_hour": "영업 시간",
"optn_prpr": "옵션 현재가",
"prdy_vrss_sign": "전일 대비 부호",
"optn_prdy_vrss": "옵션 전일 대비",
"prdy_ctrt": "전일 대비율",
"optn_oprc": "옵션 시가2",
"optn_hgpr": "옵션 최고가",
"optn_lwpr": "옵션 최저가",
"last_cnqn": "최종 거래량",
"acml_vol": "누적 거래량",
"acml_tr_pbmn": "누적 거래 대금",
"hts_thpr": "HTS 이론가",
"hts_otst_stpl_qty": "HTS 미결제 약정 수량",
"otst_stpl_qty_icdc": "미결제 약정 수량 증감",
"oprc_hour": "시가 시간",
"oprc_vrss_prpr_sign": "시가2 대비 현재가 부호",
"oprc_vrss_nmix_prpr": "시가 대비 지수 현재가",
"hgpr_hour": "최고가 시간",
"hgpr_vrss_prpr_sign": "최고가 대비 현재가 부호",
"hgpr_vrss_nmix_prpr": "최고가 대비 지수 현재가",
"lwpr_hour": "최저가 시간",
"lwpr_vrss_prpr_sign": "최저가 대비 현재가 부호",
"lwpr_vrss_nmix_prpr": "최저가 대비 지수 현재가",
"shnu_rate": "매수2 비율",
"prmm_val": "프리미엄 값",
"invl_val": "내재가치 값",
"tmvl_val": "시간가치 값",
"delta": "델타",
"gama": "감마",
"vega": "베가",
"theta": "세타",
"rho": "로우",
"hts_ints_vltl": "HTS 내재 변동성",
"esdg": "괴리도",
"otst_stpl_rgbf_qty_icdc": "미결제 약정 직전 수량 증감",
"thpr_basis": "이론 베이시스",
"unas_hist_vltl": "역사적변동성",
"cttr": "체결강도",
"dprt": "괴리율",
"mrkt_basis": "시장 베이시스",
"optn_askp1": "옵션 매도호가1",
"optn_bidp1": "옵션 매수호가1",
"askp_rsqn1": "매도호가 잔량1",
"bidp_rsqn1": "매수호가 잔량1",
"seln_cntg_csnu": "매도 체결 건수",
"shnu_cntg_csnu": "매수 체결 건수",
"ntby_cntg_csnu": "순매수 체결 건수",
"seln_cntg_smtn": "총 매도 수량",
"shnu_cntg_smtn": "총 매수 수량",
"total_askp_rsqn": "총 매도호가 잔량",
"total_bidp_rsqn": "총 매수호가 잔량",
"prdy_vol_vrss_acml_vol_rate": "전일 거래량 대비 등락율",
"avrg_vltl": "평균 변동성",
"dscs_lrqn_vol": "협의대량누적 거래량",
"dynm_mxpr": "실시간상한가",
"dynm_llam": "실시간하한가",
"dynm_prc_limt_yn": "실시간가격제한구분"
}
NUMERIC_COLUMNS = []
def main():
"""
지수옵션 실시간체결가
Returns:
None
"""
# 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=index_option_realtime_conclusion, data=["201W08427"])
# 결과 표시
def on_result(ws, tr_id: str, result: pd.DataFrame, data_map: dict):
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').round(2)
logging.info("결과:")
print(result)
kws.start(on_result=on_result)
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,121 @@
"""
Created on 20250601
"""
import logging
import sys
sys.path.extend(['../..', '.'])
import kis_auth as ka
# 로깅 설정
logging.basicConfig(level=logging.INFO)
##############################################################################################
# [국내선물옵션] 실시간시세 > 지수옵션 실시간체결가[실시간-014]
##############################################################################################
def index_option_realtime_conclusion(
tr_type: str,
tr_key: str,
) -> (dict, list[str]):
"""
지수옵션 실시간체결가 API입니다.
실시간 웹소켓 연결을 통해 지수옵션의 실시간 체결가 정보를 수신할 수 있습니다.
옵션 현재가, 시고저가, 체결량, 누적거래량, 이론가 등의 기본 정보와 함께
델타, 감마, 베가, 세타, 로우 등의 그리스 지표와 내재가치, 시간가치, 변동성 정보를 제공합니다.
옵션 거래에 필수적인 전문 지표들을 포함하는 확장된 체결가 정보입니다.
실전계좌만 지원되며 모의투자는 미지원됩니다.
Args:
tr_type (str): [필수] 구독 등록/해제 여부 (ex. "1": 구독, "2": 해제)
tr_key (str): [필수] 코드 (ex. 201S11305)
Returns:
message (str): 메시지 데이터
Example:
>>> msg, columns = index_option_realtime_conclusion("1", "101W09")
>>> print(msg, columns)
"""
# 필수 파라미터 검증
if tr_type == "":
raise ValueError("tr_type is required")
if tr_type == "":
raise ValueError("tr_type is required")
if tr_key == "":
raise ValueError("tr_key is required")
tr_id = "H0IOCNT0"
params = {
"tr_key": tr_key,
}
msg = ka.data_fetch(tr_id, tr_type, params)
columns = [
"optn_shrn_iscd",
"bsop_hour",
"optn_prpr",
"prdy_vrss_sign",
"optn_prdy_vrss",
"prdy_ctrt",
"optn_oprc",
"optn_hgpr",
"optn_lwpr",
"last_cnqn",
"acml_vol",
"acml_tr_pbmn",
"hts_thpr",
"hts_otst_stpl_qty",
"otst_stpl_qty_icdc",
"oprc_hour",
"oprc_vrss_prpr_sign",
"oprc_vrss_nmix_prpr",
"hgpr_hour",
"hgpr_vrss_prpr_sign",
"hgpr_vrss_nmix_prpr",
"lwpr_hour",
"lwpr_vrss_prpr_sign",
"lwpr_vrss_nmix_prpr",
"shnu_rate",
"prmm_val",
"invl_val",
"tmvl_val",
"delta",
"gama",
"vega",
"theta",
"rho",
"hts_ints_vltl",
"esdg",
"otst_stpl_rgbf_qty_icdc",
"thpr_basis",
"unas_hist_vltl",
"cttr",
"dprt",
"mrkt_basis",
"optn_askp1",
"optn_bidp1",
"askp_rsqn1",
"bidp_rsqn1",
"seln_cntg_csnu",
"shnu_cntg_csnu",
"ntby_cntg_csnu",
"seln_cntg_smtn",
"shnu_cntg_smtn",
"total_askp_rsqn",
"total_bidp_rsqn",
"prdy_vol_vrss_acml_vol_rate",
"avrg_vltl",
"dscs_lrqn_vol",
"dynm_mxpr",
"dynm_llam",
"dynm_prc_limt_yn"
]
return msg, columns

View File

@@ -0,0 +1,104 @@
"""
Created on 20250601
"""
import logging
import sys
import pandas as pd
sys.path.extend(['../..', '.'])
import kis_auth as ka
from index_option_realtime_quote import index_option_realtime_quote
# 로깅 설정
logging.basicConfig(level=logging.INFO)
##############################################################################################
# [국내선물옵션] 실시간시세 > 지수옵션 실시간호가[실시간-015]
##############################################################################################
COLUMN_MAPPING = {
"optn_shrn_iscd": "옵션 단축 종목코드",
"bsop_hour": "영업 시간",
"optn_askp1": "옵션 매도호가1",
"optn_askp2": "옵션 매도호가2",
"optn_askp3": "옵션 매도호가3",
"optn_askp4": "옵션 매도호가4",
"optn_askp5": "옵션 매도호가5",
"optn_bidp1": "옵션 매수호가1",
"optn_bidp2": "옵션 매수호가2",
"optn_bidp3": "옵션 매수호가3",
"optn_bidp4": "옵션 매수호가4",
"optn_bidp5": "옵션 매수호가5",
"askp_csnu1": "매도호가 건수1",
"askp_csnu2": "매도호가 건수2",
"askp_csnu3": "매도호가 건수3",
"askp_csnu4": "매도호가 건수4",
"askp_csnu5": "매도호가 건수5",
"bidp_csnu1": "매수호가 건수1",
"bidp_csnu2": "매수호가 건수2",
"bidp_csnu3": "매수호가 건수3",
"bidp_csnu4": "매수호가 건수4",
"bidp_csnu5": "매수호가 건수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_csnu": "총 매도호가 건수",
"total_bidp_csnu": "총 매수호가 건수",
"total_askp_rsqn": "총 매도호가 잔량",
"total_bidp_rsqn": "총 매수호가 잔량",
"total_askp_rsqn_icdc": "총 매도호가 잔량 증감",
"total_bidp_rsqn_icdc": "총 매수호가 잔량 증감"
}
NUMERIC_COLUMNS = []
def main():
"""
지수옵션 실시간호가
Returns:
None
"""
# 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=index_option_realtime_quote, data=["201W08427"])
# 결과 표시
def on_result(ws, tr_id: str, result: pd.DataFrame, data_map: dict):
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').round(2)
logging.info("결과:")
print(result)
kws.start(on_result=on_result)
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,95 @@
"""
Created on 20250601
"""
import logging
import sys
sys.path.extend(['../..', '.'])
import kis_auth as ka
# 로깅 설정
logging.basicConfig(level=logging.INFO)
##############################################################################################
# [국내선물옵션] 실시간시세 > 지수옵션 실시간호가[실시간-015]
##############################################################################################
def index_option_realtime_quote(
tr_type: str,
tr_key: str,
) -> (dict, list[str]):
"""
지수옵션 실시간호가 API입니다.
실시간 웹소켓 연결을 통해 지수옵션 매도/매수 호가 정보를 실시간으로 수신할 수 있습니다.
실전계좌만 지원되며, 모의투자는 지원하지 않습니다.
Args:
tr_type (str): [필수] 구독 등록/해제 여부 (ex. "1": 구독, "2": 해제)
tr_key (str): [필수] 코드 (ex. 201S11305)
Returns:
message (str): 메시지 데이터
Example:
>>> msg, columns = index_option_realtime_quote("1", "201S11305")
>>> print(msg, columns)
"""
# 필수 파라미터 검증
if tr_type == "":
raise ValueError("tr_type is required")
if tr_key == "":
raise ValueError("tr_key is required")
tr_id = "H0IOASP0"
params = {
"tr_key": tr_key,
}
msg = ka.data_fetch(tr_id, tr_type, params)
columns = [
"optn_shrn_iscd",
"bsop_hour",
"optn_askp1",
"optn_askp2",
"optn_askp3",
"optn_askp4",
"optn_askp5",
"optn_bidp1",
"optn_bidp2",
"optn_bidp3",
"optn_bidp4",
"optn_bidp5",
"askp_csnu1",
"askp_csnu2",
"askp_csnu3",
"askp_csnu4",
"askp_csnu5",
"bidp_csnu1",
"bidp_csnu2",
"bidp_csnu3",
"bidp_csnu4",
"bidp_csnu5",
"askp_rsqn1",
"askp_rsqn2",
"askp_rsqn3",
"askp_rsqn4",
"askp_rsqn5",
"bidp_rsqn1",
"bidp_rsqn2",
"bidp_rsqn3",
"bidp_rsqn4",
"bidp_rsqn5",
"total_askp_csnu",
"total_bidp_csnu",
"total_askp_rsqn",
"total_bidp_rsqn",
"total_askp_rsqn_icdc",
"total_bidp_rsqn_icdc"
]
return msg, columns

View File

@@ -0,0 +1,129 @@
"""
Created on 20250601
"""
import sys
import logging
import pandas as pd
sys.path.extend(['../..', '.'])
import kis_auth as ka
from inquire_asking_price import inquire_asking_price
# 로깅 설정
logging.basicConfig(level=logging.INFO)
##############################################################################################
# [국내선물옵션] 기본시세 > 선물옵션 시세호가[v1_국내선물-007]
##############################################################################################
COLUMN_MAPPING = {
'hts_kor_isnm': 'HTS 한글 종목명',
'futs_prpr': '선물 현재가',
'prdy_vrss_sign': '전일 대비 부호',
'futs_prdy_vrss': '선물 전일 대비',
'futs_prdy_ctrt': '선물 전일 대비율',
'acml_vol': '누적 거래량',
'futs_prdy_clpr': '선물 전일 종가',
'futs_shrn_iscd': '선물 단축 종목코드',
'futs_askp1': '선물 매도호가1',
'futs_askp2': '선물 매도호가2',
'futs_askp3': '선물 매도호가3',
'futs_askp4': '선물 매도호가4',
'futs_askp5': '선물 매도호가5',
'futs_bidp1': '선물 매수호가1',
'futs_bidp2': '선물 매수호가2',
'futs_bidp3': '선물 매수호가3',
'futs_bidp4': '선물 매수호가4',
'futs_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',
'askp_csnu1': '매도호가 건수1',
'askp_csnu2': '매도호가 건수2',
'askp_csnu3': '매도호가 건수3',
'askp_csnu4': '매도호가 건수4',
'askp_csnu5': '매도호가 건수5',
'bidp_csnu1': '매수호가 건수1',
'bidp_csnu2': '매수호가 건수2',
'bidp_csnu3': '매수호가 건수3',
'bidp_csnu4': '매수호가 건수4',
'bidp_csnu5': '매수호가 건수5',
'total_askp_rsqn': '총 매도호가 잔량',
'total_bidp_rsqn': '총 매수호가 잔량',
'total_askp_csnu': '총 매도호가 건수',
'total_bidp_csnu': '총 매수호가 건수',
'aspr_acpt_hour': '호가 접수 시간'
}
NUMERIC_COLUMNS = []
def main():
"""
선물옵션 시세호가 조회 테스트 함수
이 함수는 선물옵션 시세호가 API를 호출하여 결과를 출력합니다.
Returns:
None
"""
# pandas 출력 옵션 설정
pd.set_option('display.max_columns', None) # 모든 컬럼 표시
pd.set_option('display.width', None) # 출력 너비 제한 해제
pd.set_option('display.max_rows', None) # 모든 행 표시
# 인증 토큰 발급
ka.auth()
# case1 조회
logging.info("=== case1 조회 ===")
try:
result1, result2 = inquire_asking_price(fid_cond_mrkt_div_code="F", fid_input_iscd="101W09", env_dv="real")
except ValueError as e:
logging.error("에러 발생: %s" % str(e))
return
# output1 결과 처리
logging.info("=== output1 결과 ===")
logging.info("사용 가능한 컬럼: %s", result1.columns.tolist())
# 컬럼명 한글 변환
result1 = result1.rename(columns=COLUMN_MAPPING)
# 숫자형 컬럼 소수점 둘째자리까지 표시 (메타데이터에 number 자료형이 명시된 필드 없음)
for col in NUMERIC_COLUMNS:
if col in result1.columns:
result1[col] = pd.to_numeric(result1[col], errors='coerce').round(2)
logging.info("결과:")
print(result1)
# output2 결과 처리
logging.info("=== output2 결과 ===")
logging.info("사용 가능한 컬럼: %s", result2.columns.tolist())
# 컬럼명 한글 변환
result2 = result2.rename(columns=COLUMN_MAPPING)
# 숫자형 컬럼 소수점 둘째자리까지 표시 (메타데이터에 number 자료형이 명시된 필드 없음)
for col in NUMERIC_COLUMNS:
if col in result2.columns:
result2[col] = pd.to_numeric(result2[col], errors='coerce').round(2)
logging.info("결과:")
print(result2)
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,81 @@
"""
Created on 20250601
"""
import sys
import logging
from typing import Tuple
import pandas as pd
sys.path.extend(['../..', '.'])
import kis_auth as ka
# 로깅 설정
logging.basicConfig(level=logging.INFO)
##############################################################################################
# [국내선물옵션] 기본시세 > 선물옵션 시세호가[v1_국내선물-007]
##############################################################################################
# 상수 정의
API_URL = "/uapi/domestic-futureoption/v1/quotations/inquire-asking-price"
def inquire_asking_price(
fid_cond_mrkt_div_code: str, # [필수] FID 조건 시장 분류 코드 (ex. F: 지수선물, JF: 주식선물)
fid_input_iscd: str, # [필수] FID 입력 종목코드 (ex. 101S03)
env_dv: str # [필수] 실전모의구분 (ex. real:실전, demo:모의)
) -> Tuple[pd.DataFrame, pd.DataFrame]:
"""
선물옵션 시세호가 API입니다.
Args:
fid_cond_mrkt_div_code (str): [필수] FID 조건 시장 분류 코드 (ex. F: 지수선물, JF: 주식선물)
fid_input_iscd (str): [필수] FID 입력 종목코드 (ex. 101W09)
env_dv (str): [필수] 실전모의구분 (ex. real:실전, demo:모의)
Returns:
Tuple[pd.DataFrame, pd.DataFrame]: (output1 데이터, output2 데이터)
Example:
>>> df1, df2 = inquire_asking_price("F", "101W09", "real")
>>> print(df1)
>>> print(df2)
"""
# 필수 파라미터 검증
if fid_cond_mrkt_div_code == "":
raise ValueError("fid_cond_mrkt_div_code is required (e.g. 'F', 'JF')")
if fid_input_iscd == "":
raise ValueError("fid_input_iscd is required (e.g. '101W09')")
if env_dv == "":
raise ValueError("env_dv is required (e.g. 'real', 'demo')")
# TR_ID 설정
if env_dv == "real":
tr_id = "FHMIF10010000"
elif env_dv == "demo":
tr_id = "FHMIF10010000"
else:
raise ValueError("env_dv can only be 'real' or 'demo'")
params = {
"FID_COND_MRKT_DIV_CODE": fid_cond_mrkt_div_code,
"FID_INPUT_ISCD": fid_input_iscd
}
res = ka._url_fetch(API_URL, tr_id, "", params)
if res.isOK():
# output1 (object) -> DataFrame
output1_data = pd.DataFrame([res.getBody().output1])
# output2 (object) -> DataFrame
output2_data = pd.DataFrame([res.getBody().output2])
return output1_data, output2_data
else:
res.printError(url=API_URL)
return pd.DataFrame(), pd.DataFrame()

View File

@@ -0,0 +1,136 @@
"""
Created on 20250601
"""
import sys
import logging
import pandas as pd
sys.path.extend(['../..', '.'])
import kis_auth as ka
from inquire_balance import inquire_balance
# 로깅 설정
logging.basicConfig(level=logging.INFO)
##############################################################################################
# [국내선물옵션] 주문/계좌 > 선물옵션 잔고현황[v1_국내선물-004]
##############################################################################################
COLUMN_MAPPING = {
'cano': '종합계좌번호',
'acnt_prdt_cd': '계좌상품코드',
'pdno': '상품번호',
'prdt_type_cd': '상품유형코드',
'shtn_pdno': '단축상품번호',
'prdt_name': '상품명',
'sll_buy_dvsn_name': '매도매수구분명',
'cblc_qty': '잔고수량',
'excc_unpr': '정산단가',
'ccld_avg_unpr1': '체결평균단가1',
'idx_clpr': '지수종가',
'pchs_amt': '매입금액',
'evlu_amt': '평가금액',
'evlu_pfls_amt': '평가손익금액',
'trad_pfls_amt': '매매손익금액',
'lqd_psbl_qty': '청산가능수량',
'dnca_cash': '예수금현금',
'frcr_dncl_amt': '외화예수금액',
'dnca_sbst': '예수금대용',
'tot_dncl_amt': '총예수금액',
'tot_ccld_amt': '총체결금액',
'cash_mgna': '현금증거금',
'sbst_mgna': '대용증거금',
'mgna_tota': '증거금총액',
'opt_dfpa': '옵션차금',
'thdt_dfpa': '당일차금',
'rnwl_dfpa': '갱신차금',
'fee': '수수료',
'nxdy_dnca': '익일예수금',
'nxdy_dncl_amt': '익일예수금액',
'prsm_dpast': '추정예탁자산',
'prsm_dpast_amt': '추정예탁자산금액',
'pprt_ord_psbl_cash': '적정주문가능현금',
'add_mgna_cash': '추가증거금현금',
'add_mgna_tota': '추가증거금총액',
'futr_trad_pfls_amt': '선물매매손익금액',
'opt_trad_pfls_amt': '옵션매매손익금액',
'futr_evlu_pfls_amt': '선물평가손익금액',
'opt_evlu_pfls_amt': '옵션평가손익금액',
'trad_pfls_amt_smtl': '매매손익금액합계',
'evlu_pfls_amt_smtl': '평가손익금액합계',
'wdrw_psbl_tot_amt': '인출가능총금액',
'ord_psbl_cash': '주문가능현금',
'ord_psbl_sbst': '주문가능대용',
'ord_psbl_tota': '주문가능총액',
'pchs_amt_smtl': '매입금액합계',
'evlu_amt_smtl': '평가금액합계'
}
NUMERIC_COLUMNS = []
def main():
"""
선물옵션 잔고현황 조회 테스트 함수
이 함수는 선물옵션 잔고현황 API를 호출하여 결과를 출력합니다.
Returns:
None
"""
# pandas 출력 옵션 설정
pd.set_option('display.max_columns', None) # 모든 컬럼 표시
pd.set_option('display.width', None) # 출력 너비 제한 해제
pd.set_option('display.max_rows', None) # 모든 행 표시
# 인증 토큰 발급
ka.auth()
trenv = ka.getTREnv()
# case1 조회
logging.info("=== case1 조회 ===")
try:
result1, result2 = inquire_balance(env_dv="real", cano=trenv.my_acct, acnt_prdt_cd=trenv.my_prod, mgna_dvsn="01",
excc_stat_cd="1")
except ValueError as e:
logging.error("에러 발생: %s" % str(e))
return
# output1 결과 처리
logging.info("=== output1 결과 ===")
logging.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)
logging.info("결과:")
print(result1)
# output2 결과 처리
logging.info("=== output2 결과 ===")
logging.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)
logging.info("결과:")
print(result2)
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,138 @@
"""
Created on 20250601
"""
import sys
import time
from typing import Optional, Tuple
import logging
import pandas as pd
sys.path.extend(['../..', '.'])
import kis_auth as ka
# 로깅 설정
logging.basicConfig(level=logging.INFO)
##############################################################################################
# [국내선물옵션] 주문/계좌 > 선물옵션 잔고현황[v1_국내선물-004]
##############################################################################################
# 상수 정의
API_URL = "/uapi/domestic-futureoption/v1/trading/inquire-balance"
def inquire_balance(
env_dv: str, # [필수] 실전모의구분 (ex. real:실전, demo:모의)
cano: str, # [필수] 종합계좌번호
acnt_prdt_cd: str, # [필수] 계좌상품코드 (ex. 03)
mgna_dvsn: str, # [필수] 증거금 구분 (ex. 01:게시,02:유지)
excc_stat_cd: str, # [필수] 정산상태코드 (ex. 1:정산,2:본정산)
FK200: str = "", # 연속조회검색조건200
NK200: str = "", # 연속조회키200
tr_cont: str = "", # 연속거래여부
dataframe1: Optional[pd.DataFrame] = None, # 누적 데이터프레임1
dataframe2: Optional[pd.DataFrame] = None, # 누적 데이터프레임2
depth: int = 0, # 내부 재귀 깊이 (자동 관리)
max_depth: int = 10 # 최대 재귀 횟수 제한
) -> Tuple[pd.DataFrame, pd.DataFrame]:
"""
선물옵션 잔고현황 API입니다. 한 번의 호출에 최대 20건까지 확인 가능하며, 이후의 값은 연속조회를 통해 확인하실 수 있습니다.
Args:
env_dv (str): [필수] 실전모의구분 (ex. real:실전, demo:모의)
cano (str): [필수] 종합계좌번호
acnt_prdt_cd (str): [필수] 계좌상품코드 (ex. 03)
mgna_dvsn (str): [필수] 증거금 구분 (ex. 01:게시,02:유지)
excc_stat_cd (str): [필수] 정산상태코드 (ex. 1:정산,2:본정산)
FK200 (str): 연속조회검색조건200
NK200 (str): 연속조회키200
tr_cont (str): 연속거래여부
dataframe1 (Optional[pd.DataFrame]): 누적 데이터프레임1
dataframe2 (Optional[pd.DataFrame]): 누적 데이터프레임2
depth (int): 내부 재귀 깊이 (자동 관리)
max_depth (int): 최대 재귀 횟수 제한
Returns:
Tuple[pd.DataFrame, pd.DataFrame]: (output1, output2) 선물옵션 잔고현황 데이터
Example:
>>> df1, df2 = inquire_balance(env_dv="real", cano=trenv.my_acct, acnt_prdt_cd=trenv.my_prod, mgna_dvsn="01", excc_stat_cd="1")
>>> print(df1)
>>> print(df2)
"""
if env_dv == "":
raise ValueError("env_dv is required (e.g. 'real' or 'demo')")
if cano == "":
raise ValueError("cano is required")
if acnt_prdt_cd == "":
raise ValueError("acnt_prdt_cd is required (e.g. '03')")
if mgna_dvsn == "":
raise ValueError("mgna_dvsn is required (e.g. '01' or '02')")
if excc_stat_cd == "":
raise ValueError("excc_stat_cd is required (e.g. '1' or '2')")
if depth > max_depth:
logging.warning("Max recursive depth reached.")
if dataframe1 is None:
dataframe1 = pd.DataFrame()
if dataframe2 is None:
dataframe2 = pd.DataFrame()
return dataframe1, dataframe2
# tr_id 설정
if env_dv == "real":
tr_id = "CTFO6118R"
elif env_dv == "demo":
tr_id = "VTFO6118R"
else:
raise ValueError("env_dv can only be 'real' or 'demo'")
params = {
"CANO": cano,
"ACNT_PRDT_CD": acnt_prdt_cd,
"MGNA_DVSN": mgna_dvsn,
"EXCC_STAT_CD": excc_stat_cd,
"CTX_AREA_FK200": FK200,
"CTX_AREA_NK200": NK200
}
res = ka._url_fetch(API_URL, tr_id, tr_cont, params)
if res.isOK():
# output1 처리 (array)
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 처리 (object)
current_data2 = pd.DataFrame(res.getBody().output2, index=[0])
if dataframe2 is not None:
dataframe2 = pd.concat([dataframe2, current_data2], ignore_index=True)
else:
dataframe2 = current_data2
tr_cont = res.getHeader().tr_cont
FK200 = res.getBody().ctx_area_fk200
NK200 = res.getBody().ctx_area_nk200
if tr_cont in ["M", "F"]: # 다음 페이지 존재
logging.info("Call Next page...")
ka.smart_sleep() # 시스템 안정적 운영을 위한 지연
return inquire_balance(
env_dv, cano, acnt_prdt_cd, mgna_dvsn, excc_stat_cd,
FK200, NK200, "N", dataframe1, dataframe2, depth + 1, max_depth
)
else:
logging.info("Data fetch complete.")
return dataframe1, dataframe2
else:
res.printError(url=API_URL)
return pd.DataFrame(), pd.DataFrame()

View File

@@ -0,0 +1,109 @@
"""
Created on 20250601
"""
import sys
import logging
import pandas as pd
sys.path.extend(['../..', '.'])
import kis_auth as ka
from inquire_balance_settlement_pl import inquire_balance_settlement_pl
# 로깅 설정
logging.basicConfig(level=logging.INFO)
##############################################################################################
# [국내선물옵션] 주문/계좌 > 선물옵션 잔고정산손익내역[v1_국내선물-013]
##############################################################################################
COLUMN_MAPPING = {
'pdno': '상품번호',
'prdt_name': '상품명',
'trad_dvsn_name': '매매구분명',
'bfdy_cblc_qty': '전일잔고수량',
'new_qty': '신규수량',
'mnpl_rpch_qty': '전매환매수량',
'cblc_qty': '잔고수량',
'cblc_amt': '잔고금액',
'trad_pfls_amt': '매매손익금액',
'evlu_amt': '평가금액',
'evlu_pfls_amt': '평가손익금액',
'nxdy_dnca': '익일예수금',
'mmga_cash': '유지증거금현금',
'brkg_mgna_cash': '위탁증거금현금',
'opt_buy_chgs': '옵션매수대금',
'opt_lqd_evlu_amt': '옵션청산평가금액',
'dnca_sbst': '예수금대용',
'mmga_tota': '유지증거금총액',
'brkg_mgna_tota': '위탁증거금총액',
'opt_sll_chgs': '옵션매도대금',
'fee': '수수료',
'thdt_dfpa': '당일차금',
'rnwl_dfpa': '갱신차금',
'dnca_cash': '예수금현금'
}
NUMERIC_COLUMNS = []
def main():
"""
선물옵션 잔고정산손익내역 조회 테스트 함수
이 함수는 선물옵션 잔고정산손익내역 API를 호출하여 결과를 출력합니다.
Returns:
None
"""
# pandas 출력 옵션 설정
pd.set_option('display.max_columns', None) # 모든 컬럼 표시
pd.set_option('display.width', None) # 출력 너비 제한 해제
pd.set_option('display.max_rows', None) # 모든 행 표시
# 인증 토큰 발급
ka.auth()
trenv = ka.getTREnv()
# Case 1
logging.info("=== Case 1 ===")
try:
result1, result2 = inquire_balance_settlement_pl(cano=trenv.my_acct, acnt_prdt_cd=trenv.my_prod, inqr_dt="20230906")
except ValueError as e:
logging.error("에러 발생: %s" % str(e))
return
logging.info("사용 가능한 컬럼 (output1): %s", result1.columns.tolist())
# 컬럼명 한글 변환 및 데이터 출력 (output1)
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)
logging.info("결과 (output1):")
print(result1)
logging.info("사용 가능한 컬럼 (output2): %s", result2.columns.tolist())
# 컬럼명 한글 변환 및 데이터 출력 (output2)
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)
logging.info("결과 (output2):")
print(result2)
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,120 @@
"""
Created on 20250601
"""
import sys
import time
from typing import Optional, Tuple
import logging
import pandas as pd
sys.path.extend(['../..', '.'])
import kis_auth as ka
# 로깅 설정
logging.basicConfig(level=logging.INFO)
##############################################################################################
# [국내선물옵션] 주문/계좌 > 선물옵션 잔고정산손익내역[v1_국내선물-013]
##############################################################################################
# 상수 정의
API_URL = "/uapi/domestic-futureoption/v1/trading/inquire-balance-settlement-pl"
def inquire_balance_settlement_pl(
cano: str, # 종합계좌번호
acnt_prdt_cd: str, # 계좌상품코드 (ex. 03)
inqr_dt: str, # 조회일자
FK200: str = "", # 연속조회검색조건200
NK200: str = "", # 연속조회키200
tr_cont: str = "", # 연속거래여부
dataframe1: Optional[pd.DataFrame] = None, # 누적 데이터프레임1
dataframe2: Optional[pd.DataFrame] = None, # 누적 데이터프레임2
depth: int = 0, # 내부 재귀깊이 (자동관리)
max_depth: int = 10 # 최대 재귀 횟수 제한
) -> Tuple[pd.DataFrame, pd.DataFrame]:
"""
선물옵션 잔고정산손익내역 API입니다.
Args:
cano (str): [필수] 종합계좌번호
acnt_prdt_cd (str): [필수] 계좌상품코드 (ex. 03)
inqr_dt (str): [필수] 조회일자
FK200 (str): 연속조회검색조건200
NK200 (str): 연속조회키200
tr_cont (str): 연속거래여부
dataframe1 (Optional[pd.DataFrame]): 누적 데이터프레임1
dataframe2 (Optional[pd.DataFrame]): 누적 데이터프레임2
depth (int): 내부 재귀깊이 (자동관리)
max_depth (int): 최대 재귀 횟수 제한
Returns:
Tuple[pd.DataFrame, pd.DataFrame]: (output1 데이터, output2 데이터)
Example:
>>> df1, df2 = inquire_balance_settlement_pl(cano=trenv.my_acct, acnt_prdt_cd=trenv.my_prod, inqr_dt="20230906")
>>> print(df1)
>>> print(df2)
"""
if cano == "":
raise ValueError("cano is required")
if acnt_prdt_cd == "":
raise ValueError("acnt_prdt_cd is required")
if inqr_dt == "":
raise ValueError("inqr_dt is required")
if depth > max_depth:
logging.warning("Max recursive depth reached.")
if dataframe1 is None:
dataframe1 = pd.DataFrame()
if dataframe2 is None:
dataframe2 = pd.DataFrame()
return dataframe1, dataframe2
tr_id = "CTFO6117R"
params = {
"CANO": cano,
"ACNT_PRDT_CD": acnt_prdt_cd,
"INQR_DT": inqr_dt,
"CTX_AREA_FK200": FK200,
"CTX_AREA_NK200": NK200
}
res = ka._url_fetch(API_URL, tr_id, tr_cont, params)
if res.isOK():
# output1 처리 (array)
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 처리 (object)
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
tr_cont = res.getHeader().tr_cont
FK200 = res.getBody().ctx_area_fk200
NK200 = res.getBody().ctx_area_nk200
if tr_cont in ["M", "F"]: # 다음 페이지 존재
logging.info("Call Next page...")
ka.smart_sleep() # 시스템 안정적 운영을 위한 지연
return inquire_balance_settlement_pl(
cano, acnt_prdt_cd, inqr_dt, FK200, NK200, "N", dataframe1, dataframe2, depth + 1, max_depth
)
else:
logging.info("Data fetch complete.")
return dataframe1, dataframe2
else:
res.printError(url=API_URL)
return pd.DataFrame(), pd.DataFrame()

View File

@@ -0,0 +1,134 @@
"""
Created on 20250601
"""
import sys
import logging
import pandas as pd
sys.path.extend(['../..', '.'])
import kis_auth as ka
from inquire_balance_valuation_pl import inquire_balance_valuation_pl
# 로깅 설정
logging.basicConfig(level=logging.INFO)
##############################################################################################
# [국내선물옵션] 주문/계좌 > 선물옵션 잔고평가손익내역[v1_국내선물-015]
##############################################################################################
COLUMN_MAPPING = {
'cano': '종합계좌번호',
'acnt_prdt_cd': '계좌상품코드',
'pdno': '상품번호',
'prdt_type_cd': '상품유형코드',
'shtn_pdno': '단축상품번호',
'prdt_name': '상품명',
'sll_buy_dvsn_name': '매도매수구분명',
'cblc_qty1': '잔고수량1',
'excc_unpr': '정산단가',
'ccld_avg_unpr1': '체결평균단가1',
'idx_clpr': '지수종가',
'pchs_amt': '매입금액',
'evlu_amt': '평가금액',
'evlu_pfls_amt': '평가손익금액',
'trad_pfls_amt': '매매손익금액',
'lqd_psbl_qty': '청산가능수량',
'dnca_cash': '예수금현금',
'frcr_dncl_amt': '외화예수금액',
'dnca_sbst': '예수금대용',
'tot_dncl_amt': '총예수금액',
'tot_ccld_amt': '총체결금액',
'cash_mgna': '현금증거금',
'sbst_mgna': '대용증거금',
'mgna_tota': '증거금총액',
'opt_dfpa': '옵션차금',
'thdt_dfpa': '당일차금',
'rnwl_dfpa': '갱신차금',
'fee': '수수료',
'nxdy_dnca': '익일예수금',
'nxdy_dncl_amt': '익일예수금액',
'prsm_dpast': '추정예탁자산',
'prsm_dpast_amt': '추정예탁자산금액',
'pprt_ord_psbl_cash': '적정주문가능현금',
'add_mgna_cash': '추가증거금현금',
'add_mgna_tota': '추가증거금총액',
'futr_trad_pfls_amt': '선물매매손익금액',
'opt_trad_pfls_amt': '옵션매매손익금액',
'futr_evlu_pfls_amt': '선물평가손익금액',
'opt_evlu_pfls_amt': '옵션평가손익금액',
'trad_pfls_amt_smtl': '매매손익금액합계',
'evlu_pfls_amt_smtl': '평가손익금액합계',
'wdrw_psbl_tot_amt': '인출가능총금액',
'ord_psbl_cash': '주문가능현금',
'ord_psbl_sbst': '주문가능대용',
'ord_psbl_tota': '주문가능총액'
}
NUMERIC_COLUMNS = []
def main():
"""
선물옵션 잔고평가손익내역 조회 테스트 함수
이 함수는 선물옵션 잔고평가손익내역 API를 호출하여 결과를 출력합니다.
Returns:
None
"""
# pandas 출력 옵션 설정
pd.set_option('display.max_columns', None) # 모든 컬럼 표시
pd.set_option('display.width', None) # 출력 너비 제한 해제
pd.set_option('display.max_rows', None) # 모든 행 표시
# 인증 토큰 발급
ka.auth()
trenv = ka.getTREnv()
# case1 조회
logging.info("=== case1 조회 ===")
try:
result1, result2 = inquire_balance_valuation_pl(cano=trenv.my_acct, acnt_prdt_cd=trenv.my_prod, mgna_dvsn="01",
excc_stat_cd="1")
except ValueError as e:
logging.error("에러 발생: %s" % str(e))
return
# output1 처리
logging.info("=== output1 결과 ===")
logging.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)
logging.info("결과:")
print(result1)
# output2 처리
logging.info("=== output2 결과 ===")
logging.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)
logging.info("결과:")
print(result2)
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,129 @@
"""
Created on 20250601
"""
import sys
import time
from typing import Optional, Tuple
import logging
import pandas as pd
sys.path.extend(['../..', '.'])
import kis_auth as ka
# 로깅 설정
logging.basicConfig(level=logging.INFO)
##############################################################################################
# [국내선물옵션] 주문/계좌 > 선물옵션 잔고평가손익내역[v1_국내선물-015]
##############################################################################################
# 상수 정의
API_URL = "/uapi/domestic-futureoption/v1/trading/inquire-balance-valuation-pl"
def inquire_balance_valuation_pl(
cano: str, # [필수] 종합계좌번호 (ex. 계좌번호 체계(8-2)의 앞 8자리)
acnt_prdt_cd: str, # [필수] 계좌상품코드 (ex. 계좌번호 체계(8-2)의 뒤 2자리)
mgna_dvsn: str, # [필수] 증거금구분 (ex. 01:개시, 02:유지)
excc_stat_cd: str, # [필수] 정산상태코드 (ex. 1:정산, 2:본정산)
FK200: str = "", # 연속조회검색조건200 (ex. 연속조회검색조건200)
NK200: str = "", # 연속조회키200 (ex. 연속조회키200)
tr_cont: str = "", # 연속거래여부
dataframe1: Optional[pd.DataFrame] = None, # 누적 데이터프레임 (output1)
dataframe2: Optional[pd.DataFrame] = None, # 누적 데이터프레임 (output2)
depth: int = 0, # 내부 재귀깊이 (자동관리)
max_depth: int = 10 # 최대 재귀 횟수 제한
) -> Tuple[pd.DataFrame, pd.DataFrame]:
"""
시장별 투자자매매동향(일별) API입니다.
한국투자 HTS(eFriend Plus) > [0404] 시장별 일별동향 화면의 기능을 API로 개발한 사항으로, 해당 화면을 참고하시면 기능을 이해하기 쉽습니다.
Args:
cano (str): [필수] 종합계좌번호 (ex. 계좌번호 체계(8-2)의 앞 8자리)
acnt_prdt_cd (str): [필수] 계좌상품코드 (ex. 계좌번호 체계(8-2)의 뒤 2자리)
mgna_dvsn (str): [필수] 증거금구분 (ex. 01:개시, 02:유지)
excc_stat_cd (str): [필수] 정산상태코드 (ex. 1:정산, 2:본정산)
FK200 (str): 연속조회검색조건200 (ex. 연속조회검색조건200)
NK200 (str): 연속조회키200 (ex. 연속조회키200)
tr_cont (str): 연속거래여부
dataframe1 (Optional[pd.DataFrame]): 누적 데이터프레임 (output1)
dataframe2 (Optional[pd.DataFrame]): 누적 데이터프레임 (output2)
depth (int): 내부 재귀깊이 (자동관리)
max_depth (int): 최대 재귀 횟수 제한
Returns:
Tuple[pd.DataFrame, pd.DataFrame]: (output1 데이터프레임, output2 데이터프레임)
Example:
>>> df1, df2 = inquire_balance_valuation_pl(cano=trenv.my_acct, acnt_prdt_cd=trenv.my_prod, mgna_dvsn="01", excc_stat_cd="1")
>>> print(df1)
>>> print(df2)
"""
if cano == "":
raise ValueError("cano is required (e.g. '계좌번호 체계(8-2)의 앞 8자리')")
if acnt_prdt_cd == "":
raise ValueError("acnt_prdt_cd is required (e.g. '계좌번호 체계(8-2)의 뒤 2자리')")
if mgna_dvsn == "":
raise ValueError("mgna_dvsn is required (e.g. '01:개시, 02:유지')")
if excc_stat_cd == "":
raise ValueError("excc_stat_cd is required (e.g. '1:정산, 2:본정산')")
if depth > max_depth:
logging.warning("Max recursive depth reached.")
if dataframe1 is None:
dataframe1 = pd.DataFrame()
if dataframe2 is None:
dataframe2 = pd.DataFrame()
return dataframe1, dataframe2
tr_id = "CTFO6159R" # 선물옵션 잔고평가손익내역
params = {
"CANO": cano,
"ACNT_PRDT_CD": acnt_prdt_cd,
"MGNA_DVSN": mgna_dvsn,
"EXCC_STAT_CD": excc_stat_cd,
"CTX_AREA_FK200": FK200,
"CTX_AREA_NK200": NK200
}
res = ka._url_fetch(API_URL, tr_id, tr_cont, params)
if res.isOK():
# output1 처리 (array)
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 처리 (object)
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
tr_cont = res.getHeader().tr_cont
FK200 = res.getBody().ctx_area_fk200
NK200 = res.getBody().ctx_area_nk200
if tr_cont in ["M", "F"]: # 다음 페이지 존재
logging.info("Call Next page...")
ka.smart_sleep() # 시스템 안정적 운영을 위한 지연
return inquire_balance_valuation_pl(
cano, acnt_prdt_cd, mgna_dvsn, excc_stat_cd, FK200, NK200, "N", dataframe1, dataframe2, depth + 1,
max_depth
)
else:
logging.info("Data fetch complete.")
return dataframe1, dataframe2
else:
res.printError(url=API_URL)
return pd.DataFrame(), pd.DataFrame()

View File

@@ -0,0 +1,128 @@
"""
Created on 20250601
"""
import sys
import logging
import pandas as pd
sys.path.extend(['../..', '.'])
import kis_auth as ka
from inquire_ccnl import inquire_ccnl
# 로깅 설정
logging.basicConfig(level=logging.INFO)
##############################################################################################
# [국내선물옵션] 주문/계좌 > 선물옵션 주문체결내역조회[v1_국내선물-003]
##############################################################################################
COLUMN_MAPPING = {
'ord_gno_brno': '주문채번지점번호',
'cano': '종합계좌번호',
'csac_name': '종합계좌명',
'acnt_prdt_cd': '계좌상품코드',
'ord_dt': '주문일자',
'odno': '주문번호',
'orgn_odno': '원주문번호',
'sll_buy_dvsn_cd': '매도매수구분코드',
'trad_dvsn_name': '매매구분명',
'nmpr_type_cd': '호가유형코드',
'nmpr_type_name': '호가유형명',
'pdno': '상품번호',
'prdt_name': '상품명',
'prdt_type_cd': '상품유형코드',
'ord_qty': '주문수량',
'ord_idx': '주문지수',
'qty': '잔량',
'ord_tmd': '주문시각',
'tot_ccld_qty': '총체결수량',
'avg_idx': '평균지수',
'tot_ccld_amt': '총체결금액',
'rjct_qty': '거부수량',
'ingr_trad_rjct_rson_cd': '장내매매거부사유코드',
'ingr_trad_rjct_rson_name': '장내매매거부사유명',
'ord_stfno': '주문직원번호',
'sprd_item_yn': '스프레드종목여부',
'ord_ip_addr': '주문IP주소',
'tot_ord_qty': '총주문수량',
'tot_ccld_amt_smtl': '총체결금액합계',
'tot_ccld_qty_smtl': '총체결수량합계',
'fee_smtl': '수수료합계',
'ctac_tlno': '연락전화번호'
}
NUMERIC_COLUMNS = []
def main():
"""
선물옵션 주문체결내역조회 테스트 함수
이 함수는 선물옵션 주문체결내역조회 API를 호출하여 결과를 출력합니다.
Returns:
None
"""
# pandas 출력 옵션 설정
pd.set_option('display.max_columns', None) # 모든 컬럼 표시
pd.set_option('display.width', None) # 출력 너비 제한 해제
pd.set_option('display.max_rows', None) # 모든 행 표시
# 인증 토큰 발급
ka.auth()
trenv = ka.getTREnv()
# case1 조회
logging.info("=== case1 조회 ===")
try:
result1, result2 = inquire_ccnl(
env_dv="real",
cano=trenv.my_acct,
acnt_prdt_cd=trenv.my_prod,
strt_ord_dt="20220730",
end_ord_dt="20220830",
sll_buy_dvsn_cd="00",
ccld_nccs_dvsn="00",
sort_sqn="DS"
)
except ValueError as e:
logging.error("에러 발생: %s" % str(e))
return
# output1 결과 처리
logging.info("=== output1 결과 ===")
logging.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)
logging.info("결과:")
print(result1)
# output2 결과 처리
logging.info("=== output2 결과 ===")
logging.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)
logging.info("결과:")
print(result2)
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,172 @@
"""
Created on 20250601
"""
import sys
import time
from typing import Optional, Tuple
import logging
import pandas as pd
sys.path.extend(['../..', '.'])
import kis_auth as ka
# 로깅 설정
logging.basicConfig(level=logging.INFO)
##############################################################################################
# [국내선물옵션] 주문/계좌 > 선물옵션 주문체결내역조회[v1_국내선물-003]
##############################################################################################
# 상수 정의
API_URL = "/uapi/domestic-futureoption/v1/trading/inquire-ccnl"
def inquire_ccnl(
env_dv: str, # [필수] 실전모의구분 (ex. real:실전, demo:모의)
cano: str, # [필수] 종합계좌번호
acnt_prdt_cd: str, # [필수] 계좌상품코드 (ex. 03)
strt_ord_dt: str, # [필수] 시작주문일자 (ex. 주문내역 조회 시작 일자, YYYYMMDD)
end_ord_dt: str, # [필수] 종료주문일자 (ex. 주문내역 조회 마지막 일자, YYYYMMDD)
sll_buy_dvsn_cd: str, # [필수] 매도매수구분코드 (ex. 00:전체, 01:매도, 02:매수)
ccld_nccs_dvsn: str, # [필수] 체결미체결구분 (ex. 00:전체, 01:체결, 02:미체결)
sort_sqn: str, # [필수] 정렬순서 (ex. AS:정순, DS:역순)
pdno: str = "", # 상품번호
strt_odno: str = "", # 시작주문번호
mket_id_cd: str = "", # 시장ID코드
FK200: str = "", # 연속조회검색조건200
NK200: str = "", # 연속조회키200
tr_cont: str = "", # 연속거래여부
dataframe1: Optional[pd.DataFrame] = None, # 누적 데이터프레임1
dataframe2: Optional[pd.DataFrame] = None, # 누적 데이터프레임2
depth: int = 0, # 내부 재귀깊이 (자동관리)
max_depth: int = 10 # 최대 재귀 횟수 제한
) -> Tuple[pd.DataFrame, pd.DataFrame]:
"""
선물옵션 주문체결내역조회 API입니다. 한 번의 호출에 최대 100건까지 확인 가능하며, 이후의 값은 연속조회를 통해 확인하실 수 있습니다.
Args:
env_dv (str): [필수] 실전모의구분 (ex. real:실전, demo:모의)
cano (str): [필수] 종합계좌번호
acnt_prdt_cd (str): [필수] 계좌상품코드 (ex. 03)
strt_ord_dt (str): [필수] 시작주문일자 (ex. 주문내역 조회 시작 일자, YYYYMMDD)
end_ord_dt (str): [필수] 종료주문일자 (ex. 주문내역 조회 마지막 일자, YYYYMMDD)
sll_buy_dvsn_cd (str): [필수] 매도매수구분코드 (ex. 00:전체, 01:매도, 02:매수)
ccld_nccs_dvsn (str): [필수] 체결미체결구분 (ex. 00:전체, 01:체결, 02:미체결)
sort_sqn (str): [필수] 정렬순서 (ex. AS:정순, DS:역순)
pdno (str, optional): 상품번호. Defaults to "".
strt_odno (str, optional): 시작주문번호. Defaults to "".
mket_id_cd (str, optional): 시장ID코드. Defaults to "".
FK200 (str, optional): 연속조회검색조건200. Defaults to "".
NK200 (str, optional): 연속조회키200. Defaults to "".
tr_cont (str, optional): 연속거래여부. Defaults to "".
dataframe1 (Optional[pd.DataFrame], optional): 누적 데이터프레임1. Defaults to None.
dataframe2 (Optional[pd.DataFrame], optional): 누적 데이터프레임2. Defaults to None.
depth (int, optional): 내부 재귀깊이 (자동관리). Defaults to 0.
max_depth (int, optional): 최대 재귀 횟수 제한. Defaults to 10.
Returns:
Tuple[pd.DataFrame, pd.DataFrame]: 주문체결내역 데이터 (output1, output2)
Example:
>>> df1, df2 = inquire_ccnl(env_dv="real", cano=trenv.my_acct, acnt_prdt_cd=trenv.my_prod, strt_ord_dt="20220730", end_ord_dt="20220830", sll_buy_dvsn_cd="00", ccld_nccs_dvsn="00", sort_sqn="DS")
>>> print(df1)
>>> print(df2)
"""
# 필수 파라미터 검증
if not env_dv:
raise ValueError("env_dv is required (e.g. 'real' or 'demo')")
if not cano:
raise ValueError("cano is required")
if not acnt_prdt_cd:
raise ValueError("acnt_prdt_cd is required (e.g. '03')")
if not strt_ord_dt:
raise ValueError("strt_ord_dt is required (e.g. '20220730')")
if not end_ord_dt:
raise ValueError("end_ord_dt is required (e.g. '20220830')")
if not sll_buy_dvsn_cd:
raise ValueError("sll_buy_dvsn_cd is required (e.g. '00')")
if not ccld_nccs_dvsn:
raise ValueError("ccld_nccs_dvsn is required (e.g. '00')")
if not sort_sqn:
raise ValueError("sort_sqn is required (e.g. 'AS' or 'DS')")
# 재귀 깊이 제한 확인
if depth > max_depth:
logging.warning("Max recursive depth reached.")
if dataframe1 is None:
dataframe1 = pd.DataFrame()
if dataframe2 is None:
dataframe2 = pd.DataFrame()
return dataframe1, dataframe2
# tr_id 설정
if env_dv == "real":
tr_id = "TTTO5201R"
elif env_dv == "demo":
tr_id = "VTTO5201R"
else:
raise ValueError("env_dv can only be 'real' or 'demo'")
# 파라미터 설정
params = {
"CANO": cano,
"ACNT_PRDT_CD": acnt_prdt_cd,
"STRT_ORD_DT": strt_ord_dt,
"END_ORD_DT": end_ord_dt,
"SLL_BUY_DVSN_CD": sll_buy_dvsn_cd,
"CCLD_NCCS_DVSN": ccld_nccs_dvsn,
"SORT_SQN": sort_sqn,
"PDNO": pdno,
"STRT_ODNO": strt_odno,
"MKET_ID_CD": mket_id_cd,
"CTX_AREA_FK200": FK200,
"CTX_AREA_NK200": NK200
}
res = ka._url_fetch(API_URL, tr_id, tr_cont, params)
if res.isOK():
# 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, index=[0])
if dataframe2 is not None:
dataframe2 = pd.concat([dataframe2, current_data2], ignore_index=True)
else:
dataframe2 = current_data2
# 연속조회 정보 업데이트
tr_cont = res.getHeader().tr_cont
FK200 = res.getBody().ctx_area_fk200
NK200 = res.getBody().ctx_area_nk200
if tr_cont in ["M", "F"]: # 다음 페이지 존재
logging.info("Call Next page...")
ka.smart_sleep() # 시스템 안정적 운영을 위한 지연
return inquire_ccnl(
env_dv, cano, acnt_prdt_cd, strt_ord_dt, end_ord_dt,
sll_buy_dvsn_cd, ccld_nccs_dvsn, sort_sqn, pdno, strt_odno,
mket_id_cd, FK200, NK200, "N", dataframe1, dataframe2,
depth + 1, max_depth
)
else:
logging.info("Data fetch complete.")
return dataframe1, dataframe2
else:
res.printError(url=API_URL)
return pd.DataFrame(), pd.DataFrame()

View File

@@ -0,0 +1,108 @@
"""
Created on 20250601
"""
import sys
import logging
import pandas as pd
sys.path.extend(['../..', '.'])
import kis_auth as ka
from inquire_ccnl_bstime import inquire_ccnl_bstime
# 로깅 설정
logging.basicConfig(level=logging.INFO)
##############################################################################################
# [국내선물옵션] 주문/계좌 > 선물옵션 기준일체결내역[v1_국내선물-016]
##############################################################################################
COLUMN_MAPPING = {
'pdno': '상품번호',
'prdt_name': '상품명',
'odno': '주문번호',
'tr_type_name': '거래유형명',
'last_sttldt': '최종결제일',
'ccld_idx': '체결지수',
'ccld_qty': '체결량',
'trad_amt': '매매금액',
'fee': '수수료',
'ccld_btwn': '체결시간',
'tot_ccld_qty_smtl': '총체결수량합계',
'tot_ccld_amt_smtl': '총체결금액합계',
'fee_adjt': '수수료조정',
'fee_smtl': '수수료합계'
}
NUMERIC_COLUMNS = []
def main():
"""
선물옵션 기준일체결내역 조회 테스트 함수
이 함수는 선물옵션 기준일체결내역 API를 호출하여 결과를 출력합니다.
Returns:
None
"""
# pandas 출력 옵션 설정
pd.set_option('display.max_columns', None) # 모든 컬럼 표시
pd.set_option('display.width', None) # 출력 너비 제한 해제
pd.set_option('display.max_rows', None) # 모든 행 표시
# 인증 토큰 발급
ka.auth()
trenv = ka.getTREnv()
# case1 조회
logging.info("=== case1 조회 ===")
try:
result1, result2 = inquire_ccnl_bstime(
cano=trenv.my_acct,
acnt_prdt_cd=trenv.my_prod,
ord_dt="20230920",
fuop_tr_strt_tmd="000000",
fuop_tr_end_tmd="240000"
)
except ValueError as e:
logging.error("에러 발생: %s" % str(e))
return
# output1 처리
logging.info("=== output1 결과 ===")
logging.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)
logging.info("결과:")
print(result1)
# output2 처리
logging.info("=== output2 결과 ===")
logging.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)
logging.info("결과:")
print(result2)
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,134 @@
"""
Created on 20250601
"""
import sys
import time
from typing import Optional, Tuple
import logging
import pandas as pd
sys.path.extend(['../..', '.'])
import kis_auth as ka
# 로깅 설정
logging.basicConfig(level=logging.INFO)
##############################################################################################
# [국내선물옵션] 주문/계좌 > 선물옵션 기준일체결내역[v1_국내선물-016]
##############################################################################################
# 상수 정의
API_URL = "/uapi/domestic-futureoption/v1/trading/inquire-ccnl-bstime"
def inquire_ccnl_bstime(
cano: str, # [필수] 종합계좌번호
acnt_prdt_cd: str, # [필수] 계좌상품코드 (ex. 03)
ord_dt: str, # [필수] 주문일자 (ex. 20250101)
fuop_tr_strt_tmd: str, # [필수] 선물옵션거래시작시각 (ex. HHMMSS)
fuop_tr_end_tmd: str, # [필수] 선물옵션거래종료시각 (ex. HHMMSS)
FK200: str = "", # 연속조회검색조건200
NK200: str = "", # 연속조회키200
tr_cont: str = "", # 연속거래여부
dataframe1: Optional[pd.DataFrame] = None, # 누적 데이터프레임1
dataframe2: Optional[pd.DataFrame] = None, # 누적 데이터프레임2
depth: int = 0, # 내부 재귀깊이 (자동관리)
max_depth: int = 10 # 최대 재귀 횟수 제한
) -> Tuple[pd.DataFrame, pd.DataFrame]:
"""
선물옵션 기준일체결내역 API입니다.
Args:
cano (str): [필수] 종합계좌번호
acnt_prdt_cd (str): [필수] 계좌상품코드 (ex. 03)
ord_dt (str): [필수] 주문일자 (ex. 20250101)
fuop_tr_strt_tmd (str): [필수] 선물옵션거래시작시각 (ex. HHMMSS)
fuop_tr_end_tmd (str): [필수] 선물옵션거래종료시각 (ex. HHMMSS)
FK200 (str): 연속조회검색조건200
NK200 (str): 연속조회키200
tr_cont (str): 연속거래여부
dataframe1 (Optional[pd.DataFrame]): 누적 데이터프레임1
dataframe2 (Optional[pd.DataFrame]): 누적 데이터프레임2
depth (int): 내부 재귀깊이 (자동관리)
max_depth (int): 최대 재귀 횟수 제한
Returns:
Tuple[pd.DataFrame, pd.DataFrame]: 선물옵션 기준일체결내역 데이터 (output1, output2)
Example:
>>> df1, df2 = inquire_ccnl_bstime(cano=trenv.my_acct, acnt_prdt_cd=trenv.my_prod, ord_dt="20230920", fuop_tr_strt_tmd="000000", fuop_tr_end_tmd="240000")
>>> print(df1)
>>> print(df2)
"""
if cano == "":
raise ValueError("cano is required")
if acnt_prdt_cd == "":
raise ValueError("acnt_prdt_cd is required (e.g. '03')")
if ord_dt == "":
raise ValueError("ord_dt is required (e.g. '20250101')")
if fuop_tr_strt_tmd == "":
raise ValueError("fuop_tr_strt_tmd is required (e.g. 'HHMMSS')")
if fuop_tr_end_tmd == "":
raise ValueError("fuop_tr_end_tmd is required (e.g. 'HHMMSS')")
if depth > max_depth:
logging.warning("Max recursive depth reached.")
if dataframe1 is None:
dataframe1 = pd.DataFrame()
if dataframe2 is None:
dataframe2 = pd.DataFrame()
return dataframe1, dataframe2
tr_id = "CTFO5139R"
params = {
"CANO": cano, # 종합계좌번호
"ACNT_PRDT_CD": acnt_prdt_cd, # 계좌상품코드
"ORD_DT": ord_dt, # 주문일자
"FUOP_TR_STRT_TMD": fuop_tr_strt_tmd, # 선물옵션거래시작시각
"FUOP_TR_END_TMD": fuop_tr_end_tmd, # 선물옵션거래종료시각
"CTX_AREA_FK200": FK200, # 연속조회검색조건200
"CTX_AREA_NK200": NK200 # 연속조회키200
}
res = ka._url_fetch(API_URL, tr_id, tr_cont, params)
if res.isOK():
# output1 처리 (array)
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 처리 (object)
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
tr_cont = res.getHeader().tr_cont
FK200 = res.getBody().ctx_area_fk200
NK200 = res.getBody().ctx_area_nk200
if tr_cont in ["M", "F"]: # 다음 페이지 존재
logging.info("Call Next page...")
ka.smart_sleep() # 시스템 안정적 운영을 위한 지연
return inquire_ccnl_bstime(
cano, acnt_prdt_cd, ord_dt, fuop_tr_strt_tmd, fuop_tr_end_tmd,
FK200, NK200, "N", dataframe1, dataframe2, depth + 1, max_depth
)
else:
logging.info("Data fetch complete.")
return dataframe1, dataframe2
else:
res.printError(url=API_URL)
return pd.DataFrame(), pd.DataFrame()

View File

@@ -0,0 +1,127 @@
"""
Created on 20250601
"""
import sys
import logging
import pandas as pd
sys.path.extend(['../..', '.'])
import kis_auth as ka
from inquire_daily_amount_fee import inquire_daily_amount_fee
# 로깅 설정
logging.basicConfig(level=logging.INFO)
##############################################################################################
# [국내선물옵션] 주문/계좌 > 선물옵션기간약정수수료일별[v1_국내선물-017]
##############################################################################################
COLUMN_MAPPING = {
'ord_dt': '주문일자',
'pdno': '상품번호',
'item_name': '종목명',
'sll_agrm_amt': '매도약정금액',
'sll_fee': '매도수수료',
'buy_agrm_amt': '매수약정금액',
'buy_fee': '매수수수료',
'tot_fee_smtl': '총수수료합계',
'trad_pfls': '매매손익',
'futr_agrm': '선물약정',
'futr_agrm_amt': '선물약정금액',
'futr_agrm_amt_smtl': '선물약정금액합계',
'futr_sll_fee_smtl': '선물매도수수료합계',
'futr_buy_fee_smtl': '선물매수수수료합계',
'futr_fee_smtl': '선물수수료합계',
'opt_agrm': '옵션약정',
'opt_agrm_amt': '옵션약정금액',
'opt_agrm_amt_smtl': '옵션약정금액합계',
'opt_sll_fee_smtl': '옵션매도수수료합계',
'opt_buy_fee_smtl': '옵션매수수수료합계',
'opt_fee_smtl': '옵션수수료합계',
'prdt_futr_agrm': '상품선물약정',
'prdt_fuop': '상품선물옵션',
'prdt_futr_evlu_amt': '상품선물평가금액',
'futr_fee': '선물수수료',
'opt_fee': '옵션수수료',
'fee': '수수료',
'sll_agrm_amt': '매도약정금액',
'buy_agrm_amt': '매수약정금액',
'agrm_amt_smtl': '약정금액합계',
'sll_fee': '매도수수료',
'buy_fee': '매수수수료',
'fee_smtl': '수수료합계',
'trad_pfls_smtl': '매매손익합계'
}
NUMERIC_COLUMNS = []
def main():
"""
선물옵션기간약정수수료일별 조회 테스트 함수
이 함수는 선물옵션기간약정수수료일별 API를 호출하여 결과를 출력합니다.
테스트 데이터로 메타데이터에서 제공하는 case1 데이터를 사용합니다.
Returns:
None
"""
# pandas 출력 옵션 설정
pd.set_option('display.max_columns', None) # 모든 컬럼 표시
pd.set_option('display.width', None) # 출력 너비 제한 해제
pd.set_option('display.max_rows', None) # 모든 행 표시
# 인증 토큰 발급
ka.auth()
trenv = ka.getTREnv()
# case1 조회
logging.info("=== case1 조회 ===")
try:
result1, result2 = inquire_daily_amount_fee(
cano=trenv.my_acct,
acnt_prdt_cd=trenv.my_prod,
inqr_strt_day="20240401",
inqr_end_day="20240625"
)
except ValueError as e:
logging.error("에러 발생: %s" % str(e))
return
# output1 블록
logging.info("=== output1 결과 ===")
logging.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)
logging.info("결과:")
print(result1)
# output2 블록
logging.info("=== output2 결과 ===")
logging.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)
logging.info("결과:")
print(result2)
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,127 @@
"""
Created on 20250601
"""
import sys
import time
from typing import Optional, Tuple
import logging
import pandas as pd
sys.path.extend(['../..', '.'])
import kis_auth as ka
# 로깅 설정
logging.basicConfig(level=logging.INFO)
##############################################################################################
# [국내선물옵션] 주문/계좌 > 선물옵션기간약정수수료일별[v1_국내선물-017]
##############################################################################################
# 상수 정의
API_URL = "/uapi/domestic-futureoption/v1/trading/inquire-daily-amount-fee"
def inquire_daily_amount_fee(
cano: str, # [필수] 종합계좌번호
acnt_prdt_cd: str, # [필수] 계좌상품코드 (ex. 03)
inqr_strt_day: str, # [필수] 조회시작일 (ex. 20240401)
inqr_end_day: str, # [필수] 조회종료일 (ex. 20240625)
FK200: str = "", # 연속조회검색조건200
NK200: str = "", # 연속조회키200
tr_cont: str = "", # 연속거래여부
dataframe1: Optional[pd.DataFrame] = None, # 누적 데이터프레임1
dataframe2: Optional[pd.DataFrame] = None, # 누적 데이터프레임2
depth: int = 0, # 내부 재귀깊이 (자동관리)
max_depth: int = 10 # 최대 재귀 횟수 제한
) -> Tuple[pd.DataFrame, pd.DataFrame]:
"""
선물옵션기간약정수수료일별 API입니다.
Args:
cano (str): [필수] 종합계좌번호
acnt_prdt_cd (str): [필수] 계좌상품코드 (ex. 03)
inqr_strt_day (str): [필수] 조회시작일 (ex. 20240401)
inqr_end_day (str): [필수] 조회종료일 (ex. 20240625)
FK200 (str): 연속조회검색조건200
NK200 (str): 연속조회키200
tr_cont (str): 연속거래여부
dataframe1 (Optional[pd.DataFrame]): 누적 데이터프레임1
dataframe2 (Optional[pd.DataFrame]): 누적 데이터프레임2
depth (int): 내부 재귀깊이 (자동관리)
max_depth (int): 최대 재귀 횟수 제한
Returns:
Tuple[pd.DataFrame, pd.DataFrame]: 선물옵션기간약정수수료일별 데이터 (output1, output2)
Example:
>>> df1, df2 = inquire_daily_amount_fee(cano=trenv.my_acct, acnt_prdt_cd=trenv.my_prod, inqr_strt_day="20240401", inqr_end_day="20240625")
>>> print(df1)
>>> print(df2)
"""
if cano == "":
raise ValueError("cano is required")
if acnt_prdt_cd == "":
raise ValueError("acnt_prdt_cd is required")
if inqr_strt_day == "":
raise ValueError("inqr_strt_day is required")
if inqr_end_day == "":
raise ValueError("inqr_end_day is required")
if depth > max_depth:
logging.warning("Max recursive depth reached.")
if dataframe1 is None:
dataframe1 = pd.DataFrame()
if dataframe2 is None:
dataframe2 = pd.DataFrame()
return dataframe1, dataframe2
tr_id = "CTFO6119R" # 선물옵션기간약정수수료일별
params = {
"CANO": cano, # 종합계좌번호
"ACNT_PRDT_CD": acnt_prdt_cd, # 계좌상품코드
"INQR_STRT_DAY": inqr_strt_day, # 조회시작일
"INQR_END_DAY": inqr_end_day, # 조회종료일
"CTX_AREA_FK200": FK200, # 연속조회검색조건200
"CTX_AREA_NK200": NK200 # 연속조회키200
}
res = ka._url_fetch(API_URL, tr_id, tr_cont, params)
if res.isOK():
# output1 (array) 처리
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 (object) 처리
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
tr_cont = res.getHeader().tr_cont
FK200 = res.getBody().ctx_area_fk200
NK200 = res.getBody().ctx_area_nk200
if tr_cont in ["M", "F"]: # 다음 페이지 존재
logging.info("Call Next page...")
ka.smart_sleep() # 시스템 안정적 운영을 위한 지연
return inquire_daily_amount_fee(
cano, acnt_prdt_cd, inqr_strt_day, inqr_end_day, FK200, NK200, "N", dataframe1, dataframe2, depth + 1, max_depth
)
else:
logging.info("Data fetch complete.")
return dataframe1, dataframe2
else:
res.printError(url=API_URL)
return pd.DataFrame(), pd.DataFrame()

View File

@@ -0,0 +1,130 @@
"""
Created on 20250601
"""
import sys
import logging
import pandas as pd
sys.path.extend(['../..', '.'])
import kis_auth as ka
from inquire_daily_fuopchartprice import inquire_daily_fuopchartprice
# 로깅 설정
logging.basicConfig(level=logging.INFO)
##############################################################################################
# [국내선물옵션] 기본시세 > 선물옵션기간별시세(일/주/월/년)[v1_국내선물-008]
##############################################################################################
COLUMN_MAPPING = {
'futs_prdy_vrss': '전일 대비',
'prdy_vrss_sign': '전일 대비 부호',
'futs_prdy_ctrt': '선물 전일 대비율',
'futs_prdy_clpr': '선물 전일 종가',
'acml_vol': '누적 거래량',
'acml_tr_pbmn': '누적 거래 대금',
'hts_kor_isnm': 'HTS 한글 종목명',
'futs_prpr': '현재가',
'futs_shrn_iscd': '단축 종목코드',
'prdy_vol': '전일 거래량',
'futs_mxpr': '상한가',
'futs_llam': '하한가',
'futs_oprc': '시가',
'futs_hgpr': '최고가',
'futs_lwpr': '최저가',
'futs_prdy_oprc': '전일 시가',
'futs_prdy_hgpr': '전일 최고가',
'futs_prdy_lwpr': '전일 최저가',
'futs_askp': '매도호가',
'futs_bidp': '매수호가',
'basis': '베이시스',
'kospi200_nmix': 'KOSPI200 지수',
'kospi200_prdy_vrss': 'KOSPI200 전일 대비',
'kospi200_prdy_ctrt': 'KOSPI200 전일 대비율',
'kospi200_prdy_vrss_sign': '전일 대비 부호',
'hts_otst_stpl_qty': 'HTS 미결제 약정 수량',
'otst_stpl_qty_icdc': '미결제 약정 수량 증감',
'tday_rltv': '당일 체결강도',
'hts_thpr': 'HTS 이론가',
'dprt': '괴리율',
'stck_bsop_date': '영업 일자',
'futs_prpr': '현재가',
'futs_oprc': '시가',
'futs_hgpr': '최고가',
'futs_lwpr': '최저가',
'acml_vol': '누적 거래량',
'acml_tr_pbmn': '누적 거래 대금',
'mod_yn': '변경 여부'
}
NUMERIC_COLUMNS = []
def main():
"""
선물옵션기간별시세 조회 테스트 함수
이 함수는 선물옵션기간별시세 API를 호출하여 결과를 출력합니다.
Returns:
None
"""
# pandas 출력 옵션 설정
pd.set_option('display.max_columns', None) # 모든 컬럼 표시
pd.set_option('display.width', None) # 출력 너비 제한 해제
pd.set_option('display.max_rows', None) # 모든 행 표시
# 인증 토큰 발급
ka.auth()
# case1 조회
logging.info("=== case1 조회 ===")
try:
output1, output2 = inquire_daily_fuopchartprice(
fid_cond_mrkt_div_code="F",
fid_input_iscd="101W09",
fid_input_date_1="20250301",
fid_input_date_2="20250810",
fid_period_div_code="D",
env_dv="real"
)
except ValueError as e:
logging.error("에러 발생: %s" % str(e))
return
# output1 처리
logging.info("=== output1 결과 ===")
logging.info("사용 가능한 컬럼: %s", output1.columns.tolist())
# 컬럼명 한글 변환 및 데이터 출력
output1 = output1.rename(columns=COLUMN_MAPPING)
# 숫자형 컬럼 소수점 둘째자리까지 표시
for col in NUMERIC_COLUMNS:
if col in output1.columns:
output1[col] = pd.to_numeric(output1[col], errors='coerce').round(2)
logging.info("결과:")
print(output1)
# output2 처리
logging.info("=== output2 결과 ===")
logging.info("사용 가능한 컬럼: %s" % output2.columns.tolist())
# 컬럼명 한글 변환 및 데이터 출력
output2 = output2.rename(columns=COLUMN_MAPPING)
# 숫자형 컬럼 소수점 둘째자리까지 표시
for col in NUMERIC_COLUMNS:
if col in output2.columns:
output2[col] = pd.to_numeric(output2[col], errors='coerce').round(2)
logging.info("결과:")
print(output2)
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,109 @@
"""
Created on 20250601
"""
import sys
from typing import Tuple
import logging
import pandas as pd
sys.path.extend(['../..', '.'])
import kis_auth as ka
# 로깅 설정
logging.basicConfig(level=logging.INFO)
##############################################################################################
# [국내선물옵션] 기본시세 > 선물옵션기간별시세(일/주/월/년)[v1_국내선물-008]
##############################################################################################
# 상수 정의
API_URL = "/uapi/domestic-futureoption/v1/quotations/inquire-daily-fuopchartprice"
def inquire_daily_fuopchartprice(
fid_cond_mrkt_div_code: str, # FID 조건 시장 분류 코드
fid_input_iscd: str, # 종목코드
fid_input_date_1: str, # 조회 시작일자
fid_input_date_2: str, # 조회 종료일자
fid_period_div_code: str, # 기간분류코드
env_dv: str # 실전모의구분
) -> Tuple[pd.DataFrame, pd.DataFrame]:
"""
(지수)선물옵션 기간별시세 데이터(일/주/월/년) 조회 (최대 100건 조회)
실전계좌의 경우, 한 번의 호출에 최대 100건까지 확인 가능하며, 이후의 값은 연속조회를 통해 확인하실 수 있습니다.
모의계좌의 경우, 한 번의 호출에 최대 100건까지 확인 가능하며, 이후의 값은 연속조회를 통해 확인하실 수 있습니다.
Args:
fid_cond_mrkt_div_code (str): [필수] FID 조건 시장 분류 코드 (ex. F: 지수선물, O: 지수옵션)
fid_input_iscd (str): [필수] 종목코드 (ex. 101W09)
fid_input_date_1 (str): [필수] 조회 시작일자 (ex. 20220301)
fid_input_date_2 (str): [필수] 조회 종료일자 (ex. 20220810)
fid_period_div_code (str): [필수] 기간분류코드 (ex. D: 일봉, W: 주봉)
env_dv (str): [필수] 실전모의구분 (ex. real:실전, demo:모의)
Returns:
Tuple[pd.DataFrame, pd.DataFrame]: (기본정보, 차트데이터) 튜플
Example:
>>> output1, output2 = inquire_daily_fuopchartprice(
... fid_cond_mrkt_div_code="F",
... fid_input_iscd="101W09",
... fid_input_date_1="20250301",
... fid_input_date_2="20250810",
... fid_period_div_code="D",
... env_dv="real"
... )
>>> print(output1)
>>> print(output2)
"""
# 필수 파라미터 검증
if fid_cond_mrkt_div_code == "":
raise ValueError("fid_cond_mrkt_div_code is required (e.g. 'F: 지수선물, O: 지수옵션')")
if fid_input_iscd == "":
raise ValueError("fid_input_iscd is required (e.g. '101W09')")
if fid_input_date_1 == "":
raise ValueError("fid_input_date_1 is required (e.g. '20250301')")
if fid_input_date_2 == "":
raise ValueError("fid_input_date_2 is required (e.g. '20250810')")
if fid_period_div_code == "":
raise ValueError("fid_period_div_code is required (e.g. 'D: 일봉, W: 주봉')")
if env_dv == "":
raise ValueError("env_dv is required (e.g. 'real:실전, demo:모의')")
# tr_id 설정
if env_dv == "real":
tr_id = "FHKIF03020100"
elif env_dv == "demo":
tr_id = "FHKIF03020100"
else:
raise ValueError("env_dv can only be 'real' or 'demo'")
params = {
"FID_COND_MRKT_DIV_CODE": fid_cond_mrkt_div_code,
"FID_INPUT_ISCD": fid_input_iscd,
"FID_INPUT_DATE_1": fid_input_date_1,
"FID_INPUT_DATE_2": fid_input_date_2,
"FID_PERIOD_DIV_CODE": fid_period_div_code
}
res = ka._url_fetch(API_URL, tr_id, "", params)
if res.isOK():
# output1: object -> DataFrame (1행)
output1_data = pd.DataFrame([res.getBody().output1])
# output2: array -> DataFrame (여러행)
output2_data = pd.DataFrame(res.getBody().output2)
return output1_data, output2_data
else:
res.printError(url=API_URL)
return pd.DataFrame(), pd.DataFrame()

View File

@@ -0,0 +1,102 @@
"""
Created on 20250601
"""
import sys
import logging
import pandas as pd
sys.path.extend(['../..', '.'])
import kis_auth as ka
from inquire_deposit import inquire_deposit
# 로깅 설정
logging.basicConfig(level=logging.INFO)
##############################################################################################
# [국내선물옵션] 주문/계좌 > 선물옵션 총자산현황[v1_국내선물-014]
##############################################################################################
COLUMN_MAPPING = {
'dnca_tota': '예수금총액',
'bfdy_chck_amt': '전일수표금액',
'thdt_chck_amt': '당일수표금액',
'rlth_uwdl_dpos_amt': '실물인수도예치금액',
'brkg_mgna_cash': '위탁증거금현금',
'wdrw_psbl_tot_amt': '인출가능총금액',
'ord_psbl_cash': '주문가능현금',
'ord_psbl_tota': '주문가능총액',
'dnca_sbst': '예수금대용',
'scts_sbst_amt': '유가증권대용금액',
'frcr_evlu_amt': '외화평가금액',
'brkg_mgna_sbst': '위탁증거금대용',
'sbst_rlse_psbl_amt': '대용해제가능금액',
'mtnc_rt': '유지비율',
'add_mgna_tota': '추가증거금총액',
'add_mgna_cash': '추가증거금현금',
'rcva': '미수금',
'futr_trad_pfls': '선물매매손익',
'opt_trad_pfls_amt': '옵션매매손익금액',
'trad_pfls_smtl': '매매손익합계',
'futr_evlu_pfls_amt': '선물평가손익금액',
'opt_evlu_pfls_amt': '옵션평가손익금액',
'evlu_pfls_smtl': '평가손익합계',
'excc_dfpa': '정산차금',
'opt_dfpa': '옵션차금',
'brkg_fee': '위탁수수료',
'nxdy_dnca': '익일예수금',
'prsm_dpast_amt': '추정예탁자산금액',
'cash_mntn_amt': '현금유지금액',
'hack_acdt_acnt_move_amt': '해킹사고계좌이전금액'
}
NUMERIC_COLUMNS = []
def main():
"""
선물옵션 총자산현황 조회 테스트 함수
이 함수는 선물옵션 총자산현황 API를 호출하여 결과를 출력합니다.
Returns:
None
"""
# pandas 출력 옵션 설정
pd.set_option('display.max_columns', None) # 모든 컬럼 표시
pd.set_option('display.width', None) # 출력 너비 제한 해제
pd.set_option('display.max_rows', None) # 모든 행 표시
# 인증 토큰 발급
ka.auth()
trenv = ka.getTREnv()
# case1 조회
logging.info("=== case1 조회 ===")
try:
result = inquire_deposit(cano=trenv.my_acct, acnt_prdt_cd=trenv.my_prod)
except ValueError as e:
logging.error("에러 발생: %s" % str(e))
return
logging.info("사용 가능한 컬럼: %s", 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').round(2)
logging.info("결과:")
print(result)
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,64 @@
"""
Created on 20250601
"""
import sys
import logging
import pandas as pd
sys.path.extend(['../..', '.'])
import kis_auth as ka
# 로깅 설정
logging.basicConfig(level=logging.INFO)
##############################################################################################
# [국내선물옵션] 주문/계좌 > 선물옵션 총자산현황[v1_국내선물-014]
##############################################################################################
# 상수 정의
API_URL = "/uapi/domestic-futureoption/v1/trading/inquire-deposit"
def inquire_deposit(
cano: str, # [필수] 종합계좌번호
acnt_prdt_cd: str # [필수] 계좌상품코드 (ex. 03)
) -> pd.DataFrame:
"""
선물옵션 총자산현황 API 입니다.
Args:
cano (str): [필수] 종합계좌번호
acnt_prdt_cd (str): [필수] 계좌상품코드 (ex. 03)
Returns:
pd.DataFrame: 선물옵션 총자산현황 데이터
Example:
>>> df = inquire_deposit(cano=trenv.my_acct, acnt_prdt_cd=trenv.my_prod)
>>> print(df)
"""
if cano == "":
raise ValueError("cano is required")
if acnt_prdt_cd == "":
raise ValueError("acnt_prdt_cd is required")
tr_id = "CTRP6550R" # 선물옵션 총자산현황
params = {
"CANO": cano, # 종합계좌번호
"ACNT_PRDT_CD": acnt_prdt_cd # 계좌상품코드
}
res = ka._url_fetch(API_URL, tr_id, "", params)
if res.isOK():
current_data = pd.DataFrame([res.getBody().output])
logging.info("Data fetch complete.")
return current_data
else:
res.printError(url=API_URL)
return pd.DataFrame()

View File

@@ -0,0 +1,144 @@
"""
Created on 20250601
"""
import sys
import logging
import pandas as pd
sys.path.extend(['../..', '.'])
import kis_auth as ka
from inquire_ngt_balance import inquire_ngt_balance
# 로깅 설정
logging.basicConfig(level=logging.INFO)
##############################################################################################
# [국내선물옵션] 주문/계좌 > (야간)선물옵션 잔고현황 [국내선물-010]
##############################################################################################
COLUMN_MAPPING = {
'cano': '종합계좌번호',
'acnt_prdt_cd': '계좌상품코드',
'pdno': '상품번호',
'prdt_type_cd': '상품유형코드',
'shtn_pdno': '단축상품번호',
'prdt_name': '상품명',
'sll_buy_dvsn_name': '매도매수구분명',
'sll_buy_dvsn_cd': '매도매수구분코드',
'trad_dvsn_name': '매매구분명',
'cblc_qty': '잔고수량',
'excc_unpr': '정산단가',
'ccld_avg_unpr1': '체결평균단가1',
'idx_clpr': '지수종가',
'pchs_amt': '매입금액',
'evlu_amt': '평가금액',
'evlu_pfls_amt': '평가손익금액',
'trad_pfls_amt': '매매손익금액',
'lqd_psbl_qty': '청산가능수량',
'dnca_cash': '예수금현금',
'frcr_dncl_amt': '외화예수금액',
'dnca_sbst': '예수금대용',
'tot_dncl_amt': '총예수금액',
'cash_mgna': '현금증거금',
'sbst_mgna': '대용증거금',
'mgna_tota': '증거금총액',
'opt_dfpa': '옵션차금',
'thdt_dfpa': '당일차금',
'rnwl_dfpa': '갱신차금',
'fee': '수수료',
'nxdy_dnca': '익일예수금',
'nxdy_dncl_amt': '익일예수금액',
'prsm_dpast': '추정예탁자산',
'pprt_ord_psbl_cash': '적정주문가능현금',
'add_mgna_cash': '추가증거금현금',
'add_mgna_tota': '추가증거금총액',
'futr_trad_pfls_amt': '선물매매손익금액',
'opt_trad_pfls_amt': '옵션매매손익금액',
'futr_evlu_pfls_amt': '선물평가손익금액',
'opt_evlu_pfls_amt': '옵션평가손익금액',
'trad_pfls_amt_smtl': '매매손익금액합계',
'evlu_pfls_amt_smtl': '평가손익금액합계',
'wdrw_psbl_tot_amt': '인출가능총금액',
'ord_psbl_cash': '주문가능현금',
'ord_psbl_sbst': '주문가능대용',
'ord_psbl_tota': '주문가능총액',
'mmga_tot_amt': '유지증거금총금액',
'mmga_cash_amt': '유지증거금현금금액',
'mtnc_rt': '유지비율',
'isfc_amt': '부족금액',
'pchs_amt_smtl': '매입금액합계',
'evlu_amt_smtl': '평가금액합계'
}
NUMERIC_COLUMNS = []
def main():
"""
(야간)선물옵션 잔고현황 조회 테스트 함수
이 함수는 (야간)선물옵션 잔고현황 API를 호출하여 결과를 출력합니다.
Returns:
None
"""
# pandas 출력 옵션 설정
pd.set_option('display.max_columns', None) # 모든 컬럼 표시
pd.set_option('display.width', None) # 출력 너비 제한 해제
pd.set_option('display.max_rows', None) # 모든 행 표시
# 인증 토큰 발급
ka.auth()
trenv = ka.getTREnv()
# Case 1 조회
logging.info("=== Case 1 조회 ===")
try:
result1, result2 = inquire_ngt_balance(
cano=trenv.my_acct,
acnt_prdt_cd=trenv.my_prod,
mgna_dvsn="01",
excc_stat_cd="1"
)
except ValueError as e:
logging.error("에러 발생: %s" % str(e))
return
# output1 결과 처리
logging.info("=== output1 결과 ===")
logging.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)
logging.info("결과:")
print(result1)
# output2 결과 처리
logging.info("=== output2 결과 ===")
logging.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)
logging.info("결과:")
print(result2)
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,131 @@
"""
Created on 20250601
"""
import sys
import time
from typing import Optional, Tuple
import logging
import pandas as pd
sys.path.extend(['../..', '.'])
import kis_auth as ka
# 로깅 설정
logging.basicConfig(level=logging.INFO)
##############################################################################################
# [국내선물옵션] 주문/계좌 > (야간)선물옵션 잔고현황 [국내선물-010]
##############################################################################################
# 상수 정의
API_URL = "/uapi/domestic-futureoption/v1/trading/inquire-ngt-balance"
def inquire_ngt_balance(
cano: str, # 종합계좌번호
acnt_prdt_cd: str, # 계좌상품코드
mgna_dvsn: str, # 증거금구분
excc_stat_cd: str, # 정산상태코드
acnt_pwd: str = "", # 계좌비밀번호
FK200: str = "", # 연속조회검색조건200
NK200: str = "", # 연속조회키200
tr_cont: str = "", # 연속거래여부
dataframe1: Optional[pd.DataFrame] = None, # 누적 데이터프레임1
dataframe2: Optional[pd.DataFrame] = None, # 누적 데이터프레임2
depth: int = 0, # 내부 재귀깊이 (자동관리)
max_depth: int = 10 # 최대 재귀 횟수 제한
) -> Tuple[pd.DataFrame, pd.DataFrame]:
"""
(야간)선물옵션 잔고현황 API입니다.
Args:
cano (str): [필수] 종합계좌번호 (ex. 계좌번호 체계(8-2)의 앞 8자리)
acnt_prdt_cd (str): [필수] 계좌상품코드 (ex. 계좌번호 체계(8-2)의 뒤 2자리)
mgna_dvsn (str): [필수] 증거금구분 (ex. 01:개시, 02:유지)
excc_stat_cd (str): [필수] 정산상태코드 (ex. 1:정산, 2:본정산)
acnt_pwd (str): 계좌비밀번호
FK200 (str): 연속조회검색조건200
NK200 (str): 연속조회키200
tr_cont (str): 연속거래여부
dataframe1 (Optional[pd.DataFrame]): 누적 데이터프레임1
dataframe2 (Optional[pd.DataFrame]): 누적 데이터프레임2
depth (int): 내부 재귀깊이 (자동관리)
max_depth (int): 최대 재귀 횟수 제한
Returns:
Tuple[pd.DataFrame, pd.DataFrame]: (output1 데이터, output2 데이터)
Example:
>>> df1, df2 = inquire_ngt_balance("12345678", "01", "01", "1")
>>> print(df1, df2)
"""
# 필수 파라미터 검증
if cano == "":
raise ValueError("cano is required (e.g. '계좌번호 체계(8-2)의 앞 8자리')")
if acnt_prdt_cd == "":
raise ValueError("acnt_prdt_cd is required (e.g. '계좌번호 체계(8-2)의 뒤 2자리')")
if mgna_dvsn == "":
raise ValueError("mgna_dvsn is required (e.g. '01:개시, 02:유지')")
if excc_stat_cd == "":
raise ValueError("excc_stat_cd is required (e.g. '1:정산, 2:본정산')")
# 재귀 깊이 제한 확인
if depth > max_depth:
logging.warning("Max recursive depth reached.")
return (
dataframe1 if dataframe1 is not None else pd.DataFrame(),
dataframe2 if dataframe2 is not None else pd.DataFrame()
)
tr_id = "CTFN6118R"
params = {
"CANO": cano,
"ACNT_PRDT_CD": acnt_prdt_cd,
"MGNA_DVSN": mgna_dvsn,
"EXCC_STAT_CD": excc_stat_cd,
"ACNT_PWD": acnt_pwd,
"CTX_AREA_FK200": FK200,
"CTX_AREA_NK200": NK200
}
res = ka._url_fetch(API_URL, tr_id, tr_cont, params)
if res.isOK():
# output1 처리 (array)
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 처리 (object)
current_data2 = pd.DataFrame(res.getBody().output2, index=[0])
if dataframe2 is not None:
dataframe2 = pd.concat([dataframe2, current_data2], ignore_index=True)
else:
dataframe2 = current_data2
tr_cont = res.getHeader().tr_cont
FK200 = res.getBody().ctx_area_fk200
NK200 = res.getBody().ctx_area_nk200
if tr_cont in ["M", "F"]: # 다음 페이지 존재
logging.info("Call Next page...")
ka.smart_sleep() # 시스템 안정적 운영을 위한 지연
return inquire_ngt_balance(
cano, acnt_prdt_cd, mgna_dvsn, excc_stat_cd, acnt_pwd,
FK200, NK200, "N", dataframe1, dataframe2, depth + 1, max_depth
)
else:
logging.info("Data fetch complete.")
return (dataframe1, dataframe2)
else:
res.printError(url=API_URL)
return (pd.DataFrame(), pd.DataFrame())

View File

@@ -0,0 +1,122 @@
"""
Created on 20250601
"""
import sys
import logging
import pandas as pd
sys.path.extend(['../..', '.'])
import kis_auth as ka
from inquire_ngt_ccnl import inquire_ngt_ccnl
# 로깅 설정
logging.basicConfig(level=logging.INFO)
##############################################################################################
# [국내선물옵션] 주문/계좌 > (야간)선물옵션 주문체결 내역조회 [국내선물-009]
##############################################################################################
COLUMN_MAPPING = {
'ord_gno_brno': '주문채번지점번호',
'cano': '종합계좌번호',
'csac_name': '종합계좌명',
'acnt_prdt_cd': '계좌상품코드',
'ord_dt': '주문일자',
'odno': '주문번호',
'orgn_odno': '원주문번호',
'sll_buy_dvsn_cd': '매도매수구분코드',
'trad_dvsn_name': '매매구분명',
'nmpr_type_name': '호가유형명',
'pdno': '상품번호',
'prdt_name': '상품명',
'prdt_type_cd': '상품유형코드',
'ord_qty': '주문수량',
'ord_idx4': '주문지수',
'qty': '잔량',
'ord_tmd': '주문시각',
'tot_ccld_qty': '총체결수량',
'avg_idx': '평균지수',
'tot_ccld_amt': '총체결금액',
'rjct_qty': '거부수량',
'ingr_trad_rjct_rson_cd': '장내매매거부사유코드',
'ingr_trad_rjct_rson_name': '장내매매거부사유명',
'ord_stfno': '주문직원번호',
'sprd_item_yn': '스프레드종목여부',
'ord_ip_addr': '주문IP주소',
'tot_ord_qty': '총주문수량',
'tot_ccld_qty': '총체결수량',
'tot_ccld_qty_SMTL': '총체결수량',
'tot_ccld_amt': '총체결금액',
'tot_ccld_amt_SMTL': '총체결금액',
'fee': '수수료',
'ctac_tlno': '연락전화번호'
}
NUMERIC_COLUMNS = []
def main():
"""
(야간)선물옵션 주문체결 내역조회 테스트 함수
이 함수는 (야간)선물옵션 주문체결 내역조회 API를 호출하여 결과를 출력합니다.
Returns:
None
"""
# pandas 출력 옵션 설정
pd.set_option('display.max_columns', None) # 모든 컬럼 표시
pd.set_option('display.width', None) # 출력 너비 제한 해제
pd.set_option('display.max_rows', None) # 모든 행 표시
# 인증 토큰 발급
ka.auth()
trenv = ka.getTREnv()
# case1 조회
logging.info("=== case1 조회 ===")
try:
result1, result2 = inquire_ngt_ccnl(cano=trenv.my_acct, acnt_prdt_cd=trenv.my_prod, strt_ord_dt="20250610",
end_ord_dt="20250613", sll_buy_dvsn_cd="00", ccld_nccs_dvsn="00")
except ValueError as e:
logging.error("에러 발생: %s" % str(e))
return
# output1 처리
logging.info("=== output1 결과 ===")
logging.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)
logging.info("결과:")
print(result1)
# output2 처리
logging.info("=== output2 결과 ===")
logging.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)
logging.info("결과:")
print(result2)
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,164 @@
"""
Created on 20250601
"""
import sys
import time
from typing import Optional, Tuple
import logging
import pandas as pd
sys.path.extend(['../..', '.'])
import kis_auth as ka
# 로깅 설정
logging.basicConfig(level=logging.INFO)
##############################################################################################
# [국내선물옵션] 주문/계좌 > (야간)선물옵션 주문체결 내역조회 [국내선물-009]
##############################################################################################
# 상수 정의
API_URL = "/uapi/domestic-futureoption/v1/trading/inquire-ngt-ccnl"
def inquire_ngt_ccnl(
cano: str, # 종합계좌번호
acnt_prdt_cd: str, # 계좌상품코드
strt_ord_dt: str, # 시작주문일자
end_ord_dt: str, # 종료주문일자
sll_buy_dvsn_cd: str, # 매도매수구분코드
ccld_nccs_dvsn: str, # 체결미체결구분
sort_sqn: str = "", # 정렬순서
strt_odno: str = "", # 시작주문번호
pdno: str = "", # 상품번호
mket_id_cd: str = "", # 시장ID코드
fuop_dvsn_cd: str = "", # 선물옵션구분코드
scrn_dvsn: str = "", # 화면구분
FK200: str = "", # 연속조회검색조건200
NK200: str = "", # 연속조회키200
tr_cont: str = "", # 연속거래여부
dataframe1: Optional[pd.DataFrame] = None, # 누적 데이터프레임1
dataframe2: Optional[pd.DataFrame] = None, # 누적 데이터프레임2
depth: int = 0, # 내부 재귀깊이 (자동관리)
max_depth: int = 10 # 최대 재귀 횟수 제한
) -> Tuple[pd.DataFrame, pd.DataFrame]:
"""
(야간)선물옵션 주문체결 내역조회 API입니다.
Args:
cano (str): [필수] 종합계좌번호 (ex. 계좌번호 체계(8-2)의 앞 8자리)
acnt_prdt_cd (str): [필수] 계좌상품코드 (ex. 계좌번호 체계(8-2)의 뒤 2자리)
strt_ord_dt (str): [필수] 시작주문일자
end_ord_dt (str): [필수] 종료주문일자 (ex. 조회하려는 마지막 일자 다음일자로 조회 (ex. 20221011 까지의 내역을 조회하고자 할 경우, 20221012로 종료주문일자 설정))
sll_buy_dvsn_cd (str): [필수] 매도매수구분코드 (ex. 공란:default, 00:전체, 01:매도, 02:매수)
ccld_nccs_dvsn (str): [필수] 체결미체결구분 (ex. 00:전체, 01:체결, 02:미체결)
sort_sqn (str): 정렬순서 (ex. 공란:default(DS:정순, 그외:역순))
strt_odno (str): 시작주문번호 (ex. 공란:default)
pdno (str): 상품번호 (ex. 공란:default)
mket_id_cd (str): 시장ID코드 (ex. 공란:default)
fuop_dvsn_cd (str): 선물옵션구분코드 (ex. 공란:전체, 01:선물, 02:옵션)
scrn_dvsn (str): 화면구분 (ex. 02(Default))
FK200 (str): 연속조회검색조건200 (ex. 공란:최초 조회시, 이전 조회 Output CTX_AREA_FK200값:다음페이지 조회시(2번째부터))
NK200 (str): 연속조회키200 (ex. 공란:최초 조회시, 이전 조회 Output CTX_AREA_NK200값:다음페이지 조회시(2번째부터))
tr_cont (str): 연속거래여부
dataframe1 (Optional[pd.DataFrame]): 누적 데이터프레임1
dataframe2 (Optional[pd.DataFrame]): 누적 데이터프레임2
depth (int): 내부 재귀깊이 (자동관리)
max_depth (int): 최대 재귀 횟수 제한
Returns:
Tuple[pd.DataFrame, pd.DataFrame]: (output1 데이터, output2 데이터)
Example:
>>> df1, df2 = inquire_ngt_ccnl(cano=trenv.my_acct, acnt_prdt_cd=trenv.my_prod, strt_ord_dt="20231201", end_ord_dt="20231214", sll_buy_dvsn_cd="00", ccld_nccs_dvsn="00")
>>> print(df1)
>>> print(df2)
"""
# 필수 파라미터 검증
if cano == "" or cano is None:
raise ValueError("cano is required (e.g. '계좌번호 체계(8-2)의 앞 8자리')")
if acnt_prdt_cd == "" or acnt_prdt_cd is None:
raise ValueError("acnt_prdt_cd is required (e.g. '계좌번호 체계(8-2)의 뒤 2자리')")
if strt_ord_dt == "" or strt_ord_dt is None:
raise ValueError("strt_ord_dt is required")
if end_ord_dt == "" or end_ord_dt is None:
raise ValueError("end_ord_dt is required (e.g. '조회하려는 마지막 일자 다음일자로 조회 (ex. 20221011 까지의 내역을 조회하고자 할 경우, 20221012로 종료주문일자 설정)')")
if sll_buy_dvsn_cd == "" or sll_buy_dvsn_cd is None:
raise ValueError("sll_buy_dvsn_cd is required (e.g. '공란:default, 00:전체, 01:매도, 02:매수')")
if ccld_nccs_dvsn == "" or ccld_nccs_dvsn is None:
raise ValueError("ccld_nccs_dvsn is required (e.g. '00:전체, 01:체결, 02:미체결')")
if depth > max_depth:
logging.warning("Max recursive depth reached.")
if dataframe1 is None:
dataframe1 = pd.DataFrame()
if dataframe2 is None:
dataframe2 = pd.DataFrame()
return dataframe1, dataframe2
tr_id = "STTN5201R"
params = {
"CANO": cano,
"ACNT_PRDT_CD": acnt_prdt_cd,
"STRT_ORD_DT": strt_ord_dt,
"END_ORD_DT": end_ord_dt,
"SLL_BUY_DVSN_CD": sll_buy_dvsn_cd,
"CCLD_NCCS_DVSN": ccld_nccs_dvsn,
"SORT_SQN": sort_sqn,
"STRT_ODNO": strt_odno,
"PDNO": pdno,
"MKET_ID_CD": mket_id_cd,
"FUOP_DVSN_CD": fuop_dvsn_cd,
"SCRN_DVSN": scrn_dvsn,
"CTX_AREA_FK200": FK200,
"CTX_AREA_NK200": NK200
}
res = ka._url_fetch(API_URL, tr_id, tr_cont, params)
print(res.getBody())
if res.isOK():
# output1 (array) 처리
current_data1 = pd.DataFrame(res.getBody().output1)
# output2 (object) 처리
current_data2 = pd.DataFrame([res.getBody().output2])
if dataframe1 is not None:
dataframe1 = pd.concat([dataframe1, current_data1], ignore_index=True)
else:
dataframe1 = current_data1
if dataframe2 is not None:
dataframe2 = pd.concat([dataframe2, current_data2], ignore_index=True)
else:
dataframe2 = current_data2
tr_cont = res.getHeader().tr_cont
FK200 = res.getBody().ctx_area_fk200
NK200 = res.getBody().ctx_area_nk200
if tr_cont in ["M", "F"]: # 다음 페이지 존재
logging.info("Call Next page...")
ka.smart_sleep() # 시스템 안정적 운영을 위한 지연
return inquire_ngt_ccnl(
cano, acnt_prdt_cd, strt_ord_dt, end_ord_dt, sll_buy_dvsn_cd, ccld_nccs_dvsn,
sort_sqn, strt_odno, pdno, mket_id_cd, fuop_dvsn_cd, scrn_dvsn,
FK200, NK200, "N", dataframe1, dataframe2, depth + 1, max_depth
)
else:
logging.info("Data fetch complete.")
return dataframe1, dataframe2
else:
res.printError(url=API_URL)
return pd.DataFrame(), pd.DataFrame()

View File

@@ -0,0 +1,145 @@
"""
Created on 20250601
"""
import sys
import logging
import pandas as pd
sys.path.extend(['../..', '.'])
import kis_auth as ka
from inquire_price import inquire_price
# 로깅 설정
logging.basicConfig(level=logging.INFO)
##############################################################################################
# [국내선물옵션] 기본시세 > 선물옵션 시세[v1_국내선물-006]
##############################################################################################
COLUMN_MAPPING = {
'hts_kor_isnm': 'HTS 한글 종목명',
'futs_prpr': '선물 현재가',
'futs_prdy_vrss': '선물 전일 대비',
'prdy_vrss_sign': '전일 대비 부호',
'futs_prdy_clpr': '선물 전일 종가',
'futs_prdy_ctrt': '선물 전일 대비율',
'acml_vol': '누적 거래량',
'acml_tr_pbmn': '누적 거래 대금',
'hts_otst_stpl_qty': 'HTS 미결제 약정 수량',
'otst_stpl_qty_icdc': '미결제 약정 수량 증감',
'futs_oprc': '선물 시가2',
'futs_hgpr': '선물 최고가',
'futs_lwpr': '선물 최저가',
'futs_mxpr': '선물 상한가',
'futs_llam': '선물 하한가',
'basis': '베이시스',
'futs_sdpr': '선물 기준가',
'hts_thpr': 'HTS 이론가',
'dprt': '괴리율',
'crbr_aply_mxpr': '서킷브레이커 적용 상한가',
'crbr_aply_llam': '서킷브레이커 적용 하한가',
'futs_last_tr_date': '선물 최종 거래 일자',
'hts_rmnn_dynu': 'HTS 잔존 일수',
'futs_lstn_medm_hgpr': '선물 상장 중 최고가',
'futs_lstn_medm_lwpr': '선물 상장 중 최저가',
'delta_val': '델타 값',
'gama': '감마',
'theta': '세타',
'vega': '베가',
'rho': '로우',
'hist_vltl': '역사적 변동성',
'hts_ints_vltl': 'HTS 내재 변동성',
'mrkt_basis': '시장 베이시스',
'acpr': '행사가',
'bstp_cls_code': '업종 구분 코드',
'hts_kor_isnm': 'HTS 한글 종목명',
'bstp_nmix_prpr': '업종 지수 현재가',
'prdy_vrss_sign': '전일 대비 부호',
'bstp_nmix_prdy_vrss': '업종 지수 전일 대비',
'bstp_nmix_prdy_ctrt': '업종 지수 전일 대비율'
}
NUMERIC_COLUMNS = []
def main():
"""
선물옵션 시세 조회 테스트 함수
이 함수는 선물옵션 시세 API를 호출하여 결과를 출력합니다.
테스트 데이터로 101S09 종목을 사용합니다.
Returns:
None
"""
# pandas 출력 옵션 설정
pd.set_option('display.max_columns', None) # 모든 컬럼 표시
pd.set_option('display.width', None) # 출력 너비 제한 해제
pd.set_option('display.max_rows', None) # 모든 행 표시
# 인증 토큰 발급
ka.auth()
# case1 조회
logging.info("=== case1 조회 ===")
try:
result1, result2, result3 = inquire_price(
fid_cond_mrkt_div_code="F",
fid_input_iscd="101W09",
env_dv="real"
)
except ValueError as e:
logging.error("에러 발생: %s" % str(e))
return
# output1 처리
logging.info("=== output1 결과 ===")
logging.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)
logging.info("결과:")
print(result1)
# output2 처리
logging.info("=== output2 결과 ===")
logging.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)
logging.info("결과:")
print(result2)
# output3 처리
logging.info("=== output3 결과 ===")
logging.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)
logging.info("결과:")
print(result3)
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,91 @@
"""
Created on 20250601
"""
import sys
import logging
from typing import Tuple
import pandas as pd
sys.path.extend(['../..', '.'])
import kis_auth as ka
# 로깅 설정
logging.basicConfig(level=logging.INFO)
##############################################################################################
# [국내선물옵션] 기본시세 > 선물옵션 시세[v1_국내선물-006]
##############################################################################################
# 상수 정의
API_URL = "/uapi/domestic-futureoption/v1/quotations/inquire-price"
def inquire_price(
fid_cond_mrkt_div_code: str, # [필수] FID 조건 시장 분류 코드 (ex. F: 지수선물, O: 지수옵션)
fid_input_iscd: str, # [필수] FID 입력 종목코드 (ex. 101W09)
env_dv: str # [필수] 실전모의구분 (ex. real:실전, demo:모의)
) -> Tuple[pd.DataFrame, pd.DataFrame, pd.DataFrame]:
"""
선물옵션 시세 API입니다.
※ 종목코드 마스터파일 정제코드는 한국투자증권 Github 참고:
https://github.com/koreainvestment/open-trading-api/tree/main/stocks_info
Args:
fid_cond_mrkt_div_code (str): [필수] FID 조건 시장 분류 코드 (ex. F: 지수선물, O: 지수옵션)
fid_input_iscd (str): [필수] FID 입력 종목코드 (ex. 101W09)
env_dv (str): [필수] 실전모의구분 (ex. real:실전, demo:모의)
Returns:
Tuple[pd.DataFrame, pd.DataFrame, pd.DataFrame]: 선물옵션 시세 데이터 (output1, output2, output3)
Example:
>>> result1, result2, result3 = inquire_price(
... fid_cond_mrkt_div_code="F",
... fid_input_iscd="101W09",
... env_dv="real"
... )
>>> print(result1)
"""
# 필수 파라미터 검증
if fid_cond_mrkt_div_code == "":
raise ValueError("fid_cond_mrkt_div_code is required (e.g. 'F', 'O')")
if fid_input_iscd == "":
raise ValueError("fid_input_iscd is required (e.g. '101W09')")
if env_dv == "":
raise ValueError("env_dv is required (e.g. 'real', 'demo')")
# tr_id 설정
if env_dv == "real":
tr_id = "FHMIF10000000"
elif env_dv == "demo":
tr_id = "FHMIF10000000"
else:
raise ValueError("env_dv can only be real or demo")
params = {
"FID_COND_MRKT_DIV_CODE": fid_cond_mrkt_div_code,
"FID_INPUT_ISCD": fid_input_iscd
}
res = ka._url_fetch(API_URL, tr_id, "", params)
if res.isOK():
# output1 처리
output1 = pd.DataFrame(res.getBody().output1, index=[0])
# output2 처리
output2 = pd.DataFrame(res.getBody().output2, index=[0])
# output3 처리
output3 = pd.DataFrame(res.getBody().output3, index=[0])
return output1, output2, output3
else:
res.printError(url=API_URL)
return pd.DataFrame(), pd.DataFrame(), pd.DataFrame()

View File

@@ -0,0 +1,84 @@
"""
Created on 20250601
"""
import sys
import logging
import pandas as pd
sys.path.extend(['../..', '.'])
import kis_auth as ka
from inquire_psbl_ngt_order import inquire_psbl_ngt_order
# 로깅 설정
logging.basicConfig(level=logging.INFO)
##############################################################################################
# [국내선물옵션] 주문/계좌 > (야간)선물옵션 주문가능 조회 [국내선물-011]
##############################################################################################
COLUMN_MAPPING = {
'max_ord_psbl_qty': '최대주문가능수량',
'tot_psbl_qty': '최대주문가능수량',
'lqd_psbl_qty': '청산가능수량',
'lqd_psbl_qty_1': '청산가능수량',
'ord_psbl_qty': '주문가능수량',
'bass_idx': '기준지수'
}
NUMERIC_COLUMNS = []
def main():
"""
(야간)선물옵션 주문가능 조회 테스트 함수
이 함수는 (야간)선물옵션 주문가능 조회 API를 호출하여 결과를 출력합니다.
Returns:
None
"""
# pandas 출력 옵션 설정
pd.set_option('display.max_columns', None) # 모든 컬럼 표시
pd.set_option('display.width', None) # 출력 너비 제한 해제
pd.set_option('display.max_rows', None) # 모든 행 표시
# 인증 토큰 발급
ka.auth()
trenv = ka.getTREnv()
# case1 조회
logging.info("=== case1 조회 ===")
try:
result = inquire_psbl_ngt_order(
cano=trenv.my_acct,
acnt_prdt_cd=trenv.my_prod,
pdno="101W09",
prdt_type_cd="301",
sll_buy_dvsn_cd="02",
unit_price="322",
ord_dvsn_cd="01"
)
except ValueError as e:
logging.error("에러 발생: %s" % str(e))
return
logging.info("사용 가능한 컬럼: %s", 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').round(2)
logging.info("결과:")
print(result)
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,94 @@
"""
Created on 20250601
"""
import sys
import logging
import pandas as pd
sys.path.extend(['../..', '.'])
import kis_auth as ka
# 로깅 설정
logging.basicConfig(level=logging.INFO)
##############################################################################################
# [국내선물옵션] 주문/계좌 > (야간)선물옵션 주문가능 조회 [국내선물-011]
##############################################################################################
# 상수 정의
API_URL = "/uapi/domestic-futureoption/v1/trading/inquire-psbl-ngt-order"
def inquire_psbl_ngt_order(
cano: str, # 종합계좌번호
acnt_prdt_cd: str, # 계좌상품코드
pdno: str, # 상품번호
prdt_type_cd: str, # 상품유형코드
sll_buy_dvsn_cd: str, # 매도매수구분코드
unit_price: str, # 주문가격1
ord_dvsn_cd: str # 주문구분코드
) -> pd.DataFrame:
"""
(야간)선물옵션 주문가능 조회 API입니다.
Args:
cano (str): [필수] 종합계좌번호
acnt_prdt_cd (str): [필수] 계좌상품코드
pdno (str): [필수] 상품번호
prdt_type_cd (str): [필수] 상품유형코드 (ex. 301:선물옵션)
sll_buy_dvsn_cd (str): [필수] 매도매수구분코드 (ex. 01:매도, 02:매수)
unit_price (str): [필수] 주문가격1
ord_dvsn_cd (str): [필수] 주문구분코드 (ex. 01:지정가, 02:시장가, 03:조건부, 04:최유리, 10:지정가(IOC), 11:지정가(FOK), 12:시장가(IOC), 13:시장가(FOK), 14:최유리(IOC), 15:최유리(FOK))
Returns:
pd.DataFrame: (야간)선물옵션 주문가능 데이터
Example:
>>> df = inquire_psbl_ngt_order(cano=trenv.my_acct, acnt_prdt_cd=trenv.my_prod, pdno="101W09", prdt_type_cd="301", sll_buy_dvsn_cd="02", unit_price="322", ord_dvsn_cd="01")
>>> print(df)
"""
# 필수 파라미터 검증
if cano == "" or cano is None:
raise ValueError("cano is required")
if acnt_prdt_cd == "" or acnt_prdt_cd is None:
raise ValueError("acnt_prdt_cd is required")
if pdno == "" or pdno is None:
raise ValueError("pdno is required")
if prdt_type_cd == "" or prdt_type_cd is None:
raise ValueError("prdt_type_cd is required (e.g. '301')")
if sll_buy_dvsn_cd == "" or sll_buy_dvsn_cd is None:
raise ValueError("sll_buy_dvsn_cd is required (e.g. '01', '02')")
if unit_price == "" or unit_price is None:
raise ValueError("unit_price is required")
if ord_dvsn_cd == "" or ord_dvsn_cd is None:
raise ValueError("ord_dvsn_cd is required (e.g. '01', '02', '03', '04', '10', '11', '12', '13', '14', '15')")
tr_id = "STTN5105R"
params = {
"CANO": cano,
"ACNT_PRDT_CD": acnt_prdt_cd,
"PDNO": pdno,
"PRDT_TYPE_CD": prdt_type_cd,
"SLL_BUY_DVSN_CD": sll_buy_dvsn_cd,
"UNIT_PRICE": unit_price,
"ORD_DVSN_CD": ord_dvsn_cd
}
res = ka._url_fetch(API_URL, tr_id, "", params)
if res.isOK():
current_data = pd.DataFrame([res.getBody().output])
return current_data
else:
res.printError(url=API_URL)
return pd.DataFrame()

View File

@@ -0,0 +1,83 @@
"""
Created on 20250115
"""
import sys
import logging
import pandas as pd
sys.path.extend(['../..', '.'])
import kis_auth as ka
from inquire_psbl_order import inquire_psbl_order
# 로깅 설정
logging.basicConfig(level=logging.INFO)
##############################################################################################
# [국내선물옵션] 주문/계좌 > 선물옵션 주문가능[v1_국내선물-005]
##############################################################################################
COLUMN_MAPPING = {
'tot_psbl_qty': '총가능수량',
'lqd_psbl_qty1': '청산가능수량1',
'ord_psbl_qty': '주문가능수량',
'bass_idx': '기준지수'
}
NUMERIC_COLUMNS = []
def main():
"""
선물옵션 주문가능 조회 테스트 함수
이 함수는 선물옵션 주문가능 API를 호출하여 결과를 출력합니다.
테스트 데이터로 실전 환경의 선물옵션 계좌를 사용합니다.
Returns:
None
"""
# pandas 출력 옵션 설정
pd.set_option('display.max_columns', None) # 모든 컬럼 표시
pd.set_option('display.width', None) # 출력 너비 제한 해제
pd.set_option('display.max_rows', None) # 모든 행 표시
# 인증 토큰 발급
ka.auth()
trenv = ka.getTREnv()
# case1 조회
logging.info("=== case1 조회 ===")
try:
result = inquire_psbl_order(
env_dv="real",
cano=trenv.my_acct,
acnt_prdt_cd=trenv.my_prod,
pdno="101W09",
sll_buy_dvsn_cd="02",
unit_price="1",
ord_dvsn_cd="01"
)
except ValueError as e:
logging.error("에러 발생: %s" % str(e))
return
logging.info("사용 가능한 컬럼: %s", 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').round(2)
logging.info("결과:")
print(result)
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,101 @@
"""
Created on 20250115
"""
import sys
import logging
import pandas as pd
sys.path.extend(['../..', '.'])
import kis_auth as ka
# 로깅 설정
logging.basicConfig(level=logging.INFO)
##############################################################################################
# [국내선물옵션] 주문/계좌 > 선물옵션 주문가능[v1_국내선물-005]
##############################################################################################
# 상수 정의
API_URL = "/uapi/domestic-futureoption/v1/trading/inquire-psbl-order"
def inquire_psbl_order(
env_dv: str, # [필수] 실전모의구분 (ex. real:실전, demo:모의)
cano: str, # [필수] 종합계좌번호
acnt_prdt_cd: str, # [필수] 계좌상품코드 (ex. 03)
pdno: str, # [필수] 상품번호 (ex. 선물 6자리, 옵션 9자리)
sll_buy_dvsn_cd: str, # [필수] 매도매수구분코드 (ex. 01:매도,02:매수)
unit_price: str, # [필수] 주문가격1
ord_dvsn_cd: str # [필수] 주문구분코드
) -> pd.DataFrame:
"""
선물옵션 주문가능 API입니다. 주문가능 내역과 수량을 확인하실 수 있습니다.
Args:
env_dv (str): [필수] 실전모의구분 (ex. real:실전, demo:모의)
cano (str): [필수] 종합계좌번호
acnt_prdt_cd (str): [필수] 계좌상품코드 (ex. 03)
pdno (str): [필수] 상품번호 (ex. 선물 6자리, 옵션 9자리)
sll_buy_dvsn_cd (str): [필수] 매도매수구분코드 (ex. 01:매도,02:매수)
unit_price (str): [필수] 주문가격1
ord_dvsn_cd (str): [필수] 주문구분코드
Returns:
pd.DataFrame: 선물옵션 주문가능 데이터
Example:
>>> df = inquire_psbl_order(env_dv="real", cano=trenv.my_acct, acnt_prdt_cd=trenv.my_prod,
... pdno="101W09", sll_buy_dvsn_cd="02", unit_price="1", ord_dvsn_cd="01")
>>> print(df)
"""
# 필수 파라미터 검증
if env_dv == "":
raise ValueError("env_dv is required (e.g. 'real' or 'demo')")
if cano == "":
raise ValueError("cano is required")
if acnt_prdt_cd == "":
raise ValueError("acnt_prdt_cd is required (e.g. '03')")
if pdno == "":
raise ValueError("pdno is required (e.g. '101W09')")
if sll_buy_dvsn_cd == "":
raise ValueError("sll_buy_dvsn_cd is required (e.g. '01' or '02')")
if unit_price == "":
raise ValueError("unit_price is required")
if ord_dvsn_cd == "":
raise ValueError("ord_dvsn_cd is required")
# tr_id 설정
if env_dv == "real":
tr_id = "TTTO5105R"
elif env_dv == "demo":
tr_id = "VTTO5105R"
else:
raise ValueError("env_dv can only be 'real' or 'demo'")
params = {
"CANO": cano,
"ACNT_PRDT_CD": acnt_prdt_cd,
"PDNO": pdno,
"SLL_BUY_DVSN_CD": sll_buy_dvsn_cd,
"UNIT_PRICE": unit_price,
"ORD_DVSN_CD": ord_dvsn_cd
}
res = ka._url_fetch(API_URL, tr_id, "", params)
if res.isOK():
current_data = pd.DataFrame([res.getBody().output])
logging.info("Data fetch complete.")
return current_data
else:
res.printError(url=API_URL)
return pd.DataFrame()

View File

@@ -0,0 +1,132 @@
"""
Created on 20250601
"""
import sys
import logging
import pandas as pd
sys.path.extend(['../..', '.'])
import kis_auth as ka
from inquire_time_fuopchartprice import inquire_time_fuopchartprice
# 로깅 설정
logging.basicConfig(level=logging.INFO)
##############################################################################################
# [국내선물옵션] 기본시세 > 선물옵션 분봉조회[v1_국내선물-012]
##############################################################################################
COLUMN_MAPPING = {
'futs_prdy_vrss': '선물 전일 대비',
'prdy_vrss_sign': '전일 대비 부호',
'futs_prdy_ctrt': '선물 전일 대비율',
'futs_prdy_clpr': '선물 전일 종가',
'prdy_nmix': '전일 지수',
'acml_vol': '누적 거래량',
'acml_tr_pbmn': '누적 거래 대금',
'hts_kor_isnm': 'HTS 한글 종목명',
'futs_prpr': '선물 현재가',
'futs_shrn_iscd': '선물 단축 종목코드',
'prdy_vol': '전일 거래량',
'futs_mxpr': '선물 상한가',
'futs_llam': '선물 하한가',
'futs_oprc': '선물 시가2',
'futs_hgpr': '선물 최고가',
'futs_lwpr': '선물 최저가',
'futs_prdy_oprc': '선물 전일 시가',
'futs_prdy_hgpr': '선물 전일 최고가',
'futs_prdy_lwpr': '선물 전일 최저가',
'futs_askp': '선물 매도호가',
'futs_bidp': '선물 매수호가',
'basis': '베이시스',
'kospi200_nmix': 'KOSPI200 지수',
'kospi200_prdy_vrss': 'KOSPI200 전일 대비',
'kospi200_prdy_ctrt': 'KOSPI200 전일 대비율',
'kospi200_prdy_vrss_sign': 'KOSPI200 전일 대비 부호',
'hts_otst_stpl_qty': 'HTS 미결제 약정 수량',
'otst_stpl_qty_icdc': '미결제 약정 수량 증감',
'tday_rltv': '당일 체결강도',
'hts_thpr': 'HTS 이론가',
'dprt': '괴리율',
'stck_bsop_date': '주식 영업 일자',
'stck_cntg_hour': '주식 체결 시간',
'futs_prpr': '선물 현재가',
'futs_oprc': '선물 시가2',
'futs_hgpr': '선물 최고가',
'futs_lwpr': '선물 최저가',
'cntg_vol': '체결 거래량',
'acml_tr_pbmn': '누적 거래 대금'
}
NUMERIC_COLUMNS = []
def main():
"""
선물옵션 분봉조회 테스트 함수
이 함수는 선물옵션 분봉조회 API를 호출하여 결과를 출력합니다.
Returns:
None
"""
# pandas 출력 옵션 설정
pd.set_option('display.max_columns', None) # 모든 컬럼 표시
pd.set_option('display.width', None) # 출력 너비 제한 해제
pd.set_option('display.max_rows', None) # 모든 행 표시
# 인증 토큰 발급
ka.auth()
# case1 조회
logging.info("=== case1 조회 ===")
try:
result1, result2 = inquire_time_fuopchartprice(
fid_cond_mrkt_div_code="F",
fid_input_iscd="101T12",
fid_hour_cls_code="60",
fid_pw_data_incu_yn="Y",
fid_fake_tick_incu_yn="N",
fid_input_date_1="20230901",
fid_input_hour_1="100000"
)
except ValueError as e:
logging.error("에러 발생: %s" % str(e))
return
# output1 처리
logging.info("=== output1 결과 ===")
logging.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)
logging.info("결과:")
print(result1)
# output2 처리
logging.info("=== output2 결과 ===")
logging.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)
logging.info("결과:")
print(result2)
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,104 @@
"""
Created on 20250601
"""
import sys
from typing import Tuple
import logging
import pandas as pd
sys.path.extend(['../..', '.'])
import kis_auth as ka
# 로깅 설정
logging.basicConfig(level=logging.INFO)
##############################################################################################
# [국내선물옵션] 기본시세 > 선물옵션 분봉조회[v1_국내선물-012]
##############################################################################################
# 상수 정의
API_URL = "/uapi/domestic-futureoption/v1/quotations/inquire-time-fuopchartprice"
def inquire_time_fuopchartprice(
fid_cond_mrkt_div_code: str, # FID 조건 시장 분류 코드 (F: 지수선물, O: 지수옵션)
fid_input_iscd: str, # FID 입력 종목코드 (101T12)
fid_hour_cls_code: str, # FID 시간 구분 코드 (30: 30초, 60: 1분)
fid_pw_data_incu_yn: str, # FID 과거 데이터 포함 여부 (Y:과거, N: 당일)
fid_fake_tick_incu_yn: str, # FID 허봉 포함 여부 (N)
fid_input_date_1: str, # FID 입력 날짜1 (20230901)
fid_input_hour_1: str # FID 입력 시간1 (100000)
) -> Tuple[pd.DataFrame, pd.DataFrame]:
"""
선물옵션 분봉조회 API입니다.
실전계좌의 경우, 한 번의 호출에 최대 102건까지 확인 가능하며,
FID_INPUT_DATE_1(입력날짜), FID_INPUT_HOUR_1(입력시간)을 이용하여 다음 조회 가능합니다.
Args:
fid_cond_mrkt_div_code (str): [필수] FID 조건 시장 분류 코드 (ex. F: 지수선물, O: 지수옵션)
fid_input_iscd (str): [필수] FID 입력 종목코드 (ex. 101T12)
fid_hour_cls_code (str): [필수] FID 시간 구분 코드 (ex. 30: 30초, 60: 1분)
fid_pw_data_incu_yn (str): [필수] FID 과거 데이터 포함 여부 (ex. Y:과거, N: 당일)
fid_fake_tick_incu_yn (str): [필수] FID 허봉 포함 여부 (ex. N)
fid_input_date_1 (str): [필수] FID 입력 날짜1 (ex. 20230901)
fid_input_hour_1 (str): [필수] FID 입력 시간1 (ex. 100000)
Returns:
Tuple[pd.DataFrame, pd.DataFrame]: 선물옵션 분봉 데이터 (output1, output2)
Example:
>>> df1, df2 = inquire_time_fuopchartprice("F", "101T12", "60", "Y", "N", "20230901", "100000")
>>> print(df1)
>>> print(df2)
"""
# 필수 파라미터 검증
if fid_cond_mrkt_div_code == "":
raise ValueError("fid_cond_mrkt_div_code is required (e.g. 'F: 지수선물, O: 지수옵션')")
if fid_input_iscd == "":
raise ValueError("fid_input_iscd is required (e.g. '101T12')")
if fid_hour_cls_code == "":
raise ValueError("fid_hour_cls_code is required (e.g. '30: 30초, 60: 1분')")
if fid_pw_data_incu_yn == "":
raise ValueError("fid_pw_data_incu_yn is required (e.g. 'Y:과거, N: 당일')")
if fid_fake_tick_incu_yn == "":
raise ValueError("fid_fake_tick_incu_yn is required (e.g. 'N')")
if fid_input_date_1 == "":
raise ValueError("fid_input_date_1 is required (e.g. '20230901')")
if fid_input_hour_1 == "":
raise ValueError("fid_input_hour_1 is required (e.g. '100000')")
tr_id = "FHKIF03020200" # 선물옵션 분봉조회
params = {
"FID_COND_MRKT_DIV_CODE": fid_cond_mrkt_div_code,
"FID_INPUT_ISCD": fid_input_iscd,
"FID_HOUR_CLS_CODE": fid_hour_cls_code,
"FID_PW_DATA_INCU_YN": fid_pw_data_incu_yn,
"FID_FAKE_TICK_INCU_YN": fid_fake_tick_incu_yn,
"FID_INPUT_DATE_1": fid_input_date_1,
"FID_INPUT_HOUR_1": fid_input_hour_1
}
res = ka._url_fetch(API_URL, tr_id, "", params)
if res.isOK():
# output1: object array -> DataFrame
output1_data = pd.DataFrame(res.getBody().output1, index=[0])
# output2: array -> DataFrame
output2_data = pd.DataFrame(res.getBody().output2)
logging.info("Data fetch complete.")
return output1_data, output2_data
else:
res.printError(url=API_URL)
return pd.DataFrame(), pd.DataFrame()

View File

@@ -0,0 +1,103 @@
"""
Created on 20250601
"""
import logging
import sys
import pandas as pd
sys.path.extend(['../..', '.'])
import kis_auth as ka
from krx_ngt_futures_asking_price import krx_ngt_futures_asking_price
# 로깅 설정
logging.basicConfig(level=logging.INFO)
##############################################################################################
# [국내선물옵션] 실시간시세 > KRX야간선물 실시간호가 [실시간-065]
##############################################################################################
COLUMN_MAPPING = {
"futs_shrn_iscd": "선물 단축 종목코드",
"bsop_hour": "영업 시간",
"futs_askp1": "선물 매도호가1",
"futs_askp2": "선물 매도호가2",
"futs_askp3": "선물 매도호가3",
"futs_askp4": "선물 매도호가4",
"futs_askp5": "선물 매도호가5",
"futs_bidp1": "선물 매수호가1",
"futs_bidp2": "선물 매수호가2",
"futs_bidp3": "선물 매수호가3",
"futs_bidp4": "선물 매수호가4",
"futs_bidp5": "선물 매수호가5",
"askp_csnu1": "매도호가 건수1",
"askp_csnu2": "매도호가 건수2",
"askp_csnu3": "매도호가 건수3",
"askp_csnu4": "매도호가 건수4",
"askp_csnu5": "매도호가 건수5",
"bidp_csnu1": "매수호가 건수1",
"bidp_csnu2": "매수호가 건수2",
"bidp_csnu3": "매수호가 건수3",
"bidp_csnu4": "매수호가 건수4",
"bidp_csnu5": "매수호가 건수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_csnu": "총 매도호가 건수",
"total_bidp_csnu": "총 매수호가 건수",
"total_askp_rsqn": "총 매도호가 잔량",
"total_bidp_rsqn": "총 매수호가 잔량",
"total_askp_rsqn_icdc": "총 매도호가 잔량 증감",
"total_bidp_rsqn_icdc": "총 매수호가 잔량 증감"
}
NUMERIC_COLUMNS = []
def main():
"""
KRX야간선물 실시간호가 조회 테스트 함수
Returns:
None
"""
# 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=krx_ngt_futures_asking_price, data=["101W09"])
# 결과 표시
def on_result(ws, tr_id: str, result: pd.DataFrame, data_map: dict):
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').round(2)
logging.info("결과:")
print(result)
kws.start(on_result=on_result)
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,99 @@
"""
Created on 20250601
"""
import logging
import sys
sys.path.extend(['../..', '.'])
import kis_auth as ka
# 로깅 설정
logging.basicConfig(level=logging.INFO)
##############################################################################################
# [국내선물옵션] 실시간시세 > KRX야간선물 실시간호가 [실시간-065]
##############################################################################################
def krx_ngt_futures_asking_price(
tr_type: str,
tr_key: str,
) -> (dict, list[str]):
"""
※ 선물옵션 호가 데이터는 0.2초 필터링 옵션이 있습니다.
필터링 사유는 순간적으로 데이터가 폭증할 경우 서버 뿐만아니라 클라이언트 환경에도 부하를 줄 수 있어 적용된 사항인 점 양해 부탁드립니다.
[참고자료]
종목코드 마스터파일 파이썬 정제코드는 한국투자증권 Github 참고 부탁드립니다.
https://github.com/koreainvestment/open-trading-api/tree/main/stocks_info
Args:
tr_type (str): [필수] 등록/해제
tr_key (str): [필수] 종목코드
Returns:
message (dict): 메시지 데이터
columns (list[str]): 컬럼 정보
Example:
>>> msg, columns = krx_ngt_futures_asking_price("1", "101W9000")
>>> print(msg, columns)
"""
# 필수 파라미터 검증
if tr_type == "":
raise ValueError("tr_type is required")
if tr_key == "":
raise ValueError("tr_key is required")
tr_id = "H0MFASP0"
params = {
"tr_key": tr_key,
}
msg = ka.data_fetch(tr_id, tr_type, params)
columns = [
"futs_shrn_iscd",
"bsop_hour",
"futs_askp1",
"futs_askp2",
"futs_askp3",
"futs_askp4",
"futs_askp5",
"futs_bidp1",
"futs_bidp2",
"futs_bidp3",
"futs_bidp4",
"futs_bidp5",
"askp_csnu1",
"askp_csnu2",
"askp_csnu3",
"askp_csnu4",
"askp_csnu5",
"bidp_csnu1",
"bidp_csnu2",
"bidp_csnu3",
"bidp_csnu4",
"bidp_csnu5",
"askp_rsqn1",
"askp_rsqn2",
"askp_rsqn3",
"askp_rsqn4",
"askp_rsqn5",
"bidp_rsqn1",
"bidp_rsqn2",
"bidp_rsqn3",
"bidp_rsqn4",
"bidp_rsqn5",
"total_askp_csnu",
"total_bidp_csnu",
"total_askp_rsqn",
"total_bidp_rsqn",
"total_askp_rsqn_icdc",
"total_bidp_rsqn_icdc"
]
return msg, columns

View File

@@ -0,0 +1,115 @@
"""
Created on 20250601
"""
import logging
import sys
import pandas as pd
sys.path.extend(['../..', '.'])
import kis_auth as ka
from krx_ngt_futures_ccnl import krx_ngt_futures_ccnl
# 로깅 설정
logging.basicConfig(level=logging.INFO)
##############################################################################################
# [국내선물옵션] 실시간시세 > KRX야간선물 실시간종목체결 [실시간-064]
##############################################################################################
COLUMN_MAPPING = {
"futs_shrn_iscd": "선물 단축 종목코드",
"bsop_hour": "영업 시간",
"futs_prdy_vrss": "선물 전일 대비",
"prdy_vrss_sign": "전일 대비 부호",
"futs_prdy_ctrt": "선물 전일 대비율",
"futs_prpr": "선물 현재가",
"futs_oprc": "선물 시가2",
"futs_hgpr": "선물 최고가",
"futs_lwpr": "선물 최저가",
"last_cnqn": "최종 거래량",
"acml_vol": "누적 거래량",
"acml_tr_pbmn": "누적 거래 대금",
"hts_thpr": "HTS 이론가",
"mrkt_basis": "시장 베이시스",
"dprt": "괴리율",
"nmsc_fctn_stpl_prc": "근월물 약정가",
"fmsc_fctn_stpl_prc": "원월물 약정가",
"spead_prc": "스프레드1",
"hts_otst_stpl_qty": "HTS 미결제 약정 수량",
"otst_stpl_qty_icdc": "미결제 약정 수량 증감",
"oprc_hour": "시가 시간",
"oprc_vrss_prpr_sign": "시가2 대비 현재가 부호",
"oprc_vrss_nmix_prpr": "시가 대비 지수 현재가",
"hgpr_hour": "최고가 시간",
"hgpr_vrss_prpr_sign": "최고가 대비 현재가 부호",
"hgpr_vrss_nmix_prpr": "최고가 대비 지수 현재가",
"lwpr_hour": "최저가 시간",
"lwpr_vrss_prpr_sign": "최저가 대비 현재가 부호",
"lwpr_vrss_nmix_prpr": "최저가 대비 지수 현재가",
"shnu_rate": "매수2 비율",
"cttr": "체결강도",
"esdg": "괴리도",
"otst_stpl_rgbf_qty_icdc": "미결제 약정 직전 수량 증감",
"thpr_basis": "이론 베이시스",
"futs_askp1": "선물 매도호가1",
"futs_bidp1": "선물 매수호가1",
"askp_rsqn1": "매도호가 잔량1",
"bidp_rsqn1": "매수호가 잔량1",
"seln_cntg_csnu": "매도 체결 건수",
"shnu_cntg_csnu": "매수 체결 건수",
"ntby_cntg_csnu": "순매수 체결 건수",
"seln_cntg_smtn": "총 매도 수량",
"shnu_cntg_smtn": "총 매수 수량",
"total_askp_rsqn": "총 매도호가 잔량",
"total_bidp_rsqn": "총 매수호가 잔량",
"prdy_vol_vrss_acml_vol_rate": "전일 거래량 대비 등락율",
"dynm_mxpr": "실시간상한가",
"dynm_llam": "실시간하한가",
"dynm_prc_limt_yn": "실시간가격제한구분"
}
NUMERIC_COLUMNS = []
def main():
"""
[국내선물옵션] 실시간시세 > KRX야간선물 실시간종목체결
Returns:
None
"""
# 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=krx_ngt_futures_ccnl, data=["101W9000"])
# 결과 표시
def on_result(ws, tr_id: str, result: pd.DataFrame, data_map: dict):
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').round(2)
logging.info("결과:")
print(result)
kws.start(on_result=on_result)
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,108 @@
"""
Created on 20250601
"""
import logging
import sys
sys.path.extend(['../..', '.'])
import kis_auth as ka
# 로깅 설정
logging.basicConfig(level=logging.INFO)
##############################################################################################
# [국내선물옵션] 실시간시세 > KRX야간선물 실시간종목체결 [실시간-064]
##############################################################################################
def krx_ngt_futures_ccnl(
tr_type: str,
tr_key: str,
) -> (dict, list[str]):
"""
[참고자료]
종목코드 마스터파일 파이썬 정제코드는 한국투자증권 Github 참고 부탁드립니다.
https://github.com/koreainvestment/open-trading-api/tree/main/stocks_info
Args:
tr_type (str): [필수] 등록/해제
tr_key (str): [필수] 종목코드
Returns:
message (dict): 메시지 데이터
columns (list[str]): 컬럼 정보
Example:
>>> msg, columns = krx_ngt_futures_ccnl("1", "101W9000")
>>> print(msg, columns)
"""
# 필수 파라미터 검증
if tr_type == "":
raise ValueError("tr_type is required")
if tr_key == "":
raise ValueError("tr_key is required")
tr_id = "H0MFCNT0"
params = {
"tr_key": tr_key,
}
msg = ka.data_fetch(tr_id, tr_type, params)
columns = [
"futs_shrn_iscd",
"bsop_hour",
"futs_prdy_vrss",
"prdy_vrss_sign",
"futs_prdy_ctrt",
"futs_prpr",
"futs_oprc",
"futs_hgpr",
"futs_lwpr",
"last_cnqn",
"acml_vol",
"acml_tr_pbmn",
"hts_thpr",
"mrkt_basis",
"dprt",
"nmsc_fctn_stpl_prc",
"fmsc_fctn_stpl_prc",
"spead_prc",
"hts_otst_stpl_qty",
"otst_stpl_qty_icdc",
"oprc_hour",
"oprc_vrss_prpr_sign",
"oprc_vrss_nmix_prpr",
"hgpr_hour",
"hgpr_vrss_prpr_sign",
"hgpr_vrss_nmix_prpr",
"lwpr_hour",
"lwpr_vrss_prpr_sign",
"lwpr_vrss_nmix_prpr",
"shnu_rate",
"cttr",
"esdg",
"otst_stpl_rgbf_qty_icdc",
"thpr_basis",
"futs_askp1",
"futs_bidp1",
"askp_rsqn1",
"bidp_rsqn1",
"seln_cntg_csnu",
"shnu_cntg_csnu",
"ntby_cntg_csnu",
"seln_cntg_smtn",
"shnu_cntg_smtn",
"total_askp_rsqn",
"total_bidp_rsqn",
"prdy_vol_vrss_acml_vol_rate",
"dynm_mxpr",
"dynm_llam",
"dynm_prc_limt_yn"
]
return msg, columns

View File

@@ -0,0 +1,85 @@
"""
Created on 20250601
"""
import logging
import sys
import pandas as pd
sys.path.extend(['../..', '.'])
import kis_auth as ka
from krx_ngt_futures_ccnl_notice import krx_ngt_futures_ccnl_notice
# 로깅 설정
logging.basicConfig(level=logging.INFO)
##############################################################################################
# [국내선물옵션] 실시간시세 > KRX야간선물 실시간체결통보 [실시간-066]
##############################################################################################
COLUMN_MAPPING = {
"cust_id": "고객 ID",
"acnt_no": "계좌번호",
"oder_no": "주문번호",
"ooder_no": "원주문번호",
"seln_byov_cls": "매도매수구분",
"rctf_cls": "정정구분",
"oder_kind2": "주문종류2",
"stck_shrn_iscd": "주식 단축 종목코드",
"cntg_qty": "체결 수량",
"cntg_unpr": "체결단가",
"stck_cntg_hour": "주식 체결 시간",
"rfus_yn": "거부여부",
"cntg_yn": "체결여부",
"acpt_yn": "접수여부",
"brnc_no": "지점번호",
"oder_qty": "주문수량",
"acnt_name": "계좌명",
"cntg_isnm": "체결종목명",
"oder_cond": "주문조건"
}
NUMERIC_COLUMNS = []
def main():
"""
KRX야간선물 실시간체결통보 테스트 함수
Returns:
None
"""
# 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()
trenv = ka.getTREnv()
# 인증(auth_ws()) 이후에 선언
kws = ka.KISWebSocket(api_url="/tryitout")
# 조회
kws.subscribe(request=krx_ngt_futures_ccnl_notice, data=[trenv.my_htsid])
# 결과 표시
def on_result(ws, tr_id: str, result: pd.DataFrame, data_map: dict):
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').round(2)
logging.info("결과:")
print(result)
kws.start(on_result=on_result)
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,78 @@
"""
Created on 20250601
"""
import logging
import sys
sys.path.extend(['../..', '.'])
import kis_auth as ka
# 로깅 설정
logging.basicConfig(level=logging.INFO)
##############################################################################################
# [국내선물옵션] 실시간시세 > KRX야간선물 실시간체결통보 [실시간-066]
##############################################################################################
def krx_ngt_futures_ccnl_notice(
tr_type: str,
tr_key: str,
) -> (dict, list[str]):
"""
[참고자료]
종목코드 마스터파일 파이썬 정제코드는 한국투자증권 Github 참고 부탁드립니다.
https://github.com/koreainvestment/open-trading-api/tree/main/stocks_info
Args:
tr_type (str): [필수] 등록/해제
tr_key (str): [필수] 종목코드
Returns:
message (dict): 메시지 데이터
columns (list[str]): 컬럼 정보
Example:
>>> msg, columns = krx_ngt_futures_ccnl_notice("1", trenv.my_htsid)
>>> print(msg, columns)
"""
# 필수 파라미터 검증
if tr_type == "":
raise ValueError("tr_type is required")
if tr_key == "":
raise ValueError("tr_key is required")
tr_id = "H0MFCNI0"
params = {
"tr_key": tr_key,
}
msg = ka.data_fetch(tr_id, tr_type, params)
columns = [
"cust_id",
"acnt_no",
"oder_no",
"ooder_no",
"seln_byov_cls",
"rctf_cls",
"oder_kind2",
"stck_shrn_iscd",
"cntg_qty",
"cntg_unpr",
"stck_cntg_hour",
"rfus_yn",
"cntg_yn",
"acpt_yn",
"brnc_no",
"oder_qty",
"acnt_name",
"cntg_isnm",
"oder_cond"
]
return msg, columns

View File

@@ -0,0 +1,103 @@
"""
Created on 20250601
"""
import logging
import sys
import pandas as pd
sys.path.extend(['../..', '.'])
import kis_auth as ka
from krx_ngt_option_asking_price import krx_ngt_option_asking_price
# 로깅 설정
logging.basicConfig(level=logging.INFO)
##############################################################################################
# [국내선물옵션] 실시간시세 > KRX야간옵션 실시간호가 [실시간-033]
##############################################################################################
COLUMN_MAPPING = {
"optn_shrn_iscd": "옵션단축종목코드",
"bsop_hour": "영업시간",
"optn_askp1": "옵션매도호가1",
"optn_askp2": "옵션매도호가2",
"optn_askp3": "옵션매도호가3",
"optn_askp4": "옵션매도호가4",
"optn_askp5": "옵션매도호가5",
"optn_bidp1": "옵션매수호가1",
"optn_bidp2": "옵션매수호가2",
"optn_bidp3": "옵션매수호가3",
"optn_bidp4": "옵션매수호가4",
"optn_bidp5": "옵션매수호가5",
"askp_csnu1": "매도호가건수1",
"askp_csnu2": "매도호가건수2",
"askp_csnu3": "매도호가건수3",
"askp_csnu4": "매도호가건수4",
"askp_csnu5": "매도호가건수5",
"bidp_csnu1": "매수호가건수1",
"bidp_csnu2": "매수호가건수2",
"bidp_csnu3": "매수호가건수3",
"bidp_csnu4": "매수호가건수4",
"bidp_csnu5": "매수호가건수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_csnu": "총매도호가건수",
"total_bidp_csnu": "총매수호가건수",
"total_askp_rsqn": "총매도호가잔량",
"total_bidp_rsqn": "총매수호가잔량",
"total_askp_rsqn_icdc": "총매도호가잔량증감",
"total_bidp_rsqn_icdc": "총매수호가잔량증감"
}
NUMERIC_COLUMNS = []
def main():
"""
KRX야간옵션 실시간호가
Returns:
None
"""
# 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")
# 조회 - case1
kws.subscribe(request=krx_ngt_option_asking_price, data=["101W9000"])
# 결과 표시
def on_result(ws, tr_id: str, result: pd.DataFrame, data_map: dict):
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').round(2)
logging.info("결과:")
print(result)
kws.start(on_result=on_result)
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,97 @@
"""
Created on 20250601
"""
import logging
import sys
sys.path.extend(['../..', '.'])
import kis_auth as ka
# 로깅 설정
logging.basicConfig(level=logging.INFO)
##############################################################################################
# [국내선물옵션] 실시간시세 > KRX야간옵션 실시간호가 [실시간-033]
##############################################################################################
def krx_ngt_option_asking_price(
tr_type: str,
tr_key: str,
) -> (dict, list[str]):
"""
[참고자료]
종목코드 마스터파일 파이썬 정제코드는 한국투자증권 Github 참고 부탁드립니다.
https://github.com/koreainvestment/open-trading-api/tree/main/stocks_info
Args:
tr_type (str): [필수] 등록/해제
tr_key (str): [필수] 종목코드
Returns:
message (dict): 메시지 데이터
columns (list[str]): 컬럼 정보
Example:
>>> msg, columns = krx_ngt_option_asking_price("1", "101W09")
>>> print(msg, columns)
"""
# 필수 파라미터 검증
if tr_type == "":
raise ValueError("tr_type is required")
if tr_key == "":
raise ValueError("tr_key is required")
tr_id = "H0EUASP0"
params = {
"tr_key": tr_key,
}
msg = ka.data_fetch(tr_id, tr_type, params)
columns = [
"optn_shrn_iscd",
"bsop_hour",
"optn_askp1",
"optn_askp2",
"optn_askp3",
"optn_askp4",
"optn_askp5",
"optn_bidp1",
"optn_bidp2",
"optn_bidp3",
"optn_bidp4",
"optn_bidp5",
"askp_csnu1",
"askp_csnu2",
"askp_csnu3",
"askp_csnu4",
"askp_csnu5",
"bidp_csnu1",
"bidp_csnu2",
"bidp_csnu3",
"bidp_csnu4",
"bidp_csnu5",
"askp_rsqn1",
"askp_rsqn2",
"askp_rsqn3",
"askp_rsqn4",
"askp_rsqn5",
"bidp_rsqn1",
"bidp_rsqn2",
"bidp_rsqn3",
"bidp_rsqn4",
"bidp_rsqn5",
"total_askp_csnu",
"total_bidp_csnu",
"total_askp_rsqn",
"total_bidp_rsqn",
"total_askp_rsqn_icdc",
"total_bidp_rsqn_icdc"
]
return msg, columns

View File

@@ -0,0 +1,121 @@
"""
Created on 20250601
"""
import logging
import sys
import pandas as pd
sys.path.extend(['../..', '.'])
import kis_auth as ka
from krx_ngt_option_ccnl import krx_ngt_option_ccnl
# 로깅 설정
logging.basicConfig(level=logging.INFO)
##############################################################################################
# [국내선물옵션] 실시간시세 > KRX야간옵션 실시간체결가 [실시간-032]
##############################################################################################
COLUMN_MAPPING = {
"optn_shrn_iscd": "옵션단축종목코드",
"bsop_hour": "영업시간",
"optn_prpr": "옵션현재가",
"prdy_vrss_sign": "전일대비부호",
"optn_prdy_vrss": "옵션전일대비",
"prdy_ctrt": "전일대비율",
"optn_oprc": "옵션시가2",
"optn_hgpr": "옵션최고가",
"optn_lwpr": "옵션최저가",
"last_cnqn": "최종거래량",
"acml_vol": "누적거래량",
"acml_tr_pbmn": "누적거래대금",
"hts_thpr": "HTS이론가",
"hts_otst_stpl_qty": "HTS미결제약정수량",
"otst_stpl_qty_icdc": "미결제약정수량증감",
"oprc_hour": "시가시간",
"oprc_vrss_prpr_sign": "시가2대비현재가부호",
"oprc_vrss_nmix_prpr": "시가대비지수현재가",
"hgpr_hour": "최고가시간",
"hgpr_vrss_prpr_sign": "최고가대비현재가부호",
"hgpr_vrss_nmix_prpr": "최고가대비지수현재가",
"lwpr_hour": "최저가시간",
"lwpr_vrss_prpr_sign": "최저가대비현재가부호",
"lwpr_vrss_nmix_prpr": "최저가대비지수현재가",
"shnu_rate": "매수2비율",
"prmm_val": "프리미엄값",
"invl_val": "내재가치값",
"tmvl_val": "시간가치값",
"delta": "델타",
"gama": "감마",
"vega": "베가",
"theta": "세타",
"rho": "로우",
"hts_ints_vltl": "HTS내재변동성",
"esdg": "괴리도",
"otst_stpl_rgbf_qty_icdc": "미결제약정직전수량증감",
"thpr_basis": "이론베이시스",
"unas_hist_vltl": "역사적변동성",
"cttr": "체결강도",
"dprt": "괴리율",
"mrkt_basis": "시장베이시스",
"optn_askp1": "옵션매도호가1",
"optn_bidp1": "옵션매수호가1",
"askp_rsqn1": "매도호가잔량1",
"bidp_rsqn1": "매수호가잔량1",
"seln_cntg_csnu": "매도체결건수",
"shnu_cntg_csnu": "매수체결건수",
"ntby_cntg_csnu": "순매수체결건수",
"seln_cntg_smtn": "총매도수량",
"shnu_cntg_smtn": "총매수수량",
"total_askp_rsqn": "총매도호가잔량",
"total_bidp_rsqn": "총매수호가잔량",
"prdy_vol_vrss_acml_vol_rate": "전일거래량대비등락율",
"dynm_mxpr": "실시간상한가",
"dynm_prc_limt_yn": "실시간가격제한구분",
"dynm_llam": "실시간하한가"
}
NUMERIC_COLUMNS = []
def main():
"""
KRX야간옵션 실시간체결가
Returns:
None
"""
# 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=krx_ngt_option_ccnl, data=["101W9000"])
# 결과 표시
def on_result(ws, tr_id: str, result: pd.DataFrame, data_map: dict):
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').round(2)
logging.info("결과:")
print(result)
kws.start(on_result=on_result)
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,114 @@
"""
Created on 20250601
"""
import logging
import sys
sys.path.extend(['../..', '.'])
import kis_auth as ka
# 로깅 설정
logging.basicConfig(level=logging.INFO)
##############################################################################################
# [국내선물옵션] 실시간시세 > KRX야간옵션 실시간체결가 [실시간-032]
##############################################################################################
def krx_ngt_option_ccnl(
tr_type: str,
tr_key: str,
) -> (dict, list[str]):
"""
[참고자료]
종목코드 마스터파일 파이썬 정제코드는 한국투자증권 Github 참고 부탁드립니다.
https://github.com/koreainvestment/open-trading-api/tree/main/stocks_info
Args:
tr_type (str): [필수] 등록/해제
tr_key (str): [필수] 선물단축종목코드
Returns:
message (str): 메시지 데이터
columns (list[str]): 컬럼 정보
Example:
>>> msg, columns = krx_ngt_option_ccnl("1", "101W9000")
>>> print(msg, columns)
"""
# 필수 파라미터 검증
if tr_type == "":
raise ValueError("tr_type is required")
if tr_key == "":
raise ValueError("tr_key is required")
tr_id = "H0EUCNT0"
params = {
"tr_key": tr_key,
}
msg = ka.data_fetch(tr_id, tr_type, params)
columns = [
"optn_shrn_iscd",
"bsop_hour",
"optn_prpr",
"prdy_vrss_sign",
"optn_prdy_vrss",
"prdy_ctrt",
"optn_oprc",
"optn_hgpr",
"optn_lwpr",
"last_cnqn",
"acml_vol",
"acml_tr_pbmn",
"hts_thpr",
"hts_otst_stpl_qty",
"otst_stpl_qty_icdc",
"oprc_hour",
"oprc_vrss_prpr_sign",
"oprc_vrss_nmix_prpr",
"hgpr_hour",
"hgpr_vrss_prpr_sign",
"hgpr_vrss_nmix_prpr",
"lwpr_hour",
"lwpr_vrss_prpr_sign",
"lwpr_vrss_nmix_prpr",
"shnu_rate",
"prmm_val",
"invl_val",
"tmvl_val",
"delta",
"gama",
"vega",
"theta",
"rho",
"hts_ints_vltl",
"esdg",
"otst_stpl_rgbf_qty_icdc",
"thpr_basis",
"unas_hist_vltl",
"cttr",
"dprt",
"mrkt_basis",
"optn_askp1",
"optn_bidp1",
"askp_rsqn1",
"bidp_rsqn1",
"seln_cntg_csnu",
"shnu_cntg_csnu",
"ntby_cntg_csnu",
"seln_cntg_smtn",
"shnu_cntg_smtn",
"total_askp_rsqn",
"total_bidp_rsqn",
"prdy_vol_vrss_acml_vol_rate",
"dynm_mxpr",
"dynm_prc_limt_yn",
"dynm_llam"
]
return msg, columns

View File

@@ -0,0 +1,74 @@
"""
Created on 20250601
"""
import logging
import sys
import pandas as pd
sys.path.extend(['../..', '.'])
import kis_auth as ka
from krx_ngt_option_exp_ccnl import krx_ngt_option_exp_ccnl
# 로깅 설정
logging.basicConfig(level=logging.INFO)
##############################################################################################
# [국내선물옵션] 실시간시세 > KRX야간옵션실시간예상체결 [실시간-034]
##############################################################################################
COLUMN_MAPPING = {
"optn_shrn_iscd": "옵션단축종목코드",
"bsop_hour": "영업시간",
"antc_cnpr": "예상체결가",
"antc_cntg_vrss": "예상체결대비",
"antc_cntg_vrss_sign": "예상체결대비부호",
"antc_cntg_prdy_ctrt": "예상체결전일대비율",
"antc_mkop_cls_code": "예상장운영구분코드",
"antc_cnqn": "예상체결수량"
}
NUMERIC_COLUMNS = []
def main():
"""
KRX야간옵션실시간예상체결 조회 테스트 함수
Returns:
None
"""
# 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=krx_ngt_option_exp_ccnl, data=["101W9000"])
# 결과 표시
def on_result(ws, tr_id: str, result: pd.DataFrame, data_map: dict):
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').round(2)
logging.info("결과:")
print(result)
kws.start(on_result=on_result)
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,67 @@
"""
Created on 20250601
"""
import sys
sys.path.extend(['../..', '.'])
import kis_auth as ka
##############################################################################################
# [국내선물옵션] 실시간시세 > KRX야간옵션실시간예상체결 [실시간-034]
##############################################################################################
def krx_ngt_option_exp_ccnl(
tr_type: str,
tr_key: str,
) -> (dict, list[str]):
"""
[국내선물옵션] 실시간시세
KRX야간옵션실시간예상체결 [실시간-034]
[참고자료]
종목코드 마스터파일 파이썬 정제코드는 한국투자증권 Github 참고 부탁드립니다.
https://github.com/koreainvestment/open-trading-api/tree/main/stocks_info
Args:
tr_type (str): [필수] 등록/해제
tr_key (str): [필수] 선물단축종목코드
Returns:
message (dict): 메시지 데이터
columns (list[str]): 컬럼 정보
Example:
>>> msg, columns = krx_ngt_option_exp_ccnl("1", "101W9000")
>>> print(msg, columns)
"""
# 필수 파라미터 검증
if tr_type == "":
raise ValueError("tr_type is required")
if tr_key == "":
raise ValueError("tr_key is required")
tr_id = "H0EUANC0"
params = {
"tr_key": tr_key,
}
msg = ka.data_fetch(tr_id, tr_type, params)
columns = [
"optn_shrn_iscd",
"bsop_hour",
"antc_cnpr",
"antc_cntg_vrss",
"antc_cntg_vrss_sign",
"antc_cntg_prdy_ctrt",
"antc_mkop_cls_code",
"antc_cnqn"
]
return msg, columns

View File

@@ -0,0 +1,86 @@
"""
Created on 20250601
"""
import logging
import sys
import pandas as pd
sys.path.extend(['../..', '.'])
import kis_auth as ka
from krx_ngt_option_notice import krx_ngt_option_notice
# 로깅 설정
logging.basicConfig(level=logging.INFO)
##############################################################################################
# [국내선물옵션] 실시간시세 > KRX야간옵션실시간체결통보 [실시간-067]
##############################################################################################
COLUMN_MAPPING = {
"cust_id": "고객 ID",
"acnt_no": "계좌번호",
"oder_no": "주문번호",
"ooder_no": "원주문번호",
"seln_byov_cls": "매도매수구분",
"rctf_cls": "정정구분",
"oder_kind2": "주문종류2",
"stck_shrn_iscd": "주식 단축 종목코드",
"cntg_qty": "체결 수량",
"cntg_unpr": "체결단가",
"stck_cntg_hour": "주식 체결 시간",
"rfus_yn": "거부여부",
"cntg_yn": "체결여부",
"acpt_yn": "접수여부",
"brnc_no": "지점번호",
"oder_qty": "주문수량",
"acnt_name": "계좌명",
"cntg_isnm": "체결종목명",
"oder_cond": "주문조건"
}
NUMERIC_COLUMNS = []
def main():
"""
KRX야간옵션실시간체결통보
Returns:
None
"""
# 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()
trenv = ka.getTREnv()
# 인증(auth_ws()) 이후에 선언
kws = ka.KISWebSocket(api_url="/tryitout")
# 조회
kws.subscribe(request=krx_ngt_option_notice, data=[trenv.my_htsid])
# 결과 표시
def on_result(ws, tr_id: str, result: pd.DataFrame, data_map: dict):
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').round(2)
logging.info("결과:")
print(result)
kws.start(on_result=on_result)
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,78 @@
"""
Created on 20250601
"""
import logging
import sys
sys.path.extend(['../..', '.'])
import kis_auth as ka
# 로깅 설정
logging.basicConfig(level=logging.INFO)
##############################################################################################
# [국내선물옵션] 실시간시세 > KRX야간옵션실시간체결통보 [실시간-067]
##############################################################################################
def krx_ngt_option_notice(
tr_type: str,
tr_key: str,
) -> (dict, list[str]):
"""
[참고자료]
종목코드 마스터파일 파이썬 정제코드는 한국투자증권 Github 참고 부탁드립니다.
https://github.com/koreainvestment/open-trading-api/tree/main/stocks_info
Args:
tr_type (str): [필수] 등록/해제
tr_key (str): [필수] 고객 ID
Returns:
message (dict): 메시지 데이터
columns (list[str]): 컬럼 정보
Example:
>>> msg, columns = krx_ngt_option_notice("1", trenv.my_htsid)
>>> print(msg, columns)
"""
# 필수 파라미터 검증
if tr_type == "":
raise ValueError("tr_type is required")
if tr_key == "":
raise ValueError("tr_key is required")
tr_id = "H0EUCNI0"
params = {
"tr_key": tr_key,
}
msg = ka.data_fetch(tr_id, tr_type, params)
columns = [
"cust_id",
"acnt_no",
"oder_no",
"ooder_no",
"seln_byov_cls",
"rctf_cls",
"oder_kind2",
"stck_shrn_iscd",
"cntg_qty",
"cntg_unpr",
"stck_cntg_hour",
"rfus_yn",
"cntg_yn",
"acpt_yn",
"brnc_no",
"oder_qty",
"acnt_name",
"cntg_isnm",
"oder_cond"
]
return msg, columns

View File

@@ -0,0 +1,166 @@
"""
Created on 20250116
"""
import sys
import logging
import pandas as pd
sys.path.extend(['../..', '.'])
import kis_auth as ka
from ngt_margin_detail import ngt_margin_detail
# 로깅 설정
logging.basicConfig(level=logging.INFO)
##############################################################################################
# [국내선물옵션] 주문/계좌 > (야간)선물옵션 증거금 상세 [국내선물-024]
##############################################################################################
COLUMN_MAPPING = {
'futr_new_mgn_amt': '선물신규증거금액',
'futr_sprd_ord_mgna': '선물스프레드주문증거금',
'opt_sll_new_mgn_amt': '옵션매도신규증거금액',
'opt_buy_new_mgn_amt': '옵션매수신규증거금액',
'new_mgn_amt': '신규증거금액',
'opt_pric_mgna': '옵션가격증거금',
'fuop_pric_altr_mgna': '선물옵션가격변동증거금',
'futr_sprd_mgna': '선물스프레드증거금',
'uwdl_mgna': '인수도증거금',
'ctrt_per_min_mgna': '계약당최소증거금',
'tot_risk_mgna': '총위험증거금',
'netrisk_brkg_mgna': '순위험위탁증거금',
'opt_sll_chgs': '옵션매도대금',
'opt_buy_chgs': '옵션매수대금',
'futr_loss_amt': '선물손실금액',
'futr_prft_amt': '선물이익금액',
'thdt_ccld_net_loss_amt': '당일체결순손실금액',
'brkg_mgna': '위탁증거금',
'futr_new_mgn_amt': '선물신규증거금액',
'futr_sprd_ord_mgna': '선물스프레드주문증거금',
'opt_sll_new_mgn_amt': '옵션매도신규증거금액',
'opt_buy_new_mgn_amt': '옵션매수신규증거금액',
'new_mgn_amt': '신규증거금액',
'opt_pric_mgna': '옵션가격증거금',
'fuop_pric_altr_mgna': '선물옵션가격변동증거금',
'futr_sprd_mgna': '선물스프레드증거금',
'uwdl_mgna': '인수도증거금',
'ctrt_per_min_mgna': '계약당최소증거금',
'tot_risk_mgna': '총위험증거금',
'netrisk_brkg_mgna': '순위험위탁증거금',
'opt_sll_chgs': '옵션매도대금',
'opt_buy_chgs': '옵션매수대금',
'futr_loss_amt': '선물손실금액',
'futr_prft_amt': '선물이익금액',
'thdt_ccld_net_loss_amt': '당일체결순손실금액',
'brkg_mgna': '위탁증거금',
'dnca_cash': '예수금현금',
'dnca_sbst': '예수금대용',
'dnca_tota': '예수금총액',
'wdrw_psbl_cash_amt': '인출가능현금금액',
'wdrw_psbl_sbsa': '인출가능대용금액',
'wdrw_psbl_tot_amt': '인출가능총금액',
'ord_psbl_cash_amt': '주문가능현금금액',
'ord_psbl_sbsa': '주문가능대용금액',
'ord_psbl_tot_amt': '주문가능총금액',
'brkg_mgna_cash_amt': '위탁증거금현금금액',
'brkg_mgna_sbst': '위탁증거금대용',
'brkg_mgna_tot_amt': '위탁증거금총금액',
'add_mgna_cash_amt': '추가증거금현금금액',
'add_mgna_sbsa': '추가증거금대용금액',
'add_mgna_tot_amt': '추가증거금총금액',
'bfdy_sbst_sll_sbst_amt': '전일대용매도대용금액',
'thdt_sbst_sll_sbst_amt': '당일대용매도대용금액',
'bfdy_sbst_sll_ccld_amt': '전일대용매도체결금액',
'thdt_sbst_sll_ccld_amt': '당일대용매도체결금액',
'opt_dfpa': '옵션차금',
'excc_dfpa': '정산차금',
'fee_amt': '수수료금액',
'nxdy_dncl_amt': '익일예수금액',
'prsm_dpast_amt': '추정예탁자산금액',
'opt_buy_exus_acnt_yn': '옵션매수전용계좌여부',
'base_dpsa_gdat_grad_cd': '기본예탁금차등등급코드',
'opt_base_dpsa_gdat_grad_cd': '옵션기본예탁금차등등급코드'
}
NUMERIC_COLUMNS = []
def main():
"""
(야간)선물옵션 증거금 상세 조회 테스트 함수
이 함수는 (야간)선물옵션 증거금 상세 API를 호출하여 결과를 출력합니다.
Returns:
None
"""
# pandas 출력 옵션 설정
pd.set_option('display.max_columns', None) # 모든 컬럼 표시
pd.set_option('display.width', None) # 출력 너비 제한 해제
pd.set_option('display.max_rows', None) # 모든 행 표시
# 인증 토큰 발급
ka.auth()
trenv = ka.getTREnv()
# case1 조회
logging.info("=== case1 조회 ===")
try:
result1, result2, result3 = ngt_margin_detail(cano=trenv.my_acct, acnt_prdt_cd=trenv.my_prod, mgna_dvsn_cd="01")
except ValueError as e:
logging.error("에러 발생: %s" % str(e))
return
# output1 처리
logging.info("=== output1 결과 ===")
logging.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)
logging.info("결과:")
print(result1)
# output2 처리
logging.info("=== output2 결과 ===")
logging.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)
logging.info("결과:")
print(result2)
# output3 처리
logging.info("=== output3 결과 ===")
logging.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)
logging.info("결과:")
print(result3)
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,74 @@
"""
Created on 20250116
"""
import sys
import logging
from typing import Tuple
import pandas as pd
sys.path.extend(['../..', '.'])
import kis_auth as ka
# 로깅 설정
logging.basicConfig(level=logging.INFO)
##############################################################################################
# [국내선물옵션] 주문/계좌 > (야간)선물옵션 증거금 상세 [국내선물-024]
##############################################################################################
# 상수 정의
API_URL = "/uapi/domestic-futureoption/v1/trading/ngt-margin-detail"
def ngt_margin_detail(
cano: str, # 종합계좌번호
acnt_prdt_cd: str, # 계좌상품코드
mgna_dvsn_cd: str # 증거금 구분코드
) -> Tuple[pd.DataFrame, pd.DataFrame, pd.DataFrame]:
"""
(야간)선물옵션 증거금상세 API입니다.
한국투자 HTS(eFriend Force) > [2537] 야간선물옵션 증거금상세 화면 의 기능을 API로 개발한 사항으로, 해당 화면을 참고하시면 기능을 이해하기 쉽습니다.
Args:
cano (str): [필수] 종합계좌번호
acnt_prdt_cd (str): [필수] 계좌상품코드 (ex. 03)
mgna_dvsn_cd (str): [필수] 증거금 구분코드 (ex. 01:위탁, 02:유지)
Returns:
Tuple[pd.DataFrame, pd.DataFrame, pd.DataFrame]: (output1, output2, output3) 데이터프레임
Example:
>>> df1, df2, df3 = ngt_margin_detail(cano=trenv.my_acct, acnt_prdt_cd=trenv.my_prod, mgna_dvsn_cd="01")
>>> print(df1)
"""
if cano == "":
raise ValueError("cano is required")
if acnt_prdt_cd == "":
raise ValueError("acnt_prdt_cd is required (e.g. '03')")
if mgna_dvsn_cd == "":
raise ValueError("mgna_dvsn_cd is required (e.g. '01:위탁, 02:유지')")
tr_id = "CTFN7107R" # (야간)선물옵션 증거금 상세
params = {
"CANO": cano,
"ACNT_PRDT_CD": acnt_prdt_cd,
"MGNA_DVSN_CD": mgna_dvsn_cd
}
res = ka._url_fetch(API_URL, tr_id, "", params)
if res.isOK():
output1_data = pd.DataFrame(res.getBody().output1)
output2_data = pd.DataFrame(res.getBody().output2)
output3_data = pd.DataFrame([res.getBody().output3])
return output1_data, output2_data, output3_data
else:
res.printError(url=API_URL)
return pd.DataFrame(), pd.DataFrame(), pd.DataFrame()

View File

@@ -0,0 +1,73 @@
"""
Created on 20250601
"""
import logging
import sys
import pandas as pd
sys.path.extend(['../..', '.'])
import kis_auth as ka
from option_exp_ccnl import option_exp_ccnl
# 로깅 설정
logging.basicConfig(level=logging.INFO)
##############################################################################################
# [국내선물옵션] 실시간시세 > 주식옵션 실시간예상체결 [실시간-046]
##############################################################################################
COLUMN_MAPPING = {
"optn_shrn_iscd": "옵션단축종목코드",
"bsop_hour": "영업시간",
"antc_cnpr": "예상체결가",
"antc_cntg_vrss": "예상체결대비",
"antc_cntg_vrss_sign": "예상체결대비부호",
"antc_cntg_prdy_ctrt": "예상체결전일대비율",
"antc_mkop_cls_code": "예상장운영구분코드"
}
NUMERIC_COLUMNS = []
def main():
"""
주식옵션 실시간예상체결
Returns:
None
"""
# 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")
# 조회 - case1
kws.subscribe(request=option_exp_ccnl, data=["339W08088"])
# 결과 표시
def on_result(ws, tr_id: str, result: pd.DataFrame, data_map: dict):
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').round(2)
logging.info("결과:")
print(result)
kws.start(on_result=on_result)
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,64 @@
"""
Created on 20250601
"""
import logging
import sys
sys.path.extend(['../..', '.'])
import kis_auth as ka
# 로깅 설정
logging.basicConfig(level=logging.INFO)
##############################################################################################
# [국내선물옵션] 실시간시세 > 주식옵션 실시간예상체결 [실시간-046]
##############################################################################################
def option_exp_ccnl(
tr_type: str,
tr_key: str,
) -> (dict, list[str]):
"""
[국내선물옵션] 실시간시세
주식옵션 실시간예상체결 [실시간-046]
Args:
tr_type (str): [필수] 등록/해제
tr_key (str): [필수] 종목코드
Returns:
message (dict): 메시지 데이터
columns (list[str]): 컬럼 정보
Example:
>>> msg, columns = option_exp_ccnl("1", "101W9000")
>>> print(msg, columns)
"""
# 필수 파라미터 검증
if tr_type == "":
raise ValueError("tr_type is required")
if tr_key == "":
raise ValueError("tr_key is required")
tr_id = "H0ZOANC0"
params = {
"tr_key": tr_key,
}
msg = ka.data_fetch(tr_id, tr_type, params)
columns = [
"optn_shrn_iscd",
"bsop_hour",
"antc_cnpr",
"antc_cntg_vrss",
"antc_cntg_vrss_sign",
"antc_cntg_prdy_ctrt",
"antc_mkop_cls_code"
]
return msg, columns

View File

@@ -0,0 +1,87 @@
"""
Created on 20250116
"""
import sys
import logging
import pandas as pd
sys.path.extend(['../..', '.'])
import kis_auth as ka
from order import order
# 로깅 설정
logging.basicConfig(level=logging.INFO)
##############################################################################################
# [국내선물옵션] 주문/계좌 > 선물옵션 주문[v1_국내선물-001]
##############################################################################################
COLUMN_MAPPING = {
'KRX_FWDG_ORD_ORGNO': '한국거래소전송주문조직번호',
'ODNO': '주문번호',
'ORD_TMD': '주문시각'
}
NUMERIC_COLUMNS = []
def main():
"""
선물옵션 주문 테스트 함수
이 함수는 선물옵션 주문 API를 호출하여 결과를 출력합니다.
Returns:
None
"""
# pandas 출력 옵션 설정
pd.set_option('display.max_columns', None) # 모든 컬럼 표시
pd.set_option('display.width', None) # 출력 너비 제한 해제
pd.set_option('display.max_rows', None) # 모든 행 표시
# 인증 토큰 발급
ka.auth()
trenv = ka.getTREnv()
# case1 조회
logging.info("=== case1 조회 ===")
try:
result = order(
env_dv="real",
ord_dv="day",
ord_prcs_dvsn_cd="02",
cano=trenv.my_acct,
acnt_prdt_cd=trenv.my_prod,
sll_buy_dvsn_cd="02",
shtn_pdno="101W09",
ord_qty="1",
unit_price="0",
nmpr_type_cd="02",
krx_nmpr_cndt_cd="0",
ord_dvsn_cd="02"
)
except ValueError as e:
logging.error("에러 발생: %s" % str(e))
return
logging.info("사용 가능한 컬럼: %s", 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').round(2)
logging.info("결과:")
print(result)
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,149 @@
"""
Created on 20250116
"""
import sys
import logging
import pandas as pd
sys.path.extend(['../..', '.'])
import kis_auth as ka
# 로깅 설정
logging.basicConfig(level=logging.INFO)
##############################################################################################
# [국내선물옵션] 주문/계좌 > 선물옵션 주문[v1_국내선물-001]
##############################################################################################
# 상수 정의
API_URL = "/uapi/domestic-futureoption/v1/trading/order"
def order(
env_dv: str, # 실전모의구분
ord_dv: str, # 매도매수구분
ord_prcs_dvsn_cd: str, # 주문처리구분코드
cano: str, # 종합계좌번호
acnt_prdt_cd: str, # 계좌상품코드
sll_buy_dvsn_cd: str, # 매도매수구분코드
shtn_pdno: str, # 단축상품번호
ord_qty: str, # 주문수량
unit_price: str, # 주문가격1
nmpr_type_cd: str, # 호가유형코드
krx_nmpr_cndt_cd: str, # 한국거래소호가조건코드
ord_dvsn_cd: str, # 주문구분코드
ctac_tlno: str = "", # 연락전화번호
fuop_item_dvsn_cd: str = "" # 선물옵션종목구분코드
) -> pd.DataFrame:
"""
[국내선물옵션] 주문/계좌 > 선물옵션 주문[v1_국내선물-001]
선물옵션 주문 API입니다.
* 선물옵션 운영시간 외 API 호출 시 애러가 발생하오니 운영시간을 확인해주세요.
※ POST API의 경우 BODY값의 key값들을 대문자로 작성하셔야 합니다.
(EX. "CANO" : "12345678", "ACNT_PRDT_CD": "01",...)
※ 종목코드 마스터파일 파이썬 정제코드는 한국투자증권 Github 참고 부탁드립니다.
https://github.com/koreainvestment/open-trading-api/tree/main/stocks_info
Args:
env_dv (str): [필수] 실전모의구분 (ex. real:실전, demo:모의)
ord_dv (str): [필수] 매도매수구분 (ex. day:주간, night:야간)
ord_prcs_dvsn_cd (str): [필수] 주문처리구분코드 (ex. 02:주문전송)
cano (str): [필수] 종합계좌번호 (ex. 계좌번호 체계(8-2)의 앞 8자리)
acnt_prdt_cd (str): [필수] 계좌상품코드 (ex. 계좌번호 체계(8-2)의 뒤 2자리)
sll_buy_dvsn_cd (str): [필수] 매도매수구분코드 (ex. 01:매도, 02:매수)
shtn_pdno (str): [필수] 단축상품번호 (ex. 종목번호, 선물 6자리 (예: 101W09), 옵션 9자리 (예: 201S03370))
ord_qty (str): [필수] 주문수량
unit_price (str): [필수] 주문가격1 (ex. 시장가나 최유리 지정가인 경우 0으로 입력)
nmpr_type_cd (str): [필수] 호가유형코드 (ex. 01:지정가, 02:시장가, 03:조건부, 04:최유리)
krx_nmpr_cndt_cd (str): [필수] 한국거래소호가조건코드 (ex. 0:없음, 3:IOC, 4:FOK)
ord_dvsn_cd (str): [필수] 주문구분코드 (ex. 01:지정가, 02:시장가, 03:조건부, 04:최유리, 10:지정가(IOC), 11:지정가(FOK), 12:시장가(IOC), 13:시장가(FOK), 14:최유리(IOC), 15:최유리(FOK))
ctac_tlno (str): 연락전화번호 (ex. 고객의 연락 가능한 전화번호)
fuop_item_dvsn_cd (str): 선물옵션종목구분코드 (ex. 공란(Default))
Returns:
pd.DataFrame: 선물옵션 주문 결과 데이터
Example:
>>> df = order(env_dv="real", ord_dv="day", ord_prcs_dvsn_cd="02", cano=trenv.my_acct, acnt_prdt_cd=trenv.my_prod, sll_buy_dvsn_cd="02", shtn_pdno="101W09", ord_qty="1", unit_price="0", nmpr_type_cd="02", krx_nmpr_cndt_cd="0", ord_dvsn_cd="02")
>>> print(df)
"""
# 필수 파라미터 검증
if env_dv == "":
raise ValueError("env_dv is required (e.g. 'real', 'demo')")
if ord_dv == "":
raise ValueError("ord_dv is required (e.g. 'day', 'night')")
if ord_prcs_dvsn_cd == "":
raise ValueError("ord_prcs_dvsn_cd is required (e.g. '02')")
if cano == "":
raise ValueError("cano is required (e.g. '계좌번호 체계(8-2)의 앞 8자리')")
if acnt_prdt_cd == "":
raise ValueError("acnt_prdt_cd is required (e.g. '계좌번호 체계(8-2)의 뒤 2자리')")
if sll_buy_dvsn_cd == "":
raise ValueError("sll_buy_dvsn_cd is required (e.g. '01', '02')")
if shtn_pdno == "":
raise ValueError("shtn_pdno is required (e.g. '101W09', '201S03370')")
if ord_qty == "":
raise ValueError("ord_qty is required")
if unit_price == "":
raise ValueError("unit_price is required (e.g. '0')")
if nmpr_type_cd == "":
raise ValueError("nmpr_type_cd is required (e.g. '01', '02', '03', '04')")
if krx_nmpr_cndt_cd == "":
raise ValueError("krx_nmpr_cndt_cd is required (e.g. '0', '3', '4')")
if ord_dvsn_cd == "":
raise ValueError("ord_dvsn_cd is required (e.g. '01', '02', '03', '04', '10', '11', '12', '13', '14', '15')")
# tr_id 설정
if env_dv == "real":
if ord_dv == "day":
tr_id = "TTTO1101U"
elif ord_dv == "night":
tr_id = "STTN1101U"
else:
raise ValueError("ord_dv can only be 'day' or 'night'")
elif env_dv == "demo":
if ord_dv == "day":
tr_id = "VTTO1101U"
else:
raise ValueError("ord_dv can only be 'day' for demo environment")
else:
raise ValueError("env_dv can only be 'real' or 'demo'")
params = {
"ORD_PRCS_DVSN_CD": ord_prcs_dvsn_cd,
"CANO": cano,
"ACNT_PRDT_CD": acnt_prdt_cd,
"SLL_BUY_DVSN_CD": sll_buy_dvsn_cd,
"SHTN_PDNO": shtn_pdno,
"ORD_QTY": ord_qty,
"UNIT_PRICE": unit_price,
"NMPR_TYPE_CD": nmpr_type_cd,
"KRX_NMPR_CNDT_CD": krx_nmpr_cndt_cd,
"ORD_DVSN_CD": ord_dvsn_cd,
"CTAC_TLNO": ctac_tlno,
"FUOP_ITEM_DVSN_CD": fuop_item_dvsn_cd
}
res = ka._url_fetch(API_URL, tr_id, "", params, postFlag=True)
if res.isOK():
return pd.DataFrame(res.getBody().output, index=[0])
else:
res.printError(url=API_URL)
return pd.DataFrame()

View File

@@ -0,0 +1,92 @@
"""
Created on 20250114
"""
import sys
import logging
import pandas as pd
sys.path.extend(['../..', '.'])
import kis_auth as ka
from order_rvsecncl import order_rvsecncl
# 로깅 설정
logging.basicConfig(level=logging.INFO)
##############################################################################################
# [국내선물옵션] 주문/계좌 > 선물옵션 정정취소주문[v1_국내선물-002]
##############################################################################################
COLUMN_MAPPING = {
'ACNT_NAME': '계좌명',
'TRAD_DVSN_NAME': '매매구분명',
'ITEM_NAME': '종목명',
'ORD_TMD': '주문시각',
'ORD_GNO_BRNO': '주문채번지점번호',
'ORGN_ODNO': '원주문번호',
'ODNO': '주문번호'
}
NUMERIC_COLUMNS = []
def main():
"""
선물옵션 정정취소주문 조회 테스트 함수
이 함수는 선물옵션 정정취소주문 API를 호출하여 결과를 출력합니다.
Returns:
None
"""
# pandas 출력 옵션 설정
pd.set_option('display.max_columns', None) # 모든 컬럼 표시
pd.set_option('display.width', None) # 출력 너비 제한 해제
pd.set_option('display.max_rows', None) # 모든 행 표시
# 인증 토큰 발급
ka.auth()
trenv = ka.getTREnv()
# case1 테스트
logging.info("=== case1 테스트 ===")
try:
result = order_rvsecncl(
env_dv="real",
day_dv="day",
ord_prcs_dvsn_cd="02",
cano=trenv.my_acct,
acnt_prdt_cd=trenv.my_prod,
rvse_cncl_dvsn_cd="02",
orgn_odno="0000004018",
ord_qty="0",
unit_price="0",
nmpr_type_cd="02",
krx_nmpr_cndt_cd="0",
rmn_qty_yn="Y",
ord_dvsn_cd="01"
)
except ValueError as e:
logging.error("에러 발생: %s" % str(e))
return
logging.info("사용 가능한 컬럼: %s", 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').round(2)
logging.info("결과:")
print(result)
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,113 @@
"""
Created on 20250114
"""
import sys
import logging
import pandas as pd
sys.path.extend(['../..', '.'])
import kis_auth as ka
# 로깅 설정
logging.basicConfig(level=logging.INFO)
##############################################################################################
# [국내선물옵션] 주문/계좌 > 선물옵션 정정취소주문[v1_국내선물-002]
##############################################################################################
# 상수 정의
API_URL = "/uapi/domestic-futureoption/v1/trading/order-rvsecncl"
def order_rvsecncl(
env_dv: str, # [필수] 실전모의구분 (ex. real:실전, demo:모의)
day_dv: str, # [필수] 주야간구분 (ex. day:주간, night:야간)
ord_prcs_dvsn_cd: str, # [필수] 주문처리구분코드 (ex. 02)
cano: str, # [필수] 종합계좌번호
acnt_prdt_cd: str, # [필수] 계좌상품코드
rvse_cncl_dvsn_cd: str, # [필수] 정정취소구분코드 (ex. 01:정정, 02:취소)
orgn_odno: str, # [필수] 원주문번호
ord_qty: str, # [필수] 주문수량 (ex. 0:전량, 그 외는 수량)
unit_price: str, # [필수] 주문가격1 (ex 0:시장가/최유리, 그 외 가격)
nmpr_type_cd: str, # [필수] 호가유형코드 (ex. 01:지정가, 02:시장가, 03:조건부, 04:최유리)
krx_nmpr_cndt_cd: str, # [필수] 한국거래소호가조건코드 (ex. 0:취소/없음, 3:IOC, 4:FOK)
rmn_qty_yn: str, # [필수] 잔여수량여부 (ex. Y:전량, N:일부)
ord_dvsn_cd: str, # [필수] 주문구분코드
fuop_item_dvsn_cd: str = "" # 선물옵션종목구분코드
) -> pd.DataFrame:
"""
선물옵션 주문 건에 대하여 정정 및 취소하는 API입니다. 단, 이미 체결된 건은 정정 및 취소가 불가합니다.
※ POST API의 경우 BODY값의 key값들을 대문자로 작성하셔야 합니다.
(EX. "CANO" : "12345678", "ACNT_PRDT_CD": "01",...)
Args:
env_dv (str): [필수] 실전모의구분 (ex. real:실전, demo:모의)
day_dv (str): [필수] 주야간구분 (ex. day:주간, night:야간)
ord_prcs_dvsn_cd (str): [필수] 주문처리구분코드 (ex. 02)
cano (str): [필수] 종합계좌번호
acnt_prdt_cd (str): [필수] 계좌상품코드
rvse_cncl_dvsn_cd (str): [필수] 정정취소구분코드 (ex. 01:정정, 02:취소)
orgn_odno (str): [필수] 원주문번호
ord_qty (str): [필수] 주문수량 (ex. 0:전량, 그 외는 수량)
unit_price (str): [필수] 주문가격1 (ex 0:시장가/최유리, 그 외 가격)
nmpr_type_cd (str): [필수] 호가유형코드 (ex. 01:지정가, 02:시장가, 03:조건부, 04:최유리)
krx_nmpr_cndt_cd (str): [필수] 한국거래소호가조건코드 (ex. 0:취소/없음, 3:IOC, 4:FOK)
rmn_qty_yn (str): [필수] 잔여수량여부 (ex. Y:전량, N:일부)
ord_dvsn_cd (str): [필수] 주문구분코드
fuop_item_dvsn_cd (str): 선물옵션종목구분코드
Returns:
pd.DataFrame: 선물옵션 정정취소주문 결과 데이터
Example:
>>> df = order_rvsecncl(
... env_dv="real", day_dv="day", ord_prcs_dvsn_cd="02",
... cano=trenv.my_acct, acnt_prdt_cd=trenv.my_prod, rvse_cncl_dvsn_cd="02",
... orgn_odno="0000004018", ord_qty="0", unit_price="0",
... nmpr_type_cd="02", krx_nmpr_cndt_cd="0", rmn_qty_yn="Y",
... ord_dvsn_cd="01"
... )
>>> print(df)
"""
# tr_id 설정
if env_dv == "real":
if day_dv == "day":
tr_id = "TTTO1103U"
elif day_dv == "night":
tr_id = "TTTN1103U"
else:
raise ValueError("day_dv can only be 'day' or 'night'")
elif env_dv == "demo":
if day_dv == "day":
tr_id = "VTTO1103U"
else:
raise ValueError("day_dv can only be 'day' for demo environment")
else:
raise ValueError("env_dv is required (e.g. 'real' or 'demo')")
params = {
"ORD_PRCS_DVSN_CD": ord_prcs_dvsn_cd,
"CANO": cano,
"ACNT_PRDT_CD": acnt_prdt_cd,
"RVSE_CNCL_DVSN_CD": rvse_cncl_dvsn_cd,
"ORGN_ODNO": orgn_odno,
"ORD_QTY": ord_qty,
"UNIT_PRICE": unit_price,
"NMPR_TYPE_CD": nmpr_type_cd,
"KRX_NMPR_CNDT_CD": krx_nmpr_cndt_cd,
"RMN_QTY_YN": rmn_qty_yn,
"ORD_DVSN_CD": ord_dvsn_cd,
"FUOP_ITEM_DVSN_CD": fuop_item_dvsn_cd
}
res = ka._url_fetch(API_URL, tr_id, "", params, postFlag=True)
if res.isOK():
return pd.DataFrame(res.getBody().output)
else:
res.printError(url=API_URL)
return pd.DataFrame()

View File

@@ -0,0 +1,116 @@
"""
Created on 20250601
"""
import logging
import sys
import pandas as pd
sys.path.extend(['../..', '.'])
import kis_auth as ka
from stock_futures_realtime_conclusion import stock_futures_realtime_conclusion
# 로깅 설정
logging.basicConfig(level=logging.INFO)
##############################################################################################
# [국내선물옵션] 실시간시세 > 주식선물 실시간체결가 [실시간-029]
##############################################################################################
COLUMN_MAPPING = {
"futs_shrn_iscd": "선물단축종목코드",
"bsop_hour": "영업시간",
"stck_prpr": "주식현재가",
"prdy_vrss_sign": "전일대비부호",
"prdy_vrss": "전일대비",
"futs_prdy_ctrt": "선물전일대비율",
"stck_oprc": "주식시가2",
"stck_hgpr": "주식최고가",
"stck_lwpr": "주식최저가",
"last_cnqn": "최종거래량",
"acml_vol": "누적거래량",
"acml_tr_pbmn": "누적거래대금",
"hts_thpr": "HTS이론가",
"mrkt_basis": "시장베이시스",
"dprt": "괴리율",
"nmsc_fctn_stpl_prc": "근월물약정가",
"fmsc_fctn_stpl_prc": "원월물약정가",
"spead_prc": "스프레드1",
"hts_otst_stpl_qty": "HTS미결제약정수량",
"otst_stpl_qty_icdc": "미결제약정수량증감",
"oprc_hour": "시가시간",
"oprc_vrss_prpr_sign": "시가2대비현재가부호",
"oprc_vrss_prpr": "시가2대비현재가",
"hgpr_hour": "최고가시간",
"hgpr_vrss_prpr_sign": "최고가대비현재가부호",
"hgpr_vrss_prpr": "최고가대비현재가",
"lwpr_hour": "최저가시간",
"lwpr_vrss_prpr_sign": "최저가대비현재가부호",
"lwpr_vrss_prpr": "최저가대비현재가",
"shnu_rate": "매수2비율",
"cttr": "체결강도",
"esdg": "괴리도",
"otst_stpl_rgbf_qty_icdc": "미결제약정직전수량증감",
"thpr_basis": "이론베이시스",
"askp1": "매도호가1",
"bidp1": "매수호가1",
"askp_rsqn1": "매도호가잔량1",
"bidp_rsqn1": "매수호가잔량1",
"seln_cntg_csnu": "매도체결건수",
"shnu_cntg_csnu": "매수체결건수",
"ntby_cntg_csnu": "순매수체결건수",
"seln_cntg_smtn": "총매도수량",
"shnu_cntg_smtn": "총매수수량",
"total_askp_rsqn": "총매도호가잔량",
"total_bidp_rsqn": "총매수호가잔량",
"prdy_vol_vrss_acml_vol_rate": "전일거래량대비등락율",
"dynm_mxpr": "실시간상한가",
"dynm_llam": "실시간하한가",
"dynm_prc_limt_yn": "실시간가격제한구분"
}
NUMERIC_COLUMNS = []
def main():
"""
주식선물 실시간체결가
Returns:
None
"""
# 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=stock_futures_realtime_conclusion, data=["111W08"])
# 결과 표시
def on_result(ws, tr_id: str, result: pd.DataFrame, data_map: dict):
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').round(2)
logging.info("결과:")
print(result)
kws.start(on_result=on_result)
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,108 @@
"""
Created on 20250601
"""
import logging
import sys
sys.path.extend(['../..', '.'])
import kis_auth as ka
# 로깅 설정
logging.basicConfig(level=logging.INFO)
##############################################################################################
# [국내선물옵션] 실시간시세 > 주식선물 실시간체결가 [실시간-029]
##############################################################################################
def stock_futures_realtime_conclusion(
tr_type: str,
tr_key: str,
) -> (dict, list[str]):
"""
주식선물 실시간체결가 API입니다.
실시간 웹소켓 연결을 통해 주식선물의 실시간 체결가 정보를 수신할 수 있습니다.
주식 현재가, 시고저가, 체결량, 누적거래량, 이론가, 베이시스, 괴리율 등의 상세 정보를 제공합니다.
매도/매수 호가, 체결 건수, 미결제 약정 수량 등의 선물거래 필수 정보를 포함합니다.
실전계좌만 지원되며 모의투자는 미지원됩니다.
Args:
tr_type (str): [필수] 구독 등록/해제 여부 (ex. "1": 구독, "2": 해제)
tr_key (str): [필수] 종목코드 (ex. 101S12)
Returns:
message (str): 메시지 데이터
Example:
>>> msg, columns = stock_futures_realtime_conclusion("1", "101S12")
>>> print(msg, columns)
"""
# 필수 파라미터 검증
if tr_type == "":
raise ValueError("tr_type is required")
if tr_key == "":
raise ValueError("tr_key is required")
tr_id = "H0ZFCNT0"
params = {
"tr_key": tr_key,
}
msg = ka.data_fetch(tr_id, tr_type, params)
columns = [
"futs_shrn_iscd",
"bsop_hour",
"stck_prpr",
"prdy_vrss_sign",
"prdy_vrss",
"futs_prdy_ctrt",
"stck_oprc",
"stck_hgpr",
"stck_lwpr",
"last_cnqn",
"acml_vol",
"acml_tr_pbmn",
"hts_thpr",
"mrkt_basis",
"dprt",
"nmsc_fctn_stpl_prc",
"fmsc_fctn_stpl_prc",
"spead_prc",
"hts_otst_stpl_qty",
"otst_stpl_qty_icdc",
"oprc_hour",
"oprc_vrss_prpr_sign",
"oprc_vrss_prpr",
"hgpr_hour",
"hgpr_vrss_prpr_sign",
"hgpr_vrss_prpr",
"lwpr_hour",
"lwpr_vrss_prpr_sign",
"lwpr_vrss_prpr",
"shnu_rate",
"cttr",
"esdg",
"otst_stpl_rgbf_qty_icdc",
"thpr_basis",
"askp1",
"bidp1",
"askp_rsqn1",
"bidp_rsqn1",
"seln_cntg_csnu",
"shnu_cntg_csnu",
"ntby_cntg_csnu",
"seln_cntg_smtn",
"shnu_cntg_smtn",
"total_askp_rsqn",
"total_bidp_rsqn",
"prdy_vol_vrss_acml_vol_rate",
"dynm_mxpr",
"dynm_llam",
"dynm_prc_limt_yn"
]
return msg, columns

View File

@@ -0,0 +1,135 @@
"""
Created on 20250601
"""
import logging
import sys
import pandas as pd
sys.path.extend(['../..', '.'])
import kis_auth as ka
from stock_futures_realtime_quote import stock_futures_realtime_quote
# 로깅 설정
logging.basicConfig(level=logging.INFO)
##############################################################################################
# [국내선물옵션] 실시간시세 > 주식선물 실시간호가 [실시간-030]
##############################################################################################
COLUMN_MAPPING = {
"futs_shrn_iscd": "선물단축종목코드",
"bsop_hour": "영업시간",
"askp1": "매도호가1",
"askp2": "매도호가2",
"askp3": "매도호가3",
"askp4": "매도호가4",
"askp5": "매도호가5",
"askp6": "매도호가6",
"askp7": "매도호가7",
"askp8": "매도호가8",
"askp9": "매도호가9",
"askp10": "매도호가10",
"bidp1": "매수호가1",
"bidp2": "매수호가2",
"bidp3": "매수호가3",
"bidp4": "매수호가4",
"bidp5": "매수호가5",
"bidp6": "매수호가6",
"bidp7": "매수호가7",
"bidp8": "매수호가8",
"bidp9": "매수호가9",
"bidp10": "매수호가10",
"askp_csnu1": "매도호가건수1",
"askp_csnu2": "매도호가건수2",
"askp_csnu3": "매도호가건수3",
"askp_csnu4": "매도호가건수4",
"askp_csnu5": "매도호가건수5",
"askp_csnu6": "매도호가건수6",
"askp_csnu7": "매도호가건수7",
"askp_csnu8": "매도호가건수8",
"askp_csnu9": "매도호가건수9",
"askp_csnu10": "매도호가건수10",
"bidp_csnu1": "매수호가건수1",
"bidp_csnu2": "매수호가건수2",
"bidp_csnu3": "매수호가건수3",
"bidp_csnu4": "매수호가건수4",
"bidp_csnu5": "매수호가건수5",
"bidp_csnu6": "매수호가건수6",
"bidp_csnu7": "매수호가건수7",
"bidp_csnu8": "매수호가건수8",
"bidp_csnu9": "매수호가건수9",
"bidp_csnu10": "매수호가건수10",
"askp_rsqn1": "매도호가잔량1",
"askp_rsqn2": "매도호가잔량2",
"askp_rsqn3": "매도호가잔량3",
"askp_rsqn4": "매도호가잔량4",
"askp_rsqn5": "매도호가잔량5",
"askp_rsqn6": "매도호가잔량6",
"askp_rsqn7": "매도호가잔량7",
"askp_rsqn8": "매도호가잔량8",
"askp_rsqn9": "매도호가잔량9",
"askp_rsqn10": "매도호가잔량10",
"bidp_rsqn1": "매수호가잔량1",
"bidp_rsqn2": "매수호가잔량2",
"bidp_rsqn3": "매수호가잔량3",
"bidp_rsqn4": "매수호가잔량4",
"bidp_rsqn5": "매수호가잔량5",
"bidp_rsqn6": "매수호가잔량6",
"bidp_rsqn7": "매수호가잔량7",
"bidp_rsqn8": "매수호가잔량8",
"bidp_rsqn9": "매수호가잔량9",
"bidp_rsqn10": "매수호가잔량10",
"total_askp_csnu": "총매도호가건수",
"total_bidp_csnu": "총매수호가건수",
"total_askp_rsqn": "총매도호가잔량",
"total_bidp_rsqn": "총매수호가잔량",
"total_askp_rsqn_icdc": "총매도호가잔량증감",
"total_bidp_rsqn_icdc": "총매수호가잔량증감"
}
NUMERIC_COLUMNS = []
def main():
"""
주식선물 실시간호가
Returns:
None
"""
# 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=stock_futures_realtime_quote, data=["111W08"])
# 결과 표시
def on_result(ws, tr_id: str, result: pd.DataFrame, data_map: dict):
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').round(2)
logging.info("결과:")
print(result)
kws.start(on_result=on_result)
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,128 @@
"""
Created on 20250601
"""
import logging
import sys
sys.path.extend(['../..', '.'])
import kis_auth as ka
# 로깅 설정
logging.basicConfig(level=logging.INFO)
##############################################################################################
# [국내선물옵션] 실시간시세 > 주식선물 실시간호가 [실시간-030]
##############################################################################################
def stock_futures_realtime_quote(
tr_type: str,
tr_key: str,
) -> (dict, list[str]):
"""
주식선물 실시간호가 API입니다.
실시간 웹소켓 연결을 통해 주식선물의 실시간 호가 정보를 수신할 수 있습니다.
매도/매수 호가 1~10단계까지의 확장된 호가 정보를 제공하는 특별한 API입니다.
호가별 건수, 호가별 잔량 등의 상세 정보를 포함합니다.
선물옵션 호가 데이터는 0.2초 필터링 옵션이 적용됩니다.
실전계좌만 지원되며 모의투자는 미지원됩니다.
Args:
tr_type (str): [필수] 구독 등록/해제 여부 (ex. "1": 구독, "2": 해제)
tr_key (str): [필수] 종목코드 (ex. 101S12)
Returns:
message (str): 메시지 데이터
Example:
>>> msg, columns = stock_futures_realtime_quote("1", "101S12")
>>> print(msg, columns)
"""
# 필수 파라미터 검증
if tr_type == "":
raise ValueError("tr_type is required")
if tr_key == "":
raise ValueError("tr_key is required")
tr_id = "H0ZFASP0"
params = {
"tr_key": tr_key,
}
msg = ka.data_fetch(tr_id, tr_type, params)
columns = [
"futs_shrn_iscd",
"bsop_hour",
"askp1",
"askp2",
"askp3",
"askp4",
"askp5",
"askp6",
"askp7",
"askp8",
"askp9",
"askp10",
"bidp1",
"bidp2",
"bidp3",
"bidp4",
"bidp5",
"bidp6",
"bidp7",
"bidp8",
"bidp9",
"bidp10",
"askp_csnu1",
"askp_csnu2",
"askp_csnu3",
"askp_csnu4",
"askp_csnu5",
"askp_csnu6",
"askp_csnu7",
"askp_csnu8",
"askp_csnu9",
"askp_csnu10",
"bidp_csnu1",
"bidp_csnu2",
"bidp_csnu3",
"bidp_csnu4",
"bidp_csnu5",
"bidp_csnu6",
"bidp_csnu7",
"bidp_csnu8",
"bidp_csnu9",
"bidp_csnu10",
"askp_rsqn1",
"askp_rsqn2",
"askp_rsqn3",
"askp_rsqn4",
"askp_rsqn5",
"askp_rsqn6",
"askp_rsqn7",
"askp_rsqn8",
"askp_rsqn9",
"askp_rsqn10",
"bidp_rsqn1",
"bidp_rsqn2",
"bidp_rsqn3",
"bidp_rsqn4",
"bidp_rsqn5",
"bidp_rsqn6",
"bidp_rsqn7",
"bidp_rsqn8",
"bidp_rsqn9",
"bidp_rsqn10",
"total_askp_csnu",
"total_bidp_csnu",
"total_askp_rsqn",
"total_bidp_rsqn",
"total_askp_rsqn_icdc",
"total_bidp_rsqn_icdc"
]
return msg, columns

View File

@@ -0,0 +1,134 @@
"""
Created on 20250601
"""
import logging
import sys
import pandas as pd
sys.path.extend(['../..', '.'])
import kis_auth as ka
from stock_option_asking_price import stock_option_asking_price
# 로깅 설정
logging.basicConfig(level=logging.INFO)
##############################################################################################
# [국내선물옵션] 실시간시세 > 주식옵션 실시간호가 [실시간-045]
##############################################################################################
COLUMN_MAPPING = {
"optn_shrn_iscd": "종목코드",
"bsop_hour": "영업시간",
"optn_askp1": "옵션매도호가1",
"optn_askp2": "옵션매도호가2",
"optn_askp3": "옵션매도호가3",
"optn_askp4": "옵션매도호가4",
"optn_askp5": "옵션매도호가5",
"optn_bidp1": "옵션매수호가1",
"optn_bidp2": "옵션매수호가2",
"optn_bidp3": "옵션매수호가3",
"optn_bidp4": "옵션매수호가4",
"optn_bidp5": "옵션매수호가5",
"askp_csnu1": "매도호가건수1",
"askp_csnu2": "매도호가건수2",
"askp_csnu3": "매도호가건수3",
"askp_csnu4": "매도호가건수4",
"askp_csnu5": "매도호가건수5",
"bidp_csnu1": "매수호가건수1",
"bidp_csnu2": "매수호가건수2",
"bidp_csnu3": "매수호가건수3",
"bidp_csnu4": "매수호가건수4",
"bidp_csnu5": "매수호가건수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_csnu": "총매도호가건수",
"total_bidp_csnu": "총매수호가건수",
"total_askp_rsqn": "총매도호가잔량",
"total_bidp_rsqn": "총매수호가잔량",
"total_askp_rsqn_icdc": "총매도호가잔량증감",
"total_bidp_rsqn_icdc": "총매수호가잔량증감",
"optn_askp6": "옵션매도호가6",
"optn_askp7": "옵션매도호가7",
"optn_askp8": "옵션매도호가8",
"optn_askp9": "옵션매도호가9",
"optn_askp10": "옵션매도호가10",
"optn_bidp6": "옵션매수호가6",
"optn_bidp7": "옵션매수호가7",
"optn_bidp8": "옵션매수호가8",
"optn_bidp9": "옵션매수호가9",
"optn_bidp10": "옵션매수호가10",
"askp_csnu6": "매도호가건수6",
"askp_csnu7": "매도호가건수7",
"askp_csnu8": "매도호가건수8",
"askp_csnu9": "매도호가건수9",
"askp_csnu10": "매도호가건수10",
"bidp_csnu6": "매수호가건수6",
"bidp_csnu7": "매수호가건수7",
"bidp_csnu8": "매수호가건수8",
"bidp_csnu9": "매수호가건수9",
"bidp_csnu10": "매수호가건수10",
"askp_rsqn6": "매도호가잔량6",
"askp_rsqn7": "매도호가잔량7",
"askp_rsqn8": "매도호가잔량8",
"askp_rsqn9": "매도호가잔량9",
"askp_rsqn10": "매도호가잔량10",
"bidp_rsqn6": "매수호가잔량6",
"bidp_rsqn7": "매수호가잔량7",
"bidp_rsqn8": "매수호가잔량8",
"bidp_rsqn9": "매수호가잔량9",
"bidp_rsqn10": "매수호가잔량10"
}
NUMERIC_COLUMNS = []
def main():
"""
국내선물옵션 주식옵션 실시간호가
Returns:
None
"""
# 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=stock_option_asking_price, data=["239W08090"])
# 결과 표시
def on_result(ws, tr_id: str, result: pd.DataFrame, data_map: dict):
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').round(2)
logging.info("결과:")
print(result)
kws.start(on_result=on_result)
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,124 @@
"""
Created on 20250601
"""
import logging
import sys
sys.path.extend(['../..', '.'])
import kis_auth as ka
# 로깅 설정
logging.basicConfig(level=logging.INFO)
##############################################################################################
# [국내선물옵션] 실시간시세 > 주식옵션 실시간호가 [실시간-045]
##############################################################################################
def stock_option_asking_price(
tr_type: str,
tr_key: str,
) -> (dict, list[str]):
"""
국내선물옵션 주식옵션 실시간호가 API입니다.
Args:
tr_type (str): [필수] 등록/해제
tr_key (str): [필수] 선물단축종목코드
Returns:
message (dict): 메시지 데이터
columns (list[str]): 컬럼 정보
Example:
>>> msg, columns = stock_option_asking_price("1", "111W80")
>>> print(msg, columns)
"""
# 필수 파라미터 검증
if tr_type == "":
raise ValueError("tr_type is required")
if tr_key == "":
raise ValueError("tr_key is required")
tr_id = "H0ZOASP0"
params = {
"tr_key": tr_key,
}
msg = ka.data_fetch(tr_id, tr_type, params)
columns = [
"optn_shrn_iscd",
"bsop_hour",
"optn_askp1",
"optn_askp2",
"optn_askp3",
"optn_askp4",
"optn_askp5",
"optn_bidp1",
"optn_bidp2",
"optn_bidp3",
"optn_bidp4",
"optn_bidp5",
"askp_csnu1",
"askp_csnu2",
"askp_csnu3",
"askp_csnu4",
"askp_csnu5",
"bidp_csnu1",
"bidp_csnu2",
"bidp_csnu3",
"bidp_csnu4",
"bidp_csnu5",
"askp_rsqn1",
"askp_rsqn2",
"askp_rsqn3",
"askp_rsqn4",
"askp_rsqn5",
"bidp_rsqn1",
"bidp_rsqn2",
"bidp_rsqn3",
"bidp_rsqn4",
"bidp_rsqn5",
"total_askp_csnu",
"total_bidp_csnu",
"total_askp_rsqn",
"total_bidp_rsqn",
"total_askp_rsqn_icdc",
"total_bidp_rsqn_icdc",
"optn_askp6",
"optn_askp7",
"optn_askp8",
"optn_askp9",
"optn_askp10",
"optn_bidp6",
"optn_bidp7",
"optn_bidp8",
"optn_bidp9",
"optn_bidp10",
"askp_csnu6",
"askp_csnu7",
"askp_csnu8",
"askp_csnu9",
"askp_csnu10",
"bidp_csnu6",
"bidp_csnu7",
"bidp_csnu8",
"bidp_csnu9",
"bidp_csnu10",
"askp_rsqn6",
"askp_rsqn7",
"askp_rsqn8",
"askp_rsqn9",
"askp_rsqn10",
"bidp_rsqn6",
"bidp_rsqn7",
"bidp_rsqn8",
"bidp_rsqn9",
"bidp_rsqn10"
]
return msg, columns

View File

@@ -0,0 +1,119 @@
"""
Created on 20250601
"""
import logging
import sys
import pandas as pd
sys.path.extend(['../..', '.'])
import kis_auth as ka
from stock_option_ccnl import stock_option_ccnl
# 로깅 설정
logging.basicConfig(level=logging.INFO)
##############################################################################################
# [국내선물옵션] 실시간시세 > 주식옵션 실시간체결가 [실시간-044]
##############################################################################################
COLUMN_MAPPING = {
"optn_shrn_iscd": "종목코드",
"bsop_hour": "영업시간",
"optn_prpr": "옵션현재가",
"prdy_vrss_sign": "전일대비부호",
"optn_prdy_vrss": "옵션전일대비",
"prdy_ctrt": "전일대비율",
"optn_oprc": "옵션시가2",
"optn_hgpr": "옵션최고가",
"optn_lwpr": "옵션최저가",
"last_cnqn": "최종거래량",
"acml_vol": "누적거래량",
"acml_tr_pbmn": "누적거래대금",
"hts_thpr": "HTS이론가",
"hts_otst_stpl_qty": "HTS미결제약정수량",
"otst_stpl_qty_icdc": "미결제약정수량증감",
"oprc_hour": "시가시간",
"oprc_vrss_prpr_sign": "시가2대비현재가부호",
"oprc_vrss_nmix_prpr": "시가대비지수현재가",
"hgpr_hour": "최고가시간",
"hgpr_vrss_prpr_sign": "최고가대비현재가부호",
"hgpr_vrss_nmix_prpr": "최고가대비지수현재가",
"lwpr_hour": "최저가시간",
"lwpr_vrss_prpr_sign": "최저가대비현재가부호",
"lwpr_vrss_nmix_prpr": "최저가대비지수현재가",
"shnu_rate": "매수2비율",
"prmm_val": "프리미엄값",
"invl_val": "내재가치값",
"tmvl_val": "시간가치값",
"delta": "델타",
"gama": "감마",
"vega": "베가",
"theta": "세타",
"rho": "로우",
"hts_ints_vltl": "HTS내재변동성",
"esdg": "괴리도",
"otst_stpl_rgbf_qty_icdc": "미결제약정직전수량증감",
"thpr_basis": "이론베이시스",
"unas_hist_vltl": "역사적변동성",
"cttr": "체결강도",
"dprt": "괴리율",
"mrkt_basis": "시장베이시스",
"optn_askp1": "옵션매도호가1",
"optn_bidp1": "옵션매수호가1",
"askp_rsqn1": "매도호가잔량1",
"bidp_rsqn1": "매수호가잔량1",
"seln_cntg_csnu": "매도체결건수",
"shnu_cntg_csnu": "매수체결건수",
"ntby_cntg_csnu": "순매수체결건수",
"seln_cntg_smtn": "총매도수량",
"shnu_cntg_smtn": "총매수수량",
"total_askp_rsqn": "총매도호가잔량",
"total_bidp_rsqn": "총매수호가잔량",
"prdy_vol_vrss_acml_vol_rate": "전일거래량대비등락율"
}
NUMERIC_COLUMNS = []
def main():
"""
주식옵션 실시간체결가
Returns:
None
"""
# 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=stock_option_ccnl, data=["339W08088"])
# 결과 표시
def on_result(ws, tr_id: str, result: pd.DataFrame, data_map: dict):
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').round(2)
logging.info("결과:")
print(result)
kws.start(on_result=on_result)
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,110 @@
"""
Created on 20250601
"""
import logging
import sys
sys.path.extend(['../..', '.'])
import kis_auth as ka
# 로깅 설정
logging.basicConfig(level=logging.INFO)
##############################################################################################
# [국내선물옵션] 실시간시세 > 주식옵션 실시간체결가 [실시간-044]
##############################################################################################
def stock_option_ccnl(
tr_type: str,
tr_key: str,
) -> (dict, list[str]):
"""
주식옵션 실시간체결가 API입니다.
Args:
tr_type (str): [필수] 등록/해제
tr_key (str): [필수] 종목코드
Returns:
message (dict): 메시지 데이터
columns (list[str]): 컬럼 정보
Example:
>>> msg, columns = stock_option_ccnl("1", "101W9000")
>>> print(msg, columns)
"""
# 필수 파라미터 검증
if tr_type == "":
raise ValueError("tr_type is required")
if tr_key == "":
raise ValueError("tr_key is required")
tr_id = "H0ZOCNT0"
params = {
"tr_key": tr_key,
}
msg = ka.data_fetch(tr_id, tr_type, params)
columns = [
"optn_shrn_iscd",
"bsop_hour",
"optn_prpr",
"prdy_vrss_sign",
"optn_prdy_vrss",
"prdy_ctrt",
"optn_oprc",
"optn_hgpr",
"optn_lwpr",
"last_cnqn",
"acml_vol",
"acml_tr_pbmn",
"hts_thpr",
"hts_otst_stpl_qty",
"otst_stpl_qty_icdc",
"oprc_hour",
"oprc_vrss_prpr_sign",
"oprc_vrss_nmix_prpr",
"hgpr_hour",
"hgpr_vrss_prpr_sign",
"hgpr_vrss_nmix_prpr",
"lwpr_hour",
"lwpr_vrss_prpr_sign",
"lwpr_vrss_nmix_prpr",
"shnu_rate",
"prmm_val",
"invl_val",
"tmvl_val",
"delta",
"gama",
"vega",
"theta",
"rho",
"hts_ints_vltl",
"esdg",
"otst_stpl_rgbf_qty_icdc",
"thpr_basis",
"unas_hist_vltl",
"cttr",
"dprt",
"mrkt_basis",
"optn_askp1",
"optn_bidp1",
"askp_rsqn1",
"bidp_rsqn1",
"seln_cntg_csnu",
"shnu_cntg_csnu",
"ntby_cntg_csnu",
"seln_cntg_smtn",
"shnu_cntg_smtn",
"total_askp_rsqn",
"total_bidp_rsqn",
"prdy_vol_vrss_acml_vol_rate"
]
return msg, columns