2166 lines
87 KiB
Python
2166 lines
87 KiB
Python
import logging
|
||
import time
|
||
import sys
|
||
from typing import Optional, Tuple
|
||
|
||
import pandas as pd
|
||
|
||
sys.path.extend(['..', '.'])
|
||
import kis_auth as ka
|
||
|
||
# 로깅 설정
|
||
logging.basicConfig(level=logging.INFO, format='%(levelname)s - %(message)s')
|
||
logger = logging.getLogger(__name__)
|
||
|
||
##############################################################################################
|
||
# [국내선물옵션] 기본시세 > 국내옵션전광판_콜풋[국내선물-022]
|
||
##############################################################################################
|
||
|
||
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"
|
||
|
||
|
||
api_url = "/uapi/domestic-futureoption/v1/quotations/display-board-callput"
|
||
|
||
|
||
|
||
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()
|
||
|
||
##############################################################################################
|
||
# [국내선물옵션] 기본시세 > 국내옵션전광판_선물[국내선물-023]
|
||
##############################################################################################
|
||
|
||
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"
|
||
|
||
|
||
api_url = "/uapi/domestic-futureoption/v1/quotations/display-board-futures"
|
||
|
||
|
||
|
||
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()
|
||
|
||
##############################################################################################
|
||
# [국내선물옵션] 기본시세 > 국내옵션전광판_옵션월물리스트[국내선물-020]
|
||
##############################################################################################
|
||
|
||
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"
|
||
|
||
|
||
api_url = "/uapi/domestic-futureoption/v1/quotations/display-board-option-list"
|
||
|
||
|
||
|
||
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()
|
||
|
||
##############################################################################################
|
||
# [국내선물옵션] 기본시세 > 국내선물 기초자산 시세[국내선물-021]
|
||
##############################################################################################
|
||
|
||
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. '101V06')")
|
||
|
||
tr_id = "FHPIF05030000"
|
||
|
||
|
||
api_url = "/uapi/domestic-futureoption/v1/quotations/display-board-top"
|
||
|
||
|
||
|
||
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()
|
||
|
||
##############################################################################################
|
||
# [국내선물옵션] 기본시세 > 선물옵션 일중예상체결추이[국내선물-018]
|
||
##############################################################################################
|
||
|
||
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. '101V06')")
|
||
|
||
if fid_cond_mrkt_div_code == "":
|
||
raise ValueError("fid_cond_mrkt_div_code is required (e.g. 'F')")
|
||
|
||
tr_id = "FHPIF05110100" # 선물옵션 일중예상체결추이
|
||
|
||
|
||
api_url = "/uapi/domestic-futureoption/v1/quotations/exp-price-trend"
|
||
|
||
|
||
|
||
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()
|
||
|
||
##############################################################################################
|
||
# [국내선물옵션] 기본시세 > 선물옵션 시세호가[v1_국내선물-007]
|
||
##############################################################################################
|
||
|
||
def inquire_asking_price(
|
||
fid_cond_mrkt_div_code: str, # [필수] FID 조건 시장 분류 코드 (ex. F: 지수선물, JF: 주식선물)
|
||
fid_input_iscd: str, # [필수] FID 입력 종목코드 (ex. 101W09)
|
||
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'")
|
||
|
||
|
||
api_url = "/uapi/domestic-futureoption/v1/quotations/inquire-asking-price"
|
||
|
||
|
||
|
||
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()
|
||
|
||
##############################################################################################
|
||
# [국내선물옵션] 주문/계좌 > 선물옵션 잔고현황[v1_국내선물-004]
|
||
##############################################################################################
|
||
|
||
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'")
|
||
|
||
|
||
api_url = "/uapi/domestic-futureoption/v1/trading/inquire-balance"
|
||
|
||
|
||
|
||
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()
|
||
|
||
##############################################################################################
|
||
# [국내선물옵션] 주문/계좌 > 선물옵션 잔고정산손익내역[v1_국내선물-013]
|
||
##############################################################################################
|
||
|
||
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"
|
||
|
||
|
||
api_url = "/uapi/domestic-futureoption/v1/trading/inquire-balance-settlement-pl"
|
||
|
||
|
||
|
||
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()
|
||
|
||
##############################################################################################
|
||
# [국내선물옵션] 주문/계좌 > 선물옵션 잔고평가손익내역[v1_국내선물-015]
|
||
##############################################################################################
|
||
|
||
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" # 선물옵션 잔고평가손익내역
|
||
|
||
|
||
api_url = "/uapi/domestic-futureoption/v1/trading/inquire-balance-valuation-pl"
|
||
|
||
|
||
|
||
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()
|
||
|
||
##############################################################################################
|
||
# [국내선물옵션] 주문/계좌 > 선물옵션 주문체결내역조회[v1_국내선물-003]
|
||
##############################################################################################
|
||
|
||
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'")
|
||
|
||
# 파라미터 설정
|
||
|
||
api_url = "/uapi/domestic-futureoption/v1/trading/inquire-ccnl"
|
||
|
||
|
||
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()
|
||
|
||
##############################################################################################
|
||
# [국내선물옵션] 주문/계좌 > 선물옵션 기준일체결내역[v1_국내선물-016]
|
||
##############################################################################################
|
||
|
||
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"
|
||
|
||
|
||
api_url = "/uapi/domestic-futureoption/v1/trading/inquire-ccnl-bstime"
|
||
|
||
|
||
|
||
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()
|
||
|
||
##############################################################################################
|
||
# [국내선물옵션] 주문/계좌 > 선물옵션기간약정수수료일별[v1_국내선물-017]
|
||
##############################################################################################
|
||
|
||
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" # 선물옵션기간약정수수료일별
|
||
|
||
|
||
api_url = "/uapi/domestic-futureoption/v1/trading/inquire-daily-amount-fee"
|
||
|
||
|
||
|
||
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()
|
||
|
||
##############################################################################################
|
||
# [국내선물옵션] 기본시세 > 선물옵션기간별시세(일/주/월/년)[v1_국내선물-008]
|
||
##############################################################################################
|
||
|
||
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. 20250301)
|
||
fid_input_date_2 (str): [필수] 조회 종료일자 (ex. 20250810)
|
||
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'")
|
||
|
||
|
||
api_url = "/uapi/domestic-futureoption/v1/quotations/inquire-daily-fuopchartprice"
|
||
|
||
|
||
|
||
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()
|
||
|
||
##############################################################################################
|
||
# [국내선물옵션] 주문/계좌 > 선물옵션 총자산현황[v1_국내선물-014]
|
||
##############################################################################################
|
||
|
||
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" # 선물옵션 총자산현황
|
||
|
||
|
||
api_url = "/uapi/domestic-futureoption/v1/trading/inquire-deposit"
|
||
|
||
|
||
|
||
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()
|
||
|
||
##############################################################################################
|
||
# [국내선물옵션] 주문/계좌 > (야간)선물옵션 잔고현황 [국내선물-010]
|
||
##############################################################################################
|
||
|
||
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"
|
||
|
||
|
||
api_url = "/uapi/domestic-futureoption/v1/trading/inquire-ngt-balance"
|
||
|
||
|
||
|
||
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())
|
||
|
||
##############################################################################################
|
||
# [국내선물옵션] 주문/계좌 > (야간)선물옵션 주문체결 내역조회 [국내선물-009]
|
||
##############################################################################################
|
||
|
||
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"
|
||
|
||
|
||
api_url = "/uapi/domestic-futureoption/v1/trading/inquire-ngt-ccnl"
|
||
|
||
|
||
|
||
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()
|
||
|
||
##############################################################################################
|
||
# [국내선물옵션] 기본시세 > 선물옵션 시세[v1_국내선물-006]
|
||
##############################################################################################
|
||
|
||
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")
|
||
|
||
|
||
api_url = "/uapi/domestic-futureoption/v1/quotations/inquire-price"
|
||
|
||
|
||
|
||
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()
|
||
|
||
##############################################################################################
|
||
# [국내선물옵션] 주문/계좌 > (야간)선물옵션 주문가능 조회 [국내선물-011]
|
||
##############################################################################################
|
||
|
||
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"
|
||
|
||
|
||
api_url = "/uapi/domestic-futureoption/v1/trading/inquire-psbl-ngt-order"
|
||
|
||
|
||
|
||
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()
|
||
|
||
##############################################################################################
|
||
# [국내선물옵션] 주문/계좌 > 선물옵션 주문가능[v1_국내선물-005]
|
||
##############################################################################################
|
||
|
||
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'")
|
||
|
||
|
||
api_url = "/uapi/domestic-futureoption/v1/trading/inquire-psbl-order"
|
||
|
||
|
||
|
||
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()
|
||
|
||
##############################################################################################
|
||
# [국내선물옵션] 기본시세 > 선물옵션 분봉조회[v1_국내선물-012]
|
||
##############################################################################################
|
||
|
||
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" # 선물옵션 분봉조회
|
||
|
||
|
||
api_url = "/uapi/domestic-futureoption/v1/quotations/inquire-time-fuopchartprice"
|
||
|
||
|
||
|
||
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()
|
||
|
||
##############################################################################################
|
||
# [국내선물옵션] 주문/계좌 > (야간)선물옵션 증거금 상세 [국내선물-024]
|
||
##############################################################################################
|
||
|
||
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" # (야간)선물옵션 증거금 상세
|
||
|
||
|
||
api_url = "/uapi/domestic-futureoption/v1/trading/ngt-margin-detail"
|
||
|
||
|
||
|
||
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()
|
||
|
||
##############################################################################################
|
||
# [국내선물옵션] 주문/계좌 > 선물옵션 주문[v1_국내선물-001]
|
||
##############################################################################################
|
||
|
||
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'")
|
||
|
||
|
||
api_url = "/uapi/domestic-futureoption/v1/trading/order"
|
||
|
||
|
||
|
||
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()
|
||
|
||
##############################################################################################
|
||
# [국내선물옵션] 주문/계좌 > 선물옵션 정정취소주문[v1_국내선물-002]
|
||
##############################################################################################
|
||
|
||
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')")
|
||
|
||
|
||
api_url = "/uapi/domestic-futureoption/v1/trading/order-rvsecncl"
|
||
|
||
|
||
|
||
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()
|
||
|