from base64 import b64decode
from Crypto.Cipher import AES
from Crypto.Util.Padding import unpad
from decimal import Decimal
from pyqqq.brokerage.kis.oauth import KISAuth
from pyqqq.brokerage.kis.tr_client import KISTRClient, KISTRWebsocketClient
from typing import AsyncGenerator
import asyncio
import datetime as dtm
import json
import re
import websockets
[docs]
class KISDomesticStock:
"""
한국투자증권 국내주식 API
"""
[docs]
def __init__(self, auth: KISAuth, corp_data: dict = None):
self.auth = auth
self.corp_data = corp_data
self.tr_client = KISTRClient(auth, corp_data)
def _tr_request(self, *args, **kwargs):
return self.tr_client.request(*args, **kwargs)
[docs]
def get_price(self, fid_input_iscd: str, fid_cond_mrkt_div_code: str = "J"):
"""
(국내주식시세) 주식현재가 시세[v1_국내주식-008]
Args:
fid_input_iscd (str): FID 입력종목코드 - 종목번호(6자리) ETN의 경우 Q로 시작(EX. Q500001)
fid_cond_mrkt_div_code (str): FID 조건시장분류코드 - J:주식,ETF,ETN W:ELW NX:Nextrade UN:통합
Returns:
dict:
- rt_cd (str): 응답코드
- msg_cd (str): 메시지코드
- msg1 (str): 메시지1
- output (dict): 출력
- iscd_stat_cls_code: 종목상태구분코드 - 00:그외 51:관리종목 52:투자위험 53:투자경고 54:투자주의 55:신용가능 57:증거금 100% 58:거래정지 59:단기과열
- marg_rate: 증거금비율
- rprs_mrkt_kor_name: 대표시장한글명
- new_hgpr_lwpr_cls_code: 신고가저가구분코드 - 조회하는 종목이 신고/신저에 도달했을 경우에만 조회됨
- bstp_kor_isnm: 업종한글종목명
- temp_stop_yn: 임시정지여부
- oprc_rang_cont_yn: 시가범위연장여부
- clpr_rang_cont_yn: 종가범위연장여부
- crdt_able_yn: 신용가능여부
- grmn_rate_cls_code: 보증금비율구분코드 - 한국투자 증거금비율 (marg_rate 참고) 40:20%,30%,40% 50:50% 60:60%
- elw_pblc_yn: ELW발행여부
- stck_prpr: 주식현재가
- prdy_vrss: 전일대비
- prdy_vrss_sign: 전일대비부호 - 1:상한 2:상승 3:보합 4:하한 5:하락
- prdy_ctrt: 전일대비율
- acml_tr_pbmn: 누적 거래 대금
- acml_vol: 누적 거래량
- prdy_vrss_vol_rate: 전일 대비 거래량 비율 - 주식현재가 일자별 API 응답값 사용
- stck_oprc: 주식 시가
- stck_hgpr: 주식 최고가
- stck_lwpr: 주식 최저가
- stck_mxpr: 주식 상한가
- stck_llam: 주식 하한가
- stck_sdpr: 주식 기준가
- wghn_avrg_stck_prc: 가중 평균 주식 가격
- hts_frgn_ehrt: HTS 외국인 소진율
- frgn_ntby_qty: 외국인 순매수 수량
- pgtr_ntby_qty: 프로그램매매 순매수 수량
- pvt_scnd_dmrs_prc: 피벗 2차 디저항 가격 - 직원용 데이터
- pvt_frst_dmrs_prc: 피벗 1차 디저항 가격 - 직원용 데이터
- pvt_pont_val: 피벗 포인트 값 - 직원용 데이터
- pvt_frst_dmsp_prc: 피벗 1차 디지지 가격 - 직원용 데이터
- pvt_scnd_dmsp_prc: 피벗 2차 디지지 가격 - 직원용 데이터
- dmrs_val: 디저항 값 - 직원용 데이터
- dmsp_val: 디지지 값 - 직원용 데이터
- cpfn: 자본금
- rstc_wdth_prc: 제한 폭 가격
- stck_fcam: 주식 액면가
- stck_sspr: 주식 대용가
- aspr_unit: 호가단위
- hts_deal_qty_unit_val: HTS 매매 수량 단위 값
- lstn_stcn: 상장 주수
- hts_avls: HTS 시가총액
- per: PER
- pbr: PBR
- stac_month: 결산 월
- vol_tnrt: 거래량 회전율
- eps: EPS
- bps: BPS
- d250_hgpr: 250일 최고가
- d250_hgpr_date: 250일 최고가 일자
- d250_hgpr_vrss_prpr_rate: 250일 최고가 대비 현재가 비율
- d250_lwpr: 250일 최저가
- d250_lwpr_date: 250일 최저가 일자
- d250_lwpr_vrss_prpr_rate: 250일 최저가 대비 현재가 비율
- stck_dryy_hgpr: 주식 연중 최고가
- dryy_hgpr_vrss_prpr_rate: 연중 최고가 대비 현재가 비율
- dryy_hgpr_date: 연중 최고가 일자
- stck_dryy_lwpr: 주식 연중 최저가
- dryy_lwpr_vrss_prpr_rate: 연중 최저가 대비 현재가 비율
- dryy_lwpr_date: 연중 최저가 일자
- w52_hgpr: 52주일 최고가
- w52_hgpr_vrss_prpr_ctrt: 52주일 최고가 대비 현재가 대비
- w52_hgpr_date: 52주일 최고가 일자
- w52_lwpr: 52주일 최저가
- w52_lwpr_vrss_prpr_ctrt: 52주일 최저가 대비 현재가 대비
- w52_lwpr_date: 52주일 최저가 일자
- whol_loan_rmnd_rate: 전체 융자 잔고 비율
- ssts_yn: 공매도가능여부
- stck_shrn_iscd: 주식 단축 종목코드
- fcam_cnnm: 액면가 통화명
- cpfn_cnnm: 자본금 통화명 - 외국주권은 억으로 떨어지며, 그 외에는 만으로 표시됨
- apprch_rate: 접근도
- frgn_hldn_qty: 외국인 보유 수량
- vi_cls_code: VI적용구분코드
- ovtm_vi_cls_code: 시간외단일가VI적용구분코드
- last_ssts_cntg_qty: 최종 공매도 체결 수량
- invt_caful_yn: 투자유의여부 - Y/N
- mrkt_warn_cls_code: 시장경고코드 - 00:없음 01:투자주의 02:투자경고 03:투자위험
- short_over_yn: 단기과열여부 - Y/N
- sltr_yn: 정리매매여부 - Y/N
Raise:
ValueError: API 에러 발생시
"""
assert fid_cond_mrkt_div_code in ["J", "W", "NX", "UN"]
assert len(fid_input_iscd) == 6 or (len(fid_input_iscd) == 7 and fid_input_iscd[0] == "Q")
path = "/uapi/domestic-stock/v1/quotations/inquire-price"
tr_id = "FHKST01010100"
params = {"FID_COND_MRKT_DIV_CODE": fid_cond_mrkt_div_code, "FID_INPUT_ISCD": fid_input_iscd}
res_body, _ = self._tr_request(path, tr_id, params=params)
if res_body["rt_cd"] != "0":
raise ValueError(f"Error: ({res_body['msg_cd']}) {res_body['msg1']}")
output = res_body["output"]
decimal_keys = [
"marg_rate",
"prdy_ctrt",
"prdy_vrss_vol_rate",
"wghn_avrg_stck_prc",
"hts_frgn_ehrt",
"per",
"pbr",
"vol_tnrt",
"eps",
"bps",
"d250_hgpr_vrss_prpr_rate",
"d250_lwpr_vrss_prpr_rate",
"dryy_hgpr_vrss_prpr_rate",
"dryy_lwpr_vrss_prpr_rate",
"w52_hgpr_vrss_prpr_ctrt",
"w52_lwpr_vrss_prpr_ctrt",
"whol_loan_rmnd_rate",
"stck_fcam",
]
for k in decimal_keys:
if k in output and len(output[k]) > 0:
output[k] = Decimal(output[k])
int_keys = [
"stck_prpr",
"prdy_vrss",
"prdy_vrss_sign",
"acml_tr_pbmn",
"acml_vol",
"stck_oprc",
"stck_hgpr",
"stck_lwpr",
"stck_mxpr",
"stck_llam",
"stck_sdpr",
"frgn_ntby_qty",
"pgtr_ntby_qty",
"pvt_scnd_dmrs_prc",
"pvt_frst_dmrs_prc",
"pvt_pont_val",
"pvt_frst_dmsp_prc",
"pvt_scnd_dmsp_prc",
"dmrs_val",
"dmsp_val",
"cpfn",
"rstc_wdth_prc",
"stck_sspr",
"aspr_unit",
"hts_deal_qty_unit_val",
"lstn_stcn",
"hts_avls",
"stac_month",
"d250_hgpr",
"d250_lwpr",
"stck_dryy_hgpr",
"stck_dryy_lwpr",
"w52_hgpr",
"w52_lwpr",
"frgn_hldn_qty",
"last_ssts_cntg_qty",
]
for k in int_keys:
if k in output and len(output[k]) > 0:
output[k] = int(output[k])
date_keys = [
"d250_hgpr_date",
"d250_lwpr_date",
"dryy_hgpr_date",
"dryy_lwpr_date",
"w52_hgpr_date",
"w52_lwpr_date",
]
for k in date_keys:
if k in output and len(output[k]) > 0:
output[k] = dtm.datetime.strptime(output[k], "%Y%m%d").date()
result = {"rt_cd": res_body["rt_cd"], "msg_cd": res_body["msg_cd"], "msg1": res_body["msg1"], "output": output}
return result
[docs]
def inquire_ccnl(self, fid_input_iscd: str, fid_cond_mrkt_div_code: str = "J", tr_cont: str = ""):
"""
(국내주식시세) 주식현재가 체결[v1_국내주식-009]
국내현재가 체결 API 입니다. 종목의 체결 정보를 확인할 수 있습니다.
Args:
fid_input_iscd (str): FID 입력종목코드 - 종목번호(6자리) ETN의 경우 Q로 시작(EX. Q500001)
fid_cond_mrkt_div_code (str): FID 조건시장분류코드 - J:주식,ETF,ETN W:ELW NX:Nextrade UN:통합
Returns:
dict:
- rt_cd (str): 응답코드
- msg_cd (str): 메시지코드
- msg1 (str): 메시지1
- tr_cont (str): 연속조회가능여부
- output (list): 출력
- stck_cntg_hour: 주식 체결 시간
- stck_prpr: 주식 현재가
- prdy_vrss: 전일 대비
- prdy_vrss_sign: 전일 대비 부호 - 1:상한 2:상승 3:보합 4:하한 5:하락
- cntg_vol: 체결 거래량
- tday_rltv: 당일 체결강도 - 체결거래가 발생하는 시점의 체결강도
- prdy_ctrt: 전일 대비율
Raise:
ValueError: API 에러 발생시
"""
path = "/uapi/domestic-stock/v1/quotations/inquire-ccnl"
tr_id = "FHKST01010300"
params = {"FID_COND_MRKT_DIV_CODE": fid_cond_mrkt_div_code, "FID_INPUT_ISCD": fid_input_iscd}
res_body, res_headers = self._tr_request(path, tr_id, tr_cont, params=params)
if res_body["rt_cd"] != "0":
raise ValueError(f"Error: ({res_body['msg_cd']}) {res_body['msg1']}")
output = []
for el in res_body["output"]:
decimal_keys = ["tday_rltv", "prdy_ctrt"]
for k in decimal_keys:
if k in el and len(el[k]) > 0:
el[k] = Decimal(el[k])
int_keys = ["stck_prpr", "prdy_vrss", "prdy_vrss_sign", "cntg_vol"]
for k in int_keys:
if k in el and len(el[k]) > 0:
el[k] = int(el[k])
el["stck_cntg_hour"] = dtm.datetime.strptime(el["stck_cntg_hour"], "%H%M%S").time()
output.append(el)
result = {"rt_cd": res_body["rt_cd"], "msg_cd": res_body["msg_cd"], "msg1": res_body["msg1"], "tr_cont": res_headers["tr_cont"], "output": output}
return result
[docs]
def inquire_daily_price(self, fid_input_iscd: str, fid_cond_mrkt_div_code: str = "J", fid_period_div_code: str = "D", fid_org_adj_prc: str = "0"):
"""
(국내주식시세) 주식현재가 일자별[v1_국내주식-010]
주식현재가 일자별 API입니다. 일/주/월별 주가를 확인할 수 있으며 최근 30일(주,별)로 제한되어 있습니다.
Args:
fid_input_iscd (str): FID 입력종목코드 - 종목번호(6자리) ETN의 경우 Q로 시작(EX. Q500001)
fid_cond_mrkt_div_code (str): FID 조건시장분류코드 - J:주식,ETF,ETN NX:Nextrade UN:통합
fid_period_div_code (str): FID 기간구분코드 - D:(일)최근 30거래일 W:(주)최근 30주 M:(월)최근 30개월
fid_org_adj_prc (str): FID 조정가구분코드 - 0:수정주가 1:원주가
Returns:
dict:
- rt_cd (str): 응답코드
- msg_cd (str): 메시지코드
- msg1 (str): 메시지1
- tr_cont (str): 연속조회가능여부
- output (list): 출력
- stck_bsop_date: 주식 영업 일자
- stck_oprc: 주식 시가
- stck_hgpr: 주식 최고가
- stck_lwpr: 주식 최저가
- stck_clpr: 주식 종가
- acml_vol: 누적 거래량
- prdy_vrss_vol_rate: 전일 대비 거래량 비율
- prdy_vrss: 전일 대비
- prdy_vrss_sign: 전일 대비 부호 - 1:상한 2:상승 3:보합 4:하한 5:하락
- prdy_ctrt: 전일 대비율
- hts_frgn_ehrt: HTS 외국인 소진율
- frgn_ntby_qty: 외국인 순매수 수량
- flng_cls_code: 락 구분 코드
| 01:권리락
| 02:배당락
| 03:분배락
| 04:권배락
| 05:중간(분기)배당락
| 06:권리중간배당락
| 07:권리분기배당락
- acml_prtt_rate: 누적 분할 비율
Raise:
ValueError: API 에러 발생시
"""
url_path = "/uapi/domestic-stock/v1/quotations/inquire-daily-price"
tr_id = "FHKST01010400"
params = {"FID_COND_MRKT_DIV_CODE": fid_cond_mrkt_div_code, "FID_INPUT_ISCD": fid_input_iscd, "FID_PERIOD_DIV_CODE": fid_period_div_code, "FID_ORG_ADJ_PRC": fid_org_adj_prc}
res_body, res_headers = self._tr_request(url_path, tr_id, params=params)
if res_body["rt_cd"] != "0":
raise ValueError(f"Error: ({res_body['msg_cd']}) {res_body['msg1']}")
output = []
for el in res_body["output"]:
el["stck_bsop_date"] = dtm.datetime.strptime(el["stck_bsop_date"], "%Y%m%d").date()
int_keys = ["stck_oprc", "stck_hgpr", "stck_lwpr", "stck_clpr", "acml_vol", "prdy_vrss", "frgn_ntby_qty"]
for k in int_keys:
if k in el and len(el[k]) > 0:
el[k] = int(el[k])
decimal_keys = ["prdy_vrss_vol_rate", "prdy_vrss_sign", "prdy_ctrt", "hts_frgn_ehrt", "acml_prtt_rate"]
for k in decimal_keys:
if k in el and len(el[k]) > 0:
el[k] = Decimal(el[k])
output.append(el)
result = {
"rt_cd": res_body["rt_cd"],
"msg_cd": res_body["msg_cd"],
"msg1": res_body["msg1"],
"tr_cont": res_headers["tr_cont"],
"output": output,
}
return result
[docs]
def inquire_asking_price_exp_ccn(self, fid_input_iscd: str, fid_cond_mrkt_div_code: str = "J"):
"""
(국내주식시세) 주식현재가 호가/예상체결[v1_국내주식-011]
주식현재가 호가 예상체결 API입니다. 매수 매도 호가를 확인하실 수 있습니다. 실시간 데이터를 원하신다면 웹소켓 API를 활용하세요.
Args:
fid_input_iscd (str): FID 입력종목코드 - 종목번호(6자리) ETN의 경우 Q로 시작(EX. Q500001)
fid_cond_mrkt_div_code (str): FID 조건시장분류코드 - J:주식,ETF,ETN NX:Nextrade UN:통합
Returns:
dict:
- rt_cd (str): 응답코드
- msg_cd (str): 메시지코드
- msg1 (str): 메시지1
- output1 (list): 응답상세1
- aspr_acpt_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_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
- askp_rsqn_icdc1: 매도호가 잔량 증감1
- askp_rsqn_icdc2: 매도호가 잔량 증감2
- askp_rsqn_icdc3: 매도호가 잔량 증감3
- askp_rsqn_icdc4: 매도호가 잔량 증감4
- askp_rsqn_icdc5: 매도호가 잔량 증감5
- askp_rsqn_icdc6: 매도호가 잔량 증감6
- askp_rsqn_icdc7: 매도호가 잔량 증감7
- askp_rsqn_icdc8: 매도호가 잔량 증감8
- askp_rsqn_icdc9: 매도호가 잔량 증감9
- askp_rsqn_icdc10: 매도호가 잔량 증감10
- bidp_rsqn_icdc1: 매수호가 잔량 증감1
- bidp_rsqn_icdc2: 매수호가 잔량 증감2
- bidp_rsqn_icdc3: 매수호가 잔량 증감3
- bidp_rsqn_icdc4: 매수호가 잔량 증감4
- bidp_rsqn_icdc5: 매수호가 잔량 증감5
- bidp_rsqn_icdc6: 매수호가 잔량 증감6
- bidp_rsqn_icdc7: 매수호가 잔량 증감7
- bidp_rsqn_icdc8: 매수호가 잔량 증감8
- bidp_rsqn_icdc9: 매수호가 잔량 증감9
- bidp_rsqn_icdc10: 매수호가 잔량 증감10
- total_askp_rsqn: 총 매도호가 잔량
- total_bidp_rsqn: 총 매수호가 잔량
- total_askp_rsqn_icdc: 총 매도호가 잔량 증감
- total_bidp_rsqn_icdc: 총 매수호가 잔량 증감
- ovtm_total_askp_icdc: 시간외 총 매도호가 증감
- ovtm_total_bidp_icdc: 시간외 총 매수호가 증감
- ovtm_total_askp_rsqn: 시간외 총 매도호가 잔량
- ovtm_total_bidp_rsqn: 시간외 총 매수호가 잔량
- ntby_aspr_rsqn: 순매수 호가 잔량
- new_mkop_cls_code: 신 장운영 구분 코드
- '00':장전 예상체결가와 장마감 동시호가
- '49':장후 예상체결가
- (1)첫 번째 비트: 1:장개시전 2:장중 3:장종료후 4:시간외단일가 7:일반Buy-in 8:당일Buy-in
- (2)두 번째 비트: 0:보통 1:종가 2:대량 3:바스켓 7:정리매매 8:Buy-in
- output2 (list): 응답상세2
- antc_mkop_cls_code: 예상 장운영 구분 코드 - 311:예상체결시작 112:예상체결종료
- stck_prpr: 주식 현재가
- stck_oprc: 주식 시가
- stck_hgpr: 주식 최고가
- stck_lwpr: 주식 최저가
- stck_sdpr: 주식 기준가
- antc_cnpr: 예상 체결가
- antc_cntg_vrss_sign: 예상 체결 대비 부호 - 1:상한 2:상승 3:보합 4:하한 5:하락
- antc_cntg_vrss: 예상 체결 대비
- antc_cntg_prdy_ctrt: 예상 체결 전일 대비율
- antc_vol: 예상 거래량
- stck_shrn_iscd: 주식 단축 종목코드
- vi_cls_code: VI적용구분코드
Raise:
ValueError: API 에러 발생시
"""
url_path = "/uapi/domestic-stock/v1/quotations/inquire-asking-price-exp-ccn"
tr_id = "FHKST01010200"
params = {"FID_COND_MRKT_DIV_CODE": fid_cond_mrkt_div_code, "FID_INPUT_ISCD": fid_input_iscd}
res_body, res_headers = self._tr_request(url_path, tr_id, params=params)
if res_body["rt_cd"] != "0":
raise ValueError(f"Error: ({res_body['msg_cd']}) {res_body['msg1']}")
output1 = res_body["output1"]
for k in output1.keys():
if k == "aspr_acpt_hour":
output1[k] = dtm.datetime.strptime(output1[k], "%H%M%S").time()
elif k == "new_mkop_cls_code":
pass
else:
output1[k] = int(output1[k])
output2 = res_body["output2"]
for k in output2.keys():
if k in ["antc_mkop_cls_code", "stck_shrn_iscd", "vi_cls_code"]:
pass
elif k == "antc_cntg_prdy_ctrt":
output2[k] = Decimal(output2[k])
else:
output2[k] = int(output2[k])
result = {"rt_cd": res_body["rt_cd"], "msg_cd": res_body["msg_cd"], "msg1": res_body["msg1"], "tr_cont": res_headers["tr_cont"], "output1": output1, "output2": output2}
return result
def inquire_investor(self, fid_input_iscd: str, fid_cond_mrkt_div_code: str = "J"):
"""
(국내주식시세) 주식현재가 투자자[v1_국내주식-012]
주식현재가 투자자 API입니다. 개인, 외국인, 기관 등 투자 정보를 확인할 수 있습니다. (30건)
[유의사항]
- 외국인은 외국인(외국인투자등록 고유번호가 있는 경우)+기타 외국인을 지칭합니다.
- 당일 데이터는 장 종료 후 제공됩니다.
Args:
fid_input_iscd (str): FID 입력종목코드 - 종목번호(6자리) ETN의 경우 Q로 시작(EX. Q500001)
fid_cond_mrkt_div_code (str): FID 조건시장분류코드 - J:주식,ETF,ETN NX:Nextrade UN:통합
Returns:
dict:
- rt_cd (str): 응답코드
- msg_cd (str): 메시지코드
- msg1 (str): 메시지1
- output (list): 응답상세
- stck_bsop_date: 주식 영업 일자
- stck_clpr: 주식 종가
- prdy_vrss: 전일 대비
- prdy_vrss_sign: 전일 대비 부호
- prsn_ntby_qty: 개인 순매수 수량
- frgn_ntby_qty: 외국인 순매수 수량
- orgn_ntby_qty: 기관계 순매수 수량
- prsn_ntby_tr_pbmn: 개인 순매수 거래 대금
- frgn_ntby_tr_pbmn: 외국인 순매수 거래 대금
- orgn_ntby_tr_pbmn: 기관계 순매수 거래 대금
- prsn_shnu_vol: 개인 매수2 거래량
- frgn_shnu_vol: 외국인 매수2 거래량
- orgn_shnu_vol: 기관계 매수2 거래량
- prsn_shnu_tr_pbmn: 개인 매수2 거래 대금
- frgn_shnu_tr_pbmn: 외국인 매수2 거래 대금
- orgn_shnu_tr_pbmn: 기관계 매수2 거래 대금
- prsn_seln_vol: 개인 매도 거래량
- frgn_seln_vol: 외국인 매도 거래량
- orgn_seln_vol: 기관계 매도 거래량
- prsn_seln_tr_pbmn: 개인 매도 거래 대금
- frgn_seln_tr_pbmn: 외국인 매도 거래 대금
- orgn_seln_tr_pbmn: 기관계 매도 거래 대금
Raise:
ValueError: API 에러 발생시
"""
url_path = "/uapi/domestic-stock/v1/quotations/inquire-investor"
tr_id = "FHKST01010900"
params = {
"FID_COND_MRKT_DIV_CODE": fid_cond_mrkt_div_code,
"FID_INPUT_ISCD": fid_input_iscd,
}
res_body, res_headers = self._tr_request(url_path, tr_id, params=params)
if res_body["rt_cd"] != "0":
raise ValueError(f"Error: ({res_body['msg_cd']}) {res_body['msg1']}")
output = []
for el in res_body["output"]:
el["stck_bsop_date"] = dtm.datetime.strptime(el["stck_bsop_date"], "%Y%m%d").date()
int_keys = [
"stck_clpr",
"prdy_vrss",
"prdy_vrss_sign",
"prsn_ntby_qty",
"frgn_ntby_qty",
"orgn_ntby_qty",
"prsn_ntby_tr_pbmn",
"frgn_ntby_tr_pbmn",
"orgn_ntby_tr_pbmn",
"prsn_shnu_vol",
"frgn_shnu_vol",
"orgn_shnu_vol",
"prsn_shnu_tr_pbmn",
"frgn_shnu_tr_pbmn",
"orgn_shnu_tr_pbmn",
"prsn_seln_vol",
"frgn_seln_vol",
"orgn_seln_vol",
"prsn_seln_tr_pbmn",
"frgn_seln_tr_pbmn",
"orgn_seln_tr_pbmn",
]
for k in int_keys:
if k in el and len(el[k]) > 0:
el[k] = int(el[k])
output.append(el)
result = {
"rt_cd": res_body["rt_cd"],
"msg_cd": res_body["msg_cd"],
"msg1": res_body["msg1"],
"tr_cont": res_headers["tr_cont"],
"output": output,
}
return result
[docs]
def inquire_daily_itemchartprice(self, fid_input_iscd: str, fid_input_date_1: dtm.date, fid_input_date_2: dtm.date, fid_period_div_code: str, fid_cond_mrkt_div_code: str = "J", fid_org_adj_prc: str = "0"):
"""
(국내주식시세) 국내주식기간별시세(일/주/월/년)[v1_국내주식-016]
국내주식기간별시세(일/주/월/년) API입니다.
실전계좌/모의계좌의 경우, 한 번의 호출에 최대 100건까지 확인 가능합니다.
Args:
fid_input_iscd (str): FID 입력종목코드 - 종목번호(6자리) ETN의 경우 Q로 시작(EX. Q500001)
fid_input_date_1 (datetime.date): FID 입력일자1 - 조회 시작일자 (ex. dtm.date(2024, 1, 01))
fid_input_date_2 (datetime.date): FID 입력일자2 - 조회 종료일자 (ex. dtm.date(2024, 1, 31))
fid_period_div_code (str): FID 기간구분코드 - D:일별 W:주별 M:월별 Y:년별
fid_cond_mrkt_div_code (str): FID 조건시장분류코드 - J:주식,ETF,ETN NX:Nextrade UN:통합
fid_org_adj_prc (str): FID 조정가구분코드 - 0:수정주가 1:원주가
Returns:
dict:
- rt_cd (str): 응답코드
- msg_cd (str): 메시지코드
- msg1 (str): 메시지1
- tr_cont (str): 연속조회가능여부
- output1 (object): 응답상세1
- prdy_vrss: 전일 대비
- prdy_vrss_sign: 전일 대비 부호
- prdy_ctrt: 전일 대비율
- stck_prdy_clpr: 주식 전일 종가
- acml_vol: 누적 거래량
- acml_tr_pbmn: 누적 거래 대금
- hts_kor_isnm: HTS 한글 종목명
- stck_prpr: 주식 현재가
- stck_shrn_iscd: 주식 단축 종목코드
- prdy_vol: 전일 거래량
- stck_mxpr: 상한가
- stck_llam: 하한가
- stck_oprc: 시가
- stck_hgpr: 최고가
- stck_lwpr: 최저가
- stck_prdy_oprc: 주식 전일 시가
- stck_prdy_hgpr: 주식 전일 최고가
- stck_prdy_lwpr: 주식 전일 최저가
- askp: 매도호가
- bidp: 매수호가
- prdy_vrss_vol: 전일 대비 거래량
- vol_tnrt: 거래량 회전율
- stck_fcam: 주식 액면가
- lstn_stcn: 상장 주수
- cpfn: 자본금
- hts_avls: 시가총액
- per: PER
- eps: EPS
- pbr: PBR
- itewhol_loan_rmnd_ratem: name 전체 융자 잔고 비율
- output2: (list): 일별데이터
- stck_bsop_date: 주식 영업 일자
- stck_clpr: 주식 종가
- stck_oprc: 주식 시가
- stck_hgpr: 주식 최고가
- stck_lwpr: 주식 최저가
- acml_vol: 누적 거래량
- acml_tr_pbmn: 누적 거래 대금
- flng_cls_code: 락 구분 코드
| 00:해당사항없음(락이 발생안한 경우)
| 01:권리락
| 02:배당락
| 03:분배락
| 04:권배락
| 05:중간(분기)배당락
| 06:권리중간배당락
| 07:권리분기배당락
- prtt_rate: 분할 비율
- mod_yn: 분할변경여부
- prdy_vrss_sign: 전일 대비 부호
- prdy_vrss: 전일 대비
- revl_issu_reas: 재평가사유코드
Raise:
ValueError: API 에러 발생시
"""
url_path = "/uapi/domestic-stock/v1/quotations/inquire-daily-itemchartprice"
tr_id = "FHKST03010100"
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.strftime("%Y%m%d"),
"FID_INPUT_DATE_2": fid_input_date_2.strftime("%Y%m%d"),
"FID_PERIOD_DIV_CODE": fid_period_div_code,
"FID_ORG_ADJ_PRC": fid_org_adj_prc,
}
res_body, res_headers = self._tr_request(url_path, tr_id, params=params)
if res_body["rt_cd"] != "0":
raise ValueError(f"Error: ({res_body['msg_cd']}) {res_body['msg1']}")
output1 = res_body["output1"]
int_keys = [
"prdy_vrss",
"prdy_vrss_sign",
"stck_prdy_clpr",
"acml_vol",
"acml_tr_pbmn",
"stck_prpr",
"prdy_vol",
"stck_mxpr",
"stck_llam",
"stck_oprc",
"stck_hgpr",
"stck_lwpr",
"stck_prdy_oprc",
"stck_prdy_hgpr",
"stck_prdy_lwpr",
"askp",
"bidp",
"prdy_vrss_vol",
"lstn_stcn",
"cpfn",
"hts_avls",
]
for k in int_keys:
if k in output1 and len(output1[k]) > 0:
output1[k] = int(output1[k])
decimal_keys = [
"prdy_ctrt",
"vol_tnrt",
"per",
"eps",
"pbr",
"itewhol_loan_rmnd_ratem name",
"stck_fcam",
]
for k in decimal_keys:
if k in output1 and len(output1[k]) > 0:
output1[k] = Decimal(output1[k])
output2 = []
for el in res_body["output2"]:
for k in el.keys():
if k == "stck_bsop_date":
el[k] = dtm.datetime.strptime(el[k], "%Y%m%d").date()
elif k in ["mod_yn", "revl_issu_reas"]:
pass
elif k == "prtt_rate":
el[k] = Decimal(el[k])
else:
el[k] = int(el[k])
output2.append(el)
result = {"rt_cd": res_body["rt_cd"], "msg_cd": res_body["msg_cd"], "msg1": res_body["msg1"], "tr_cont": res_headers["tr_cont"], "output1": output1, "output2": output2}
return result
[docs]
def inquire_daily_indexchartprice(self, fid_input_iscd: str, fid_input_date_1: dtm.date, fid_input_date_2: dtm.date, fid_period_div_code: str):
"""
(국내주식시세) 국내주식업종기간별시세(일/주/월/년)[v1_국내주식-021]
국내주식 업종기간별시세(일/주/월/년) API입니다.
실전계좌/모의계좌의 경우, 한 번의 호출에 최대 50건까지 확인 가능합니다.
Args:
fid_input_iscd (str): 업종상세코드 - 0001:종합 0002:대형주, ... 포탈(FAQ:종목정보 다운로드 - 업종코드 참조)
fid_input_date_1 (datetime.date): FID 입력일자1 - 조회 시작일자 (ex. dtm.date(2024, 1, 01))
fid_input_date_2 (datetime.date): FID 입력일자2 - 조회 종료일자 (ex. dtm.date(2024, 1, 31))
fid_period_div_code (str): FID 기간구분코드 - D:일별 W:주별 M:월별 Y:년별
Returns:
dict:
- rt_cd (str): 응답코드
- msg_cd (str): 메시지코드
- msg1 (str): 메시지1
- output1 (object): 응답상세1
- BSTP_NMIX_PRDY_VRSS: 업종 지수 전일 대비 - 업종 지수 전일 대비
- PRDY_VRSS_SIGN: 전일 대비 부호 - 전일 대비 부호
- BSTP_NMIX_PRDY_CTRT: 업종 지수 전일 대비율 - 업종 지수 전일 대비율
- PRDY_NMIX: 전일 지수 - 전일 지수
- ACML_VOL: 누적 거래량 - 누적 거래량
- ACML_TR_PBMN: 누적 거래 대금 - 누적 거래 대금
- HTS_KOR_ISNM: HTS 한글 종목명 - HTS 한글 종목명
- BSTP_NMIX_PRPR: 업종 지수 현재가 - 업종 지수 현재가
- BSTP_CLS_CODE: 업종 구분 코드 - 업종 구분 코드
- PRDY_VOL: 전일 거래량 - 전일 거래량
- BSTP_NMIX_OPRC: 업종 지수 시가 - 업종 지수 시가
- BSTP_NMIX_HGPR: 업종 지수 최고가 - 업종 지수 최고가
- BSTP_NMIX_LWPR: 업종 지수 최저가 - 업종 지수 최저가
- FUTS_PRDY_OPRC: 업종 전일 시가 - 업종 전일 시가
- FUTS_PRDY_HGPR: 업종 전일 최고가 - 업종 전일 최고가
- FUTS_PRDY_LWPR: 업종 전일 최저가 - 업종 전일 최저가
- output2 (list): 응답상세2
- STCK_BSOP_DATE: 영업 일자 - 영업 일자
- BSTP_NMIX_PRPR: 업종 지수 현재가 - 업종 지수 현재가
- BSTP_NMIX_OPRC: 업종 지수 시가 - 업종 지수 시가
- BSTP_NMIX_HGPR: 업종 지수 최고가 - 업종 지수 최고가
- BSTP_NMIX_LWPR: 업종 지수 최저가 - 업종 지수 최저가
- ACML_VOL: 누적 거래량 - 누적 거래량
- ACML_TR_PBMN: 누적 거래 대금 - 누적 거래 대금
- MOD_YN: 변경 여부 - 변경 여부
Raise:
ValueError: API 에러 발생시
"""
url_path = "/uapi/domestic-stock/v1/quotations/inquire-daily-indexchartprice"
tr_id = "FHKUP03500100"
params = {"FID_COND_MRKT_DIV_CODE": "U", "FID_INPUT_ISCD": fid_input_iscd, "FID_INPUT_DATE_1": fid_input_date_1.strftime("%Y%m%d"), "FID_INPUT_DATE_2": fid_input_date_2.strftime("%Y%m%d"), "FID_PERIOD_DIV_CODE": fid_period_div_code}
res_body, res_headers = self._tr_request(url_path, tr_id, params=params)
if res_body["rt_cd"] != "0":
raise ValueError(f"Error: ({res_body['msg_cd']}) {res_body['msg1']}")
output1 = res_body["output1"]
decimal_keys = ["bstp_nmix_prdy_vrss", "bstp_nmix_prdy_ctrt", "prdy_nmix", "bstp_nmix_oprc", "bstp_nmix_prpr", "bstp_nmix_hgpr", "bstp_nmix_lwpr", "futs_prdy_oprc", "futs_prdy_hgpr", "futs_prdy_lwpr"]
for k in decimal_keys:
if k in output1 and len(output1[k]) > 0:
output1[k] = Decimal(output1[k])
int_keys = ["prdy_vrss_sign", "acml_vol", "acml_tr_pbmn", "prdy_vol"]
for k in int_keys:
if k in output1 and len(output1[k]) > 0:
output1[k] = int(output1[k])
output2 = []
for el in res_body["output2"]:
for k in el.keys():
if k in ["bstp_nmix_prpr", "bstp_nmix_oprc", "bstp_nmix_hgpr", "bstp_nmix_lwpr"]:
el[k] = Decimal(el[k])
elif k == "stck_bsop_date":
el[k] = dtm.datetime.strptime(el[k], "%Y%m%d").date()
elif k in ["acml_vol", "acml_tr_pbmn"]:
el[k] = int(el[k])
output2.append(el)
result = {"rt_cd": res_body["rt_cd"], "msg_cd": res_body["msg_cd"], "msg1": res_body["msg1"], "output1": output1, "output2": output2}
return result
[docs]
def inquire_time_itemconclusion(self, fid_input_iscd: str, fid_input_hour_1: dtm.time, fid_cond_mrkt_div_code: str = "J", tr_cont: str = ""):
"""
(국내주식시세) 주식현재가 당일시간대별체결[v1_국내주식-023]
주식현재가 당일시간대별체결 API입니다.
Args:
fid_input_iscd (str): FID 입력종목코드 - 종목번호(6자리) ETN의 경우 Q로 시작(EX. Q500001)
fid_input_hour_1 (datetime.time): FID 입력시간1 - 기준시간 ex)dtm.time(15, 50, 0) 입력 시 15시 50분 기준 이전 체결내역이 조회됨
fid_cond_mrkt_div_code (str): FID 조건시장분류코드 - J:주식,ETF,ETN NX:Nextrade UN:통합
tr_cont (str): 연속조회여부
Returns:
dict:
- rt_cd (str): 응답코드
- msg_cd (str): 메시지코드
- msg1 (str): 메시지1
- tr_cont (str): 연속조회가능여부
- output1 (object): 응답상세1 - 기본정보
- stck_prpr: 주식 현재가
- prdy_vrss: 전일 대비
- prdy_vrss_sign: 전일 대비 부호
- prdy_ctrt: 전일 대비율
- acml_vol: 누적 거래량
- prdy_vol: 전일 거래량
- rprs_mrkt_kor_name: 대표 시장 한글명
- output2 (list): 응답상세2 - 시간대체결 정보
- stck_cntg_hour: 주식 체결 시간
- stck_prpr: 주식 현재가
- prdy_vrss: 전일 대비
- prdy_vrss_sign: 전일 대비 부호
- prdy_ctrt: 전일 대비율
- askp: 매도호가
- bidp: 매수호가
- tday_rltv: 당일 체결강도
- acml_vol: 누적 거래량
- cnqn: 체결량
Raise:
ValueError: API 에러 발생시
"""
url_path = "/uapi/domestic-stock/v1/quotations/inquire-time-itemconclusion"
tr_id = "FHPST01060000"
params = {"FID_COND_MRKT_DIV_CODE": fid_cond_mrkt_div_code, "FID_INPUT_ISCD": fid_input_iscd, "FID_INPUT_HOUR_1": fid_input_hour_1.strftime("%H%M%S")}
res_body, res_headers = self._tr_request(url_path, tr_id, tr_cont, params=params)
if res_body["rt_cd"] != "0":
raise ValueError(f"Error: ({res_body['msg_cd']}) {res_body['msg1']}")
output1 = res_body["output1"]
for k in output1.keys():
if k == "rprs_mrkt_kor_name":
pass
elif k == "prdy_ctrt":
output1[k] = Decimal(output1[k])
else:
output1[k] = int(output1[k])
output2 = []
for el in res_body["output2"]:
for k in el.keys():
if k == "stck_cntg_hour":
el[k] = dtm.datetime.strptime(el[k], "%H%M%S").time()
elif k in ["prdy_ctrt", "tday_rltv"]:
el[k] = Decimal(el[k])
else:
el[k] = int(el[k])
output2.append(el)
result = {"rt_cd": res_body["rt_cd"], "msg_cd": res_body["msg_cd"], "msg1": res_body["msg1"], "tr_cont": res_headers["tr_cont"], "output1": output1, "output2": output2}
return result
[docs]
def inquire_time_overtimeconclusion(self, fid_input_iscd: str, tr_cont: str = ""):
"""
(국내주식시세) 주식현재가 시간외시간별체결[v1_국내주식-025]
주식현재가 시간외시간별체결 API입니다.
Args:
fid_input_iscd (str): FID 입력종목코드 - 종목번호(6자리) ETN의 경우 Q로 시작(EX. Q500001)
tr_cont (str): 연속조회여부
Returns:
dict:
- rt_cd (str): 응답코드
- msg_cd (str): 메시지코드
- msg1 (str): 메시지1
- tr_cont (str): 연속조회가능여부
- output1 (dict): 응답상세1 - 기본정보
- ovtm_untp_prpr: 시간외 단일가 현재가
- ovtm_untp_prdy_vrss: 시간외 단일가 전일 대비
- ovtm_untp_prdy_vrss_sign: 시간외 단일가 전일 대비 부호
- ovtm_untp_prdy_ctrt: 시간외 단일가 전일 대비율
- ovtm_untp_vol: 시간외 단일가 거래량
- ovtm_untp_tr_pbmn: 시간외 단일가 거래 대금
- ovtm_untp_mxpr: 시간외 단일가 상한가
- ovtm_untp_llam: 시간외 단일가 하한가
- ovtm_untp_oprc: 시간외 단일가 시가2
- ovtm_untp_hgpr: 시간외 단일가 최고가
- ovtm_untp_lwpr: 시간외 단일가 최저가
- ovtm_untp_antc_cnpr: 시간외 단일가 예상 체결가
- ovtm_untp_antc_cntg_vrss: 시간외 단일가 예상 체결 대비
- ovtm_untp_antc_cntg_vrss_sign: 시간외 단일가 예상 체결 대비
- ovtm_untp_antc_cntg_ctrt: 시간외 단일가 예상 체결 대비율
- ovtm_untp_antc_vol: 시간외 단일가 예상 거래량
- uplm_sign: 상한 부호
- lslm_sign: 하한 부호
- output2 (list): 응답상세2 - 시간대별체결 정보
- stck_cntg_hour: 주식 체결 시간
- stck_prpr: 주식 현재가
- prdy_vrss: 전일 대비
- prdy_vrss_sign: 전일 대비 부호
- prdy_ctrt: 전일 대비율
- askp: 매도호가
- bidp: 매수호가
- acml_vol: 누적 거래량
- cntg_vol: 체결 거래량
Raise:
ValueError: API 에러 발생시
"""
url_path = "/uapi/domestic-stock/v1/quotations/inquire-time-overtimeconclusion"
tr_id = "FHPST02310000"
params = {"FID_COND_MRKT_DIV_CODE": "J", "FID_INPUT_ISCD": fid_input_iscd, "FID_HOUR_CLS_CODE": "1"}
res_body, res_headers = self._tr_request(url_path, tr_id, tr_cont, params=params)
if res_body["rt_cd"] != "0":
raise ValueError(f"Error: ({res_body['msg_cd']}) {res_body['msg1']}")
output1 = res_body["output1"]
for k in output1.keys():
if k in ["ovtm_untp_antc_cntg_ctrt", "ovtm_untp_prdy_ctrt"]:
output1[k] = Decimal(output1[k])
else:
output1[k] = int(output1[k])
output2 = []
for el in res_body["output2"]:
for k in el.keys():
if k == "prdy_ctrt":
el[k] = Decimal(el[k])
elif k == "stck_cntg_hour":
el[k] = dtm.datetime.strptime(el[k], "%H%M%S").time()
else:
el[k] = int(el[k])
output2.append(el)
result = {"rt_cd": res_body["rt_cd"], "msg_cd": res_body["msg_cd"], "msg1": res_body["msg1"], "tr_cont": res_headers["tr_cont"], "output1": output1, "output2": output2}
return result
[docs]
def inquire_daily_overtimeprice(self, fid_input_iscd: str, tr_cont: str = ""):
"""
(국내주식시세) 주식현재가 시간외일자별주가[v1_국내주식-026]
주식현재가 시간외일자별주가 API입니다.
Args:
fid_input_iscd (str): FID 입력종목코드 - 종목번호(6자리) ETN의 경우 Q로 시작(EX. Q500001)
Returns:
dict:
- rt_cd (str): 응답코드
- msg_cd (str): 메시지코드
- msg1 (str): 메시지1
- tr_cont (str): 연속조회가능여부
- output1 (dict): 응답상세1 - 기본정보
- ovtm_untp_prpr: 시간외 단일가 현 재가
- ovtm_untp_prdy_vrss: 시간외 단일가 전일 대비
- ovtm_untp_prdy_vrss_sign: 시간외 단일가 전일 대비 부호
- ovtm_untp_prdy_ctrt: 시간외 단일가 전일 대비율
- ovtm_untp_vol: 시간외 단일가 거래량
- ovtm_untp_tr_pbmn: 시간외 단일가 거래 대금
- ovtm_untp_mxpr: 시간외 단일가 상한가
- ovtm_untp_llam: 시간외 단일가 하한가
- ovtm_untp_oprc: 시간외 단일가 시가2
- ovtm_untp_hgpr: 시간외 단일가 최고가
- ovtm_untp_lwpr: 시간외 단일가 최저가
- ovtm_untp_antc_cnpr: 시간외 단일가 예상 체결가
- ovtm_untp_antc_cntg_vrss: 시간외 단일가 예상 체결 대비
- ovtm_untp_antc_cntg_vrss_sign: 시간외 단일가 예상 체결 대비
- ovtm_untp_antc_cntg_ctrt: 시간외 단일가 예상 체결 대비율
- ovtm_untp_antc_vol: 시간외 단일가 예상 거래량
- output2 (list): 응답상세2 - 일자별 정보
- stck_bsop_date: 주식 영업 일자
- ovtm_untp_prpr: 시간외 단일가 현재가
- ovtm_untp_prdy_vrss: 시간외 단일가 전일 대비
- ovtm_untp_prdy_vrss_sign: 시간외 단일가 전일 대비 부호
- ovtm_untp_prdy_ctrt: 시간외 단일가 전일 대비율
- ovtm_untp_vol: 시간외 단일가 거래량
- stck_clpr: 주식 종가
- prdy_vrss: 전일 대비
- prdy_vrss_sign: 전일 대비 부호
- prdy_ctrt: 전일 대비율
- acml_vol: 누적 거래량
- ovtm_untp_tr_pbmn: 시간외 단일가 거래대금
Raise:
ValueError: API 에러 발생시
"""
url_path = "/uapi/domestic-stock/v1/quotations/inquire-daily-overtimeprice"
tr_id = "FHPST02320000"
params = {"FID_COND_MRKT_DIV_CODE": "J", "FID_INPUT_ISCD": fid_input_iscd}
res_body, res_headers = self._tr_request(url_path, tr_id, tr_cont, params=params)
if res_body["rt_cd"] != "0":
raise ValueError(f"Error: ({res_body['msg_cd']}) {res_body['msg1']}")
output1 = res_body["output1"]
for k in output1.keys():
if k in ["ovtm_untp_antc_cntg_ctrt", "ovtm_untp_prdy_ctrt"]:
output1[k] = Decimal(output1[k])
else:
output1[k] = int(output1[k])
output2 = []
for el in res_body["output2"]:
for k in el.keys():
if k in ["prdy_ctrt", "ovtm_untp_prdy_ctrt"]:
el[k] = Decimal(el[k])
else:
el[k] = int(el[k])
output2.append(el)
result = {"rt_cd": res_body["rt_cd"], "msg_cd": res_body["msg_cd"], "msg1": res_body["msg1"], "tr_cont": res_headers["tr_cont"], "output1": output1, "output2": res_body["output2"]}
return result
[docs]
def inquire_time_itemchartprice(
self,
fid_input_iscd: str,
fid_input_hour_1: dtm.time | int,
fid_cond_mrkt_div_code: str = "J",
fid_pw_data_incu_yn: str = "Y",
):
"""
(국내주식시세) 주식당일분봉조회[v1_국내주식-022]
주식당일분봉조회 API입니다.
실전계좌/모의계좌의 경우, 한 번의 호출에 최대 30건까지 확인 가능합니다.
Args:
fid_input_iscd (str): FID 입력종목코드 - 종목번호(6자리) ETN의 경우 Q로 시작(EX. Q500001)
fid_input_hour_1 (datetime.date|int) - 조회대상(FID_COND_MRKT_DIV_CODE)에 따라 입력하는 값 상이
| 종목(J)일 경우, 조회 시작일자(HHMMSS)
| ex) "123000" 입력 시 12시 30분 이전부터 1분 간격으로 조회
|
| 업종(U)일 경우, 조회간격(초) (60 or 120 만 입력 가능)
| ex) "60" 입력 시 현재시간부터 1분간격으로 조회
| "120" 입력 시 현재시간부터 2분간격으로 조회
|
| ※ FID_INPUT_HOUR_1 에 미래일시 입력 시에 현재가로 조회됩니다.
| ex) 오전 10시에 113000 입력 시에 오전 10시~11시30분 사이의 데이터가 오전 10시 값으로 조회됨
fid_cond_mrkt_div_code (str): FID 조건시장분류코드 - J:주식,ETF,ETN U:업종 NX:Nextrade UN:통합
fid_pw_data_incu_yn (str): FID 과거 데이터 포함 여부 - N:당일데이터만조회 Y:과거데이터포함조회
Returns:
dict:
- rt_cd (str): 응답코드
- msg_cd (str): 메시지코드
- msg1 (str): 메시지1
- output1 (dict): 응답상세1 - 기본정보
- prdy_vrss: 전일 대비
- prdy_vrss_sign: 전일 대비 부호
- prdy_ctrt: 전일 대비율
- stck_prdy_clpr: 주식 전일 종가
- acml_vol: 누적 거래량
- acml_tr_pbmn: 누적 거래 대금
- hts_kor_isnm: HTS 한글 종목명
- stck_prpr: 주식 현재가
- output2 (list): 응답상세2 - 조회결과 상세
- stck_bsop_date: 주식 영업 일자
- stck_cntg_hour: 주식 체결 시간
- acml_tr_pbmn: 누적 거래 대금
- stck_prpr: 주식 현재가
- stck_oprc: 주식 시가2
- stck_hgpr: 주식 최고가
- stck_lwpr: 주식 최저가
- cntg_vol: 체결 거래량
Raise:
ValueError: API 에러 발생시
"""
assert fid_cond_mrkt_div_code in ["J", "U", "NX", "UN"], 'fid_cond_mrkt_div_code must be one of "J", "U", "NX", or "UN"'
assert fid_pw_data_incu_yn in ["Y", "N"], 'fid_pw_data_incu_yn must be "Y" or "N"'
assert fid_cond_mrkt_div_code in ["J", "NX", "UN"] and isinstance(fid_input_hour_1, dtm.time) or fid_cond_mrkt_div_code == "U" and isinstance(fid_input_hour_1, int), "fid_input_hour_1 type mismatch"
if type(fid_input_hour_1) is int:
assert fid_input_hour_1 in [60, 120], "fid_input_hour_1 must be 60 or 120"
url_path = "/uapi/domestic-stock/v1/quotations/inquire-time-itemchartprice"
tr_id = "FHKST03010200"
params = {
"FID_ETC_CLS_CODE": "",
"FID_COND_MRKT_DIV_CODE": fid_cond_mrkt_div_code,
"FID_INPUT_ISCD": fid_input_iscd,
"FID_INPUT_HOUR_1": fid_input_hour_1.strftime("%H%M%S") if isinstance(fid_input_hour_1, dtm.time) else str(fid_input_hour_1),
"FID_PW_DATA_INCU_YN": fid_pw_data_incu_yn,
}
res_body, res_headers = self._tr_request(url_path, tr_id, params=params)
if res_body["rt_cd"] != "0":
raise ValueError(f"Error: ({res_body['msg_cd']}) {res_body['msg1']}")
output1 = res_body["output1"]
for k in output1.keys():
if k == "hts_kor_isnm":
pass
elif k == "prdy_ctrt":
output1[k] = Decimal(output1[k])
else:
output1[k] = int(output1[k])
output2 = []
for el in res_body["output2"]:
for k in el.keys():
if k == "stck_bsop_date":
el[k] = dtm.datetime.strptime(el[k], "%Y%m%d").date()
elif k == "stck_cntg_hour":
el[k] = dtm.datetime.strptime(el[k], "%H%M%S").time()
else:
el[k] = int(el[k])
output2.append(el)
result = {
"rt_cd": res_body["rt_cd"],
"msg_cd": res_body["msg_cd"],
"msg1": res_body["msg1"],
"tr_cont": res_headers["tr_cont"],
"output1": output1,
"output2": output2,
}
return result
[docs]
def search_info(self, pdno: str, prdt_type_cd: str):
"""
(국내주식시세) 상품기본조회[v1_국내주식-029]
Args:
pdno (str): 상품번호
| 주식(하이닉스):000660 (코드:300)
| 선물(101S12):KR4101SC0009 (코드:301)
| 미국(AAPL):AAPL (코드:512)
prdt_type_cd (str): 상품유형코드
| '300':주식
| '301':선물옵션
| '302':채권
| '512':미국 나스닥 / 513 미국 뉴욕 / 529 미국 아멕스
| '515':일본
| '501':홍콩 / 543 홍콩CNY / 558 홍콩USD
| '507':베트남 하노이 / 508 베트남 호치민
| '551':중국 상해A / 552 중국 심천A
Returns:
dict:
- rt_cd (str): 응답코드
- msg_cd (str): 메시지코드
- msg1 (str): 메시지1
- output (dict): 응답상세
- pdno: 상품번호
- prdt_type_cd: 상품유형코드
- prdt_name: 상품명
- prdt_name120: 상품명120
- prdt_abrv_name: 상품약어명
- prdt_eng_name: 상품영문명
- prdt_eng_name120: 상품영문명120
- prdt_eng_abrv_name: 상품영문약어명
- std_pdno: 표준상품번호
- shtn_pdno: 단축상품번호
- prdt_sale_stat_cd: 상품판매상태코드
- prdt_risk_grad_cd: 상품위험등급코드
- prdt_clsf_cd: 상품분류코드
- prdt_clsf_name: 상품분류명
- sale_strt_dt: 판매시작일자
- sale_end_dt: 판매종료일자
- wrap_asst_type_cd: 랩어카운트자산유형코드
- ivst_prdt_type_cd: 투자상품유형코드
- ivst_prdt_type_cd_name: 투자상품유형코드명
- frst_erlm_dt: 최초등록일자
Raise:
ValueError: API 에러 발생시
"""
assert not self.auth.paper_trading, "실전계좌에서만 사용 가능한 API입니다."
assert prdt_type_cd in ["300", "301", "302", "512", "513", "529", "515", "501", "543", "558", "507", "508", "551", "552"], "unknown prdt_type_cd"
url_path = "/uapi/domestic-stock/v1/quotations/search-info"
tr_id = "CTPF1604R"
params = {"pdno": pdno, "prdt_type_cd": prdt_type_cd}
res_body, res_headers = self._tr_request(url_path, tr_id, params=params)
if res_body["rt_cd"] != "0":
raise ValueError(f"Error: ({res_body['msg_cd']}) {res_body['msg1']}")
output = res_body["output"]
result = {"rt_cd": res_body["rt_cd"], "msg_cd": res_body["msg_cd"], "msg1": res_body["msg1"], "output": output}
return result
[docs]
def chk_holiday(self, base_dt: dtm.date, ctx_area_nk: str = "", ctx_area_fk: str = ""):
"""
(국내주식시세) 휴일여부조회[v1_국내주식-030]
국내휴장일조회 API입니다.
영업일, 거래일, 개장일, 결제일 여부를 조회할 수 있습니다.
주문을 넣을 수 있는지 확인하고자 하실 경우 개장일여부(opnd_yn)을 사용하시면 됩니다.
Args:
base_dt (datetime.date): 기준일자.
ctx_area_nk (str): 연속조회키
ctx_area_fk (str): 연속조회검색조건
Returns:
dict:
- rt_cd (str): 응답코드.
- msg_cd (str): 메시지코드.
- msg1 (str): 메시지1.
- tr_cont (str): 연속 조회 가능 여부
- ctx_area_nk (str): 연속조회키
- ctx_area_fk (str): 연속조회검색조건
- output (list): 응답상세.
- bass_dt (datetime.date): 기준일자
- wday_dvsn_cd (str): 요일구분코드 - 01:일요일, 02:월요일, 03:화요일, 04:수요일, 05:목요일, 06:금요일, 07:토요일
- bzdy_yn (bool): 영업일여부 - 금융기관이 업무를 하는 날
- tr_day_yn (bool): 거래일여부 - 증권 업무가 가능한 날(입출금, 이체 등의 업무 포함)
- opnd_yn (bool): 개장일여부 - 주식시장이 개장되는 날. 주문을 넣고자 할 경우 개장일여부(opnd_yn)를 사용
- sttl_day_yn (bool): 결제일여부 - 주식 거래에서 실제로 주식을 인수하고 돈을 지불하는 날
Raise:
ValueError: API 에러 발생시
"""
assert not self.auth.paper_trading, "실전계좌에서만 사용 가능한 API입니다."
url_path = "/uapi/domestic-stock/v1/quotations/chk-holiday"
tr_id = "CTCA0903R"
tr_cont = "" if ctx_area_fk == "" else "N"
params = {"BASS_DT": base_dt.strftime("%Y%m%d"), "CTX_AREA_NK": ctx_area_nk, "CTX_AREA_FK": ctx_area_fk}
res_body, res_headers = self._tr_request(url_path, tr_id, tr_cont, params=params)
if res_body["rt_cd"] != "0":
raise ValueError(f"Error: ({res_body['msg_cd']}) {res_body['msg1']}")
output = []
for el in res_body["output"]:
el["bass_dt"] = dtm.datetime.strptime(el["bass_dt"], "%Y%m%d").date()
for k in el.keys():
if k in ["wday_dvsn_cd", "bzdy_yn", "tr_day_yn", "opnd_yn", "sttl_day_yn"]:
el[k] = True if el[k] == "Y" else False
output.append(el)
result = {
"rt_cd": res_body["rt_cd"],
"msg_cd": res_body["msg_cd"],
"msg1": res_body["msg1"],
"tr_cont": res_headers["tr_cont"],
"ctx_area_nk": res_body["ctx_area_nk"].strip(),
"ctx_area_fk": res_body["ctx_area_fk"].strip(),
"output": output,
}
return result
[docs]
def get_foreign_institution_total(self, fid_input_iscd: str, fid_div_cls_code: str, fid_rank_sort_cls_code: str, fid_etc_cls_code: str, tr_cont: str = ""):
"""
(국내주식시세) 국내기관_외국인 매매종목가집계[국내주식-037]
국내기관_외국인 매매종목가집계 API입니다.
증권사 직원이 장중에 집계/입력한 자료를 단순 누계한 수치로서,
입력시간은 외국인 09:30, 11:20, 13:20, 14:30 / 기관종합 10:00, 11:20, 13:20, 14:30 이며 사정에 따라 변동될 수 있습니다.
Args:
fid_input_iscd (str): 입력 종목코드 - 0000:전체, 0001:코스피, 1001:코스닥, ... 포탈 (FAQ : 종목정보 다운로드 - 업종코드 참조)
fid_div_cls_code (str): 분류 구분 코드 - 0: 수량정열, 1: 금액정열
fid_rank_sort_cls_code (str): 순위 정렬 구분 코드 - 0: 순매수상위, 1: 순매도상위
fid_etc_cls_code (str): 기타 구분 정렬 - 0:전체 1:외국인 2:기관계 3:기타
tr_cont (str): 연속조회여부
Returns:
dict
- rt_cd (str): 응답코드
- tr_cont (str): 연속조회가능여부
- msg_cd (str): 메시지코드
- msg1 (str): 메시지1
- output (list): 응답상세
- hts_kor_isnm: HTS 한글 종목명
- mksc_shrn_iscd: 유가증권 단축 종목코드
- ntby_qty: 순매수 수량
- stck_prpr: 주식 현재가
- prdy_vrss_sign: 전일 대비 부호
- prdy_vrss: 전일 대비
- prdy_ctrt: 전일 대비율
- acml_vol: 누적 거래량
- frgn_ntby_qty: 외국인 순매수 수량
- orgn_ntby_qty: 기관계 순매수 수량
- ivtr_ntby_qty: 투자신탁 순매수 수량
- bank_ntby_qty: 은행 순매수 수량
- insu_ntby_qty: 보험 순매수 수량
- mrbn_ntby_qty: 종금 순매수 수량
- fund_ntby_qty: 기금 순매수 수량
- etc_orgt_ntby_vol: 기타 단체 순매수 거래량
- etc_corp_ntby_vol: 기타 법인 순매수 거래량
- frgn_ntby_tr_pbmn: 외국인 순매수 거래 대금 - frgn_ntby_tr_pbmn ~ etc_corp_ntby_tr_pbmn (단위 : 백만원, 수량*현재가)
- orgn_ntby_tr_pbmn: 기관계 순매수 거래 대금
- ivtr_ntby_tr_pbmn: 투자신탁 순매수 거래 대금
- bank_ntby_tr_pbmn: 은행 순매수 거래 대금
- insu_ntby_tr_pbmn: 보험 순매수 거래 대금
- mrbn_ntby_tr_pbmn: 종금 순매수 거래 대금
- fund_ntby_tr_pbmn: 기금 순매수 거래 대금
- etc_orgt_ntby_tr_pbmn: 기타 단체 순매수 거래 대금
- etc_corp_ntby_tr_pbmn: 기타 법인 순매수 거래 대금
Raise:
ValueError: API 에러 발생시
"""
assert not self.auth.paper_trading, "실전계좌에서만 사용 가능한 API입니다."
assert fid_div_cls_code in ["0", "1"], 'fid_div_cls_code must be "0" or "1"'
assert fid_rank_sort_cls_code in ["0", "1"], 'fid_rank_sort_cls_code must be "0" or "1"'
assert fid_etc_cls_code in ["0", "1", "2", "3"], 'fid_etc_cls_code must be "0", "1", "2" or "3"'
url_path = "/uapi/domestic-stock/v1/quotations/foreign-institution-total"
tr_id = "FHPTJ04400000"
params = {
"FID_COND_MRKT_DIV_CODE": "V",
"FID_COND_SCR_DIV_CODE": "16449",
"FID_INPUT_ISCD": fid_input_iscd,
"FID_DIV_CLS_CODE": fid_div_cls_code,
"FID_RANK_SORT_CLS_CODE": fid_rank_sort_cls_code,
"FID_ETC_CLS_CODE": fid_etc_cls_code,
}
res_body, res_headers = self._tr_request(url_path, tr_id, tr_cont, params=params)
if res_body["rt_cd"] != "0":
raise ValueError(f"Error: ({res_body['msg_cd']}) {res_body['msg1']}")
output = []
for el in res_body["output"]:
for k in el.keys():
if k == "prdy_ctrt":
el[k] = Decimal(el[k])
elif k == "hts_kor_isnm":
pass
else:
el[k] = int(el[k])
output.append(el)
result = {"rt_cd": res_body["rt_cd"], "tr_cont": res_headers["tr_cont"], "msg_cd": res_body["msg_cd"], "msg1": res_body["msg1"], "output": output}
return result
[docs]
def get_stock_condition_search_list(self, user_id: str, tr_cont: str = ""):
"""
(국내주식시세) 종목조건검색 목록조회[국내주식-038]
HTS(efriend Plus) [0110] 조건검색에서 등록 및 서버저장한 나의 조건 목록을 확인할 수 있는 API입니다.
종목조건검색 목록조회 API(/uapi/domestic-stock/v1/quotations/psearch-title)의 output인 'seq'을 종목조건검색조회 API(/uapi/domestic-stock/v1/quotations/psearch-result)의 input으로 사용하시면 됩니다.
※ 시스템 안정성을 위해 API로 제공되는 조건검색 결과의 경우 조건당 100건으로 제한을 둔 점 양해 부탁드립니다.
※ [0110] 화면의 '대상변경' 설정사항은 HTS [0110] 사용자 조건검색 화면에만 적용됨에 유의 부탁드립니다.
※ '조회가 계속 됩니다. (다음을 누르십시오.)' 오류 발생 시 해결방법
→ HTS(efriend Plus) [0110] 조건검색 화면에서 조건을 등록하신 후, 왼쪽 하단의 "사용자조건 서버저장" 클릭하셔서 등록한 조건들을 서버로 보낸 후 다시 API 호출 시도 부탁드립니다.
Args:
user_id (str): 사용자 HTS ID
tr_cont (str): 연속조회여부
Returns:
dict:
- rt_cd (str): 응답코드
- tr_cont (str): 연속조회가능여부
- msg_cd (str): 메시지코드
- msg1 (str): 메시지1
- output (list): 응답상세
- seq (str): 조건키값 - 해당 값을 종목조건검색조회 API의 input으로 사용 (0번부터 시작)
- grp_nm (str): 그룹명 - HTS(eFriend Plus) [0110] "사용자조건검색"화면을 통해 등록한 사용자조건 그룹
- condition_nm (str): 조건명 - 등록한 사용자 조건명
Raise:
ValueError: API 에러 발생시
"""
assert not self.auth.paper_trading, "실전계좌에서만 사용 가능한 API입니다."
url_path = "/uapi/domestic-stock/v1/quotations/psearch-title"
tr_id = "HHKST03900300"
params = {"user_id": user_id}
res_body, res_headers = self._tr_request(url_path, tr_id, tr_cont, params=params)
if res_body["rt_cd"] != "0":
raise ValueError(f"Error: ({res_body['msg_cd']}) {res_body['msg1']}")
output = []
for el in res_body["output2"]:
output.append(el)
result = {
"rt_cd": res_body["rt_cd"],
"tr_cont": res_headers["tr_cont"],
"msg_cd": res_body["msg_cd"],
"msg1": res_body["msg1"],
"output": output,
}
return result
[docs]
def get_stock_condition_search_results(self, user_id: str, seq: str, tr_cont: str = ""):
"""
(국내주식시세) 종목조건검색조회 [국내주식-039]
HTS(efriend Plus) [0110] 조건검색에서 등록 및 서버저장한 나의 조건 목록을 확인할 수 있는 API입니다.
종목조건검색 목록조회 API(/uapi/domestic-stock/v1/quotations/psearch-title)의 output인 'seq'을 종목조건검색조회 API(/uapi/domestic-stock/v1/quotations/psearch-result)의 input으로 사용하시면 됩니다.
※ 시스템 안정성을 위해 API로 제공되는 조건검색 결과의 경우 조건당 100건으로 제한을 둔 점 양해 부탁드립니다.
※ [0110] 화면의 '대상변경' 설정사항은 HTS [0110] 사용자 조건검색 화면에만 적용됨에 유의 부탁드립니다.
※ '조회가 계속 됩니다. (다음을 누르십시오.)' 오류 발생 시 해결방법
→ HTS(efriend Plus) [0110] 조건검색 화면에서 조건을 등록하신 후, 왼쪽 하단의 "사용자조건 서버저장" 클릭하셔서 등록한 조건들을 서버로 보낸 후 다시 API 호출 시도 부탁드립니다.
※ {"rt_cd":"1","msg_cd":"MCA05918","msg1":"종목코드 오류입니다."} 메시지 발생 이유
→ 조건검색 결과 검색된 종목이 0개인 경우 위 응답값을 수신하게 됩니다.
Args:
user_id (str): 사용자 HTS ID
seq (str): 사용자조건 키값 - 종목조건검색 목록조회 API의 output인 'seq'값을 사용 (0번부터 시작)
tr_cont (str): 연속조회여부
Returns:
dict:
- rt_cd (str): 응답코드
- tr_cont (str): 연속조회가능여부
- msg_cd (str): 메시지코드
- msg1 (str): 메시지1
- output (list): 응답상세
- code (str): 종목코드
- name (str): 종목명
- daebi (int): 전일대비부호 (1:상한 2:상승 3:보합 4:하한 5:하락)
- price (int): 현재가
- chgrate (Decimal): 등락율
- acml_vol (Decimal): 거래량
- trade_amt (Decimal): 거래대금
- change (Decimal): 전일대비
- cttr (Decimal): 체결강도
- open (Decimal): 시가
- high (Decimal): 고가
- low (Decimal): 저가
- high52 (Decimal): 52주최고가
- low52 (Decimal): 52주최저가
- expprice (Decimal): 예상체결가
- expchange (Decimal): 예상대비
- expchggrate (Decimal): 예상등락률
- expcvol (Decimal): 예상체결수량
- chgrate2 (Decimal): 전일거래량대비율
- expdaebi (int): 예상대비부호
- recprice (Decimal): 기준가
- uplmtprice (Decimal): 상한가
- dnlmtprice (Decimal): 하한가
- stotprice (Decimal): 시가총액
"""
url_path = "/uapi/domestic-stock/v1/quotations/psearch-result"
tr_id = "HHKST03900400"
params = {
"user_id": user_id,
"seq": seq,
}
res_body, res_headers = self._tr_request(url_path, tr_id, tr_cont, params=params)
if res_body["rt_cd"] != "0":
raise ValueError(f"Error: ({res_body['msg_cd']}) {res_body['msg1']}")
output = []
for el in res_body["output2"]:
for k in el.keys():
if el[k] is None or len(el[k]) == 0:
pass
elif k in ["code", "name"]:
pass
elif k in ["daebi", "expdaebi"]:
el[k] = int(el[k])
else:
el[k] = Decimal(el[k])
output.append(el)
result = {
"rt_cd": res_body["rt_cd"],
"tr_cont": res_headers["tr_cont"],
"msg_cd": res_body["msg_cd"],
"msg1": res_body["msg1"],
"output": output,
}
return result
[docs]
def get_program_trade_by_stock(self, fid_input_iscd: str, tr_cont: str = ""):
"""
(국내주식시세) 종목별 프로그램매매추이(체결)[v1_국내주식-044]
국내주식 종목별 프로그램매매추이(체결) API입니다.
한국투자 HTS(eFriend Plus) > [0465] 종목별 프로그램 매매추이 화면(혹은 한국투자 MTS > 국내 현재가 > 기타수급 > 프로그램) 의 기능을 API로 개발한 사항으로, 해당 화면을 참고하시면 기능을 이해하기 쉽습니다.
Args:
fid_input_iscd (str): 입력 종목코드 - 종목번호(6자리) ETN의 경우 Q로 시작(EX. Q500001)
tr_cont (str): 연속조회여부
Returns:
dict:
- rt_cd (str): 응답코드
- tr_cont (str): 연속조회가능여부
- msg_cd (str): 메시지코드
- msg1 (str): 메시지1
- output (list): 응답상세
- bsop_hour: 영업 시간
- stck_prpr: 주식 현재가
- prdy_vrss: 전일 대비
- prdy_vrss_sign: 전일 대비 부호
- prdy_ctrt: 전일 대비율
- acml_vol: 누적 거래량
- whol_smtn_seln_vol: 전체 합계 매도 거래량
- whol_smtn_shnu_vol: 전체 합계 매수2 거래량
- whol_smtn_ntby_qty: 전체 합계 순매수 수량
- whol_smtn_seln_tr_pbmn: 전체 합계 매도 거래 대금
- whol_smtn_shnu_tr_pbmn: 전체 합계 매수2 거래 대금
- whol_smtn_ntby_tr_pbmn: 전체 합계 순매수 거래 대금
- whol_ntby_vol_icdc: 전체 순매수 거래량 증감
- whol_ntby_tr_pbmn_icdc: 전체 순매수 거래 대금 증감
Raise:
ValueError: API 에러 발생시
"""
assert not self.auth.paper_trading, "실전계좌에서만 사용 가능한 API입니다."
url_path = "/uapi/domestic-stock/v1/quotations/program-trade-by-stock"
tr_id = "FHPPG04650101"
params = {"FID_INPUT_ISCD": fid_input_iscd, "FID_COND_MRKT_DIV_CODE": "UN"}
res_body, res_headers = self._tr_request(url_path, tr_id, tr_cont, params=params)
if res_body["rt_cd"] != "0":
raise ValueError(f"Error: ({res_body['msg_cd']}) {res_body['msg1']}")
output = []
for el in res_body["output"]:
for k in el.keys():
if k in ["prdy_ctrt"]:
el[k] = Decimal(el[k])
elif k == "bsop_hour":
el[k] = dtm.datetime.strptime(el[k], "%H%M%S").time()
else:
el[k] = int(el[k])
output.append(el)
result = {
"rt_cd": res_body["rt_cd"],
"msg_cd": res_body["msg_cd"],
"msg1": res_body["msg1"],
"tr_cont": res_headers["tr_cont"],
"output": output,
}
return result
[docs]
def get_volume_rank(self, fid_input_iscd: str, fid_div_cls_code: str, fid_blng_cls_code: str, fid_trgt_cls_code: str, fid_trgt_excls_cls_code: str, fid_input_price_1: int = None, fid_input_price_2: int = None, fid_vol_cnt: int = None):
"""
(국내주식시세) 거래량순위[v1_국내주식-047]
국내주식 거래량순위 API입니다.
한국투자 HTS(eFriend Plus) > [0171] 거래량 순위 화면의 기능을 API로 개발한 사항으로, 해당 화면을 참고하시면 기능을 이해하기 쉽습니다.
최대 30건 확인 가능하며, 다음 조회가 불가합니다.
+30건 이상의 목록 조회가 필요한 경우, 대안으로 종목조건검색 API를 이용해서 원하는 종목 100개까지 검색할 수 있는 기능을 제공하고 있습니다.
종목조건검색 API는 HTS(efriend Plus) [0110] 조건검색에서 등록 및 서버저장한 나의 조건 목록을 확인할 수 있는 API로,
HTS [0110]에서 여러가지 조건을 설정할 수 있는데, 그 중 거래량 순위(ex. 0봉전 거래량 상위순 100종목) 에 대해서도 설정해서 종목을 검색할 수 있습니다.
자세한 사용 방법은 공지사항 - [조건검색 필독] 조건검색 API 이용안내 참고 부탁드립니다.
Args:
fid_input_iscd (str): 입력 종목코드 0000(전체) 기타(업종코드)
fid_div_cls_code (str): 분류 구분 코드 0:전체 1:보통주 2:우선주
fid_blng_cls_code (str): 소속 구분 코드 0:평균거래량 1:거래증가율 2:평균거래회전율 3:거래금액순 4:평균거래금액회전율
fid_trgt_cls_code (str): 대상 구분 코드
| 1 or 0 9자리 (차례대로 증거금 30% 40% 50% 60% 100% 신용보증금 30% 40% 50% 60%)
| ex) "111111111"
fid_trgt_exls_cls_code (str): 대상 제외 구분 코드
| 1 or 0 6자리 (차례대로 투자위험/경고/주의 관리종목 정리매매 불성실공시 우선주 거래정지)
| ex) "000000"
fid_input_price_1 (int): 입력 가격1 - 가격 ~
| ex) 0
| 전체 가격 대상 조회 시 FID_INPUT_PRICE_1, FID_INPUT_PRICE_2 모두 None
fid_input_price_2 (int): 입력 가격2 - ~ 가격
| ex) 1000000
| 전체 가격 대상 조회 시 FID_INPUT_PRICE_1, FID_INPUT_PRICE_2 모두 None
fid_vol_cnt (int): 거래량 수 - 거래량 ~
| ex) 100000
| 전체 거래량 대상 조회 시 FID_VOL_CNT None
Returns:
dict:
- rt_cd (str): 응답코드
- msg_cd (str): 메시지코드
- msg1 (str): 메시지1
- output (list): 응답상세
- hts_kor_isnm: HTS 한글 종목명
- mksc_shrn_iscd: 유가증권 단축 종목코드
- data_rank: 데이터 순위
- stck_prpr: 주식 현재가
- prdy_vrss_sign: 전일 대비 부호
- prdy_vrss: 전일 대비
- prdy_ctrt: 전일 대비율
- acml_vol: 누적 거래량
- prdy_vol: 전일 거래량
- lstn_stcn: 상장 주수
- avrg_vol: 평균 거래량
- n_befr_clpr_vrss_prpr_rate: N일전종가대비현재가대비율
- vol_inrt: 거래량증가율
- vol_tnrt: 거래량 회전율
- nday_vol_tnrt: N일 거래량 회전율
- avrg_tr_pbmn: 평균 거래 대금
- tr_pbmn_tnrt: 거래대금회전율
- nday_tr_pbmn_tnrt: N일 거래대금 회전율
- acml_tr_pbmn: 누적 거래 대금
Raise:
ValueError: API 에러 발생시
"""
assert not self.auth.paper_trading, "실전계좌에서만 사용 가능한 API입니다."
assert fid_div_cls_code in ["0", "1"], 'fid_div_cls_code must be "0" or "1"'
assert fid_blng_cls_code in ["0", "1", "2", "3", "4"], 'fid_blng_cls_code must be "0", "1", "2", "3" or "4"'
assert len(fid_trgt_cls_code) == 9, "fid_trgt_cls_code length must be 9"
assert all([x in ["0", "1"] for x in fid_trgt_cls_code]), 'fid_trgt_cls_code must be "0" or "1"'
assert len(fid_trgt_excls_cls_code) == 6, "fid_trgt_excls_cls_code length must be 6"
assert all([x in ["0", "1"] for x in fid_trgt_excls_cls_code]), 'fid_trgt_excls_cls_code must be "0" or "1"'
assert fid_input_price_1 is None or isinstance(fid_input_price_1, int), "fid_input_price_1 must be None or int"
assert fid_input_price_2 is None or isinstance(fid_input_price_2, int), "fid_input_price_2 must be None or int"
assert fid_vol_cnt is None or isinstance(fid_vol_cnt, int), "fid_vol_cnt must be None or int"
url_path = "/uapi/domestic-stock/v1/quotations/volume-rank"
tr_id = "FHPST01710000"
params = {
"FID_COND_MRKT_DIV_CODE": "J",
"FID_COND_SCR_DIV_CODE": "20171",
"FID_INPUT_ISCD": fid_input_iscd,
"FID_DIV_CLS_CODE": fid_div_cls_code,
"FID_BLNG_CLS_CODE": fid_blng_cls_code,
"FID_TRGT_CLS_CODE": fid_trgt_cls_code,
"FID_TRGT_EXLS_CLS_CODE": fid_trgt_excls_cls_code,
"FID_INPUT_PRICE_1": "" if fid_input_price_1 is None else int(fid_input_price_1),
"FID_INPUT_PRICE_2": "" if fid_input_price_2 is None else int(fid_input_price_2),
"FID_VOL_CNT": "" if fid_vol_cnt is None else int(fid_vol_cnt),
"FID_INPUT_DATE_1": "0",
}
res_body, res_headers = self._tr_request(url_path, tr_id, params=params)
if res_body["rt_cd"] != "0":
raise ValueError(f"Error: ({res_body['msg_cd']}) {res_body['msg1']}")
output = []
for el in res_body["output"]:
for k in el.keys():
if k in ["hts_kor_isnm", "mksc_shrn_iscd"]:
pass
elif k in ["prdy_ctrt", "n_befr_clpr_vrss_prpr_rate", "vol_inrt", "vol_tnrt", "nday_vol_tnrt", "tr_pbmn_tnrt", "nday_tr_pbmn_tnrt"]:
el[k] = Decimal(el[k])
else:
el[k] = int(el[k])
output.append(el)
result = {"rt_cd": res_body["rt_cd"], "msg_cd": res_body["msg_cd"], "msg1": res_body["msg1"], "output": output}
return result
[docs]
def get_investor_trend_estimate(self, mksc_shrn_iscd: str):
"""
(국내주식시세) 종목별 외인기관 추정가집계[v1_국내주식-046]
국내주식 종목별 외국인, 기관 추정가집계 API입니다.
한국투자 MTS > 국내 현재가 > 투자자 > 투자자동향 탭 > 왼쪽구분을 '추정(주)'로 선택 시 확인 가능한 데이터를 API로 개발한 사항으로, 해당 화면을 참고하시면 기능을 이해하기 쉽습니다.
증권사 직원이 장중에 집계/입력한 자료를 단순 누계한 수치로서,
입력시간은 외국인 09:30, 11:20, 13:20, 14:30 / 기관종합 10:00, 11:20, 13:20, 14:30 이며, 사정에 따라 변동될 수 있습니다.
Args:
mksc_shrn_iscd (str): 종목코드
Returns:
dict:
- rt_cd (str): 응답코드
- msg_cd (str): 메시지코드
- msg1 (str): 메시지1
- output (list): 응답상세
- bsop_hour_gb: 입력구분 - 1:09시30분 입력 2:10시00분 입력 3:11시20분 입력 4:13시20분 입력 5:14시30분 입력
- frgn_fake_ntby_qty: 외국인수량 (가집계)
- orgn_fake_ntby_qty: 기관수량 (가집계)
- sum_fake_ntby_qty: 합산수량 (가집계)
Raise:
ValueError: API 에러 발생시
"""
assert not self.auth.paper_trading, "실전계좌에서만 사용 가능한 API입니다."
url_path = "/uapi/domestic-stock/v1/quotations/investor-trend-estimate"
tr_id = "HHPTJ04160200"
params = {"MKSC_SHRN_ISCD": mksc_shrn_iscd}
res_body, res_headers = self._tr_request(url_path, tr_id, params=params)
if res_body["rt_cd"] != "0":
raise ValueError(f"Error: ({res_body['msg_cd']}) {res_body['msg1']}")
output = []
for el in res_body["output2"]:
for k in el.keys():
if k == "bsop_hour_gb":
pass
else:
el[k] = int(el[k])
output.append(el)
result = {"rt_cd": res_body["rt_cd"], "msg_cd": res_body["msg_cd"], "msg1": res_body["msg1"], "output": res_body["output2"]}
return result
[docs]
def inquire_time_indexchartprice(self, fid_etc_cls_code: str, fid_input_iscd: str, fid_input_hour_1: int, fid_pw_data_incu_yn: str, tr_cont: str = ""):
"""
(국내주식시세) 업종 분봉조회[v1_국내주식-045]
업종분봉조회 API입니다.
실전계좌의 경우, 한 번의 호출에 최대 102건까지 확인 가능합니다.
Args:
fid_etc_cls_code (str): 기타 구분 코드 - 0:기본 1:장마감,시간외 제외
fid_input_iscd (str): 입력 종목코드 - 0001:종합, 1001:코스닥종합
fid_input_hour_1 (int): 입력 시간1 - 30,60->1분 600->10분 3600->1시간
fid_pw_data_incu_yn (str): 과거 데이터 포함 여부 - Y:과거 N:당일
tr_cont (str): 연속조회여부. '':초기조회, 'N':연속조회
Returns:
dict:
- rt_cd (str): 응답코드
- msg_cd (str): 메시지코드
- msg1 (str): 메시지1
- output1 (dict): 응답상세
- bstp_nmix_prdy_vrss: 업종 지수 전일 대비
- prdy_vrss_sign: 전일 대비 부호
- bstp_nmix_prdy_ctrt: 업종 지수 전일 대비율
- prdy_nmix: 전일 지수
- acml_vol: 누적 거래량
- acml_tr_pbmn: 누적 거래 대금
- hts_kor_isnm: HTS 한글 종목명
- bstp_nmix_prpr: 업종 지수 현재가
- bstp_cls_code: 업종 구분 코드
- prdy_vol: 전일 거래량
- bstp_nmix_oprc: 업종 지수 시가2
- bstp_nmix_hgpr: 업종 지수 최고가
- bstp_nmix_lwpr: 업종 지수 최저가
- futs_prdy_oprc: 선물 전일 시가
- futs_prdy_hgpr: 선물 전일 최고가
- futs_prdy_lwpr: 선물 전일 최저가
- output2 (list): 응답상세
- stck_bsop_date: 주식 영업 일자
- stck_cntg_hour: 주식 체결 시간
- bstp_nmix_prpr: 업종 지수 현재가
- bstp_nmix_oprc: 업종 지수 시가2
- bstp_nmix_hgpr: 업종 지수 최고가
- bstp_nmix_lwpr: 업종 지수 최저가
- cntg_vol: 체결 거래량
- acml_tr_pbmn: 누적 거래 대금
Raise:
ValueError: API 에러 발생시
"""
assert not self.auth.paper_trading, "실전계좌에서만 사용 가능한 API입니다."
assert fid_etc_cls_code in ["0", "1"], 'fid_etc_cls_code must be "0" or "1"'
assert fid_input_iscd in ["0001", "1001"], 'fid_input_iscd must be "0001" or "1001"'
assert fid_pw_data_incu_yn in ["Y", "N"], 'fid_pw_data_incu_yn must be "Y" or "N"'
url_path = "/uapi/domestic-stock/v1/quotations/inquire-time-indexchartprice"
tr_id = "FHKUP03500200"
params = {"FID_COND_MRKT_DIV_CODE": "U", "FID_ETC_CLS_CODE": fid_etc_cls_code, "FID_INPUT_ISCD": fid_input_iscd, "FID_INPUT_HOUR_1": str(fid_input_hour_1), "FID_PW_DATA_INCU_YN": fid_pw_data_incu_yn}
res_body, res_headers = self._tr_request(url_path, tr_id, tr_cont, params=params)
if res_body["rt_cd"] != "0":
raise ValueError(f"Error: ({res_body['msg_cd']}) {res_body['msg1']}")
output1 = res_body["output1"]
for k in output1.keys():
if k in ["hts_kor_isnm", "bstp_cls_code"]:
pass
elif k in ["prdy_vrss_sign", "acml_vol", "acml_tr_pbmn", "prdy_vol"]:
output1[k] = int(output1[k])
else:
output1[k] = Decimal(output1[k])
output2 = []
for el in res_body["output2"]:
for k in el.keys():
if k == "stck_bsop_date":
el[k] = dtm.datetime.strptime(el[k], "%Y%m%d").date()
elif k == "stck_cntg_hour":
el[k] = dtm.datetime.strptime(el[k], "%H%M%S").time()
elif k in ["cntg_vol", "acml_tr_pbmn"]:
el[k] = int(el[k])
else:
el[k] = Decimal(el[k])
output2.append(el)
result = {"rt_cd": res_body["rt_cd"], "msg_cd": res_body["msg_cd"], "msg1": res_body["msg1"], "tr_cont": res_headers["tr_cont"], "output1": output1, "output2": output2}
return result
[docs]
def inquire_time_dailychartprice(self, fid_input_iscd: str, fid_input_date_1: dtm.date, fid_input_hour_1: dtm.time, fid_cond_mrkt_div_code: str = "J", fid_pw_data_incu_yn: str = "Y", fid_fake_tick_incu_yn: str = "N"):
"""
(국내주식시세) 주식일별 분봉조회[v1_국내주식-213]
주식일별분봉조회 API입니다.
실전계좌의 경우, 한 번의 호출에 최대 100건까지 확인 가능하며, FID_INPUT_DATE_1, FID_INPUT_HOUR_1 이용하여 과거일자 분봉조회 가능합니다.
과거 분봉 조회 시, 당사 서버에서 보관하고 있는 만큼의 데이터만 확인이 가능합니다. (최대 1년 분봉 보관)
Args:
fid_input_iscd (str): 종목번호(6자리) ETN의 경우 Q로 시작(EX. Q500001)
fid_input_date_1 (dt.date): 조회 시작일자 (ex. dtm.date(2024, 2, 8))
fid_input_hour_1 (dt.time): 조회 시작시간 (ex. dtm.time(15, 30, 0))
fid_cond_mrkt_div_code (str): FID 조건시장분류코드 - J:주식,ETF,ETN NX:Nextrade UN:통합
fid_pw_data_incu_yn (str): 과거 데이터 포함 여부 - Y:과거 N:당일만 조회
fid_fake_tick_incu_yn (str): 허봉 포함 여부 - Y:포함 N:미포함
Returns:
dict:
- rt_cd (str): 응답코드
- msg_cd (str): 메시지코드
- msg1 (str): 메시지1
- output1 (dict): 응답상세1
- prdy_vrss: 전일 대비
- prdy_vrss_sign: 전일 대비 부호
- prdy_ctrt: 전일 대비율
- stck_prdy_clpr: 주식 전일 종가
- acml_vol: 누적 거래량
- acml_tr_pbmn: 누적 거래 대금
- hts_kor_isnm: HTS 한글 종목명
- stck_prpr: 주식 현재가
- output2 (list): 응답상세2
- stck_bsop_date: 주식 영업 일자
- stck_cntg_hour: 주식 체결 시간
- stck_prpr: 주식 현재가
- stck_oprc: 주식 시가2
- stck_hgpr: 주식 최고가
- stck_lwpr: 주식 최저가
- cntg_vol: 체결 거래량
- acml_tr_pbmn: 누적 거래 대금
Raise:
ValueError: API 에러 발생시
"""
assert not self.auth.paper_trading, "실전계좌에서만 사용 가능한 API입니다."
assert len(fid_input_iscd) >= 6, "fid_input_iscd length must be 6"
assert fid_cond_mrkt_div_code in ["J", "NX", "UN"], 'fid_cond_mrkt_div_code must be one of "J", "NX", or "UN"'
assert fid_pw_data_incu_yn in ["Y", "N"], 'fid_pw_data_incu_yn must be "Y" or "N"'
assert fid_fake_tick_incu_yn in ["Y", "N"], 'fid_fake_tick_incu_yn must be "Y" or "N"'
url_path = "/uapi/domestic-stock/v1/quotations/inquire-time-dailychartprice"
tr_id = "FHKST03010230"
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.strftime("%Y%m%d"),
"FID_INPUT_HOUR_1": fid_input_hour_1.strftime("%H%M%S"),
"FID_PW_DATA_INCU_YN": fid_pw_data_incu_yn,
"FID_FAKE_TICK_INCU_YN": fid_fake_tick_incu_yn,
}
res_body, res_headers = self._tr_request(url_path, tr_id, params=params)
if res_body["rt_cd"] != "0":
raise ValueError(f"Error: ({res_body['msg_cd']}) {res_body['msg1']}")
output1 = res_body["output1"]
for k in output1.keys():
if k in ["hts_kor_isnm"]:
pass
elif k == ["prdy_vrss_sign", "stck_prdy_clpr", "acml_vol", "acml_tr_pbmn"]:
output1[k] = int(output1[k])
else:
output1[k] = Decimal(output1[k])
output2 = []
for el in res_body["output2"]:
for k in el.keys():
if k == "stck_bsop_date":
el[k] = dtm.datetime.strptime(el[k], "%Y%m%d").date()
elif k == "stck_cntg_hour":
el[k] = dtm.datetime.strptime(el[k], "%H%M%S").time()
elif k in ["cntg_vol", "acml_tr_pbmn"]:
el[k] = int(el[k])
else:
el[k] = Decimal(el[k])
output2.append(el)
result = {
"rt_cd": res_body["rt_cd"],
"msg_cd": res_body["msg_cd"],
"msg1": res_body["msg1"],
"tr_cont": res_headers["tr_cont"],
"output1": output1,
"output2": output2,
}
return result
[docs]
def inquire_price_2(self, fid_input_iscd: str, fid_cond_mrkt_div_code: str = "J"):
"""
(국내주식시세) 주식현재가 시세2[v1_국내주식-054]
주식현재가 시세2 API입니다.
Args:
fid_input_iscd (str): 입력 종목코드
fid_cond_mrkt_div_code (str): FID 조건시장분류코드 - J:주식,ETF,ETN NX:Nextrade UN:통합
Returns:
dict:
- rt_cd (str): 응답코드
- msg_cd (str): 메시지코드
- msg1 (str): 메시지1
- output (dict): 응답상세
- rprs_mrkt_kor_name: 대표 시장 한글 명
- new_hgpr_lwpr_cls_code: 신 고가 저가 구분 코드 - 특정 경우에만 데이터 출력
- mxpr_llam_cls_code: 상하한가 구분 코드 - 특정 경우에만 데이터 출력
- crdt_able_yn: 신용 가능 여부
- stck_mxpr: 주식 상한가
- elw_pblc_yn: ELW 발행 여부
- prdy_clpr_vrss_oprc_rate: 전일 종가 대비 시가2 비율
- crdt_rate: 신용 비율
- marg_rate: 증거금 비율
- lwpr_vrss_prpr: 최저가 대비 현재가
- lwpr_vrss_prpr_sign: 최저가 대비 현재가 부호
- prdy_clpr_vrss_lwpr_rate: 전일 종가 대비 최저가 비율
- stck_lwpr: 주식 최저가
- hgpr_vrss_prpr: 최고가 대비 현재가
- hgpr_vrss_prpr_sign: 최고가 대비 현재가 부호
- prdy_clpr_vrss_hgpr_rate: 전일 종가 대비 최고가 비율
- stck_hgpr: 주식 최고가
- oprc_vrss_prpr: 시가2 대비 현재가
- oprc_vrss_prpr_sign: 시가2 대비 현재가 부호
- mang_issu_yn: 관리 종목 여부
- divi_app_cls_code: 동시호가배분처리코드 - 11:매수상한배분 12:매수하한배분 13: 매도상한배분 14:매도하한배분
- short_over_yn: 단기과열여부
- mrkt_warn_cls_code: 시장경고코드 - 00: 없음 01: 투자주의 02:투자경고 03:투자위험
- invt_caful_yn: 투자유의여부
- stange_runup_yn: 이상급등여부
- ssts_hot_yn: 공매도과열 여부
- low_current_yn: 저유동성 종목 여부
- vi_cls_code: VI적용구분코드
- short_over_cls_code: 단기과열구분코드
- stck_llam: 주식 하한가
- new_lstn_cls_name: 신규 상장 구분 명
- vlnt_deal_cls_name: 임의 매매 구분 명
- flng_cls_name: 락 구분 이름 - 특정 경우에만 데이터 출력
- revl_issu_reas_name: 재평가 종목 사유 명 - 특정 경우에만 데이터 출력
- mrkt_warn_cls_name: 시장 경고 구분 명 - 특정 경우에만 데이터 출력 "투자환기" / "투자경고"
- stck_sdpr: 주식 기준가
- bstp_cls_code: 업종 구분 코드
- stck_prdy_clpr: 주식 전일 종가
- insn_pbnt_yn: 불성실 공시 여부
- fcam_mod_cls_name: 액면가 변경 구분 명 - 특정 경우에만 데이터 출력
- stck_prpr: 주식 현재가
- prdy_vrss: 전일 대비
- prdy_vrss_sign: 전일 대비 부호
- prdy_ctrt: 전일 대비율
- acml_tr_pbmn: 누적 거래 대금
- acml_vol: 누적 거래량
- prdy_vrss_vol_rate: 전일 대비 거래량 비율
- bstp_kor_isnm: 업종 한글 종목명
- sltr_yn: 정리매매 여부
- trht_yn: 거래정지 여부
- oprc_rang_cont_yn: 시가 범위 연장 여부
- vlnt_fin_cls_code: 임의 종료 구분 코드
- stck_oprc: 주식 시가2
- prdy_vol: 전일 거래량
Raise:
ValueError: API 에러 발생시
"""
assert not self.auth.paper_trading, "실전계좌에서만 사용 가능한 API입니다."
url_path = "/uapi/domestic-stock/v1/quotations/inquire-price-2"
tr_id = "FHPST01010000"
params = {"FID_COND_MRKT_DIV_CODE": fid_cond_mrkt_div_code, "FID_INPUT_ISCD": fid_input_iscd}
res_body, res_headers = self._tr_request(url_path, tr_id, params=params)
if res_body["rt_cd"] != "0":
raise ValueError(f"Error: ({res_body['msg_cd']}) {res_body['msg1']}")
output = res_body["output"]
for k in output.keys():
if k in ["prdy_ctrt", "prdy_vrss_vol_rate", "prdy_clpr_vrss_oprc_rate", "prdy_clpr_vrss_hgpr_rate", "prdy_clpr_vrss_lwpr_rate", "marg_rate", "crdt_rate"]:
output[k] = Decimal(output[k])
elif k in [
"stck_prpr",
"prdy_vrss",
"prdy_vrss_sign",
"acml_tr_pbmn",
"acml_vol",
"prdy_vol",
"stck_prdy_clpr",
"stck_oprc",
"oprc_vrss_prpr_sign",
"oprc_vrss_prpr",
"stck_hgpr",
"hgpr_vrss_prpr_sign",
"hgpr_vrss_prpr",
"stck_lwpr",
"lwpr_vrss_prpr_sign",
"lwpr_vrss_prpr",
"stck_mxpr",
"stck_llam",
"bstp_cls_code",
"stck_sdpr",
]:
output[k] = int(output[k])
else:
output[k] = output[k].strip()
result = {"rt_cd": res_body["rt_cd"], "msg_cd": res_body["msg_cd"], "msg1": res_body["msg1"], "output": res_body["output"]}
return result
[docs]
def inquire_daily_trade_volume(self, fid_input_iscd: str, fid_input_date_1: dtm.date, fid_input_date_2: dtm.date, tr_cont: str = ""):
"""
(국내주식시세) 종목별일별매수매도체결량 [v1_국내주식-056]
종목별일별매수매도체결량 API입니다. 실전계좌의 경우, 한 번의 호출에 최대 100건까지 확인 가능합니다.
국내주식 종목의 일별 매수체결량, 매도체결량 데이터를 확인할 수 있습니다.
Args:
fid_input_iscd (str): 입력 종목코드
fid_input_date_1 (dtm.date): 입력 일자1 - from
fid_input_date_2 (dtm.date): 입력 일자2 - to
tr_cont (str): 연속조회여부
Returns:
dict:
- rt_cd (str): 응답코드
- msg_cd (str): 메시지코드
- msg1 (str): 메시지1
- tr_cont (str): 연속조회가능여부
- output1 (dict): 응답상세
- shnu_cnqn_smtn: 매수 체결량 합계 - 당일 매수체결량 합계
- seln_cnqn_smtn: 매도 체결량 합계 - 당일 매도체결량 합계
- output2 (list): 응답상세
- stck_bsop_date: 주식 영업 일자
- total_seln_qty: 총 매도 수량
- total_shnu_qty: 총 매수 수량
Raise:
ValueError: API 에러 발생시
"""
assert not self.auth.paper_trading, "실전계좌에서만 사용 가능한 API입니다."
url_path = "/uapi/domestic-stock/v1/quotations/inquire-daily-trade-volume"
tr_id = "FHKST03010800"
params = {"FID_COND_MRKT_DIV_CODE": "J", "FID_INPUT_ISCD": fid_input_iscd, "FID_INPUT_DATE_1": fid_input_date_1.strftime("%Y%m%d"), "FID_INPUT_DATE_2": fid_input_date_2.strftime("%Y%m%d"), "FID_PERIOD_DIV_CODE": "D"}
res_body, res_headers = self._tr_request(url_path, tr_id, tr_cont, params=params)
if res_body["rt_cd"] != "0":
raise ValueError(f"Error: ({res_body['msg_cd']}) {res_body['msg1']}")
output1 = res_body["output1"]
for k in output1.keys():
output1[k] = int(output1[k])
output2 = []
for el in res_body["output2"]:
for k in el.keys():
if k == "stck_bsop_date":
el[k] = dtm.datetime.strptime(el[k], "%Y%m%d").date()
else:
el[k] = int(el[k])
output2.append(el)
result = {"rt_cd": res_body["rt_cd"], "msg_cd": res_body["msg_cd"], "msg1": res_body["msg1"], "tr_cont": res_headers["tr_cont"], "output1": output1, "output2": output2}
return result
[docs]
def inquire_index_price(self, fid_input_iscd: str):
"""
(국내주식시세) 국내업종 현재지수[v1_국내주식-063]
국내업종 현재지수 API입니다.
한국투자 HTS(eFriend Plus) > [0210] 업종 현재지수 화면 의 기능을 API로 개발한 사항으로, 해당 화면을 참고하시면 기능을 이해하기 쉽습니다.
Args:
fid_input_iscd (str): 입력 종목코드 - 코스피(0001), 코스닥(1001), 코스피200(2001)
Returns:
dict:
- rt_cd (str): 응답코드
- msg_cd (str): 메시지코드
- msg1 (str): 메시지1
- output (dict): 응답상세
- bstp_nmix_prpr: 업종 지수 현재가
- bstp_nmix_prdy_vrss: 업종 지수 전일 대비
- prdy_vrss_sign: 전일 대비 부호
- bstp_nmix_prdy_ctrt: 업종 지수 전일 대비율
- acml_vol: 누적 거래량
- prdy_vol: 전일 거래량
- acml_tr_pbmn: 누적 거래 대금
- prdy_tr_pbmn: 전일 거래 대금
- bstp_nmix_oprc: 업종 지수 시가2
- prdy_nmix_vrss_nmix_oprc: 전일 지수 대비 지수 시가2
- oprc_vrss_prpr_sign: 시가2 대비 현재가 부호
- bstp_nmix_oprc_prdy_ctrt: 업종 지수 시가2 전일 대비율
- bstp_nmix_hgpr: 업종 지수 최고가
- prdy_nmix_vrss_nmix_hgpr: 전일 지수 대비 지수 최고가
- hgpr_vrss_prpr_sign: 최고가 대비 현재가 부호
- bstp_nmix_hgpr_prdy_ctrt: 업종 지수 최고가 전일 대비율
- bstp_nmix_lwpr: 업종 지수 최저가
- prdy_clpr_vrss_lwpr: 전일 종가 대비 최저가
- lwpr_vrss_prpr_sign: 최저가 대비 현재가 부호
- prdy_clpr_vrss_lwpr_rate: 전일 종가 대비 최저가 비율
- ascn_issu_cnt: 상승 종목 수
- uplm_issu_cnt: 상한 종목 수
- stnr_issu_cnt: 보합 종목 수
- down_issu_cnt: 하락 종목 수
- lslm_issu_cnt: 하한 종목 수
- dryy_bstp_nmix_hgpr: 연중업종지수최고가
- dryy_hgpr_vrss_prpr_rate: 연중 최고가 대비 현재가 비율
- dryy_bstp_nmix_hgpr_date: 연중업종지수최고가일자
- dryy_bstp_nmix_lwpr: 연중업종지수최저가
- dryy_lwpr_vrss_prpr_rate: 연중 최저가 대비 현재가 비율
- dryy_bstp_nmix_lwpr_date: 연중업종지수최저가일자
- total_askp_rsqn: 총 매도호가 잔량
- total_bidp_rsqn: 총 매수호가 잔량
- seln_rsqn_rate: 매도 잔량 비율
- shnu_rsqn_rate: 매수2 잔량 비율
- ntby_rsqn: 순매수 잔량
Raise:
ValueError: API 에러 발생시
"""
assert not self.auth.paper_trading, "실전계좌에서만 사용 가능한 API입니다."
url_path = "/uapi/domestic-stock/v1/quotations/inquire-index-price"
tr_id = "FHPUP02100000"
params = {"FID_COND_MRKT_DIV_CODE": "U", "FID_INPUT_ISCD": fid_input_iscd}
res_body, res_headers = self._tr_request(url_path, tr_id, params=params)
if res_body["rt_cd"] != "0":
raise ValueError(f"Error: ({res_body['msg_cd']}) {res_body['msg1']}")
output = res_body["output"]
for k in output.keys():
if k in ["dryy_bstp_nmix_hgpr_date", "dryy_bstp_nmix_lwpr_date"]:
output[k] = dtm.datetime.strptime(output[k], "%Y%m%d").date()
elif k in [
"bstp_nmix_prdy_vrss",
"bstp_nmix_prdy_ctrt",
"bstp_nmix_prpr",
"bstp_nmix_oprc",
"prdy_nmix_vrss_nmix_oprc",
"bstp_nmix_oprc_prdy_ctrt",
"bstp_nmix_hgpr",
"prdy_nmix_vrss_nmix_hgpr",
"bstp_nmix_hgpr_prdy_ctrt",
"bstp_nmix_lwpr",
"prdy_clpr_vrss_lwpr",
"prdy_clpr_vrss_lwpr_rate",
"dryy_bstp_nmix_hgpr",
"dryy_hgpr_vrss_prpr_rate",
"dryy_bstp_nmix_lwpr",
"dryy_lwpr_vrss_prpr_rate",
"seln_rsqn_rate",
"shnu_rsqn_rate",
]:
output[k] = Decimal(output[k])
else:
output[k] = int(output[k])
result = {"rt_cd": res_body["rt_cd"], "msg_cd": res_body["msg_cd"], "msg1": res_body["msg1"], "output": output}
return result
[docs]
def inquire_index_daily_price(
self,
fid_period_div_code: str,
fid_input_iscd: str,
fid_input_date_1: dtm.date,
):
"""
(국내주식시세) 국내업종 일자별지수[v1_국내주식-065]
국내업종 일자별지수 API입니다. 한 번의 조회에 100건까지 확인 가능합니다.
한국투자 HTS(eFriend Plus) > [0212] 업종 일자별지수 화면 의 기능을 API로 개발한 사항으로, 해당 화면을 참고하시면 기능을 이해하기 쉽습니다.
Args:
fid_period_div_code (str): 기간 구분 코드 - D:일 W:주 M:월
fid_input_iscd (str): 입력 종목코드 - 코스피(0001), 코스닥(1001), 코스피200(2001)
fid_input_date_1 (dtm.date): 입력 일자1
Returns:
dict:
- rt_cd (str): 응답코드
- msg_cd (str): 메시지코드
- msg1 (str): 메시지1
- output1 (dict): 응답상세
- bstp_nmix_prpr: 업종 지수 현재가
- bstp_nmix_prdy_vrss: 업종 지수 전일 대비
- prdy_vrss_sign: 전일 대비 부호
- bstp_nmix_prdy_ctrt: 업종 지수 전일 대비율
- acml_vol: 누적 거래량
- acml_tr_pbmn: 누적 거래 대금
- bstp_nmix_oprc: 업종 지수 시가2
- bstp_nmix_hgpr: 업종 지수 최고가
- bstp_nmix_lwpr: 업종 지수 최저가
- prdy_vol: 전일 거래량
- ascn_issu_cnt: 상승 종목 수
- down_issu_cnt: 하락 종목 수
- stnr_issu_cnt: 보합 종목 수
- uplm_issu_cnt: 상한 종목 수
- lslm_issu_cnt: 하한 종목 수
- prdy_tr_pbmn: 전일 거래 대금
- dryy_bstp_nmix_hgpr_date: 연중업종지수최고가일자
- dryy_bstp_nmix_hgpr: 연중업종지수최고가
- dryy_bstp_nmix_lwpr: 연중업종지수최저가
- dryy_bstp_nmix_lwpr_date: 연중업종지수최저가일자
- output2 (list): 응답상세
- stck_bsop_date: 주식 영업 일자
- bstp_nmix_prpr: 업종 지수 현재가
- prdy_vrss_sign: 전일 대비 부호
- bstp_nmix_prdy_vrss: 업종 지수 전일 대비
- bstp_nmix_prdy_ctrt: 업종 지수 전일 대비율
- bstp_nmix_oprc: 업종 지수 시가2
- bstp_nmix_hgpr: 업종 지수 최고가
- bstp_nmix_lwpr: 업종 지수 최저가
- acml_vol_rlim: 누적 거래량 비중
- acml_vol: 누적 거래량
- acml_tr_pbmn: 누적 거래 대금
- invt_new_psdg: 투자 신 심리도
- d20_dsrt: 20일 이격도
Raise:
ValueError: API 에러 발생시
"""
assert not self.auth.paper_trading, "실전계좌에서만 사용 가능한 API입니다."
assert fid_period_div_code in ["D", "W", "M"], 'fid_period_div_code must be "D", "W" or "M"'
assert fid_input_iscd in ["0001", "1001", "2001"], 'fid_input_iscd must be "0001", "1001" or "2001"'
url_path = "/uapi/domestic-stock/v1/quotations/inquire-index-daily-price"
tr_id = "FHPUP02120000"
params = {"FID_PERIOD_DIV_CODE": fid_period_div_code, "FID_COND_MRKT_DIV_CODE": "U", "FID_INPUT_ISCD": fid_input_iscd, "FID_INPUT_DATE_1": fid_input_date_1.strftime("%Y%m%d")}
res_body, res_headers = self._tr_request(url_path, tr_id, params=params)
if res_body["rt_cd"] != "0":
raise ValueError(f"Error: ({res_body['msg_cd']}) {res_body['msg1']}")
output1 = res_body["output1"]
"""
{
'dryy_bstp_nmix_lwpr_date': '20240118'
'dryy_bstp_nmix_hgpr_date': '20240219',
'bstp_nmix_prpr': '2664.20',
'bstp_nmix_prdy_vrss': '10.89',
'bstp_nmix_prdy_ctrt': '0.41',
'bstp_nmix_oprc': '2671.69',
'bstp_nmix_hgpr': '2671.69',
'bstp_nmix_lwpr': '2653.99',
'dryy_bstp_nmix_hgpr': '2683.39',
'dryy_bstp_nmix_lwpr': '2429.12',
'prdy_vrss_sign': '2',
'acml_vol': '406329',
'acml_tr_pbmn': '8946698',
'prdy_vol': '562144',
'ascn_issu_cnt': '319',
'down_issu_cnt': '545',
'stnr_issu_cnt': '71',
'uplm_issu_cnt': '1',
'lslm_issu_cnt': '0',
'prdy_tr_pbmn': '9150151',
}
"""
for k in output1.keys():
if k in ["dryy_bstp_nmix_lwpr_date", "dryy_bstp_nmix_hgpr_date"]:
try:
output1[k] = dtm.datetime.strptime(output1[k], "%Y%m%d").date()
except ValueError:
output1[k] = None
elif k in ["bstp_nmix_prpr", "bstp_nmix_prdy_vrss", "bstp_nmix_prdy_ctrt", "bstp_nmix_oprc", "bstp_nmix_hgpr", "bstp_nmix_lwpr", "dryy_bstp_nmix_hgpr", "dryy_bstp_nmix_lwpr"]:
output1[k] = Decimal(output1[k])
else:
output1[k] = int(output1[k])
output2 = []
for el in res_body["output2"]:
for k in el.keys():
if k == "stck_bsop_date":
el[k] = dtm.datetime.strptime(el[k], "%Y%m%d").date()
elif k in ["acml_vol", "prdy_vrss_sign", "acml_tr_pbmn"]:
el[k] = int(el[k])
else:
el[k] = Decimal(el[k])
output2.append(el)
result = {"rt_cd": res_body["rt_cd"], "msg_cd": res_body["msg_cd"], "msg1": res_body["msg1"], "output1": output1, "output2": output2}
return result
[docs]
def inquire_index_category_price(self, fid_blng_cls_code: str, fid_input_iscd: str, fid_mrkt_cls_code: str):
"""
(국내주식시세) 국내업종 구분별전체시세[v1_국내주식-066]
국내업종 구분별전체시세 API입니다.
한국투자 HTS(eFriend Plus) > [0214] 업종 전체시세 화면 의 기능을 API로 개발한 사항으로, 해당 화면을 참고하시면 기능을 이해하기 쉽습니다.
Args:
fid_blng_cls_code (str): FID 소속 구분 코드
| 시장구분코드(K:거래소) 0:전업종, 1:기타구분, 2:자본금구분 3:상업별구분
| 시장구분코드(Q:코스닥) 0:전업종, 1:기타구분, 2:벤처구분 3:일반구분
| 시장구분코드(K2:코스닥) 0:전업종
fid_input_iscd (str): FID 입력 종목코드 - 코스피(0001), 코스닥(1001), 코스피200(2001)
fid_mrkt_cls_code (str): FID 시장 구분 코드 - 시장구분코드(K:거래소, Q:코스닥, K2:코스피200)
Returns:
dict:
- rt_cd (str): 응답코드
- msg_cd (str): 메시지코드
- msg1 (str): 메시지1
- output1 (dict): 응답상세
- bstp_nmix_prpr: 업종 지수 현재가
- bstp_nmix_prdy_vrss: 업종 지수 전일 대비
- prdy_vrss_sign: 전일 대비 부호
- bstp_nmix_prdy_ctrt: 업종 지수 전일 대비율
- acml_vol: 누적 거래량
- acml_tr_pbmn: 누적 거래 대금
- bstp_nmix_oprc: 업종 지수 시가2
- bstp_nmix_hgpr: 업종 지수 최고가
- bstp_nmix_lwpr: 업종 지수 최저가
- prdy_vol: 전일 거래량
- ascn_issu_cnt: 상승 종목 수
- down_issu_cnt: 하락 종목 수
- stnr_issu_cnt: 보합 종목 수
- uplm_issu_cnt: 상한 종목 수
- lslm_issu_cnt: 하한 종목 수
- prdy_tr_pbmn: 전일 거래 대금
- dryy_bstp_nmix_hgpr_date: 연중업종지수최고가일자
- dryy_bstp_nmix_hgpr: 연중업종지수최고가
- dryy_bstp_nmix_lwpr: 연중업종지수최저가
- dryy_bstp_nmix_lwpr_date: 연중업종지수최저가일자
- output2 (list): 응답상세
- bstp_cls_code: 업종 구분 코드
- hts_kor_isnm: HTS 한글 종목명
- bstp_nmix_prpr: 업종 지수 현재가
- bstp_nmix_prdy_vrss: 업종 지수 전일 대비
- prdy_vrss_sign: 전일 대비 부호
- bstp_nmix_prdy_ctrt: 업종 지수 전일 대비율
- acml_vol: 누적 거래량
- acml_tr_pbmn: 누적 거래 대금
- acml_vol_rlim: 누적 거래량 비중
- acml_tr_pbmn_rlim: 누적 거래 대금 비중
Raise:
ValueError: API 에러 발생시
"""
assert not self.auth.paper_trading, "실전계좌에서만 사용 가능한 API입니다."
assert fid_blng_cls_code in ["0", "1", "2", "3"], 'fid_blng_cls_code must be "0", "1", "2" or "3"'
assert fid_input_iscd in ["0001", "1001", "2001"], 'fid_input_iscd must be "0001", "1001" or "2001"'
assert fid_mrkt_cls_code in ["K", "Q", "K2"], 'fid_mrkt_cls_code must be "K", "Q" or "K2"'
url_path = "/uapi/domestic-stock/v1/quotations/inquire-index-category-price"
tr_id = "FHPUP02140000"
params = {"FID_COND_MRKT_DIV_CODE": "U", "FID_BLNG_CLS_CODE": fid_blng_cls_code, "FID_INPUT_ISCD": fid_input_iscd, "FID_COND_SCR_DIV_CODE": "20214", "FID_MRKT_CLS_CODE": fid_mrkt_cls_code}
res_body, res_headers = self._tr_request(url_path, tr_id, params=params)
if res_body["rt_cd"] != "0":
raise ValueError(f"Error: ({res_body['msg_cd']}) {res_body['msg1']}")
output1 = res_body["output1"]
for k in output1.keys():
if k in ["dryy_bstp_nmix_lwpr_date", "dryy_bstp_nmix_hgpr_date"]:
output1[k] = dtm.datetime.strptime(output1[k], "%Y%m%d").date()
elif k in ["bstp_nmix_prpr", "bstp_nmix_prdy_vrss", "bstp_nmix_prdy_ctrt", "bstp_nmix_oprc", "bstp_nmix_hgpr", "bstp_nmix_lwpr", "dryy_bstp_nmix_hgpr", "dryy_bstp_nmix_lwpr"]:
output1[k] = Decimal(output1[k])
else:
output1[k] = int(output1[k])
output2 = []
for el in res_body["output2"]:
for k in el.keys():
if k in ["bstp_cls_code", "hts_kor_isnm"]:
pass
elif k in ["prdy_vrss_sign", "acml_vol", "acml_tr_pbmn"]:
if len(el[k]) > 0:
el[k] = int(el[k])
else:
if len(el[k]) > 0:
el[k] = Decimal(el[k])
output2.append(el)
result = {"rt_cd": res_body["rt_cd"], "msg_cd": res_body["msg_cd"], "msg1": res_body["msg1"], "output1": output1, "output2": output2}
return result
[docs]
def search_stock_info(self, prdt_type_cd: str, pdno: str):
"""
(국내주식시세) 주식기본조회[v1_국내주식-067]
주식기본조회 API입니다.
국내주식 종목의 종목상세정보를 확인할 수 있습니다.
Args:
prdt_type_cd (str): 상품유형코드 - 300:주식 301:선물옵션 302:채권 306:ELS
pdno (str): 상품번호
Returns:
dict:
- tr_cd (str): 응답코드
- msg_cd (str): 메시지코드
- msg1 (str): 메시지1
- output (dict): 응답상세
- pdno: 상품번호
- prdt_type_cd: 상품유형코드
- mket_id_cd: 시장ID코드
- scty_grp_id_cd: 증권그룹ID코드
- excg_dvsn_cd: 거래소구분코드
- setl_mmdd: 결산월일
- lstg_stqt: 상장주수
- lstg_cptl_amt: 상장자본금액
- cpta: 자본금
- papr: 액면가
- issu_pric: 발행가격
- kospi200_item_yn: 코스피200종목여부
- scts_mket_lstg_dt: 유가증권시장상장일자
- scts_mket_lstg_abol_dt: 유가증권시장상장폐지일자
- kosdaq_mket_lstg_dt: 코스닥시장상장일자
- kosdaq_mket_lstg_abol_dt: 코스닥시장상장폐지일자
- frbd_mket_lstg_dt: 프리보드시장상장일자
- frbd_mket_lstg_abol_dt: 프리보드시장상장폐지일자
- reits_kind_cd: 리츠종류코드
- etf_dvsn_cd: ETF구분코드
- oilf_fund_yn: 유전펀드여부
- idx_bztp_lcls_cd: 지수업종대분류코드
- idx_bztp_mcls_cd: 지수업종중분류코드
- idx_bztp_scls_cd: 지수업종소분류코드
- stck_kind_cd: 주식종류코드
- mfnd_opng_dt: 뮤추얼펀드개시일자
- mfnd_end_dt: 뮤추얼펀드종료일자
- dpsi_erlm_cncl_dt: 예탁등록취소일자
- etf_cu_qty: ETFCU수량
- prdt_name: 상품명
- prdt_name120: 상품명120
- prdt_abrv_name: 상품약어명
- std_pdno: 표준상품번호
- prdt_eng_name: 상품영문명
- prdt_eng_name120: 상품영문명120
- prdt_eng_abrv_name: 상품영문약어명
- dpsi_aptm_erlm_yn: 예탁지정등록여부
- etf_txtn_type_cd: ETF과세유형코드
- etf_type_cd: ETF유형코드
- lstg_abol_dt: 상장폐지일자
- nwst_odst_dvsn_cd: 신주구주구분코드
- sbst_pric: 대용가격
- thco_sbst_pric: 당사대용가격
- thco_sbst_pric_chng_dt: 당사대용가격변경일자
- tr_stop_yn: 거래정지여부
- admn_item_yn: 관리종목여부
- thdt_clpr: 당일종가
- bfdy_clpr: 전일종가
- clpr_chng_dt: 종가변경일자
- std_idst_clsf_cd: 표준산업분류코드
- std_idst_clsf_cd_name: 표준산업분류코드명
- idx_bztp_lcls_cd_name: 지수업종대분류코드명
- idx_bztp_mcls_cd_name: 지수업종중분류코드명
- idx_bztp_scls_cd_name: 지수업종소분류코드명
- ocr_no: OCR번호
- crfd_item_yn: 크라우드펀딩종목여부
- elec_scty_yn: 전자증권여부
Raise:
ValueError: API 에러 발생시
"""
assert not self.auth.paper_trading, "실전계좌에서만 사용 가능한 API입니다."
assert prdt_type_cd in ["300", "301", "302", "306"], 'prdt_type_cd must be "300", "301", "302" or "306"'
url_path = "/uapi/domestic-stock/v1/quotations/search-stock-info"
tr_id = "CTPF1002R"
params = {"PRDT_TYPE_CD": prdt_type_cd, "PDNO": pdno}
res_body, res_headers = self._tr_request(url_path, tr_id, params=params)
if res_body["rt_cd"] != "0":
raise ValueError(f"Error: ({res_body['msg_cd']}) {res_body['msg1']}")
output = res_body["output"]
for k in output.keys():
if k in ["lstg_stqt", "lstg_cptl_amt", "cpta", "papr", "issu_pric", "etf_cu_qty", "sbst_pric", "thco_sbst_pric", "thdt_clpr", "bfdy_clpr"]:
if len(output[k]) > 0:
output[k] = int(output[k])
result = {"rt_cd": res_body["rt_cd"], "msg_cd": res_body["msg_cd"], "msg1": res_body["msg1"], "output": output}
return result
[docs]
def get_balance_sheet(self, fid_div_cls_code: str, fid_input_iscd: str, fid_cond_mrkt_div_code: str = "J"):
"""
(국내주식) 대차대조표[v1_국내주식-078]
국내주식 대차대조표 API입니다.
한국투자 HTS(eFriend Plus) > [0635] 재무분석종합 화면의 하단 '1. 대차대조표' 기능을 API로 개발한 사항으로, 해당 화면을 참고하시면 기능을 이해하기 쉽습니다.
Args:
fid_div_cls_code (str): 분류 구분 코드 - 0: 년, 1: 분기
fid_cond_mrkt_div_code (str): 조건 시장 분류 코드 - J
fid_input_iscd (str): 입력 종목코드 - 예: 000660 (종목코드)
Returns:
dict:
- rt_cd (str): 성공 실패 여부
- msg_cd (str): 응답코드
- msg1 (str): 응답메세지
- output (list of dict): 응답상세
- stac_yymm (str): 결산 년월
- cras (str): 유동자산
- fxas (str): 고정자산
- total_aset (str): 자산총계
- flow_lblt (str): 유동부채
- fix_lblt (str): 고정부채
- total_lblt (str): 부채총계
- cpfn (str): 자본금
- cfp_surp (str): 자본 잉여금
- prfi_surp (str): 이익 잉여금
- total_cptl (str): 자본총계
Raise:
ValueError: API 에러 발생시
"""
assert fid_div_cls_code in ["0", "1"]
assert len(fid_input_iscd) >= 6
path = "/uapi/domestic-stock/v1/finance/balance-sheet"
tr_id = "FHKST66430100"
params = {
"fid_div_cls_code": fid_div_cls_code,
"fid_cond_mrkt_div_code": fid_cond_mrkt_div_code,
"fid_input_iscd": fid_input_iscd,
}
res_body, _ = self._tr_request(path, tr_id, params=params)
output = res_body["output"]
for item in output:
for key in item:
if key != "stac_yymm":
item[key] = Decimal(item[key])
result = {
"rt_cd": res_body["rt_cd"],
"msg_cd": res_body["msg_cd"],
"msg1": res_body["msg1"],
"output": output,
}
return result
[docs]
def get_financial_ratio(self, fid_div_cls_code: str, fid_input_iscd: str, fid_cond_mrkt_div_code: str = "J"):
"""
(국내주식) 재무비율[v1_국내주식-080]
국내주식 재무비율 API입니다.
한국투자 HTS(eFriend Plus) > [0635] 재무분석종합 화면의 우측의 '재무 비율' 기능을 API로 개발한 사항으로, 해당 화면을 참고하시면 기능을 이해하기 쉽습니다.
Args:
fid_div_cls_code (str): 분류 구분 코드 - 0: 년, 1: 분기
fid_cond_mrkt_div_code (str): 조건 시장 분류 코드 - J
fid_input_iscd (str): 입력 종목코드 - 예: 000660 (종목코드)
Returns:
dict:
- rt_cd (str): 성공 실패 여부
- msg_cd (str): 응답코드
- msg1 (str): 응답메세지
- output (list of dict): 응답상세
- stac_yymm (str): 결산 년월
- grs (str): 매출액 증가율
- bsop_prfi_inrt (str): 영업 이익 증가율 (적자지속, 흑자전환, 적자전환인 경우 0으로 표시)
- ntin_inrt (str): 순이익 증가율
- roe_val (str): ROE 값
- eps (str): EPS
- sps (str): 주당매출액
- bps (str): BPS
- rsrv_rate (str): 유보 비율
- lblt_rate (str): 부채 비율
Raise:
ValueError: API 에러 발생시
"""
assert fid_div_cls_code in ["0", "1"]
assert len(fid_input_iscd) >= 6
path = "/uapi/domestic-stock/v1/finance/financial-ratio"
tr_id = "FHKST66430300"
params = {
"fid_div_cls_code": fid_div_cls_code,
"fid_cond_mrkt_div_code": fid_cond_mrkt_div_code,
"fid_input_iscd": fid_input_iscd,
}
res_body, _ = self._tr_request(path, tr_id, params=params)
output = res_body["output"]
for item in output:
for key in item:
if key != "stac_yymm":
item[key] = Decimal(item[key])
result = {
"rt_cd": res_body["rt_cd"],
"msg_cd": res_body["msg_cd"],
"msg1": res_body["msg1"],
"output": output,
}
return result
[docs]
def get_income_statement(self, fid_div_cls_code: str, fid_input_iscd: str):
"""
(국내주식시세) 국내주식 손익계산서[v1_국내주식-079]
Args:
fid_div_cls_code (str): 분류 구분 코드 (0:년 1:분기)
fid_input_iscd (str): 종목코드
Returns:
dict:
- rt_cd (str): 응답코드
- msg_cd (str): 메시지코드
- msg1 (str): 메시지
- output (list): 응답상세
- stac_yymm: 결산 년월
- sale_account: 매출액
- sale_cost: 매출 원가
- sale_totl_prfi: 매출 총
- depr_cost: 감가상각비 - 출력되지 않는 데이터(99.99 로 표시)
- sell_mang: 판매 및 관리비 - 출력되지 않는 데이터(99.99 로 표시)
- bsop_prti: 영업 이익
- bsop_non_ernn: 영업 외 수익 - 출력되지 않는 데이터(99.99 로 표시)
- bsop_non_expn: 영업 외 비용 - 출력되지 않는 데이터(99.99 로 표시)
- op_prfi: 경상 이익
- spec_prfi: 특별 이익
- spec_loss: 특별 손실
- thtr_ntin: 당기순이익
"""
assert fid_div_cls_code in ["0", "1"]
assert len(fid_input_iscd) >= 6
path = "/uapi/domestic-stock/v1/finance/income-statement"
tr_id = "FHKST66430200"
params = {
"fid_div_cls_code": fid_div_cls_code,
"fid_cond_mrkt_div_code": "J",
"fid_input_iscd": fid_input_iscd,
}
res_body, _ = self._tr_request(path, tr_id, params=params)
output = res_body["output"]
for item in output:
for key in item:
if key != "stac_yymm":
item[key] = Decimal(item[key])
result = {
"rt_cd": res_body["rt_cd"],
"msg_cd": res_body["msg_cd"],
"msg1": res_body["msg1"],
"output": output,
}
return result
[docs]
def get_dividend_schedule(self, gb1: str, f_dt: str, t_dt: str, sht_cd: str = "", high_gb: str = "0", cts: str = "") -> dict:
"""
(예탁원정보) 배당일정[v1_국내주식-145]
예탁원정보(배당일정) API입니다.
한국투자 HTS(eFriend Plus) > [0658] 배당 화면의 기능을 API로 개발한 사항으로, 해당 화면을 참고하시면 기능을 이해하기 쉽습니다.
Args:
gb1 (str): 조회구분 - 0: 배당전체, 1: 결산배당, 2: 중간배당
f_dt (str): 조회일자From - 일자 ~
t_dt (str): 종목코드To - ~ 일자
sht_cd (str): 종목코드 - 공백: 전체, 특정종목 조회시 : 종목코드
Returns:
dict:
- rt_cd (str): 성공 실패 여부
- msg_cd (str): 응답코드
- msg1 (str): 응답메세지
- output1 (list of dict): 응답상세
- record_date (str): 기준일
- sht_cd (str): 종목코드
- isin_name (str): 종목명
- divi_kind (str): 배당종류
- face_val (int): 액면가
- per_sto_divi_amt (int): 현금배당금
- divi_rate (Decimal): 현금배당률(%)
- stk_divi_rate (Decimal): 주식배당률(%)
- divi_pay_dt (str): 배당금지급일
- stk_div_pay_dt (str): 주식배당지급일
- odd_pay_dt (str): 단주대금지급일
- stk_kind (str): 주식종류
- high_divi_gb (str): 고배당종목여부
Raise:
ValueError: API 에러 발생시
"""
assert gb1 in ["0", "1", "2"]
assert f_dt.isdigit() and len(f_dt) == 8
assert t_dt.isdigit() and len(t_dt) == 8
assert len(sht_cd) in [0, 6]
path = "/uapi/domestic-stock/v1/ksdinfo/dividend"
tr_id = "HHKDB669102C0"
params = {
"cts": cts,
"gb1": gb1,
"f_dt": f_dt,
"t_dt": t_dt,
"sht_cd": sht_cd,
"high_gb": high_gb,
}
res_body, _ = self._tr_request(path, tr_id, params=params)
output = res_body["output1"]
for item in output:
for key in item:
if key in ["divi_rate", "stk_divi_rate"]:
try:
if item[key].strip() != "":
item[key] = Decimal(item[key])
except Exception:
pass
elif key in ["face_val", "per_sto_divi_amt"]:
try:
item[key] = int(item[key])
except Exception:
pass
result = {
"rt_cd": res_body["rt_cd"],
"msg_cd": res_body["msg_cd"],
"msg1": res_body["msg1"],
"output": output,
}
return result
def inquire_vi_status(
self,
fid_div_cls_code: str,
fid_cond_scr_div_code: str,
fid_mrkt_cls_code: str,
fid_rank_sort_cls_code: str,
fid_input_date_1: str,
fid_input_iscd: str = "",
fid_trgt_cls_code: str = "",
fid_trgt_exls_cls_code: str = "",
):
"""
(국내주식시세) 변동성완화장치(VI) 현황 [v1_국내주식-055]
HTS(eFriend Plus) [0139] 변동성 완화장치(VI) 현황 데이터를 확인할 수 있는 API입니다.
최근 30건까지 확인 가능합니다.
Args:
fid_div_cls_code (str): FID 분류 구분 코드 - 0:전체 1:상승 2:하락
fid_cond_scr_div_code (str): FID 조건 화면 분류 코드 - 20139
fid_mrkt_cls_code (str): FID 시장 구분 코드 - 0:전체 K:거래소 Q:코스닥
fid_rank_sort_cls_code (str): FID 순위 정렬 구분 코드 - 0:전체 1:정적 2:동적 3:정적&동적
fid_input_date_1 (str): FID 입력 날짜1 - 영업일
fid_input_iscd (str): FID 입력 종목코드
fid_trgt_cls_code (str): FID 대상 구분 코드
fid_trgt_exls_cls_code (str): FID 대상 제외 구분 코드
Returns:
dict:
- rt_cd (str): 성공 실패 여부
- msg_cd (str): 응답코드
- msg1 (str): 응답메세지
- output (list): 응답상세
- hts_kor_isnm (str): HTS 한글 종목명
- mksc_shrn_iscd (str): 유가증권 단축 종목코드
- vi_cls_code (str): VI발동상태 - Y: 발동 / N: 해제
- bsop_date (datetime.date): 영업 일자
- cntg_vi_hour (datetime.time): VI발동시간
- vi_cncl_hour (datetime.time): VI해제시간
- vi_kind_code (str): VI종류코드 - 1:정적 2:동적 3:정적&동적
- vi_prc (int): VI발동가격
- vi_stnd_prc (int): 정적VI발동기준가격
- vi_dprt (Decimal): 정적VI발동괴리율(%)
- vi_dmc_stnd_prc (int): 동적VI발동기준가격
- vi_dmc_dprt (Decimal): 동적VI발동괴리율(%)
- vi_count (int): VI발동횟수
Raises:
ValueError: API 에러 발생시
"""
assert fid_div_cls_code in ["0", "1", "2"], 'fid_div_cls_code must be "0", "1" or "2"'
assert fid_mrkt_cls_code in ["0", "K", "Q"], 'fid_mrkt_cls_code must be "0", "K" or "Q"'
assert fid_rank_sort_cls_code in ["0", "1", "2", "3"], 'fid_rank_sort_cls_code must be "0", "1", "2" or "3"'
url_path = "/uapi/domestic-stock/v1/quotations/inquire-vi-status"
tr_id = "FHPST01390000"
params = {
"FID_DIV_CLS_CODE": fid_div_cls_code,
"FID_COND_SCR_DIV_CODE": fid_cond_scr_div_code,
"FID_MRKT_CLS_CODE": fid_mrkt_cls_code,
"FID_RANK_SORT_CLS_CODE": fid_rank_sort_cls_code,
"FID_INPUT_DATE_1": fid_input_date_1,
"FID_INPUT_ISCD": fid_input_iscd,
"FID_TRGT_CLS_CODE": fid_trgt_cls_code,
"FID_TRGT_EXLS_CLS_CODE": fid_trgt_exls_cls_code,
}
res_body, _ = self._tr_request(url_path, tr_id, params=params)
if res_body["rt_cd"] != "0":
raise ValueError(f"Error: ({res_body['msg_cd']}) {res_body['msg1']}")
output = []
for el in res_body["output"]:
# 날짜 형식 변환
if "bsop_date" in el and len(el["bsop_date"]) == 8:
el["bsop_date"] = dtm.datetime.strptime(el["bsop_date"], "%Y%m%d").date()
# 시간 형식 변환
for time_field in ["cntg_vi_hour", "vi_cncl_hour"]:
if time_field in el and len(el[time_field]) == 6:
el[time_field] = dtm.datetime.strptime(el[time_field], "%H%M%S").time()
# Decimal 변환
for decimal_field in ["vi_dprt", "vi_dmc_dprt"]:
if decimal_field in el and len(el[decimal_field]) > 0:
el[decimal_field] = Decimal(el[decimal_field])
# 정수 변환
for int_field in ["vi_prc", "vi_stnd_prc", "vi_dmc_stnd_prc", "vi_count"]:
if int_field in el and len(el[int_field]) > 0:
el[int_field] = int(el[int_field])
output.append(el)
result = {
"rt_cd": res_body["rt_cd"],
"msg_cd": res_body["msg_cd"],
"msg1": res_body["msg1"].strip(),
"output": output,
}
return result
[docs]
def order_cash(
self,
cano: str,
acnt_prdt_cd: str,
side: str,
pdno: str,
ord_dvsn: str,
ord_qty: int,
ord_unpr: int = None,
cndt_pric: int = None,
excg_id_dvsn_cd: str = "KRX",
):
"""
(국내주식주문) 주식주문(현금)[v1_국내주식-001]
국내주식주문(현금) API 입니다.
| ※ TTC0802U(현금매수) 사용하셔서 미수매수 가능합니다. 단, 거래하시는 계좌가 증거금40%계좌로 신청이 되어있어야 가능합니다.
| ※ 신용매수는 별도의 API가 준비되어 있습니다.
| ※ ORD_UNPR(주문단가)가 없는 주문은 상한가로 주문금액을 선정하고 이후 체결이되면 체결금액로 정산됩니다.
| ※ 종목코드 마스터파일 파이썬 정제코드는 한국투자증권 Github 참고 부탁드립니다.
| https://github.com/koreainvestment/open-trading-api/tree/main/stocks_info
Args:
cano (str): 계좌번호
acnt_prdt_cd (str): 계좌상품코드
side (str): 매매구분 - 매수:buy 매도:sell
pdno (str): 상품번호
ord_dvsn (str): 주문구분
| 00:지정가
| 01:시장가
| 02:조건부지정가
| 03:최유리지정가
| 04:최우선지정가
| 05:장전 시간외 (08:20~08:40)
| 06:장후 시간외 (15:30~16:00)
| 07:시간외 단일가(16:00~18:00)
| 08:자기주식
| 09:자기주식S-Option
| 10:자기주식금전신탁
| 11:IOC지정가 (즉시체결,잔량취소)
| 12:FOK지정가 (즉시체결,전량취소)
| 13:IOC시장가 (즉시체결,잔량취소)
| 14:FOK시장가 (즉시체결,전량취소)
| 15:IOC최유리 (즉시체결,잔량취소)
| 16:FOK최유리 (즉시체결,전량취소)
| 21:중간가
| 22:스톱지정가
| 23:중간가IOC
| 24:중간가FOK
ord_qty (int): 주문수량
ord_unpr (int): 주문단가
cndt_pric (int): 조건가격 - 스톱지정가 주문 사용 시 필수
excg_id_dvsn_cd (str): 거래소ID구분코드 - KRX:KRX NXT:NXT
Returns:
dict:
- rt_cd (str): 응답코드
- msg_cd (str): 메시지코드
- msg1 (str): 메시지1
- output (dict): 응답상세
- KRX_FWDG_ORD_ORGNO: 한국거래소전송주문조직번호 - 주문시 한국투자증권 시스템에서 지정된 영업점코드
- ODNO: 주문번호 - 주문시 한국투자증권 시스템에서 채번된 주문번호
- ORD_TMD: 주문시각 - 주문시각
Raise:
ValueError: API 에러 발생시
"""
assert side in ["sell", "buy"]
assert type(ord_dvsn) is str and len(ord_dvsn) == 2, "ord_dvsn must be a string of length 2"
assert 0 <= int(ord_dvsn) <= 16 or 21 <= int(ord_dvsn) <= 24, "ord_dvsn must be an integer between 00~16 or 21~24"
assert type(ord_qty) is int and ord_qty > 0, "ord_qty must be a positive integer"
assert excg_id_dvsn_cd in ["KRX", "NXT"], "excg_id_dvsn_cd must be 'KRX' or 'NXT'"
if ord_dvsn in ["00", "02", "11", "12", "22"]: # 지정가, 조건부지정가, IOC/FOK지정가, 스톱지정가
assert type(ord_unpr) in (int, Decimal) and ord_unpr > 0, "ord_unpr must be a positive integer when limit order"
if ord_dvsn in ["22"]:
assert type(cndt_pric) in (int, Decimal) and cndt_pric > 0, "cndt_pric must be a positive integer when stop limit order"
url_path = "/uapi/domestic-stock/v1/trading/order-cash"
if side == "sell":
tr_id = "VTTC0011U" if self.auth.paper_trading else "TTTC0011U"
else:
tr_id = "VTTC0012U" if self.auth.paper_trading else "TTTC0012U"
req_body = {
"CANO": cano,
"ACNT_PRDT_CD": acnt_prdt_cd,
"PDNO": pdno,
"ORD_DVSN": ord_dvsn,
"ORD_QTY": str(ord_qty),
"ORD_UNPR": "0" if ord_unpr is None else str(ord_unpr),
"EXCG_ID_DVSN_CD": excg_id_dvsn_cd,
"CNDT_PRIC": "0" if cndt_pric is None else str(cndt_pric),
}
res_body, _ = self._tr_request(url_path, tr_id, body=req_body, method="POST")
if res_body["rt_cd"] != "0":
raise ValueError(f"Error: ({res_body['msg_cd']}) {res_body['msg1']}")
res_body["ORD_TMD"] = dtm.datetime.strptime(res_body["output"]["ORD_TMD"], "%H%M%S").time()
return res_body
def order_credit(
self,
cano: str,
acnt_prdt_cd: str,
side: str,
pdno: str,
crdt_type: str,
load_dt: dtm.date,
ord_dvsn: str,
ord_qty: int,
rvsn_ord_yn: str,
ord_unpr: int = None,
):
"""
(국내주식주문) 주식주문(신용)[v1_국내주식-002]
국내주식주문(신용) API입니다.
※ 모의투자는 사용 불가합니다.
Args:
cano (str): 계좌번호
acnt_prdt_cd (str): 계좌상품코드
side (str): 매매구분 - 신용매수:buy 신용매도:sell
pdno (str): 상품번호
crdt_type (str): 신용유형
| - 신용매수
| - 21:자기융자신규
| - 23:유동융자신규
| - 26:유동대주상환
| - 28:자기대주상환
| - 신용매도
| - 25:자기융자상환
| - 27:유동융자상환
| - 22:유동대주신규
| - 24:자기대주신규
load_dt (dtm.date): 대출일자
| 신용매수: 신규 대출로, 오늘날짜 입력
| 신용매도: 매도할 종목의 대출일자 입력
| * 주식잔고조회 API(TTC8434R)의 INQR_DVSN(조회구분)을 01(대출일별)로 조회하여서 조회된 주문의 LOAN_DT(대출일자) 입력
ord_dvsn (str): 주문구분
| 00:지정가
| 01:시장가
| 02:조건부지정가
| 03:최유리지정가
| 04:최우선지정가
| 05:장전 시간외 (08:20~08:40)
| 06:장후 시간외 (15:30~16:00)
| 07:시간외 단일가(16:00~18:00)
| 08:자기주식
| 09:자기주식S-Option
| 10:자기주식금전신탁
| 11:IOC지정가 (즉시체결,잔량취소)
| 12:FOK지정가 (즉시체결,전량취소)
| 13:IOC시장가 (즉시체결,잔량취소)
| 14:FOK시장가 (즉시체결,전량취소)
| 15:IOC최유리 (즉시체결,잔량취소)
| 16:FOK최유리 (즉시체결,전량취소)
ord_qty (int): 주문수량
rsvn_ord_yn (str): 예약주문여부
| - 정규 증권시장이 열리지 않는 시간 (15:10분 ~ 익일 7:30분) 에 주문을 미리 설정 하여 다음 영업일 또는 설정한 기간 동안 아침 동시 호가에 주문하는 것.
| - 예약주문:Y, 즉시주문:N
ord_unpr (int): 주문단가
Returns:
dict:
- rt_cd (str): 응답코드
- msg_cd (str): 메시지코드
- msg1 (str): 메시지1
- output (dict): 응답상세
- KRX_FWDG_ORD_ORGNO: 한국거래소전송주문조직번호 - 주문시 한국투자증권 시스템에서 지정된 영업점코드
- ODNO: 주문번호 - 주문시 한국투자증권 시스템에서 채번된 주문번호
- ORD_TMD: 주문시각 - 주문시각
Raise:
ValueError: API 에러 발생시
"""
assert not self.auth.paper_trading, "실전계좌에서만 사용 가능한 API입니다."
assert side in ["sell", "buy"]
if side == "sell":
assert crdt_type in ["25", "27", "22", "24"], 'crdt_type must be "25", "27", "22" or "24" when sell'
else:
assert crdt_type in ["21", "23", "26", "28"], 'crdt_type must be "21", "23", "26" or "28" when buy'
assert type(ord_dvsn) is str and len(ord_dvsn) == 2 and int(ord_dvsn) >= 0 and int(ord_dvsn) <= 16, "ord_dvsn must be a string of integer between 00 and 16"
assert type(ord_qty) is int and ord_qty > 0, "ord_qty must be a positive integer"
if ord_dvsn in ["00", "02", "11", "12"]: # 지정가, 조건부지정가, IOC/FOK지정가
assert type(ord_unpr) is int and ord_unpr > 0, "ord_unpr must be a positive integer when limit order"
assert rvsn_ord_yn in ["Y", "N"], 'rvsn_ord_yn must be "Y" or "N"'
url_path = "/uapi/domestic-stock/v1/trading/order-credit"
if side == "sell":
tr_id = "TTTC0051U"
else:
tr_id = "TTTC0052U"
req_body = {
"CANO": cano,
"ACNT_PRDT_CD": acnt_prdt_cd,
"PDNO": pdno,
"CRDT_TYPE": crdt_type,
"LOAD_DT": load_dt.strftime("%Y%m%d"),
"ORD_DVSN": ord_dvsn,
"ORD_QTY": str(ord_qty),
"ORD_UNPR": "0" if ord_unpr is None else str(ord_unpr),
}
res_body, _ = self._tr_request(url_path, tr_id, json=req_body, method="POST")
if res_body["rt_cd"] != "0":
raise ValueError(f"Error: ({res_body['msg_cd']}) {res_body['msg1']}")
res_body["output"]["ORD_TMD"] = dtm.datetime.strptime(res_body["ORD_TMD"], "%H%M%S").time()
return res_body
[docs]
def order_rvsecncl(
self,
cano: str,
acnt_prdt_cd: str,
orgn_odno: str,
ord_dvsn: str,
rvse_cncl_dvsn_cd: str,
ord_qty: int,
ord_unpr: int,
qty_all_ord_yn: str,
cndt_pric: int = None,
excg_id_dvsn_cd: str = "KRX",
):
"""
(국내주식주문) 주식주문(정정취소)[v1_국내주식-003]
주문 건에 대하여 정정 및 취소하는 API입니다. 단, 이미 체결된 건은 정정 및 취소가 불가합니다.
Args:
cano (str): 종합계좌번호 - 계좌번호 체계(8-2)의 앞 8자리
acnt_prdt_cd (str): 계좌상품코드 - 계좌번호 체계(8-2)의 뒤 2자리
orgn_odno (str): 원주문번호 - 주식일별주문체결조회 API output1의 odno(주문번호) 값 입력. 주문시 한국투자증권 시스템에서 채번된 주문번호
ord_dvsn (str): 주문구분
| 00:지정가
| 01:시장가
| 02:조건부지정가
| 03:최유리지정가
| 04:최우선지정가
| 05:장전 시간외
| 06:장후 시간외
| 07:시간외 단일가
| 08:자기주식
| 09:자기주식S-Option
| 10:자기주식금전신탁
| 11:IOC지정가 (즉시체결,잔량취소)
| 12:FOK지정가 (즉시체결,전량취소)
| 13:IOC시장가 (즉시체결,잔량취소)
| 14:FOK시장가 (즉시체결,전량취소)
| 15:IOC최유리 (즉시체결,잔량취소)
| 16:FOK최유리 (즉시체결,전량취소)
| 21:중간가
| 22:스톱지정가
| 23:중간가IOC
| 24:중간가FOK
rvse_cncl_dvsn_cd (str): 정정취소구분코드 - 정정:01 취소:02
ord_qty (int): 주문수량 - 전부 취소/정정시 0 입력, 일부 취소/정정시 취소/정정 수량 입력
ord_unpr (int): 주문단가 - 정정주문 1주당 가격, 취소시 0 설정
qty_all_ord_yn (str): 잔량전부주문여부 - Y:잔량전부 N:잔량일부
cndt_pric (int): 조건가격 - 스톱지정가 호가에서 정정할 때 사용
excg_id_dvsn_cd (str): 거래소ID구분코드 - KRX:KRX NXT:NXT
Returns:
dict:
- rt_cd (str): 응답코드
- msg_cd (str): 메시지코드
- msg1 (str): 메시지1
- output (dict): 응답상세
- KRX_FWDG_ORD_ORGNO: 한국거래소전송주문조직번호 - 주문시 한국투자증권 시스템에서 지정된 영업점코드
- ODNO: 주문번호 - 주문시 한국투자증권 시스템에서 채번된 주문번호
- ORD_TMD: 주문시각 - 주문시각
"""
url_path = "/uapi/domestic-stock/v1/trading/order-rvsecncl"
tr_id = "VTTC0013U" if self.auth.paper_trading else "TTTC0013U"
req_body = {
"CANO": cano,
"ACNT_PRDT_CD": acnt_prdt_cd,
"KRX_FWDG_ORD_ORGNO": "",
"ORGN_ODNO": orgn_odno,
"ORD_DVSN": ord_dvsn,
"RVSE_CNCL_DVSN_CD": rvse_cncl_dvsn_cd,
"ORD_QTY": str(ord_qty),
"ORD_UNPR": str(ord_unpr),
"QTY_ALL_ORD_YN": qty_all_ord_yn,
"CNDT_PRIC": "0" if cndt_pric is None else str(cndt_pric),
"EXCG_ID_DVSN_CD": excg_id_dvsn_cd,
}
res_body, _ = self._tr_request(url_path, tr_id, body=req_body, method="POST")
if res_body["rt_cd"] != "0":
raise ValueError(f"Error: ({res_body['msg_cd']}) {res_body['msg1']}")
res_body["output"]["ORD_TMD"] = dtm.datetime.strptime(res_body["output"]["ORD_TMD"], "%H%M%S").time()
return res_body
[docs]
def inquire_psbl_rvsecncl(
self,
cano: str,
acnt_prdt_cd: str,
inqr_dvsn_1: str = "1",
inqr_dvsn_2: str = "0",
ctx_area_fk100: str = "",
ctx_area_nk100: str = "",
excg_id_dvsn_cd: str = "KRX",
):
"""
(국내주식주문) 주식정정취소가능주문조회[v1_국내주식-004]
주식정정취소가능주문조회 API입니다. 한 번의 호출에 최대 50건까지 확인 가능하며, 이후의 값은 연속조회를 통해 확인하실 수 있습니다.
Args:
cano (str): 종합계좌번호 - 계좌번호 체계(8-2)의 앞 8자리
acnt_prdt_cd (str): 계좌상품코드 - 계좌번호 체계(8-2)의 뒤 2자리
inqr_dvsn_1 (str): 조회구분1 - 0:조회순서 1:주문순 2:종목순
inqr_dvsn_2 (str): 조회구분2 - 0:전체 1:매도 2:매수
ctx_area_fk100 (str): CTX_AREA_FK100
ctx_area_nk100 (str): CTX_AREA_NK100
excg_id_dvsn_cd (str): KRX:KRX NXT:NXT
Returns:
dict:
- rt_cd (str): 응답코드
- msg_cd (str): 메시지코드
- msg1 (str): 메시지1
- tr_cont (str): 연속 조회 가능 여부
- ctx_area_fk100 (str): 연속조회검색조건100
- ctx_area_nk100 (str): 연속조회검색키100
- output (list): 응답상세
- ord_gno_brno: 주문채번지점번호 - 주문시 한국투자증권 시스템에서 지정된 영업점코드
- odno: 주문번호 - 주문시 한국투자증권 시스템에서 채번된 주문번호
- orgn_odno: 원주문번호 - 정정/취소주문 인경우 원주문번호
- ord_dvsn_name: 주문구분명
- pdno: 상품번호 - 종목번호(뒤 6자리만 해당)
- prdt_name: 상품명 - 종목명
- rvse_cncl_dvsn_name: 정정취소구분명 - 정정 또는 취소 여부 표시
- ord_qty: 주문수량 - 주문수량
- ord_unpr: 주문단가 - 1주당 주문가격
- ord_tmd: 주문시각 - 주문시각(시분초HHMMSS)
- tot_ccld_qty: 총체결수량 - 주문 수량 중 체결된 수량
- tot_ccld_amt: 총체결금액 - 주문금액 중 체결금액
- psbl_qty: 가능수량 - 정정/취소 주문 가능 수량
- sll_buy_dvsn_cd: 매도매수구분코드 - 01:매도 02:매수
- ord_dvsn_cd: 주문구분코드
| 00:지정가
| 01:시장가
| 02:조건부지정가
| 03:최유리지정가
| 04:최우선지정가
| 05:장전 시간외
| 06:장후 시간외
| 07:시간외 단일가
| 08:자기주식
| 09:자기주식S-Option
| 10:자기주식금전신탁
| 11:IOC지정가 (즉시체결,잔량취소)
| 12:FOK지정가 (즉시체결,전량취소)
| 13:IOC시장가 (즉시체결,잔량취소)
| 14:FOK시장가 (즉시체결,전량취소)
| 15:IOC최유리 (즉시체결,잔량취소)
| 16:FOK최유리 (즉시체결,전량취소)
| 51:장중대량
- mgco_aptm_odno: 운용사지정주문번호 - 주문 번호 (운용사 통한 주문)
Raise:
ValueError: API 에러 발생시
"""
assert not self.auth.paper_trading, "실전계좌에서만 사용 가능한 API입니다."
url_path = "/uapi/domestic-stock/v1/trading/inquire-psbl-rvsecncl"
tr_id = "TTTC0084R"
tr_cont = "" if ctx_area_fk100 == "" else "N"
params = {
"CANO": cano,
"ACNT_PRDT_CD": acnt_prdt_cd,
"INQR_DVSN_1": inqr_dvsn_1,
"INQR_DVSN_2": inqr_dvsn_2,
"CTX_AREA_FK100": ctx_area_fk100,
"CTX_AREA_NK100": ctx_area_nk100,
}
res_body, res_header = self._tr_request(url_path, tr_id, tr_cont, params=params)
if res_body["rt_cd"] != "0":
raise ValueError(f"Error: ({res_body['msg_cd']}) {res_body['msg1']}")
output = []
for el in res_body["output"]:
for k in el.keys():
if k == "ord_tmd":
el[k] = dtm.datetime.strptime(el[k], "%H%M%S").time()
elif k in ["ord_qty", "ord_unpr", "tot_ccld_qty", "tot_ccld_amt", "psbl_qty"]:
el[k] = int(el[k])
output.append(el)
result = {
"rt_cd": res_body["rt_cd"],
"tr_cont": res_header["tr_cont"],
"msg_cd": res_body["msg_cd"],
"msg1": res_body["msg1"].strip(),
"ctx_area_fk100": res_body["ctx_area_fk100"].strip(),
"ctx_area_nk100": res_body["ctx_area_nk100"].strip(),
"output": output,
}
return result
[docs]
def inquire_daily_ccld(
self,
cano: str,
acnt_prdt_cd: str,
inqr_strt_dt: dtm.date,
inqr_end_dt: dtm.date,
sll_buy_dvsn_cd: str = "00",
inqr_dvsn: str = "00",
pdno: str = "",
odno: str = "",
ccld_dvsn: str = "00",
inqr_dvsn_3: str = "00",
inqr_dvsn_1: str = "",
ctx_area_fk100: str = "",
ctx_area_nk100: str = "",
tr_cont: str = "",
excg_id_dvsn_cd: str = "KRX",
):
"""
(국내주식주문) 주식일별주문체결조회[v1_국내주식-005]
| 주식일별주문체결조회 API입니다.
| 실전계좌의 경우, 한 번의 호출에 최대 100건까지 확인 가능하며, 이후의 값은 연속조회를 통해 확인하실 수 있습니다.
| 모의계좌의 경우, 한 번의 호출에 최대 15건까지 확인 가능하며, 이후의 값은 연속조회를 통해 확인하실 수 있습니다.
| * 다만, 3개월 이전 체결내역 조회(CTSC9115R) 의 경우,
| 장중에는 많은 거래량으로 인해 순간적으로 DB가 밀렸거나 응답을 늦게 받거나 하는 등의 이슈가 있을 수 있어
| ① 가급적 장 종료 이후(15:30 이후) 조회하시고
| ② 조회기간(INQR_STRT_DT와 INQR_END_DT 사이의 간격)을 보다 짧게 해서 조회하는 것을 권유드립니다.
Args:
cano (str): 종합계좌번호 - 계좌번호 체계(8-2)의 앞 8자리
acnt_prdt_cd (str): 계좌상품코드 - 계좌번호 체계(8-2)의 뒤 2자리
inqr_strt_dt (datetime.date): 조회시작일자
inqr_end_dt (datetime.datestr): 조회종료일자
sll_buy_dvsn_cd (str): 매도매수구분코드 - 00:전체 01:매도 02:매수
inqr_dvsn (str): 조회구분 - 00:역순 01:정순
pdno (str): 상품번호 - 종목번호(6자리) 공란:전체 조회
ccld_dvsn (str): 체결구분 - 00:전체 01:체결 02:미체결
inqr_dvsn_3 (str): 조회구분3 - 00:전체 01:현금 02:융자 03:대출 04:대주
inqr_dvsn_1 (str): 조회구분1 - 공란:전체 1:ELW 2:프리보드
ctx_area_fk100 (str): 연속조회검색조건100 - "":최초 조회시 이전 조회 ctx_area_fk100 값:다음페이지 조회시(2번째부터)
ctx_area_nk100 (str): 연속조회키100 - "":최초 조회시 이전 조회 ctx_area_nk100 값:다음페이지 조회시(2번째부터)
excg_id_dvsn_cd (str): 거래소ID구분코드 - KRX:KRX NXT:NXT
Returns:
dict:
- rt_cd (str): 응답코드
- msg_cd (str): 메시지코드
- msg1 (str): 메시지1
- tr_cont (str): TR내용
- ctx_area_fk100 (str): 연속조회검색조건100
- ctx_area_nk100 (str): 연속조회키100
- output1 (list): 응답상세
- ord_dt: 주문일자 - 주문일자
- ord_gno_brno: 주문채번지점번호 - 주문시 한국투자증권 시스템에서 지정된 영업점코드
- odno: 주문번호 - 주문시 한국투자증권 시스템에서 채번된 주문번호, 지점별 일자별로 채번됨
- 주문번호 유일조건: ord_dt(주문일자) + ord_gno_brno(주문채번지점번호) + odno(주문번호)
- orgn_odno: 원주문번호 - 이전 주문에 채번된 주문번호
- ord_dvsn_name: 주문구분명
- sll_buy_dvsn_cd: 매도매수구분코드 - 01:매도 02:매수
- sll_buy_dvsn_cd_name: 매도매수구분코드명 - * 반대매매 인경우 "임의매도"로 표시됨
- pdno: 상품번호 - 종목번호(6자리)
- prdt_name: 상품명 - 종목명
- ord_qty: 주문수량
- ord_unpr: 주문단가
- ord_tmd: 주문시각
- tot_ccld_qty: 총체결수량
- avg_prvs: 평균가 - 체결평균가 ( 총체결금액 / 총체결수량 )
- cncl_yn: 취소여부
- tot_ccld_amt: 총체결금액
- loan_dt: 대출일자
- ord_dvsn_cd: 주문구분코드
| 00:지정가
| 01:시장가
| 02:조건부지정가
| 03:최유리지정가
| 04:최우선지정가
| 05:장전 시간외
| 06:장후 시간외
| 07:시간외 단일가
| 08:자기주식
| 09:자기주식S-Option
| 10:자기주식금전신탁
| 11:IOC지정가 (즉시체결,잔량취소)
| 12:FOK지정가 (즉시체결,전량취소)
| 13:IOC시장가 (즉시체결,잔량취소)
| 14:FOK시장가 (즉시체결,전량취소)
| 15:IOC최유리 (즉시체결,잔량취소)
| 16:FOK최유리 (즉시체결,전량취소)
- cncl_cfrm_qty: 취소확인수량
- rmn_qty: 잔여수량
- rjct_qty: 거부수량
- ccld_cndt_name: 체결조건명
- infm_tmd: 통보시각 - ※ 실전투자계좌로는 해당값이 제공되지 않습니다.
- ctac_tlno: 연락전화번호
- prdt_type_cd: 상품유형코드 - 300:주식 301:선물옵션 302:채권 306:ELS
- excg_id_dvsn_cd: 거래소ID구분코드 - KRX:KRX NXT:NXT
| 01:한국증권
| 02:증권거래소
| 03:코스닥
| 04:K-OTC
| 05:선물거래소
| 06:CME
| 07:EUREX
| 21:금현물
| 51:홍콩
| 52:상해B
| 53:심천
| 54:홍콩거래소
| 55:미국
| 56:일본
| 57:상해A
| 58:심천A
| 59:베트남
| 61:장전시간외시장
| 64:경쟁대량매매
| 65:경매매시장
| 81:시간외단일가시장
- output2 (dict): 응답상세
- tot_ord_qty: 총주문수량 - 미체결주문수량 + 체결수량 (취소주문제외)
- tot_ccld_qty: 총체결수량
- pchs_avg_pric: 매입평균가격 - 총체결금액 / 총체결수량
- tot_ccld_amt: 총체결금액
- prsm_tlex_smtl: 추정제비용합계 - 제세 + 주문수수료
※ 해당 값은 당일 데이터에 대해서만 제공됩니다.
Raise:
ValueError: API 에러 발생시
"""
def __is_within_3month(dt: dtm.date):
target_date = dtm.date.today().replace(day=1)
for _ in range(3):
target_date = target_date - dtm.timedelta(days=1)
target_date = target_date.replace(day=1)
three_month_ago = target_date
return dt >= three_month_ago
assert __is_within_3month(inqr_strt_dt) == __is_within_3month(inqr_end_dt), "3개월 이전 채결내역은 분리하여 조회해주세요."
within_3month = __is_within_3month(inqr_strt_dt)
url_path = "/uapi/domestic-stock/v1/trading/inquire-daily-ccld"
if self.auth.paper_trading:
tr_id = "VTTC0081R" if within_3month else "VTSC9215R"
else:
tr_id = "TTTC0081R" if within_3month else "CTSC9215R"
params = {
"CANO": cano,
"ACNT_PRDT_CD": acnt_prdt_cd,
"INQR_STRT_DT": inqr_strt_dt.strftime("%Y%m%d"),
"INQR_END_DT": inqr_end_dt.strftime("%Y%m%d"),
"SLL_BUY_DVSN_CD": sll_buy_dvsn_cd,
"INQR_DVSN": inqr_dvsn,
"PDNO": pdno,
"CCLD_DVSN": ccld_dvsn,
"ORD_GNO_BRNO": "",
"ODNO": odno,
"INQR_DVSN_3": inqr_dvsn_3,
"INQR_DVSN_1": inqr_dvsn_1,
"EXCG_ID_DVSN_CD": excg_id_dvsn_cd,
"CTX_AREA_FK100": ctx_area_fk100,
"CTX_AREA_NK100": ctx_area_nk100,
}
res_body, res_header = self._tr_request(url_path, tr_id, tr_cont, params=params)
if res_body["rt_cd"] != "0":
raise ValueError(f"Error: ({res_body['msg_cd']}) {res_body['msg1']}")
output1 = []
for el in res_body["output1"]:
for k in el.keys():
if k == ["ord_dt", "rsvn_ord_end_dt", "loan_dt"]:
if len(el[k]) == 8:
el[k] = dtm.datetime.strptime(el[k], "%Y%m%d").date()
elif k in ["ord_tmd", "infm_tmd"]:
if len(el[k]) == 6:
el[k] = dtm.datetime.strptime(el[k], "%H%M%S").time()
elif k in ["ord_qty", "ord_unpr", "tot_ccld_qty", "avg_prvs", "tot_ccld_amt", "cncl_cfrm_qty", "rmn_qty", "rjct_qty"]:
if len(el[k]) > 0:
el[k] = int(el[k])
output1.append(el)
output2 = res_body["output2"]
for k in output2.keys():
if k == "pchs_avg_pric":
if len(output2[k]) > 0:
output2[k] = Decimal(output2[k])
else:
output2[k] = int(output2[k])
result = {
"rt_cd": res_body["rt_cd"],
"msg_cd": res_body["msg_cd"],
"msg1": res_body["msg1"].strip(),
"tr_cont": res_header["tr_cont"],
"ctx_area_fk100": res_body["ctx_area_fk100"].strip(),
"ctx_area_nk100": res_body["ctx_area_nk100"].strip(),
"output1": output1,
"output2": output2,
}
return result
[docs]
def inquire_balance(self, cano: str, acnt_prdt_cd: str, inqr_dvsn: str, afhr_flpr_yn: str = "N", fund_sttl_icld_yn: str = "N", prcs_dvsn: str = "00", ctx_area_fk100: str = "", ctx_area_nk100: str = "", tr_cont: str = ""):
"""
(국내주식주문) 주식잔고조회[v1_국내주식-006]
주식 잔고조회 API입니다.
실전계좌의 경우, 한 번의 호출에 최대 50건까지 확인 가능하며, 이후의 값은 연속조회를 통해 확인하실 수 있습니다.
모의계좌의 경우, 한 번의 호출에 최대 20건까지 확인 가능하며, 이후의 값은 연속조회를 통해 확인하실 수 있습니다.
* 당일 전량매도한 잔고도 보유수량 0으로 보여질 수 있으나, 해당 보유수량 0인 잔고는 최종 D-2일 이후에는 잔고에서 사라집니다.
Args:
cano (str): 종합계좌번호 - 계좌번호 체계(8-2)의 앞 8자리
acnt_prdt_cd (str): 계좌상품코드 - 계좌번호 체계(8-2)의 뒤 2자리
inqr_dvsn (str): 조회구분 - 01:대출일별 02:종목별
afhr_flpr_yn (str): 시간외단일가여부 - N:기본값 Y:시간외단일가
fund_sttl_icld_yn (str): 펀드결제분포함여부 - N:포함하지 않음 Y:포함
prcs_dvsn (str): 처리구분 - 00:전일매매포함 01:전일매매미포함
ctx_area_fk100 (str): 연속조회검색조건100 - 공란:최초 조회시. 이전 조회 output ctx_area_fk100 값:다음페이지 조회시(2번째부터)
ctx_area_nk100 (str): 연속조회키100 - 공란:최초 조회시. 이전 조회 output ctx_area_nk100 값:다음페이지 조회시(2번째부터)
tr_cont (str): 연속조회여부 - 공란:최초 조회시. N:연속조회 시
Returns:
dict:
- rt_cd (str): 응답코드
- msg_cd (str): 메시지코드
- msg1 (str): 응답메시지
- tr_cont (str): 연속조회가능여부
- ctx_area_fk100 (str): 연속조회검색조건100
- ctx_area_nk100 (str): 연속조회키100
- output1 (list): 응답상세1
- pdno: 상품번호 - 종목번호(뒷 6자리)
- prdt_name: 상품명 - 종목명
- trad_dvsn_name: 매매구분명 - 매수매도구분
- bfdy_buy_qty: 전일매수수량
- bfdy_sll_qty: 전일매도수량
- thdt_buyqty: 금일매수수량
- thdt_sll_qty: 금일매도수량
- hldg_qty: 보유수량
- ord_psbl_qty: 주문가능수량
- pchs_avg_pric: 매입평균가격 = 매입금액 / 보유수량
- pchs_amt: 매입금액
- prpr: 현재가
- evlu_amt: 평가금액
- evlu_pfls_amt: 평가손익금액 = 평가금액 - 매입금액
- evlu_pfls_rt: 평가손익율
- evlu_erng_rt: 평가수익율 - 미사용항목(0으로 출력)
- loan_dt: 대출일자 - INQR_DVSN(조회구분)을 01(대출일별)로 설정해야 값이 나옴
- loan_amt: 대출금액
- stln_slng_chgs: 대주매각대금
- expd_dt: 만기일자
- fltt_rt: 등락율
- bfdy_cprs_icdc: 전일대비증감
- item_mgna_rt_name: 종목증거금율명
- grta_rt_name: 보증금율명
- sbst_pric: 대용가격 - 증권매매의 위탁보증금으로서 현금 대신에 사용되는 유가증권 가격
- stck_loan_unpr: 주식대출단가
- output2 (list): 응답상세2
- dnca_tot_amt: 예수금총금액 - 예수금
- nxdy_excc_amt: 익일정산금액 - D+1 예수금
- prvs_rcdl_excc_amt: 가수도정산금액 - D+2 예수금
- cma_evlu_amt: CMA평가금액
- bfdy_buy_amt: 전일매수금액
- thdt_buy_amt: 금일매수금액
- nxdy_auto_rdpt_amt: 익일자동상환금액
- bfdy_sll_amt: 전일매도금액
- thdt_sll_amt: 금일매도금액
- d2_auto_rdpt_amt: D+2자동상환금액
- bfdy_tlex_amt: 전일제비용금액
- thdt_tlex_amt: 금일제비용금액
- tot_loan_amt: 총대출금액
- scts_evlu_amt: 유가평가금액
- tot_evlu_amt: 총평가금액 - 유가증권 평가금액 합계금액 + D+2 예수금
- nass_amt: 순자산금액
- fncg_gld_auto_rdpt_yn: 융자금자동상환여부 - 보유현금에 대한 융자금만 차감여부. 신용융자 매수체결 시점에서는 융자비율을 매매대금 100%로 계산 하였다가 수도결제일에 보증금에 해당하는 금액을 고객의 현금으로 충당하여 융자금을 감소시키는 업무
- pchs_amt_smtl_amt: 매입금액합계금액
- evlu_amt_smtl_amt: 평가금액합계금액 - 유가증권 평가금액 합계금액
- evlu_pfls_smtl_amt: 평가손익합계금액
- tot_stln_slng_chgs: 총대주매각대금
- bfdy_tot_asst_evlu_amt: 전일총자산평가금액
- asst_icdc_amt: 자산증감액
- asst_icdc_erng_rt: 자산증감수익율 - 데이터 미제공
Raise:
ValueError: API 에러 발생시
"""
assert afhr_flpr_yn in ["Y", "N"], 'afhr_flpr_yn must be "Y" or "N"'
assert inqr_dvsn in ["01", "02"], 'inqr_dvsn must be "01" or "02"'
assert fund_sttl_icld_yn in ["Y", "N"], 'fund_sttl_icld_yn must be "Y" or "N"'
assert prcs_dvsn in ["00", "01"], 'prcs_dvsn must be "00" or "01"'
url_path = "/uapi/domestic-stock/v1/trading/inquire-balance"
tr_id = "VTTC8434R" if self.auth.paper_trading else "TTTC8434R"
params = {
"CANO": cano,
"ACNT_PRDT_CD": acnt_prdt_cd,
"INQR_DVSN": inqr_dvsn,
"AFHR_FLPR_YN": afhr_flpr_yn,
"OFL_YN": "",
"UNPR_DVSN": "01",
"FUND_STTL_ICLD_YN": fund_sttl_icld_yn,
"FNCG_AMT_AUTO_RDPT_YN": "N",
"PRCS_DVSN": prcs_dvsn,
"CTX_AREA_FK100": ctx_area_fk100,
"CTX_AREA_NK100": ctx_area_nk100,
"TR_CONT": tr_cont,
}
res_body, res_header = self._tr_request(url_path, tr_id, tr_cont, params=params)
if res_body["rt_cd"] != "0":
raise ValueError(f"Error: ({res_body['msg_cd']}) {res_body['msg1']}")
output1 = []
for el in res_body["output1"]:
for k in el.keys():
if len(el[k]) == 0 or k in ["pdno", "prdt_name", "trad_dvsn_name", "item_mgna_rt_name", "grta_rt_name"]:
pass
elif k in ["loan_dt", "expd_dt"]:
el[k] = dtm.datetime.strptime(el[k], "%Y%m%d").date()
elif k in ["pchs_avg_pric", "evlu_pfls_rt", "evlu_erng_rt", "stck_loan_unpr", "fltt_rt"]:
el[k] = Decimal(el[k])
else:
try:
el[k] = int(el[k])
except Exception:
pass
output1.append(el)
output2 = []
for el in res_body["output2"]:
for k in el.keys():
if len(el[k]) == 0 or el[k] == "fncg_gld_auto_rdpt_yn":
pass
elif k == "asst_icdc_erng_rt":
el[k] = Decimal(el[k])
else:
try:
el[k] = int(el[k])
except Exception:
pass
output2.append(el)
result = {
"rt_cd": res_body["rt_cd"],
"msg_cd": res_body["msg_cd"],
"msg1": res_body["msg1"].strip(),
"tr_cont": res_header["tr_cont"].strip(),
"ctx_area_fk100": res_body["ctx_area_fk100"].strip(),
"ctx_area_nk100": res_body["ctx_area_nk100"].strip(),
"output1": output1,
"output2": output2,
}
return result
[docs]
def inquire_psbl_order(self, cano: str, acnt_prdt_cd: str, pdno: str, ord_dvsn: str, ord_unpr: int = None, cma_evlu_amt: str = "N", ovrs_icld_yn: str = "N"):
"""
(국내주식주문) 매수가능조회[v1_국내주식-007]
| 매수가능 조회 API입니다.
| 실전계좌/모의계좌의 경우, 한 번의 호출에 최대 1건까지 확인 가능합니다.
|
| 1) 매수가능금액 확인
| . 미수 사용 X: nrcvb_buy_amt(미수없는매수금액) 확인
| . 미수 사용 O: max_buy_amt(최대매수금액) 확인
|
| 2) 매수가능수량 확인
| . 특정 종목 전량매수 시 가능수량을 확인하실 경우 ORD_DVSN:00(지정가)는 종목증거금율이 반영되지 않습니다.
| 따라서 "반드시" ORD_DVSN:01(시장가)로 지정하여 종목증거금율이 반영된 가능수량을 확인하시기 바랍니다.
|
| (다만, 조건부지정가 등 특정 주문구분(ex.IOC)으로 주문 시 가능수량을 확인할 경우 주문 시와 동일한 주문구분(ex.IOC) 입력하여 가능수량 확인)
|
| . 미수 사용 X: ORD_DVSN:01(시장가) or 특정 주문구분(ex.IOC)로 지정하여 nrcvb_buy_qty(미수없는매수수량) 확인
| . 미수 사용 O: ORD_DVSN:01(시장가) or 특정 주문구분(ex.IOC)로 지정하여 max_buy_qty(최대매수수량) 확인
Args:
cano (str): 종합계좌번호 계좌번호 체계(8-2)의 앞 8자리
acnt_prdt_cd (str): 계좌상품코드 계좌번호 체계(8-2)의 뒤 2자리
pdno (str): 상품번호 종목번호(6자리)
ord_unpr (int): 주문단가 1주당 가격 * 시장가(ORD_DVSN:01)로 조회 시, 공란으로 입력
ord_dvsn (str): 주문구분
| * 특정 종목 전량매수 시 가능수량을 확인할 경우 00:지정가는 증거금율이 반영되지 않으므로 증거금율이 반영되는 01: 시장가로 조회
| * 다만, 조건부지정가 등 특정 주문구분(ex.IOC)으로 주문 시 가능수량을 확인할 경우 주문 시와 동일한 주문구분(ex.IOC) 입력하여 가능수량 확인
| * 공란 시, 매수수량 없이 매수금액만 조회됨.
|
| 00:지정가
| 01:시장가
| 02:조건부지정가
| 03:최유리지정가
| 04:최우선지정가
| 05:장전 시간외
| 06:장후 시간외
| 07:시간외 단일가
| 08:자기주식
| 09:자기주식S-Option
| 10:자기주식금전신탁
| 11:IOC지정가 (즉시체결,잔량취소)
| 12:FOK지정가 (즉시체결,전량취소)
| 13:IOC시장가 (즉시체결,잔량취소)
| 14:FOK시장가 (즉시체결,전량취소)
| 15:IOC최유리 (즉시체결,잔량취소)
| 16:FOK최유리 (즉시체결,전량취소)
| 51:장중대량
| 52:장중바스켓
| 62:장개시전 시간외대량
| 63:장개시전 시간외바스켓
| 67:장개시전 금전신탁자사주
| 69:장개시전 자기주식
| 72:시간외대량
| 77:시간외자사주신탁
| 79:시간외대량자기주식
| 80:바스켓
cma_evlu_amt_icld_yn (str): CMA평가금액포함여부 Y:포함 N:포함하지 않음
ovrs_icld_yn (str): 해외포함여부 Y:포함 N:포함하지 않음
Returns:
dict:
- rt_cd (str): 응답코드
- msg_cd (str): 메시지코드
- msg1 (str): 응답메시지
- output (dict): 응답상세
- ord_psbl_cash: 주문가능현금
- ord_psbl_sbst: 주문가능대용
- ruse_psbl_amt: 재사용가능금액
- fund_rpch_chgs: 펀드환매대금
- psbl_qty_calc_unpr: 가능수량계산단가
- nrcvb_buy_amt: 미수없는매수금액 - 미수를 사용하지 않으실 경우 nrcvb_buy_amt(미수없는매수금액)을 확인
- nrcvb_buy_qty: 미수없는매수수량 - 미수를 사용하지 않으실 경우 nrcvb_buy_qty(미수없는매수수량)을 확인
* 특정 종목 전량매수 시 가능수량을 확인하실 경우 조회 시 ORD_DVSN:01(시장가)로 지정 필수
* 다만, 조건부지정가 등 특정 주문구분(ex.IOC)으로 주문 시 가능수량을 확인할 경우 주문 시와 동일한 주문구분(ex.IOC) 입력
- max_buy_amt: 최대매수금액 - 미수를 사용하시는 경우 max_buy_amt(최대매수금액)를 확인
- max_buy_qty: 최대매수수량 - 미수를 사용하시는 경우 max_buy_qty(최대매수수량)를 확인
* 특정 종목 전량매수 시 가능수량을 확인하실 경우 조회 시 ORD_DVSN:01(시장가)로 지정 필수
* 다만, 조건부지정가 등 특정 주문구분(ex.IOC)으로 주문 시 가능수량을 확인할 경우 주문 시와 동일한 주문구분(ex.IOC) 입력
- cma_evlu_amt: CMA평가금액
- ovrs_re_use_amt_wcrc: 해외재사용금액원화
- ord_psbl_frcr_amt_wcrc: 주문가능외화금액원화
"""
url_path = "/uapi/domestic-stock/v1/trading/inquire-psbl-order"
tr_id = "VTTC8908R" if self.auth.paper_trading else "TTTC8908R"
params = {
"CANO": cano,
"ACNT_PRDT_CD": acnt_prdt_cd,
"PDNO": pdno,
"ORD_UNPR": str(ord_unpr) if ord_unpr is not None else "",
"ORD_DVSN": ord_dvsn,
"CMA_EVLU_AMT_ICLD_YN": cma_evlu_amt,
"OVRS_ICLD_YN": ovrs_icld_yn,
}
res_body, _ = self._tr_request(url_path, tr_id, params=params)
if res_body["rt_cd"] != "0":
raise ValueError(f"Error: ({res_body['msg_cd']}) {res_body['msg1']}")
output = res_body["output"]
"""
{
'ord_psbl_cash': '10000000',
'ord_psbl_sbst': '0',
'ruse_psbl_amt': '0',
'fund_rpch_chgs': '0',
'psbl_qty_calc_unpr': '21645',
'nrcvb_buy_amt': '9950248',
'nrcvb_buy_qty': '459',
'max_buy_amt': '9950248',
'max_buy_qty': '459',
'cma_evlu_amt': '0',
'ovrs_re_use_amt_wcrc': '0',
'ord_psbl_frcr_amt_wcrc': '0'
}
"""
for k in output.keys():
output[k] = int(output[k])
result = {
"rt_cd": res_body["rt_cd"],
"msg_cd": res_body["msg_cd"],
"msg1": res_body["msg1"].strip(),
"output": output,
}
return result
[docs]
def inquire_balance_rlz_pl(
self, cano: str, acnt_prdt_cd: str, afhr_flpr_yn: str = "N", fund_sttl_icld_yn: str = "N", prcs_dvsn: str = "00", cost_icld_yn: str = "N", ctx_area_fk100: str = "", ctx_area_nk100: str = "", tr_cont: str = ""
):
"""
(국내주식주문) 주식잔고조회_실현손익[v1_국내주식-041]
주식잔고조회_실현손익 API입니다.
| 한국투자 HTS(eFriend Plus) [0800] 국내 체결기준잔고 화면을 API로 개발한 사항으로, 해당 화면을 참고하시면 기능을 이해하기 쉽습니다.
| (참고: 포럼 - 공지사항 - 신규 API 추가 안내(주식잔고조회_실현손익 외 1건))
Args:
cano (str): 종합계좌번호 - 계좌번호 체계(8-2)의 앞 8자리
acnt_prdt_cd (str): 계좌상품코드 - 계좌번호 체계(8-2)의 뒤 2자리
afhr_flpr_yn (str): 시간외단일가여부 - N:기본값 Y:시간외단일가
fund_sttl_icld_yn (str): 펀드결제포함여부 - N:포함하지 않음 Y:포함
prcs_dvsn (str): PRCS_DVSN - 00:전일매매포함 01:전일매매미포함
cost_icld_yn (str): 비용포함여부
ctx_area_fk100 (str): 연속조회검색조건100 - 공란:최초 조회시. 이전 조회 output ctx_area_fk100 값:다음페이지 조회시(2번째부터)
ctx_area_nk100 (str): 연속조회키100 - 공란:최초 조회시. 이전 조회 output ctx_area_nk100 값:다음페이지 조회시(2번째부터)
Returns:
dict:
- rt_cd (str): 응답코드
- msg_cd (str): 메시지코드
- msg1 (str): 응답메시지
- output1 (list): 응답상세1
- pdno: 상품번호 - 종목번호(뒷 6자리)
- prdt_name: 상품명 - 종목명
- trad_dvsn_name: 매매구분명 - 매수매도구분
- bfdy_buy_qty: 전일매수수량
- bfdy_sll_qty: 전일매도수량
- thdt_buyqty: 금일매수수량
- thdt_sll_qty: 금일매도수량
- hldg_qty: 보유수량
- ord_psbl_qty: 주문가능수량
- pchs_avg_pric: 매입평균가격 - 매입금액 / 보유수량
- pchs_amt: 매입금액
- prpr: 현재가
- evlu_amt: 평가금액
- evlu_pfls_amt: 평가손익금액 - 평가금액 - 매입금액
- evlu_pfls_rt: 평가손익율
- evlu_erng_rt: 평가수익율
- loan_dt: 대출일자
- loan_amt: 대출금액
- stln_slng_chgs: 대주매각대금 - 신용 거래에서, 고객이 증권 회사로부터 대부받은 주식의 매각 대금
- expd_dt: 만기일자
- stck_loan_unpr: 주식대출단가
- bfdy_cprs_icdc: 전일대비증감
- fltt_rt: 등락율
- output2 (list): 응답상세2
- dnca_tot_amt: 예수금총금액
- nxdy_excc_amt: 익일정산금액
- prvs_rcdl_excc_amt: 가수도정산금액
- cma_evlu_amt: CMA평가금액
- bfdy_buy_amt: 전일매수금액
- thdt_buy_amt: 금일매수금액
- nxdy_auto_rdpt_amt: 익일자동상환금액
- bfdy_sll_amt: 전일매도금액
- thdt_sll_amt: 금일매도금액
- d2_auto_rdpt_amt: D+2자동상환금액
- bfdy_tlex_amt: 전일제비용금액
- thdt_tlex_amt: 금일제비용금액
- tot_loan_amt: 총대출금액
- scts_evlu_amt: 유가평가금액
- tot_evlu_amt: 총평가금액
- nass_amt: 순자산금액
- fncg_gld_auto_rdpt_yn: 융자금자동상환여부
- pchs_amt_smtl_amt: 매입금액합계금액
- evlu_amt_smtl_amt: 평가금액합계금액
- evlu_pfls_smtl_amt: 평가손익합계금액
- tot_stln_slng_chgs: 총대주매각대금
- bfdy_tot_asst_evlu_amt: 전일총자산평가금액
- asst_icdc_amt: 자산증감액
- asst_icdc_erng_rt: 자산증감수익율
- rlzt_pfls: 실현손익
- rlzt_erng_rt: 실현수익율
- real_evlu_pfls: 실평가손익
- real_evlu_pfls_erng_rt: 실평가손익수익율
Raise:
ValueError: API 에러 발생시
"""
assert self.auth.paper_trading is False, "실전계좌에서만 조회 가능합니다."
url_path = "/uapi/domestic-stock/v1/trading/inquire-balance-rlz-pl"
tr_id = "TTTC8494R"
params = {
"CANO": cano,
"ACNT_PRDT_CD": acnt_prdt_cd,
"AFHR_FLPR_YN": afhr_flpr_yn,
"OFL_YN": "",
"INQR_DVSN": "00",
"UNPR_DVSN": "01",
"FUND_STTL_ICLD_YN": fund_sttl_icld_yn,
"FNCG_AMT_AUTO_RDPT_YN": "N",
"PRCS_DVSN": prcs_dvsn,
"COST_ICLD_YN": cost_icld_yn,
"CTX_AREA_FK100": ctx_area_fk100,
"CTX_AREA_NK100": ctx_area_nk100,
"TR_CONT": tr_cont,
}
res_body, res_header = self._tr_request(url_path, tr_id, tr_cont, params=params)
if res_body["rt_cd"] != "0":
raise ValueError(f"Error: ({res_body['msg_cd']}) {res_body['msg1']}")
output1 = []
for el in res_body["output1"]:
for k in el.keys():
if len(el[k]) == 0 or k in ["pdno", "prdt_name", "trad_dvsn_name"]:
pass
elif k in ["loan_dt", "expd_dt"]:
el[k] = dtm.datetime.strptime(el[k], "%Y%m%d").date()
elif k in ["evlu_pfls_rt", "evlu_erng_rt", "fltt_rt", "pchs_avg_pric", "stck_loan_unpr"]:
el[k] = Decimal(el[k])
else:
el[k] = int(el[k])
output1.append(el)
output2 = []
for el in res_body["output2"]:
for k in el.keys():
if len(el[k]) == 0 or k in ["fncg_gld_auto_rdpt_yn"]:
pass
elif k in ["asst_icdc_erng_rt", "rlzt_erng_rt", "real_evlu_pfls_erng_rt"]:
el[k] = Decimal(el[k])
else:
el[k] = int(el[k])
output2.append(el)
result = {
"rt_cd": res_body["rt_cd"],
"msg_cd": res_body["msg_cd"],
"msg1": res_body["msg1"].strip(),
"tr_cont": res_header["tr_cont"].strip(),
"ctx_area_fk100": res_body["ctx_area_fk100"].strip(),
"ctx_area_nk100": res_body["ctx_area_nk100"].strip(),
"output1": output1,
"output2": output2,
}
return result
[docs]
def inquire_credit_psamount(self, cano: str, acnt_prdt_cd: str, pdno: str, ord_unpr: int, ord_dvsn: str, crdt_type: str, cma_evlu_amt_icld_yn: str = "N", ovrs_icld_yn: str = "N"):
"""
(국내주식주문) 신용매수가능조회[v1_국내주식-042]
Args:
cano (str): 종합계좌번호 - 계좌번호 체계(8-2)의 앞 8자리
acnt_prdt_cd (str): 계좌상품코드 - 계좌번호 체계(8-2)의 뒤 2자리
pdno (str): 상품번호 - 종목코드(6자리)
ord_unpr (int): 주문단가 - 1주당 가격. * 장전 시간외, 장후 시간외, 시장가의 경우 1주당 가격을 공란으로 비우지 않음 0으로 입력 권고
ord_dvsn (str): 주문구분 - 00:지정가 01:시장가 02:조건부지정가 03:최유리지정가 04:최우선지정가 05:장전 시간외 06:장후 시간외 07:시간외 단일가 등
crdt_type (str): 신용유형 - 21:자기융자신규 23:유통융자신규 26:유통대주상환 28:자기대주상환 25:자기융자상환 27:유통융자상환 22:유통대주신규 24:자기대주신규
cma_evlu_amt_icld_yn (str): CMA평가금액포함여부 - Y/N
ovrs_icld_yn (str): 해외포함여부 - Y/N
Returns:
dict:
- rt_cd (str): 응답코드
- msg_cd (str): 메시지코드
- msg1 (str): 응답메시지
- output1 (list): 응답상세1
- ORD_PSBL_CASH: 주문가능현금
- ORD_PSBL_SBST: 주문가능대용
- RUSE_PSBL_AMT: 재사용가능금액
- FUND_RPCH_CHGS: 펀드환매대금
- PSBL_QTY_CALC_UNPR: 가능수량계산단가
- NRCVB_BUY_AMT: 미수없는매수금액
- NRCVB_BUY_QTY: 미수없는매수수량
- MAX_BUY_AMT: 최대매수금액
- MAX_BUY_QTY: 최대매수수량
- CMA_EVLU_AMT: CMA평가금액
- OVRS_RE_USE_AMT_WCRC: 해외재사용금액원화
- ORD_PSBL_FRCR_AMT_WCRC: 주문가능외화금액원화
Raise:
ValueError: API 에러 발생시
"""
assert self.auth.paper_trading is False, "실전계좌에서만 조회 가능합니다."
url_path = "/uapi/domestic-stock/v1/trading/inquire-credit-psamount"
tr_id = "TTTC8909R"
params = {
"CANO": cano,
"ACNT_PRDT_CD": acnt_prdt_cd,
"PDNO": pdno,
"ORD_UNPR": ord_unpr,
"ORD_DVSN": ord_dvsn,
"CRDT_TYPE": crdt_type,
"CMA_EVLU_AMT_ICLD_YN": cma_evlu_amt_icld_yn,
"OVRS_ICLD_YN": ovrs_icld_yn,
}
res_body, _ = self._tr_request(url_path, tr_id, params=params)
if res_body["rt_cd"] != "0":
raise ValueError(f"Error: ({res_body['msg_cd']}) {res_body['msg1']}")
output = res_body["output"]
for k in output.keys():
if len(output[k]) == 0:
pass
else:
output[k] = int(output[k])
result = {
"rt_cd": res_body["rt_cd"],
"msg_cd": res_body["msg_cd"],
"msg1": res_body["msg1"].strip(),
"output": output,
}
return result
[docs]
def inquire_account_balance(self, cano: str, acnt_prdt_cd: str):
"""
(국내주식주문) 투자계좌자산현황조회[v1_국내주식-048]
투자계좌자산현황조회 API입니다.
output1은 한국투자 HTS(eFriend Plus) > [0891] 계좌 자산비중(결제기준) 화면 아래 테이블의 기능을 API로 개발한 사항으로, 해당 화면을 참고하시면 기능을 이해하기 쉽습니다.
Args:
cano (str): 종합계좌번호 - 계좌번호 체계(8-2)의 앞 8자리
acnt_prdt_cd (str): 계좌상품코드 - 계좌번호 체계(8-2)의 뒤 2자리
Returns:
dict:
- rt_cd (str): 응답코드
- msg_cd (str): 메시지코드
- msg1 (str): 응답메시지
- output1 (list): 응답상세1
- pchs_amt: 매입금액
- evlu_amt: 평가금액
- evlu_pfls_amt: 평가손익금액
- crdt_lnd_amt: 신용대출금액
- real_nass_amt: 실제순자산금액
- whol_weit_rt: 전체비중율
- output2 (dict): 응답상세2
- pchs_amt_smtl: 매입금액합계 - 유가매입금액
- nass_tot_amt: 순자산총금액
- loan_amt_smtl: 대출금액합계
- evlu_pfls_amt_smtl: 평가손익금액합계 - 평가손익금액
- evlu_amt_smtl: 평가금액합계 - 유가평가금액
- tot_asst_amt: 총자산금액 - 자산금액
- tot_lnda_tot_ulst_lnda: 총대출금액총융자대출금액
- cma_auto_loan_amt: CMA자동대출금액
- tot_mgln_amt: 총담보대출금액
- stln_evlu_amt: 대주평가금액
- crdt_fncg_amt: 신용융자금액
- ocl_apl_loan_amt: OCL_APL대출금액
- pldg_stup_amt: 질권설정금액
- frcr_evlu_tota: 외화평가총액
- tot_dncl_amt: 총예수금액
- cma_evlu_amt: CMA평가금액
- dncl_amt: 예수금액
- tot_sbst_amt: 총대용금액
- thdt_rcvb_amt: 당일미수금액
- ovrs_stck_evlu_amt1: 해외주식평가금액1
- ovrs_bond_evlu_amt: 해외채권평가금액
- mmf_cma_mgge_loan_amt: MMFCMA담보대출금액
- sbsc_dncl_amt: 청약예수금액
- pbst_sbsc_fnds_loan_use_amt: 공모주청약자금대출사용금액
- etpr_crdt_grnt_loan_amt: 기업신용공여대출금액
Raise:
ValueError: API 에러 발생시
"""
assert self.auth.paper_trading is False, "실전계좌에서만 조회 가능합니다."
url_path = "/uapi/domestic-stock/v1/trading/inquire-account-balance"
tr_id = "CTRP6548R"
params = {
"CANO": cano,
"ACNT_PRDT_CD": acnt_prdt_cd,
"INQR_DVSN_1": "",
"BSPR_BF_DT_APLY_YN": "",
}
res_body, _ = self._tr_request(url_path, tr_id, params=params)
if res_body["rt_cd"] != "0":
raise ValueError(f"Error: ({res_body['msg_cd']}) {res_body['msg1']}")
output1 = []
for el in res_body["output1"]:
for k in el.keys():
if len(el[k]) == 0:
pass
elif k == "whol_weit_rt":
el[k] = Decimal(el[k])
else:
el[k] = int(el[k])
output1.append(el)
output2 = res_body["output2"]
for k in output2.keys():
if len(output2[k]) == 0:
pass
elif k in ["ovrs_stck_evlu_amt1", "ovrs_bond_evlu_amt"]:
output2[k] = Decimal(output2[k])
else:
output2[k] = int(output2[k])
result = {"rt_cd": res_body["rt_cd"], "msg_cd": res_body["msg_cd"], "msg1": res_body["msg1"].strip(), "output1": output1, "output2": output2}
return result
[docs]
def inquire_period_trade_profit(self, cano: str, acnt_prdt_cd: str, inqr_strt_dt: dtm.date, inqr_end_dt: dtm.date, sort_dvsn: str = "00", pdno: str = "", ctx_area_nk100: str = "", ctx_area_fk100: str = "", tr_cont: str = ""):
"""
(국내주식주문) 기간별매매손익현황조회[v1_국내주식-060]
기간별매매손익현황조회 API입니다.
한국투자 HTS(eFriend Plus) > [0856] 기간별 매매손익 화면 에서 "종목별" 클릭 시의 기능을 API로 개발한 사항으로, 해당 화면을 참고하시면 기능을 이해하기 쉽습니다.
Args:
cano (str): 종합계좌번호
sort_dvsn (str): 정렬구분 - 00:최근순(기본값) 01:과거순 02:최근순
acnt_prdt_cd (str): 계좌상품코드
pdno (str): 상품번호 - "" 공란입력 시, 전체 (기본값)
inqr_strt_dt (datetime.date): 조회시작일자
inqr_end_dt (datetime.date): 조회종료일자
ctx_area_nk100 (str): 연속조회키100
ctx_area_fk100 (str): 연속조회검색조건100
tr_cont (str): 연속조회여부 - 공란:최초 조회시. 'N':연속조회시
Returns:
dict:
- rt_cd (str): 응답코드
- msg_cd (str): 메시지코드
- msg1 (str): 응답메시지
- output1 (dict): 응답상세1
- trad_dt: 매매일자
- pdno: 상품번호 - 종목번호(뒤 6자리만 해당)
- prdt_name: 상품명
- trad_dvsn_name: 매매구분명
- loan_dt: 대출일자
- hldg_qty: 보유수량
- pchs_unpr: 매입단가
- buy_qty: 매수수량
- buy_amt: 매수금액
- sll_pric: 매도가격
- sll_qty: 매도수량
- sll_amt: 매도금액
- rlzt_pfls: 실현손익
- pfls_rt: 손익률
- fee: 수수료
- tl_tax: 제세금
- loan_int: 대출이자
- ctx_area_fk100: 연속조회검색조건100
- ctx_area_nk100: 연속조회키100 - 100
- output2 (list): 응답상세2
- sll_qty_smtl: 매도수량합계
- sll_tr_amt_smtl: 매도거래금액합계
- sll_fee_smtl: 매도수수료합계
- sll_tltx_smtl: 매도제세금합계
- sll_excc_amt_smtl: 매도정산금액합계
- buyqty_smtl: 매수수량합계
- buy_tr_amt_smtl: 매수거래금액합계
- buy_fee_smtl: 매수수수료합계
- buy_tax_smtl: 매수제세금합계
- buy_excc_amt_smtl: 매수정산금액합계
- tot_qty: 총수량
- tot_tr_amt: 총거래금액
- tot_fee: 총수수료
- tot_tltx: 총제세금
- tot_excc_amt: 총정산금액
- tot_rlzt_pfls: 총실현손익
- loan_int: 대출이자
- tot_pftrt: 총수익률
Raise:
ValueError: API 에러 발생시
"""
assert self.auth.paper_trading is False, "실전계좌에서만 조회 가능합니다."
assert sort_dvsn in ["00", "01", "02"], "sort_dvsn은 00, 01, 02 중 하나여야 합니다."
url_path = "/uapi/domestic-stock/v1/trading/inquire-period-trade-profit"
tr_id = "TTTC8715R"
params = {
"CANO": cano,
"SORT_DVSN": sort_dvsn,
"ACNT_PRDT_CD": acnt_prdt_cd,
"PDNO": pdno,
"INQR_STRT_DT": inqr_strt_dt.strftime("%Y%m%d"),
"INQR_END_DT": inqr_end_dt.strftime("%Y%m%d"),
"CBLC_DVSN": "00",
"CTX_AREA_NK100": ctx_area_nk100,
"CTX_AREA_FK100": ctx_area_fk100,
}
res_body, res_header = self._tr_request(url_path, tr_id, tr_cont, params=params)
if res_body["rt_cd"] != "0":
raise ValueError(f"Error: ({res_body['msg_cd']}) {res_body['msg1']}")
output1 = []
for el in res_body["output1"]:
for k in el.keys():
if len(el[k]) == 0 or k in ["pdno", "prdt_name", "trad_dvsn_name"]:
pass
elif k in ["trad_dt", "loan_dt"]:
el[k] = dtm.datetime.strptime(el[k], "%Y%m%d").date()
elif k in ["pfls_rt"]:
el[k] = Decimal(el[k])
else:
el[k] = int(el[k])
output1.append(el)
output2 = res_body["output2"]
"""
{
'sll_qty_smtl': '111',
'sll_tr_amt_smtl': '1940820',
'sll_fee_smtl': '81',
'sll_tltx_smtl': '1660',
'sll_excc_amt_smtl': '1939079',
'buyqty_smtl': '83',
'buy_tr_amt_smtl': '965290',
'buy_fee_smtl': '40',
'buy_tax_smtl': '0',
'buy_excc_amt_smtl': '965330',
'tot_qty': '194',
'tot_tr_amt': '2906110',
'tot_fee': '121',
'tot_tltx': '1660',
'tot_excc_amt': '2904409',
'tot_rlzt_pfls': '8029',
'loan_int': '0',
'tot_pftrt': '0.41579277'
}
"""
for k in output2.keys():
if len(output2[k]) == 0:
pass
elif k == "tot_pftrt":
output2[k] = Decimal(output2[k])
else:
output2[k] = int(output2[k])
result = {
"rt_cd": res_body["rt_cd"],
"msg_cd": res_body["msg_cd"],
"msg1": res_body["msg1"].strip(),
"ctx_area_fk100": res_body["ctx_area_fk100"].strip(),
"ctx_area_nk100": res_body["ctx_area_nk100"].strip(),
"tr_cont": res_header["tr_cont"].strip(),
"output1": output1,
"output2": output2,
}
return result
[docs]
def inquire_period_profit(self, cano: str, acnt_prdt_cd: str, inqr_strt_dt: dtm.date, inqr_end_dt: dtm.date, pdno: str = "", sort_dvsn: str = "00", ctx_area_nk100: str = "", ctx_area_fk100: str = "", tr_cont: str = ""):
"""
(국내주식주문) 기간별손익일별합산조회[v1_국내주식-052]
기간별손익일별합산조회 API입니다.
한국투자 HTS(eFriend Plus) > [0856] 기간별 매매손익 화면 에서 "일별" 클릭 시의 기능을 API로 개발한 사항으로, 해당 화면을 참고하시면 기능을 이해하기 쉽습니다.
Args:
acnt_prdt_cd (str): 계좌상품코드
cano (str): 종합계좌번호
inqr_strt_dt (datetime.date): 조회시작일자
inqr_end_dt (datetime.date): 조회종료일자
pdno (str): 상품번호 - "" 공란입력 시, 전체
sort_dvsn (str): 정렬구분 - 00:최근순 01:과거순 02:최근순
ctx_area_nk100 (str): 연속조회키100
ctx_area_fk100 (str): 연속조회검색조건100
tr_cont (str): 연속조회여부 - 공란:최초 조회시. 'N':연속조회시
Returns:
dict:
- rt_cd (str): 응답코드
- msg_cd (str): 메시지코드
- msg1 (str): 응답메시지
- output1 (list): 응답상세1
- trad_dt: 매매일자
- buy_amt: 매수금액
- sll_amt: 매도금액
- rlzt_pfls: 실현손익
- fee: 수수료
- loan_int: 대출이자
- tl_tax: 제세금
- pfls_rt: 손익률
- sll_qty1: 매도수량1
- buy_qty1: 매수수량1
- outpu2 (dict): 응답상세2
- sll_qty_smtl: 매도수량합계
- sll_tr_amt_smtl: 매도거래금액합계
- sll_fee_smtl: 매도수수료합계
- sll_tltx_smtl: 매도제세금합계
- sll_excc_amt_smtl: 매도정산금액합계
- buy_qty_smtl: 매수수량합계
- buy_tr_amt_smtl: 매수거래금액합계
- buy_fee_smtl: 매수수수료합계
- buy_tax_smtl: 매수제세금합계
- buy_excc_amt_smtl: 매수정산금액합계
- tot_qty: 총수량
- tot_tr_amt: 총거래금액
- tot_fee: 총수수료
- tot_tltx: 총제세금
- tot_excc_amt: 총정산금액
- tot_rlzt_pfls: 총실현손익
- loan_int: 대출이자
Raise:
ValueError: API 에러 발생시
"""
assert self.auth.paper_trading is False, "실전계좌에서만 조회 가능합니다."
url_path = "/uapi/domestic-stock/v1/trading/inquire-period-profit"
tr_id = "TTTC8708R"
params = {
"CANO": cano,
"ACNT_PRDT_CD": acnt_prdt_cd,
"PDNO": pdno,
"INQR_STRT_DT": inqr_strt_dt.strftime("%Y%m%d"),
"INQR_END_DT": inqr_end_dt.strftime("%Y%m%d"),
"SORT_DVSN": sort_dvsn,
"INQR_DVSN": "00",
"CBLC_DVSN": "00",
"CTX_AREA_NK100": ctx_area_nk100,
"CTX_AREA_FK100": ctx_area_fk100,
}
res_body, res_header = self._tr_request(url_path, tr_id, tr_cont, params=params)
if res_body["rt_cd"] != "0":
raise ValueError(f"Error: ({res_body['msg_cd']}) {res_body['msg1']}")
output1 = []
for el in res_body["output1"]:
for k in el.keys():
if len(el[k]) == 0:
pass
elif k == "trad_dt":
el[k] = dtm.datetime.strptime(el[k], "%Y%m%d").date()
elif k == "pfls_rt":
el[k] = Decimal(el[k])
else:
el[k] = int(el[k])
output1.append(el)
output2 = res_body["output2"]
for k in output2.keys():
if len(output2[k]) == 0:
pass
output2[k] = int(output2[k])
result = {
"rt_cd": res_body["rt_cd"],
"msg_cd": res_body["msg_cd"],
"msg1": res_body["msg1"].strip(),
"ctx_area_fk100": res_body["ctx_area_fk100"].strip(),
"ctx_area_nk100": res_body["ctx_area_nk100"].strip(),
"tr_cont": res_header["tr_cont"].strip(),
"output1": output1,
"output2": output2,
}
return result
[docs]
async def listen_order_event(self, hts_id: str, stop_event: asyncio.Event) -> AsyncGenerator:
"""
주식 주문 이벤트를 실시간으로 수신하고 처리하는 비동기 제너레이터 함수입니다.
이 함수는 지정된 HTS ID를 사용하여 웹소켓 연결을 통해 주문 이벤트를 실시간으로 수신합니다.
주문 이벤트 데이터는 암호화되어 전송될 수 있으며, 이 함수는 암호화된 데이터를 해독하여 주문의 상세 정보를 추출합니다.
추출된 정보는 비동기적으로 소비할 수 있도록 제너레이터로 반환됩니다.
Args:
hts_id (str): 주식 거래 시스템에서 사용되는 고유 식별자.
Yields:
dict: 주문에 관한 상세 정보를 포함하는 사전형 데이터. 각 키는 다음과 같습니다:
- "cust_id": 고객 ID (HTS ID)
- "acnt_no": 계좌번호
- "oder_no": 주문번호
- "ooder_no": 원주문번호
- "seln_byov_cls": 매도매수구분 (01:매도, 02:매수)
- "rctf_cls": 정정구분
- "oder_kind": 주문종류
- "oder_cond": 주문조건
- "stck_shrn_iscd": 주식단축코드
- "cntg_qty": 체결수량
- "cntg_unpr": 체결 단가
- "stck_cntg_hour": 체결 시간
- "rfus_yn": 거부여부 (0:정상, 1:거부)
- "cntg_yn": 체결여부 (1:주문,정정,취소,거부, 2:체결)
- "acpt_yn": 접수여부 (1:접수, 2:확인, 3:취소)
- "brnc_no": 지점번호
- "oder_qty": 주문수량
- "acnt_name": 계좌명
- "cntg_isnm": 체결종목명
- "crdt_cls": 신용구분
- "crdt_loan_date": 신용대출일자
- "cntg_isnm40": 체결종목명40
- "oder_prc": 주문가격
Examples:
>>> async for order_event in listen_order_event('your_hts_id'):
>>> print(order_event)
{'cust_id': 'your_hts_id', 'acnt_no': 'your_acnt_no', 'oder_no': '0000149078', 'ooder_no': '0000148379', 'seln_byov_cls': '02', 'rctf_cls': '1', 'oder_kind': '00', 'oder_cond': '0', 'stck_shrn_iscd': '360750', 'cntg_qty': 1, 'cntg_unpr': 12610, 'stck_cntg_hour': '140149', 'rfus_yn': '0', 'cntg_yn': '1', 'acpt_yn': '2', 'brnc_no': '91253', 'oder_qty': 1, 'acnt_name': '강지훈', 'cntg_isnm': 'TIGER 미국S&P5', 'crdt_cls': '10', 'crdt_loan_date': '', 'cntg_isnm40': 'TIGER 미국S&P500', 'oder_prc': ''}
{'cust_id': 'your_hts_id', 'acnt_no': 'your_acnt_no', 'oder_no': '0000149273', 'ooder_no': '0000149078', 'seln_byov_cls': '02', 'rctf_cls': '2', 'oder_kind': '00', 'oder_cond': '0', 'stck_shrn_iscd': '360750', 'cntg_qty': 1, 'cntg_unpr': 0, 'stck_cntg_hour': '140231', 'rfus_yn': '0', 'cntg_yn': '1', 'acpt_yn': '2', 'brnc_no': '91253', 'oder_qty': 1, 'acnt_name': '강지훈', 'cntg_isnm': 'TIGER 미국S&P5', 'crdt_cls': '10', 'crdt_loan_date': '', 'cntg_isnm40': 'TIGER 미국S&P500', 'oder_prc': ''}
Note:
이 함수는 비동기 I/O를 사용하므로 async for 문을 사용하여 이벤트를 소비해야 합니다.
"""
payload_pattern = re.compile(r"^(0|1)\|[^\|]+\|\d+\|([A-Za-z0-9+/=]+(\^[A-Za-z0-9+/=]+)*)?$")
iv = None
key = None
tr_ids = ["H0STCNI9", "H0STCNI0"]
async def __on_connect(ws: websockets.WebSocketClientProtocol):
payload = {
"header": {
"approval_key": self.auth.get_approval_key(),
"custtype": "B" if self.corp_data else "P",
"tr_type": "1", # 1:등록, 2:해제
"content-type": "utf-8",
},
"body": {
"input": {
"tr_id": "H0STCNI9" if self.auth.paper_trading else "H0STCNI0",
"tr_key": hts_id,
}
},
}
await ws.send(json.dumps(payload))
def __parse_order_event_payload(data):
keys = [
"cust_id", # 고객 ID (HTS ID)
"acnt_no", # 계좌번호
"oder_no", # 주문번호
"ooder_no", # 원주문번호
"seln_byov_cls", # 매도매수구분 (01:매도, 02:매수)
"rctf_cls", # 정정구분
"oder_kind", # 주문종류 주문통보: 주문낸 주문종류로 수신, 체결통보: 00으로 수신
"oder_cond", # 주문조건
"stck_shrn_iscd", # 주식단축코드
"cntg_qty", # 체결수량 - 체결통보(CNTG_YN=2)시 체결 수량, 정정/취소/거부 접수 통보(CNTG_YN=1)시 주문수량을 의미함
"cntg_unpr", # 체결 단가
"stck_cntg_hour", # 체결 시간
"rfus_yn", # 거부여부 (0:정상, 1:거부)
"cntg_yn", # 체결여부 (1:주문,정정,취소,거부, 2:체결)
"acpt_yn", # 접수여부 (1:접수, 2:확인, 3:취소)
"brnc_no", # 지점번호
"oder_qty", # 주문수량
"acnt_name", # 계좌명
"ord_cond_prc", # 스톱지정가일때만 표시
"ord_exg_gb", # 주문거래소 구분 (1:KRX, 2:NXT, 3:SOR-KRX, 4:SOR-NXT)
"popup_yn", # 실시간체결창 표시여부 (Y/N)
"filler", # 필러
"crdt_cls", # 신용구분
"crdt_loan_date", # 신용대출일자
"cntg_isnm40", # 체결종목명40
"oder_prc", # 주문가격 - 체결통보(CNTG_YN=2)시 주문가격, 주문,정정,취소,거부 접수 통보(CNTG_YN=1)시 체결단가(빈값으로 수신)
]
tokens = data.split("|")
tr_id = tokens[1]
if tr_id in tr_ids:
if iv and key:
decoded_str = _aes_cbc_base64_dec(key, iv, tokens[3])
values = decoded_str.split("^")
result = {}
for i, k in enumerate(keys):
if k in ["cntg_unpr", "oder_prc", "cntg_qty", "oder_qty"] and len(values[i]) > 0:
result[k] = int(values[i])
else:
result[k] = values[i] if i < len(values) else ""
return result
def __parse_iv_and_key(data):
nonlocal iv
nonlocal key
try:
data = json.loads(data)
body = data.get("body")
if body:
output = body.get("output")
if output:
if "iv" in output and "key" in output:
iv = output.get("iv")
key = output.get("key")
except json.JSONDecodeError:
pass
client = KISTRWebsocketClient(self.auth, __on_connect, stop_event)
async for data in client.listen():
if payload_pattern.match(data):
event_data = __parse_order_event_payload(data)
if event_data:
yield event_data
else:
__parse_iv_and_key(data)
def _aes_cbc_base64_dec(key, iv, cipher_text):
"""
:param key: str type AES256 secret key value
:param iv: str type AES256 Initialize Vector
:param cipher_text: Base64 encoded AES256 str
:return: Base64-AES256 decodec str
"""
cipher = AES.new(key.encode("utf-8"), AES.MODE_CBC, iv.encode("utf-8"))
return bytes.decode(unpad(cipher.decrypt(b64decode(cipher_text)), AES.block_size))