Source code for pyqqq.brokerage.kis.overseas_stock

from decimal import Decimal
from typing import Dict, List, Optional
from pyqqq.brokerage.kis.oauth import KISAuth
from pyqqq.brokerage.kis.tr_client import KISTRClient
import datetime as dtm


[docs] class KISOverseasStock:
[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, market: str, symbol: str) -> dict: ''' (해외주식현재가) 해외주식 현재 체결가 [v1_해외주식-009] Args: market (str): 거래소코드 symbol (str): 종목코드 Returns: dict: 현재 체결가 정보 - rsym: D+시장구분(3자리)+종목코드 - zdiv: 소수점자리수 - base: 전일종가 - pvol: 전일의 거래량 - last: 현재가 - 당일 조회시점의 가격 - sign: 대비기호 - 1:상한 2:상승 3:보합 4:하한 5:하락 - diff: 대비 - 전일 종가와 당일 현재가의 차이 (당일 현재가 - 전일 종가) - rate: 등락율 = 전일 대비 / 당일 현재가 * 100 - tvol: 당일 조회시점까지 전체 거래금액 - tamt: 당일 조회시점까지 전체 거래금액 - ordy: 매수주문 가능 종목 여부 Raises: ValueError: API 호출 실패시 발생 ''' path = '/uapi/overseas-price/v1/quotations/price' query = { 'AUTH': '', 'EXCD': market, 'SYMB': symbol } tr_id = 'HHDFS00000300' body, resp_header = self._tr_request(path, tr_id, params=query) if body['rt_cd'] != '0': raise ValueError(f"Error: ({body['msg_cd']}) {body['msg1']}") output = body['output'] for k in output.keys(): if len(output[k]) == 0: pass elif k in ['rsym', 'ordy']: pass elif k in ['pvol', 'sign', 'tvol', 'tamt']: output[k] = int(output[k]) else: output[k] = Decimal(output[k]) return { 'tr_id': resp_header['tr_id'], 'tr_cont': resp_header['tr_cont'], 'gt_uid': resp_header['gt_uid'], 'rt_cd': body['rt_cd'], 'msg_cd': body['msg_cd'], 'msg1': body['msg1'], 'output': output, }
[docs] def get_dailyprice(self, excd: str, symb: str, gubn: str, modp: str, bymd: str = '', keyb: str = '', tr_cont: str = ''): ''' (해외주식현재가) 해외주식 기간별시세[v1_해외주식-010] Args: excd (str): 거래소코드 (NAS, NYS, AMS) symb (str): 종목코드 gubn (str): 구분 - "0":일 "1":주 "3":월 bymd (str): 조회일자 (YYYYMMDD) modp (str): 수정주가반영여부 - "0":미반영 "1":반영 keyb (str): NEXT KEY BUFF - 응답시 다음값이 있으면 값이 셋팅되어 있으므로 다음 조회시 응답값 그대로 셋팅 tr_cont (str): 연속조회여부 - 공백: 초기조회, "N": 연속조회 Returns: dict: - rt_cd: 응답코드 - msg_cd: 응답메시지코드 - msg1: 응답메시지1 - gt_uid: 고유번호 - output1: 응답상세1 (dict) - rsym: D+시장구분(3자리)+종목코드 - zdiv: 소수점자리수 - nrec: 조회된 건수 - output2: 응답상세2 (list) - xymd: 일자 - clos: 종가 - sign: 대비기호 - 1:상한 2:상승 3:보합 4:하한 5:하락 - diff: 대비 - 전일 종가와 당일 현재가의 차이 (당일 현재가 - 전일 종가) - rate: 등락율 = 전일 대비 / 당일 현재가 * 100 - open: 시가 - high: 고가 - low: 저가 - tvol: 거래량 - tamt: 거래대금 - pbid: 매수호가 - vbid: 매수잔량 - pask: 매도호가 - vask: 매도잔량 Raises: ValueError: API 호출 실패시 발생 ''' path = '/uapi/overseas-price/v1/quotations/dailyprice' params = { 'AUTH': '', 'EXCD': excd, 'SYMB': symb, 'GUBN': gubn, 'BYMD': bymd, 'MODP': modp, 'KEYB': keyb } tr_id = 'HHDFS76240000' body, header = self._tr_request(path, tr_id, tr_cont, params) if body['rt_cd'] != '0': raise ValueError(f"Error: ({body['msg_cd']}) {body['msg1']}") output1 = body['output1'] output1['nrec'] = int(output1['nrec']) output1['zdiv'] = int(output1['zdiv']) output2 = [] for data in body['output2']: output2.append( { "xymd": dtm.datetime.strptime(data["xymd"], "%Y%m%d").date(), # 일자 "clos": Decimal(data["clos"]), # 종가 "sign": int(data["sign"]), # 대비기호 - 1:상한 2:상승 3:보합 4:하한 5:하락 "diff": Decimal(data["diff"]), # 대비 - 전일 종가와 당일 현재가의 차이 (당일 현재가 - 전일 종가) "rate": Decimal(data["rate"]), # 등락율 = 전일 대비 / 당일 현재가 * 100 "open": Decimal(data["open"]), # 시가 "high": Decimal(data["high"]), # 고가 "low": Decimal(data["low"]), # 저가 "tvol": int(data["tvol"]), # 거래량 "tamt": Decimal(data["tamt"]), # 거래대금 "pbid": Decimal(data["pbid"]), # 매수호가 "vbid": int(data["vbid"]), # 매수잔량 "pask": Decimal(data["pask"]), # 매도호가 "vask": int(data["vask"]), # 매도잔량 } ) return { 'tr_id': header['tr_id'], 'tr_cont': header['tr_cont'], 'gt_uid': header['gt_uid'], 'rt_cd': body['rt_cd'], 'msg_cd': body['msg_cd'], 'msg1': body['msg1'], 'output1': output1, 'output2': output2 }
[docs] def inquire_daily_chartprice(self, fid_cond_mrkt_div_code: str, fid_input_iscd: str, fid_input_date_1: dtm.date, fid_input_date_2: dtm.date, fid_period_div_code: str, tr_cont: str = ""): ''' (해외주식현재가) 해외주식 종목/지수/환율기간별시세(일/주/월/년)[v1_해외주식-012] Args: fid_cond_mrkt_div_code (str): 시장구분코드 - "N":해외지수 "X":환율 fid_input_iscd (str): 종목코드 (해외주식 마스터 코드 참조. 다우30, 나스닥100, S&P500 종목만 조회가능) fid_input_date_1 (dtm.date): 조회시작일자 fid_input_date_2 (dtm.date): 조회종료일자 fid_period_div_code (str): 기간구분코드 - "D":일 "W":주 "M":월 "Y":년 tr_cont (str): 연속조회여부 - 공백: 초기조회, "N": 연속조회 Returns: dict: - rt_cd: 응답코드 - msg_cd: 응답메시지코드 - msg1: 응답메시지1 - output1: 응답상세1 (dict) - ovrs_nmix_prdy_vrss: 전일대비 - prdy_vrss_sign: 전일대비부호 - 1:상한 2:상승 3:보합 4:하한 5:하락 - prdy_ctrt: 전일 대비율 - ovrs_nmix_prdy_clpr: 전일종가 - acml_vol: 누적거래량 - hts_kor_isnm: HTS 한글 종목명 - ovrs_nmix_prpr: 현재가 - stck_shrn_iscd: 단축 종목코드 - ovrs_prod_oprc: 시가 - ovrs_prod_hgpr: 최고가 - ovrs_prod_lwpr: 최저가 - output2: 응답상세2 (list) - stck_bsop_date: 영업일자 - ovrs_nmix_prpr: 현재가 - ovrs_nmix_oprc: 시가 - ovrs_nmix_hgpr: 최고가 - ovrs_nmix_lwpr: 최저가 - acml_vol: 누적 거래량 - mod_yn: 변경 여부 ''' assert fid_cond_mrkt_div_code in ['N', 'X'] assert fid_period_div_code in ['D', 'W', 'M', 'Y'] path = '/uapi/overseas-price/v1/quotations/inquire-daily-chartprice' 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 } tr_id = 'FHKST03030100' body, header = self._tr_request(path, tr_id, tr_cont, params) if body['rt_cd'] != '0': raise ValueError(f"Error: ({body['msg_cd']}) {body['msg1']}") output1 = body['output1'] output1 = { 'ovrs_nmix_prdy_vrss': Decimal(output1['ovrs_nmix_prdy_vrss']), 'prdy_vrss_sign': int(output1['prdy_vrss_sign']), 'prdy_ctrt': Decimal(output1['prdy_ctrt']), 'ovrs_nmix_prdy_clpr': Decimal(output1['ovrs_nmix_prdy_clpr']), 'acml_vol': int(output1['acml_vol']), 'hts_kor_isnm': output1['hts_kor_isnm'], 'ovrs_nmix_prpr': Decimal(output1['ovrs_nmix_prpr']), 'stck_shrn_iscd': output1['stck_shrn_iscd'], 'ovrs_prod_oprc': Decimal(output1['ovrs_prod_oprc']), 'ovrs_prod_hgpr': Decimal(output1['ovrs_prod_hgpr']), 'ovrs_prod_lwpr': Decimal(output1['ovrs_prod_lwpr']), } output2 = [] for el in body['output2']: output2.append({ 'stck_bsop_date': dtm.datetime.strptime(el['stck_bsop_date'], '%Y%m%d').date(), 'ovrs_nmix_prpr': Decimal(el['ovrs_nmix_prpr']), 'ovrs_nmix_oprc': Decimal(el['ovrs_nmix_oprc']), 'ovrs_nmix_hgpr': Decimal(el['ovrs_nmix_hgpr']), 'ovrs_nmix_lwpr': Decimal(el['ovrs_nmix_lwpr']), 'acml_vol': int(el['acml_vol']), 'mod_yn': el['mod_yn'], }) result = { 'tr_id': header['tr_id'], 'tr_cont': header['tr_cont'], 'rt_cd': body['rt_cd'], 'msg_cd': body['msg_cd'], 'msg1': body['msg1'], 'output1': output1, 'output2': output2 } return result
[docs] def get_price_detail(self, excd: str, symb: str): ''' (해외주식현재가) 해외주식 현재가 상세정보[v1_해외주식-029] 해외주식 현재가상세 API입니다. 해당 API를 활용하여 해외주식 종목의 매매단위(vnit), 호가단위(e_hogau), PER, PBR, EPS, BPS 등의 데이터를 확인하실 수 있습니다. 해외주식 시세는 무료시세(지연시세)만이 제공되며, API로는 유료시세(실시간시세)를 받아보실 수 없습니다. | ※ 지연시세 지연시간 : 미국 - 실시간무료(0분지연) / 홍콩, 베트남, 중국 - 15분지연 / 일본 - 20분지연 | 미국의 경우 0분지연시세로 제공되나, 장중 당일 시가는 상이할 수 있으며, 익일 정정 표시됩니다. ※ 추후 HTS(efriend Plus) [7781] 시세신청(실시간) 화면에서 유료 서비스 신청 시 실시간 시세 수신할 수 있도록 변경 예정 Args: excd (str): 거래소코드 symb (str): 종목코드 tr_cont (str): 연속조회여부 - 공백: 초기조회, "N": 연속조회 Returns: dict: - rt_cd: 응답코드 - msg_cd: 응답메시지코드 - msg1: 응답메시지1 - output: 응답상세 - rsym: D+시장구분(3자리)+종목코드 - pvol: 전일의 거래량 - open: 시가 - high: 고가 - low: 저가 - last: 현재가 - base: 전일종가 - tomv: 시가총액 - pamt: 전일거래대금 - uplp: 상한가 - dnlp: 하한가 - h52p: 52주 최고가 - h52d: 52주 최고일자 - l52p: 52주 최저가 - l52d: 52주 최저일자 - perx: PER - pbrx: PBR - epsx: EPS - bpsx: BPS - shar: 발행주식수 - mcap: 자본금 - curr: 통화 - zdiv: 소수점자리수 - vnit: 매매단위 - t_xprc: 원환산당일가격 - t_xdif: 원환산당일대비 - t_xrat: 원환산당일등락 - p_xprc: 원환산전일가격 - p_xdif: 원환산전일대비 - p_xrat: 원환산전일등락 - t_rate: 당일환율 - p_rate: 전일환율 - t_xsgn: 원환산당일기호 - p_xsng: 원환산전일기호 - e_ordyn: 매수주문 가능 여부. 가능 "O" - e_hogau: 호가단위 - e_icod: 업종(섹터) - e_parp: 액면가 - tvol: 거래량 - tamt: 거래대금 - etyp_nm: ETP 분류명 Raise: ValueError: API 호출 실패시 ''' path = '/uapi/overseas-price/v1/quotations/price-detail' tr_id = 'HHDFS76200200' tr_cont = '' params = { 'AUTH': '', 'EXCD': excd, 'SYMB': symb } body, header = self._tr_request(path, tr_id, tr_cont, params) if body['rt_cd'] != '0': raise ValueError(f"Error: ({body['msg_cd']}) {body['msg1']}") output = body['output'] for k in output.keys(): if len(output[k]) == 0: pass elif k in ['rsym', 'curr', 'e_ordyn', 'e_icod', 'etyp_nm']: pass elif k in ['pvol', 'shar', 'vnit', 'tvol', 'tamt', 'zdiv', 't_xsgn', 'p_xsng']: output[k] = int(output[k]) elif k in ['h52d', 'l52d']: output[k] = dtm.datetime.strptime(output[k], '%Y%m%d').date() else: output[k] = Decimal(output[k]) result = { 'tr_id': header['tr_id'], 'tr_cont': header['tr_cont'], 'rt_cd': body['rt_cd'], 'msg_cd': body['msg_cd'], 'msg1': body['msg1'], 'output': output } return result
[docs] def inquire_time_itemchartprice( self, excd: str, symb: str, nmin: int = 1, pinc: int = 0, next: str = "", nrec: int = 120, keyb: str = "", ): """ (해외주식현재가) 해외주식분봉조회[v1_해외주식-030] | 해외주식분봉조회 API입니다. | 실전계좌의 경우, 최근 120건까지 확인 가능합니다. Args: excd (str): 거래소코드 symb (str): 종목코드 nmin (int): 분봉단위 - 1:1분봉 2:2분봉, ... next (str): 다음 여부 pinc (int): 전일포함여부 - 0: 당일, 1: 전일포함 nrec (int): 요청갯수 - 레코드요청갯수 (최대 120) keyb (str): NEXT KEY BUFF - 응답시 다음값이 있으면 값이 셋팅되어 있으므로 다음 조회시 응답값 그대로 셋팅 Returns: dict: - rt_cd: 응답코드 - msg_cd: 응답메시지코드 - msg1: 응답메시지1 - output1: 응답상세1 (dict) - rsym: D+시장구분(3자리)+종목코드 - zdiv: 소수점자리수 - stim: 시작시간 - etim: 종료시간 - sktm: 시작시간 - ektm: 종료시간 - next: 다음시작시간 - more: 더보기여부 - nrec: 조회된 건수 - output2: 응답상세2 (list) - tymd: 일자 - xymd: 일자 - xhms: 시간 - kymd: 일자 - khms: 시간 - open: 시가 - high: 고가 - low: 저가 - last: 현재가 - evol: 거래량 - eamt: 거래대금 Raises: ValueError: API 호출 실패시 """ assert nrec > 0 and nrec <= 120 assert nmin > 0 assert pinc == 0 or pinc == 1 path = '/uapi/overseas-price/v1/quotations/inquire-time-itemchartprice' tr_id = "HHDFS76950200" tr_cont = "" params = { "AUTH": "", "EXCD": excd, "SYMB": symb, "NMIN": str(nmin), "PINC": str(pinc), "NEXT": next, "NREC": str(nrec), "FILL": "", "KEYB": keyb, } body, header = self._tr_request(path, tr_id, tr_cont, params) if body['rt_cd'] != '0': raise ValueError(f"Error: ({body['msg_cd']}) {body['msg1']}") output1 = body['output1'] output1 = { "rsym": output1["rsym"], "zdiv": int(output1["zdiv"]), "stim": dtm.datetime.strptime(output1["stim"], "%H%M%S").time(), "etim": dtm.datetime.strptime(output1["etim"], "%H%M%S").time(), "sktm": dtm.datetime.strptime(output1["sktm"], "%H%M%S").time(), "ektm": dtm.datetime.strptime(output1["ektm"], "%H%M%S").time(), "next": output1["next"], "more": output1["more"], "nrec": int(output1["nrec"]), } output2 = [] for el in body['output2']: output2.append({ 'tymd': dtm.datetime.strptime(el['tymd'], '%Y%m%d').date(), 'xymd': dtm.datetime.strptime(el['xymd'], '%Y%m%d').date(), 'xhms': dtm.datetime.strptime(el['xhms'], '%H%M%S').time(), 'kymd': dtm.datetime.strptime(el['kymd'], '%Y%m%d').date(), 'khms': dtm.datetime.strptime(el['khms'], '%H%M%S').time(), 'open': Decimal(el['open']), 'high': Decimal(el['high']), 'low': Decimal(el['low']), 'last': Decimal(el['last']), 'evol': int(el['evol']), 'eamt': int(el['eamt']), }) result = { 'tr_id': header['tr_id'], 'tr_cont': header['tr_cont'], 'rt_cd': body['rt_cd'], 'msg_cd': body['msg_cd'], 'msg1': body['msg1'], 'output1': output1, 'output2': output2 } return result
[docs] def inquire_time_indexchartprice(self, fid_cond_mrkt_div_code: str, fid_input_iscd: str, fid_hour_cls_code: str, fid_pw_data_incu_yn: str): ''' (해외주식현재가) 해외지수분봉조회[v1_해외주식-031] | 해외지수분봉조회 API입니다. | 실전계좌의 경우, 최근 102건까지 확인 가능합니다. Args: fid_cond_mrkt_div_code (str): 조건 시장 분류 코드 - "N":해외지수 "X":환율 "KX":원화환율 fid_input_iscd (str): 종목번호(ex. TSLA) fid_hour_cls_code (str): 시간구분코드 - "0":정규장 "1":시간외 fid_pw_data_incu_yn (str): 과거데이터포함여부 - "Y":포함 "N":미포함 Returns: dict: - rt_cd: 응답코드 - msg_cd: 응답메시지코드 - msg1: 응답메시지1 - output1: 응답상세1 (dict) - ovrs_nmix_prdy_vrss: 전일대비 - prdy_vrss_sign: 전일대비부호 - 1:상한 2:상승 3:보합 4:하한 5:하락 - hts_kor_isnm: HTS 한글 종목명 - prdy_ctrt: 전일 대비율 - ovrs_nmix_prdy_clpr: 전일종가 - stck_shrn_iscd: 단축 종목코드 - ovrs_prod_oprc: 시가 - ovrs_prod_hgpr: 최고가 - ovrs_prod_lwpr: 최저가 - output2: 응답상세2 (list) - stck_bsop_date: 영업일자 - stck_cntg_hour: 거래시간 - optn_prpr: 현재가 - optn_oprc: 시가 - optn_hgpr: 최고가 - optn_lwpr: 최저가 - cntg_vol: 거래량 ''' assert fid_cond_mrkt_div_code in ['N', 'X', 'KX'] assert fid_hour_cls_code in ['0', '1'] assert fid_pw_data_incu_yn in ['Y', 'N'] path = '/uapi/overseas-price/v1/quotations/inquire-time-indexchartprice' tr_id = 'FHKST03030200' tr_cont = '' params = { 'FID_COND_MRKT_DIV_CODE': fid_cond_mrkt_div_code, 'FID_INPUT_ISCD': fid_input_iscd, 'FID_HOUR_CLS_CODE': fid_hour_cls_code, 'FID_PW_DATA_INCU_YN': fid_pw_data_incu_yn, } body, header = self._tr_request(path, tr_id, tr_cont, params) if body['rt_cd'] != '0': raise ValueError(f"Error: ({body['msg_cd']}) {body['msg1']}") output1 = body['output1'] output1 = { 'ovrs_nmix_prdy_vrss': Decimal(output1['ovrs_nmix_prdy_vrss']), 'prdy_vrss_sign': int(output1['prdy_vrss_sign']), 'hts_kor_isnm': output1['hts_kor_isnm'], 'prdy_ctrt': Decimal(output1['prdy_ctrt']), 'ovrs_nmix_prdy_clpr': Decimal(output1['ovrs_nmix_prdy_clpr']), 'acml_vol': int(output1['acml_vol']), 'ovrs_nmix_prpr': Decimal(output1['ovrs_nmix_prpr']), 'stck_shrn_iscd': output1['stck_shrn_iscd'], 'ovrs_prod_oprc': Decimal(output1['ovrs_prod_oprc']), 'ovrs_prod_hgpr': Decimal(output1['ovrs_prod_hgpr']), 'ovrs_prod_lwpr': Decimal(output1['ovrs_prod_lwpr']), } output2 = [] for el in body['output2']: output2.append({ 'stck_bsop_date': dtm.datetime.strptime(el['stck_bsop_date'], '%Y%m%d').date(), 'stck_cntg_hour': dtm.datetime.strptime(el['stck_cntg_hour'], '%H%M%S').time(), 'optn_prpr': Decimal(el['optn_prpr']), 'optn_oprc': Decimal(el['optn_oprc']), 'optn_hgpr': Decimal(el['optn_hgpr']), 'optn_lwpr': Decimal(el['optn_lwpr']), 'cntg_vol': int(el['cntg_vol']), }) result = { 'tr_id': header['tr_id'], 'tr_cont': header['tr_cont'], 'rt_cd': body['rt_cd'], 'msg_cd': body['msg_cd'], 'msg1': body['msg1'], 'output1': output1, 'output2': output2 } return result
[docs] def order(self, cano: str, actn_prdt_cd: str, ovrs_excg_cd: str, pdno: str, ord_qty: int, ovrs_ord_unpr: Decimal, sll_type: str, ord_dvsn: str, ctac_tlno: str = None, mgco_aptm_odno: str = None): ''' (해외주식주문) 해외주식 주문[v1_해외주식-001] 해외주식 주문 API입니다. | * 모의투자의 경우, 모든 해외 종목 매매가 지원되지 않습니다. 일부 종목만 매매 가능한 점 유의 부탁드립니다. | | * 해외주식 서비스 신청 후 이용 가능합니다. (아래 링크 3번 해외증권 거래신청 참고) | https://securities.koreainvestment.com/main/bond/research/_static/TF03ca010001.jsp | | * 해외 거래소 운영시간 외 API 호출 시 애러가 발생하오니 운영시간을 확인해주세요. | * 해외 거래소 운영시간(한국시간 기준) | 1) 미국 : 23:30 ~ 06:00 (썸머타임 적용 시 22:30 ~ 05:00) | 2) 일본 : (오전) 09:00 ~ 11:30, (오후) 12:30 ~ 15:00 | 3) 상해 : 10:30 ~ 16:00 | 4) 홍콩 : (오전) 10:30 ~ 13:00, (오후) 14:00 ~ 17:00 | | ※ POST API의 경우 BODY값의 key값들을 대문자로 작성하셔야 합니다. | (EX. "CANO" : "12345678", "ACNT_PRDT_CD": "01",...) | | ※ 종목코드 마스터파일 파이썬 정제코드는 한국투자증권 Github 참고 부탁드립니다. | https://github.com/koreainvestment/open-trading-api/tree/main/stocks_info Args: cano (str): 계좌번호 actn_prdt_cd (str): 계좌상품코드 ovrs_excg_cd (str): 해외거래소코드 pdno (str): 상품번호 ord_qty (int): 주문수량 ovrs_ord_unpr (Decimal): 해외주식주문가격 ctac_tlno (str): 연락처 mgco_aptm_odno (str): 관리자처리주문번호 sll_type (str): 매매구분 - "00":매도 "":매수 ord_dvsn (str): 주문구분 | [Header tr_id TTTT1002U(미국 매수 주문)] | 00 : 지정가 | 32 : LOO(장개시지정가) | 34 : LOC(장마감지정가) | * 모의투자 VTTT1002U(미국 매수 주문)로는 00:지정가만 가능 | | [Header tr_id TTTT1006U(미국 매도 주문)] | 00 : 지정가 | 31 : MOO(장개시시장가) | 32 : LOO(장개시지정가) | 33 : MOC(장마감시장가) | 34 : LOC(장마감지정가) | * 모의투자 VTTT1006U(미국 매도 주문)로는 00:지정가만 가능 | | [Header tr_id TTTS1001U(홍콩 매도 주문)] | 00 : 지정가 | 50 : 단주지정가 | * 모의투자 VTTS1001U(홍콩 매도 주문)로는 00:지정가만 가능 | | [그외 tr_id] | 제거 Returns: dict: - rt_cd: 응답코드 - msg_cd: 응답메시지코드 - msg1: 응답메시지1 - output: 응답상세 (dict) - krx_fwdg_ord_orgno: 한국거래소전송주문조직번호 - odno: 주문번호 - ord_tmd: 주문시각 ''' assert ovrs_excg_cd in ['NASD', 'NYSE', 'AMEX', 'SEHK', 'SHAA', 'SZAA', 'HASE', 'VNSE', 'TKSE'] def __infer_tr_id(): pair = ('매수', '매도') paper_trading_pair = ('매수', '매도') if ovrs_excg_cd in ['NASD', 'NYSE', 'AMEX']: # 미국 pair = ('TTTT1002U', 'TTTT1006U') paper_trading_pair = ('VTTT1002U', 'VTTT1001U') elif ovrs_excg_cd == 'TKSE': # 일본 pair = ('TTTS0308U', 'TTTS0307U') paper_trading_pair = ('VTTS0308U', 'VTTS0307U') elif ovrs_excg_cd == 'SEHK': # 홍콩 pair = ('TTTS1002U', 'TTTS1001U') paper_trading_pair = ('VTTS1002U', 'VTTS1001U') elif ovrs_excg_cd == 'SHAA': # 상해 pair = ('TTTS0202U', 'TTTS1005U') paper_trading_pair = ('VTTS0202U', 'VTTS1005U') elif ovrs_excg_cd == 'SZAA': # 심천 pair = ('TTTS0305U', 'TTTS0304U') paper_trading_pair = ('VTTS0305U', 'VTTS0304U') elif ovrs_excg_cd in ['HASE', 'VNSE']: # 베트남 pair = ('TTTS0311U', 'TTTS0310U') paper_trading_pair = ('VTTS0311U', 'VTTS0310U') idx = 1 if sll_type == '00' else 0 if self.auth.paper_trading: return paper_trading_pair[idx] else: return pair[idx] path = '/uapi/overseas-stock/v1/trading/order' tr_id = __infer_tr_id() tr_cont = '' body = { 'CANO': cano, 'ACNT_PRDT_CD': actn_prdt_cd, 'OVRS_EXCG_CD': ovrs_excg_cd, 'PDNO': pdno, 'ORD_QTY': str(ord_qty), 'OVRS_ORD_UNPR': str(ovrs_ord_unpr), 'ORD_SVR_DVSN_CD': '0', } body['CTAC_TLNO'] = ctac_tlno or '' body['MGCO_APTM_ODNO'] = mgco_aptm_odno or '' if sll_type == '00': body['SLL_TYPE'] = sll_type if ord_dvsn: body['ORD_DVSN'] = ord_dvsn body, _ = self._tr_request(path, tr_id, tr_cont, body=body, method='POST') if body['rt_cd'] != '0': raise ValueError(f"Error: ({body['msg_cd']}) {body['msg1']}") return { 'rt_cd': body['rt_cd'], 'msg_cd': body['msg_cd'], 'msg1': body['msg1'], 'output': body['output'], }
[docs] def order_rvsecncl(self, cano: str, acnt_prdt_cd: str, ovrs_excg_cd: str, pdno: str, orgn_odno: str, rvse_cncl_dvsn_cd: str, ord_qty: int, ovrs_ord_unpr: Decimal, mgco_aptm_odno: str = None): ''' (해외주식주문) 해외주식 정정취소주문[v1_해외주식-002] | 접수된 해외주식 주문을 정정하거나 취소하기 위한 API입니다. | (해외주식주문 시 Return 받은 ODNO를 참고하여 API를 호출하세요.) | * 해외주식 서비스 신청 후 이용 가능합니다. (아래 링크 3번 해외증권 거래신청 참고) | https://securities.koreainvestment.com/main/bond/research/_static/TF03ca010001.jsp | * 해외 거래소 운영시간 외 API 호출 시 애러가 발생하오니 운영시간을 확인해주세요. | * 해외 거래소 운영시간(한국시간 기준) | 1) 미국 : 23:30 ~ 06:00 (썸머타임 적용 시 22:30 ~ 05:00) | 2) 일본 : (오전) 09:00 ~ 11:30, (오후) 12:30 ~ 15:00 | 3) 상해 : 10:30 ~ 16:00 | 4) 홍콩 : (오전) 10:30 ~ 13:00, (오후) 14:00 ~ 17:00 Args: cano (str): 종합계좌번호 - 계좌번호 체계(8-2)의 앞 8자리 acnt_prdt_cd (str): 계좌상품코드 - 계좌번호 체계(8-2)의 뒤 2자리 ovrs_excg_cd (str): 해외거래소코드 | NASD : 나스닥 | NYSE : 뉴욕 | AMEX : 아멕스 | SEHK : 홍콩 | SHAA : 중국상해 | SZAA : 중국심천 | TKSE : 일본 | HASE : 베트남 하노이 | VNSE : 베트남 호치민 pdno (str): 상품번호 orgn_odno (str): 원주문번호 - 정정 또는 취소할 원주문번호 (해외주식_주문 API ouput ODNO or 해외주식 미체결내역 API output ODNO 참고) rvse_cncl_dvsn_cd (str): 정정취소구분코드 - 01:정정 02:취소 ord_qty (str): 주문수량 ovrs_ord_unpr (str): 해외주문단가 - 취소주문 시, "0" 입력 mgco_aptm_odno (str): 운용사지정주문번호 Returns: dict: - rt_cd: 응답코드 - msg_cd: 응답메시지코드 - msg1: 응답메시지1 - output: 응답상세 - KRX_FWDG_ORD_ORGNO: 한국거래소전송주문조직번호 - 주문시 한국투자증권 시스템에서 지정된 영업점코드 - ODNO: 주문번호 - 주문시 한국투자증권 시스템에서 채번된 주문번호 - ORD_TMD: 주문시각 - 주문시각(시분초HHMMSS) ''' assert ovrs_excg_cd in ['NASD', 'NYSE', 'AMEX', 'SEHK', 'SHAA', 'SZAA', 'HASE', 'VNSE', 'TKSE'] def __infer_tr_id(): if ovrs_excg_cd in ['NASD', 'NYSE', 'AMEX']: # 미국 live = 'TTTT1004U' paper = 'VTTT1004U' elif ovrs_excg_cd == 'TKSE': # 일본 live = 'TTTS0309U' paper = 'VTTS0309U' elif ovrs_excg_cd == 'SEHK': # 홍콩 live = 'TTTS1003U' paper = 'VTTS1003U' elif ovrs_excg_cd == 'SHAA': # 상해 live = 'TTTS0302U' paper = 'VTTS0302U' elif ovrs_excg_cd == 'SZAA': # 심천 live = 'TTTS0306U' paper = 'VTTS0306U' elif ovrs_excg_cd in ['HASE', 'VNSE']: # 베트남 live = 'TTTS0312U' paper = 'VTTS0312U' if self.auth.paper_trading: return paper else: return live path = '/uapi/overseas-stock/v1/trading/order-rvsecncl' tr_id = __infer_tr_id() tr_cont = '' req_body = { 'CANO': cano, 'ACNT_PRDT_CD': acnt_prdt_cd, 'OVRS_EXCG_CD': ovrs_excg_cd, 'PDNO': pdno, 'ORGN_ODNO': orgn_odno, 'RVSE_CNCL_DVSN_CD': rvse_cncl_dvsn_cd, 'ORD_QTY': str(ord_qty), 'OVRS_ORD_UNPR': str(ovrs_ord_unpr), 'ORD_SVR_DVSN_CD': '0', } if mgco_aptm_odno: req_body['MGCO_APTM_ODNO'] = mgco_aptm_odno body, _ = self._tr_request(path, tr_id, tr_cont, body=req_body, method='POST') if body['rt_cd'] != '0': raise ValueError(f"Error: ({body['msg_cd']}) {body['msg1']}") result = { 'rt_cd': body['rt_cd'], 'msg_cd': body['msg_cd'], 'msg1': body['msg1'], 'output': body['output'], } return result
[docs] def inquire_nccs(self, cano: str, acnt_prdt_cd: str, ovrs_excg_cd: str, sort_sqn: str = "", ctx_area_fk200: str = "", ctx_area_nk200: str = ""): """ (해외주식주문) 해외주식 미체결내역[v1_해외주식-005] 접수된 해외주식 주문 중 체결되지 않은 미체결 내역을 조회하는 API입니다. | * 해외주식 서비스 신청 후 이용 가능합니다. (아래 링크 3번 해외증권 거래신청 참고) | https://securities.koreainvestment.com/main/bond/research/_static/TF03ca010001.jsp | ※ 해외 거래소 운영시간(한국시간 기준) | 1) 미국 : 23:30 ~ 06:00 (썸머타임 적용 시 22:30 ~ 05:00) | 2) 일본 : (오전) 09:00 ~ 11:30, (오후) 12:30 ~ 15:00 | 3) 상해 : 10:30 ~ 16:00 | 4) 홍콩 : (오전) 10:30 ~ 13:00, (오후) 14:00 ~ 17:00 Args: cano (str): 계좌번호 acnt_prdt_cd (str): 계좌상품코드 ovsrs_excg_cd (str): 해외거래소코드 sort_sqn (str): 정렬순서 - "DS": 정순, 그외: 역순 ctx_area_fk200 (str): 연속조회검색조건200 - 초기조회 시 공백, 다음페이지 조회시 이전 조회 결과의 CTX_AREA_FK200값 ctx_area_nk200 (str): 연속조회키200 - 초기조회 시 공백, 다음페이지 조회시 이전 조회 결과의 CTX_AREA_NK200값 Returns: dict: - rt_cd: 응답코드 - msg_cd: 응답메시지코드 - msg1: 응답메시지1 - ctx_area_fk200: 연속조회검색조건200 - ctx_area_nk200: 연속조회키200 - output: 응답상세 (list) - ord_dt: 주문일자 - ord_gno_brno: 주문채번지점번호 - odno: 주문번호 - orgn_odno: 원주문번호 - pdno: 상품번호 - prdt_name: 상품명 - sll_buy_dvsn_cd: 매도매수구분코드 - 01:매도 02:매수 - sll_buy_dvsn_cd_name: 매도매수구분코드명 - rvse_cncl_dvsn_cd: 정정취소구분코드 - 01:정정 02:취소 - rvse_cncl_dvsn_cd_name: 정정취소구분명 - rjct_rson: 거부사유 - rjct_rson_name: 거부사유명 - ord_tmd: 주문시각 - tr_mket_name: 거래시장명 - tr_crcy_cd: 통화코드 - USD:미국달러 HKD:홍콩달러 JPY:일본엔 CNY:중국위안 VND:베트남동 - natn_cd: 국가코드 - natn_kor_name: 국가한글명 - ft_ord_qty: FT주문수량 - ft_ccld_qty: FT체결수량 - nccs_qty: 미체결수량 - ft_ord_unpr3: FT주문단가3 - ft_ccld_unpr3 FT체결단가3 - gt_ccld_amt3: FT체결금액3 - ovrs_excg_cd: 해외거래소코드 - prcs_stat_name: 처리상태명 - loan_type_cd: 대출유형코드 - loan_dt: 대출일자 - usa_amk_exts_rqst_yn: 미국애프터마켓연장신청여부 Y/N Raises: ValueError: API 호출 실패시 발생 """ path = "/uapi/overseas-stock/v1/trading/inquire-nccs" tr_id = "VTTS3018R" if self.auth.paper_trading else "TTTS3018R" tr_cont = "" params = {"CANO": cano, "ACNT_PRDT_CD": acnt_prdt_cd, "OVRS_EXCG_CD": ovrs_excg_cd, "SORT_SQN": sort_sqn, "CTX_AREA_FK200": ctx_area_fk200, "CTX_AREA_NK200": ctx_area_nk200} body, _ = self._tr_request(path, tr_id, tr_cont, params) if body["rt_cd"] != "0": raise ValueError(f"Error: ({body['msg_cd']}) {body['msg1']}") output = [] for el in body["output"]: copied = el.copy() for k in ["ft_ord_qty", "ft_ccld_qty", "nccs_qty"]: if copied.get(k) is not None: copied[k] = int(copied[k]) output.append(copied) result = { "rt_cd": body["rt_cd"], "msg_cd": body["msg_cd"], "msg1": body["msg1"], "ctx_area_fk200": body["ctx_area_fk200"], "ctx_area_nk200": body["ctx_area_nk200"], "output": output, } return result
[docs] def order_resv( self, cano: str, acnt_prdt_cd: str, pdno: str, ovrs_excg_cd: str, ft_ord_qty: int, ft_ord_unpr3: Decimal, sll_buy_dvsn_cd: str, rvse_cncl_dvsn_cd: Optional[str] = None, prdt_type_cd: Optional[str] = None, rsvn_ord_rcit_dt: Optional[str] = None, ord_dvsn: Optional[str] = None, ovrs_rsvn_odno: Optional[str] = None, ): """ 해외주식 예약주문접수[v1_해외주식-002] 해외주식 예약 주문을 접수하는 함수입니다. 미국, 중국, 홍콩, 일본, 베트남 시장의 주식을 예약 매매할 수 있습니다. 미국 거래소 운영 시간 외에 예약 주문을 하거나, 기타 해외 거래소에 대해 지정가 주문을 할 수 있습니다. 미국 예약 매도 주문의 경우 MOO(장 개시 시장가) 주문도 가능합니다. Args: cano (str): 종합계좌번호 (8자리). acnt_prdt_cd (str): 계좌상품코드 (2자리). pdno (str): 상품번호 ovrs_excg_cd (str): 해외 거래소 코드 (예: NASD: 나스닥, NYSE: 뉴욕). ft_ord_qty (str): 주문 수량. ft_ord_unpr3 (str): 주문 단가. sll_buy_dvsn_cd (str): 매도/매수 구분 코드. (01: 매도, 02: 매수) rvse_cncl_dvsn_cd (str, optional): 정정/취소 구분 코드. (00: 매도/매수 주문 시 필수, 02: 취소) prdt_type_cd (str, optional): 상품유형코드 (일본/홍콩/중국/베트남 인 경우만 사용) rsvn_ord_rcit_dt (str, optional): 예약 주문 접수 일자. (일본/홍콩/중국/베트남 인 경우만 사용) ord_dvsn (str, optional): 주문 구분 (미국 예약 매도 주문 시 사용, 00: 지정가, 31: MOO(시장가)). ovrs_rsvn_odno (str, optional): 해외 예약 주문 번호 (취소 시 사용). Returns: dict: 주문 접수에 대한 응답 정보. - rt_cd (str): 성공 여부 (0: 성공, 0 이외의 값: 실패). - msg_cd (str): 응답 코드. - msg1 (str): 응답 메시지. - output (dict): 응답 상세. - ODNO (str): 한국 거래소 전송 주문 조직 번호 (미국 예약 주문 시 출력). - RSVN_ORD_RCIT_DT (str): 예약 주문 접수 일자 (중국/홍콩/일본/베트남 예약 주문 시 출력). - OVRS_RSVN_ODNO (str): 해외 예약 주문 번호 (중국/홍콩/일본/베트남 예약 주문 시 출력). Raises: ValueError: 필수 인자가 없거나 잘못된 경우 발생. """ assert ovrs_excg_cd in ["NASD", "NYSE", "AMEX", "SEHK", "SHAA", "SZAA", "HASE", "VNSE", "TKSE"] def __infer_tr_id(): pair = ("매수", "매도") paper_trading_pair = ("매수", "매도") if ovrs_excg_cd in ["NASD", "NYSE", "AMEX"]: # 미국 pair = ("TTTT3014U", "TTTT3016U") paper_trading_pair = ("VTTT3014U", "VTTT3016U") else: pair = ("TTTS3013U", "TTTS3013U") paper_trading_pair = ("VTTS3013U", "VTTS3013U") idx = 1 if sll_buy_dvsn_cd == "01" else 0 if self.auth.paper_trading: return paper_trading_pair[idx] else: return pair[idx] path = "/uapi/overseas-stock/v1/trading/order-resv" tr_id = __infer_tr_id() tr_cont = "" body = { "CANO": cano, "ACNT_PRDT_CD": acnt_prdt_cd, "OVRS_EXCG_CD": ovrs_excg_cd, "PDNO": pdno, "FT_ORD_QTY": str(ft_ord_qty), "FT_ORD_UNPR3": str(ft_ord_unpr3), "ORD_SVR_DVSN_CD": "0", } if ovrs_excg_cd not in ["NASD", "NYSE", "AMEX"]: body["SLL_BUY_DVSN_CD"] = sll_buy_dvsn_cd if rvse_cncl_dvsn_cd: body["RVSE_CNCL_DVSN_CD"] = rvse_cncl_dvsn_cd if prdt_type_cd: body["PRDT_TYPE_CD"] = prdt_type_cd if rsvn_ord_rcit_dt: body["RSVN_ORD_RCIT_DT"] = rsvn_ord_rcit_dt if ord_dvsn: body["ORD_DVSN"] = ord_dvsn if ovrs_rsvn_odno: body["OVRS_RSVN_ODNO"] = ovrs_rsvn_odno body, _ = self._tr_request(path, tr_id, tr_cont, body=body, method="POST") if body["rt_cd"] != "0": raise ValueError(f"Error: ({body['msg_cd']}) {body['msg1']}") return { "rt_cd": body["rt_cd"], "msg_cd": body["msg_cd"], "msg1": body["msg1"], "output": body["output"], }
[docs] def order_resv_ccnl( self, cano: str, acnt_prdt_cd: str, rsyn_ord_rcit_dt: dtm.date, ovrs_rsnv_odno: str, ): """ 해외주식 예약주문접수취소[v1_해외주식-004] 해외주식 예약 주문을 취소하는 함수입니다. 미국 주식 예약 주문을 취소할 때 사용됩니다. (예약 주문 접수 시 반환된 ODNO를 사용하여 주문을 취소합니다.) Args: cano (str): 종합계좌번호 (8자리). acnt_prdt_cd (str): 계좌상품코드 (2자리). rsyn_ord_rctt_dt (str): 해외 주문 접수 일자 (YYYYMMDD 형식). ovrs_rsvn_odno (str): 해외 예약 주문 번호 (예약 주문 접수 시 반환된 ODNO). Returns: dict: 주문 취소에 대한 응답 정보. - rt_cd (str): 성공 여부 (0: 성공, 0 이외의 값: 실패). - msg_cd (str): 응답 코드. - msg1 (str): 응답 메시지. - output (dict): 응답 상세. - OVRS_RSVN_ODNO (str): 해외 예약 주문 번호. Raises: ValueError: 필수 인자가 없거나 잘못된 경우 발생. """ path = "/uapi/overseas-stock/v1/trading/order-resv-ccnl" tr_id = "TTTT3017U" if not self.auth.paper_trading else "VTTT3017U" tr_cont = "" body = { "CANO": cano, "ACNT_PRDT_CD": acnt_prdt_cd, "RSVN_ORD_RCIT_DT": rsyn_ord_rcit_dt.strftime("%Y%m%d"), "OVRS_RSVN_ODNO": ovrs_rsnv_odno, } body, _ = self._tr_request(path, tr_id, tr_cont, body=body, method="POST") if body["rt_cd"] != "0": raise ValueError(f"Error: ({body['msg_cd']}) {body['msg1']}") return { "rt_cd": body["rt_cd"], "msg_cd": body["msg_cd"], "msg1": body["msg1"], "output": body["output"], }
def order_resv_list( self, cano: str, acnt_prdt_cd: str, inqr_strt_dt: dtm.date, inqr_end_dt: dtm.date, inqr_dvsn_cd: str = "00", prdt_type_cd: str = "", ovrs_excg_cd: str = "", ctx_area_fk200: str = "", ctx_area_nk200: str = "", ) -> List: """ 해외주식 예약 주문을 조회하는 함수입니다. 특정 기간 동안의 예약 주문 내역을 조회할 수 있습니다. Args: cano (str): 종합계좌번호 (8자리). acnt_prdt_cd (str): 계좌상품코드 (2자리). inqr_strt_dt (str): 조회 시작 일자 (YYYYMMDD 형식). inqr_end_dt (str): 조회 종료 일자 (YYYYMMDD 형식). inqr_dvsn_cd (str): 조회 구분 코드 (00: 전체, 01: 일반 해외주식, 02: 미니스탁). prdt_type_cd (str): 상품 유형 코드 (조회할 거래소에 따라 다름, 공백 시 전체 조회). ovrs_excg_cd (str): 해외 거래소 코드 (예: NASD: 나스닥, NYSE: 뉴욕, AMEX: 아멕스). ctx_area_fk200 (str): 연속 조회 검색 조건 (최초 조회 시 공란). ctx_area_nk200 (str): 연속 조회 키 (최초 조회 시 공란). Returns: dict: 조회된 예약 주문 내역. - rt_cd (str): 성공 여부 (0: 성공, 0 이외의 값: 실패). - msg_cd (str): 응답 코드. - msg1 (str): 응답 메시지. - ctx_area_fk200 (str): 연속 조회 검색 조건. - ctx_area_nk200 (str): 연속 조회 키. - output (list): 예약 주문 상세 내역. - cncl_yn (bool): 취소 여부. - rsvn_ord_rcit_dt (dtm.date): 예약 주문 접수 일자. - ovrs_rsvn_odno (str): 해외 예약 주문 번호. - ord_dt (dtm.date): 주문 일자. - sll_buy_dvsn_cd (str): 매도/매수 구분 코드. - sll_buy_dvsn_name (str): 매도/매수 구분 명칭. - ovrs_rsvn_ord_stat_cd (str): 해외 예약 주문 상태 코드. - ovrs_rsvn_ord_stat_cd_name (str): 해외 예약 주문 상태 명칭. - pdno (str): 상품 번호. - prdt_name (str): 상품 명. - ft_ord_qty (int): 주문 수량. - ft_ord_unpr3 (Decimal): 주문 단가. - ft_ccld_qty (int): 체결 수량. - ft_ccld_unpr3 (Decimal): 체결 단가. - nprc_rson_text (str): 미처리 사유 내용. Raises: ValueError: 필수 인자가 없거나 잘못된 경우 발생. """ path = "/uapi/overseas-stock/v1/trading/order-resv-list" tr_id = "TTTT3039R" # 미국 tr_cont = "" 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"), "INQR_DVSN_CD": inqr_dvsn_cd, "PRDT_TYPE_CD": prdt_type_cd, "OVRS_EXCG_CD": ovrs_excg_cd, "CTX_AREA_FK200": ctx_area_fk200, "CTX_AREA_NK200": ctx_area_nk200, } body, _ = self._tr_request(path, tr_id, tr_cont, params=params, method="GET") if body["rt_cd"] != "0": raise ValueError(f"Error: ({body['msg_cd']}) {body['msg1']}") output = [] for d in body["output"]: copied = d.copy() for k in copied.keys(): if k in ["ft_ord_qty", "ft_ccld_qty"]: if copied.get(k) is not None: copied[k] = int(copied[k]) if k in ["ft_ord_unpr3", "ft_ccld_unpr3"]: if copied.get(k) is not None: copied[k] = Decimal(copied[k]) if k in ["cncl_yn"]: copied[k] = copied[k] == "Y" if k in ["rsvn_ord_rcit_dt", "ord_dt"]: if copied.get(k) is not None and len(copied[k]) > 0: copied[k] = dtm.datetime.strptime(copied[k], "%Y%m%d").date() output.append(copied) return { "rt_cd": body["rt_cd"], "msg_cd": body["msg_cd"], "msg1": body["msg1"], "output": output, }
[docs] def inquire_balance(self, cano: str, acnt_prdt_cd: str, ovrs_excg_cd: str, tr_crcy_cd: str, ctx_area_fk200: str = "", ctx_area_nk200: str = ""): ''' (해외주식주문) 해외주식 잔고조회[v1_해외주식-006] | 해외주식 잔고를 조회하는 API 입니다. | 실전계좌의 경우, 한 번의 호출에 최대 100건까지 확인 가능하며, 이후의 값은 연속조회를 통해 확인하실 수 있습니다. | | * 해외주식 서비스 신청 후 이용 가능합니다. (아래 링크 3번 해외증권 거래신청 참고) | https://securities.koreainvestment.com/main/bond/research/_static/TF03ca010001.jsp | | * 미니스탁 잔고는 해당 API로 확인이 불가합니다. Args: cano (str): 계좌번호 acnt_prdt_cd (str): 계좌상품코드 ovrs_excg_cd (str): 해외거래소코드 tr_crcy_cd (str): 통화코드 ctx_area_fk200 (str): 연속조회검색조건200 - 초기조회 시 공백, 다음페이지 조회시 이전 조회 결과의 CTX_AREA_FK200값 ctx_area_nk200 (str): 연속조회키200 - 초기조회 시 공백, 다음페이지 조회시 이전 조회 결과의 CTX_AREA_NK200값 Returns: dict: - rt_cd: 응답코드 - msg_cd: 응답메시지코드 - msg1: 응답메시지1 - ctx_area_fk200: 연속조회검색조건200 - ctx_area_nk200: 연속조회키200 - output1: 응답상세1 (list) - cano: 계좌번호 - acnt_prdt_cd: 계좌상품코드 - prdt_type_cd: 상품유형코드 - ovrs_pdno: 해외상품번호 - ovrs_item_name: 해외종목명 - frcr_evlu_pfls_amt: 외화평가손익금액 - evlu_pfls_rt: 평가손익율 - pchs_avg_pric: 매입평균가격 - ovrs_cblc_qty: 해외잔고수량 - ord_psbl_qty: 주문가능수량 - frcr_pchs_amt1: 외화매입금액1 - ovrs_stck_evlu_amt: 해외주식평가금액 - now_pric2: 현재가격2 - tr_crcy_cd: 거래통화코드 - HKD:홍콩달러 CNY:중국위안화 JPY:일본엔화 VND:베트남동 - ovrs_excg_cd: 해외거래소코드 - NASD:나스닥 NYSE:뉴욕 AMEX:아멕스 SEHK:홍콩 SHAA:중국상해 SZAA:중국심천 TKSE:일본 HASE:하노이거래소 VNSE:호치민거래소 - loan_type_cd: 대출유형코드 - 00:해당사항없음 01:자기융자일반형 03:자기융자투자형 05:유통융자일반형 06:유통융자투자형 07:자기대주 09:유통대주 11:주식담보대출 12:수익증권담보대출 13:ELS담보대출 14:채권담보대출 15:해외주식담보대출 16:기업신용공여 31:소액자동담보대출 41:매도담보대출 42:환매자금대출 43:매입환매자금대출 44:대여매도담보대출 81:대차거래 82:법인CMA론 91:공모주청약자금대출 92:매입자금 93:미수론서비스 94:대여 - loan_dt: 대출일자 - expd_dt: 만기일자 - output2: 응답상세2 - frcr_pchs_amt1: 외화매입금액1 - ovrs_rlzt_pfls_amt: 해외실현손익금액 - ovrs_tot_pfls: 해외총손익 - rlzt_erng_rt: 실현수익율 - tot_evlu_pfls_amt: 총평가손익금액 - tot_pftrt: 총수익률 - frcr_buy_amt_smtl1: 외화매수금액합계1 - ovrs_rlzt_pfls_amt2: 해외실현손익금액2 - frcr_buy_amt_smtl2: 외화매수금액합계2 Raises: ValueError: API 호출 실패시 발생 ''' path = '/uapi/overseas-stock/v1/trading/inquire-balance' tr_id = 'VTTS3012R' if self.auth.paper_trading else 'TTTS3012R' tr_cont = '' params = { 'CANO': cano, 'ACNT_PRDT_CD': acnt_prdt_cd, 'OVRS_EXCG_CD': ovrs_excg_cd, 'TR_CRCY_CD': tr_crcy_cd, 'CTX_AREA_FK200': ctx_area_fk200, 'CTX_AREA_NK200': ctx_area_nk200, } body, _ = self._tr_request(path, tr_id, tr_cont, params) if body['rt_cd'] != '0': raise ValueError(f"Error: ({body['msg_cd']}) {body['msg1']}") output1 = [] for el in body['output1']: copied = el.copy() for k in ['frcr_evlu_pfls_amt', 'evlu_pfls_rt', 'pchs_avg_pric', 'frcr_pchs_amt1', 'ovrs_stck_evlu_amt', 'now_pric2']: if copied.get(k) is not None and len(copied[k]) > 0: copied[k] = Decimal(copied[k]) for k in ['ovrs_cblc_qty', 'ord_psbl_qty']: if copied.get(k) is not None and len(copied[k]) > 0: copied[k] = int(copied[k]) for k in ['loan_dt', 'expd_dt']: if copied.get(k) is not None and len(copied[k]) > 0: copied[k] = dtm.datetime.strptime(copied[k], '%Y%m%d').date() output1.append(copied) output2 = body['output2'].copy() for k in output2.keys(): if output2.get(k) is not None and len(output2[k]): output2[k] = Decimal(output2[k]) result = { 'rt_cd': body['rt_cd'], 'msg_cd': body['msg_cd'], 'msg1': body['msg1'], 'output1': output1, 'output2': output2, 'ctx_area_fk200': body['ctx_area_fk200'], 'ctx_area_nk200': body['ctx_area_nk200'], } return result
[docs] def inquire_ccnl(self, cano: str, acnt_prdt_cd: str, ord_strt_dt: dtm.date, ord_end_dt: dtm.date, ovrs_excg_cd: str, pdno: str = None, sll_buy_dvsn: str = "00", ccld_nccs_dvsn: str = "00", sort_sqn: str = "DS", ctx_area_fk200: str = "", ctx_area_nk200: str = ""): ''' (해외주식주문) 해외주식 주문체결내역[v1_해외주식-007] | 일정 기간의 해외주식 주문 체결 내역을 확인하는 API입니다. | 실전계좌의 경우, 한 번의 호출에 최대 20건까지 확인 가능하며, 이후의 값은 연속조회를 통해 확인하실 수 있습니다. | 모의계좌의 경우, 한 번의 호출에 최대 15건까지 확인 가능하며, 이후의 값은 연속조회를 통해 확인하실 수 있습니다. | * 해외주식 서비스 신청 후 이용 가능합니다. (아래 링크 3번 해외증권 거래신청 참고) | https://securities.koreainvestment.com/main/bond/research/_static/TF03ca010001.jsp | ※ 해외 거래소 운영시간(한국시간 기준) | 1) 미국 : 23:30 ~ 06:00 (썸머타임 적용 시 22:30 ~ 05:00) | 2) 일본 : (오전) 09:00 ~ 11:30, (오후) 12:30 ~ 15:00 | 3) 상해 : 10:30 ~ 16:00 | 4) 홍콩 : (오전) 10:30 ~ 13:00, (오후) 14:00 ~ 17:00 Args: cano (str): 계좌번호 acnt_prdt_cd (str): 계좌상품코드 ord_strt_dt (dtm.date): 조회시작일 ord_end_dt (dtm.date): 조회종료일 pdno (str): 상품번호. 전종목일경우 '%' 입력. 모의투자계좌의 경우 ""(전체조회)만 가능 sll_buy_dvsn (str): 매매구분 - "00":전체 "01":매도 "02":매수 ccld_nccs_dvsn (str): 체결미체결구분 - "00":전체 "01":체결 "02":미체결 ovrs_excg_cd (str): 해외거래소코드 sort_sqn (str): 정렬순서 - "DS": 정순, "AS": 역순 ctx_area_fk200 (str): 연속조회검색조건200 - 초기조회 시 공백, 다음페이지 조회시 이전 조회 결과의 CTX_AREA_FK200값 ctx_area_nk200 (str): 연속조회키200 - 초기조회 시 공백, 다음페이지 조회시 이전 조회 결과의 CTX_AREA_NK200값 Returns: dict: - rt_cd: 응답코드 - msg_cd: 응답메시지코드 - msg1: 응답메시지1 - ctx_area_fk200: 연속조회검색조건200 - ctx_area_nk200: 연속조회키200 - output: 응답상세 (list) - ord_dt: 주문일자 - ord_gno_brno: 주문채번지점번호 - odno: 주문번호 - ※ 정정취소주문 시, 해당 값 odno(주문번호) 넣어서 사용 - orgn_odno: 원주문번호 - sll_buy_dvsn_cd: 매도매수구분코드 - 01:매도 02:매수 - sll_buy_dvsn_cd_name: 매도매수구분코드명 - rvse_cncl_dvsn: 정정취소구분 - 01:정정 02:취소 - rvse_cncl_dvsn_name: 정정취소구분명 - pdno: 상품번호 - prdt_name: 상품명 - ft_ord_qty: FT주문수량 - ft_ord_unpr3: FT주문단가3 - ft_ccld_qty: FT체결수량 - ft_ccld_unpr3: FT체결단가3 - ft_ccld_amt3: FT체결금액3 - nccs_qty: 미체결수량 - prcs_stat_name: 처리상태명 - rjct_rson: 거부사유 - ord_tmd: 주문시각 - tr_mket_name: 거래시장명 - tr_natn: 거래국가 - tr_natn_name: 거래국가명 - ovrs_excg_cd: 해외거래소코드 - NASD:나스닥 NYSE:뉴욕 AMEX:아멕스 SEHK:홍콩 SHAA:중국상해 SZAA:중국심천 TKSE:일본 HASE:베트남 하노이 VNSE:베트남 호치민 - tr_crcy_cd: 거래통화코드 - dmst_ord_dt: 국내주문일자 - thco_ord_tmd: 당사주문시각 - loan_type_cd: 대출유형코드 - mdia_dvsn_name: 매체구분명 - loan_dt: 대출일자 - rjct_rson_name: 거부사유명 - usa_amk_exts_rqst_yn: 미국애프터마켓연장신청여부 Raise: ValueError: API 호출 실패시 발생 ''' assert sll_buy_dvsn in ['00', '01', '02'] assert ccld_nccs_dvsn in ['00', '01', '02'] assert sort_sqn in ['DS', 'AS'] if pdno is None: pdno = '' if self.auth.paper_trading else '%' path = '/uapi/overseas-stock/v1/trading/inquire-ccnl' tr_id = 'VTTS3035R' if self.auth.paper_trading else 'TTTS3035R' tr_cont = '' params = { 'CANO': cano, 'ACNT_PRDT_CD': acnt_prdt_cd, 'PDNO': pdno, 'ORD_STRT_DT': ord_strt_dt.strftime('%Y%m%d'), 'ORD_END_DT': ord_end_dt.strftime('%Y%m%d'), 'SLL_BUY_DVSN': sll_buy_dvsn, 'CCLD_NCCS_DVSN': ccld_nccs_dvsn, 'OVRS_EXCG_CD': ovrs_excg_cd, 'SORT_SQN': sort_sqn, 'ORD_DT': '', 'ORD_GNO_BRNO': '', 'ODNO': '', 'CTX_AREA_FK200': ctx_area_fk200, 'CTX_AREA_NK200': ctx_area_nk200, } res_body, _ = self._tr_request(path, tr_id, tr_cont, 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']: copied = el.copy() for k in ["ord_dt", "loan_dt", "dmst_ord_dt"]: if copied.get(k) is not None and len(copied[k]) > 0: copied[k] = dtm.datetime.strptime(copied[k], '%Y%m%d').date() for k in ['ft_ord_qty', 'ft_ccld_qty', 'nccs_qty']: if copied.get(k) is not None: copied[k] = int(copied[k]) for k in ['ft_ord_unpr3', 'ft_ccld_unpr3', 'ft_ccld_amt3']: if copied.get(k) is not None: copied[k] = Decimal(copied[k]) copied['ord_tmd'] = dtm.datetime.strptime(copied['ord_tmd'], '%H%M%S').time() output.append(copied) result = { 'rt_cd': res_body['rt_cd'], 'msg_cd': res_body['msg_cd'], 'msg1': res_body['msg1'], 'ctx_area_fk200': res_body['ctx_area_fk200'], 'ctx_area_nk200': res_body['ctx_area_nk200'], 'output': output, } return result
[docs] def inquire_psamount(self, cano: str, acnt_prdt_cd: str, ovrs_excg_cd: str, ovrs_ord_unpr: Decimal, item_cd: str): ''' (해외주식주문) 해외주식 매수가능금액조회[v1_해외주식-014] | 해외주식 매수가능금액조회 API입니다. | ※ 모의투자는 사용 불가합니다. | * 해외주식 서비스 신청 후 이용 가능합니다. (아래 링크 3번 해외증권 거래신청 참고) | https://securities.koreainvestment.com/main/bond/research/_static/TF03ca010001.jsp Args: cano (str): 계좌번호 acnt_prdt_cd (str): 계좌상품코드 ovrs_excg_cd (str): 해외거래소코드 - NASD:나스닥 NYSE:뉴욕 AMEX:아멕스 SEHK:홍콩 SHAA:중국상해 SZAA:중국심천 TKSE:일본 HASE:하노이거래소 VNSE:호치민거래소 ovrs_ord_unpr (Decimal): 해외주문단가 item_cd (str): 종목코드 Returns: dict: - rt_cd: 응답코드 - msg_cd: 응답메시지코드 - msg1: 응답메시지1 - output: 응답상세 (dict) - tr_crcy_cd: 거래통화코드 - ord_psbl_frcr_amt: 주문가능외화금액 - sll_ruse_psbl_amt: 매도재사용가능금액 - 가능금액 산정 시 사용 - ovrs_ord_psbl_amt: 해외주문가능금액 - 한국투자 앱 해외주식 주문화면내 "외화" 인경우 주문가능금액 - max_ord_psbl_qty: 최대주문가능수량 - 한국투자 앱 해외주식 주문화면내 "외화" 인경우 주문가능수량 - 매수 시 수량단위 절사해서 사용 - 예 : (100주단위) 545 주 -> 500 주 / (10주단위) 545 주 -> 540 주 - echm_af_ord_psbl_amt: 환전이후주문가능금액 - echm_af_ord_psbl_qty: 환전이후주문가능수량 - ord_psbl_qty: 주문가능수량 - exrt: 환율 - frcr_ord_psbl_amt1: 외화주문가능금액1 - 한국투자 앱 해외주식 주문화면내 "통합" 인경우 주문가능금액 - ovrs_max_ord_psbl_qty: 해외최대주문가능수량 - 한국투자 앱 해외주식 주문화면내 "통합" 인경우 주문가능수량. 매수 시 수량단위 절사해서 사용. 예: (100주단위) 545주 -> 500주 / (10주단위) 545주 -> 540주 Raises: ValueError: API 호출 실패시 발생 ''' assert self.auth.paper_trading is False, "모의투자에서는 사용할 수 없는 API입니다." url_path = '/uapi/overseas-stock/v1/trading/inquire-psamount' tr_id = 'TTTS3007R' tr_cont = '' params = { 'CANO': cano, 'ACNT_PRDT_CD': acnt_prdt_cd, 'OVRS_EXCG_CD': ovrs_excg_cd, 'OVRS_ORD_UNPR': str(ovrs_ord_unpr), 'ITEM_CD': item_cd, } res_body, _ = self._tr_request(url_path, tr_id, tr_cont, params) if res_body['rt_cd'] != '0': raise ValueError(f"Error: ({res_body['msg_cd']}) {res_body['msg1']}") output = res_body['output'].copy() for k in ['ord_psbl_frcr_amt', 'sll_ruse_psbl_amt', 'ovrs_ord_psbl_amt', 'echm_af_ord_psbl_amt', 'exrt', 'frcr_ord_psbl_amt1']: if output.get(k) is not None and len(output.get(k)) > 0: output[k] = Decimal(output[k]) for k in ['max_ord_psbl_qty', 'echm_af_ord_psbl_qty', 'ord_psbl_qty', 'ovrs_max_ord_psbl_qty']: if output.get(k) is not None and len(output.get(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': res_body['output'], } return result
[docs] def inquire_period_profit(self, cano: str, acnt_prdt_cd: str, inqr_strt_dt: dtm.date, inqr_end_dt: dtm.date, wcrc_frcr_dvsn_cd: str, ovrs_excg_cd: str = "", crcy_cd: str = "", pdno: str = "", ctx_area_fk200: str = "", ctx_area_nk200: str = ""): ''' (해외주식주문) 해외주식 기간손익[v1_해외주식-032] 해외주식 기간손익 API입니다. | * 해외주식 서비스 신청 후 이용 가능합니다. (아래 링크 3번 해외증권 거래신청 참고) | https://securities.koreainvestment.com/main/bond/research/_static/TF03ca010001.jsp Args: cano (str): 계좌번호 acnt_prdt_cd (str): 계좌상품코드 inqr_strt_dt (dtm.date): 조회시작일 inqr_end_dt (dtm.date): 조회종료일 wcrc_frcr_dvsn_cd (str): 외화통화구분코드 - 01:원화 02:외화 ovrs_excg_cd (str): 해외거래소코드 - 공란:전체 NASD:미국 SEHK:홍콩 SHAA:중국 TKSE:일본 HASE:베트남 crcy_cd (str): 통화코드 - 공란:전체 USD:미국달러 HKD:홍콩달러 CNY:중국위안화 JPY:일본엔화 VND:베트남동 pdno (str): 상품번호 - 공란:전체 ctx_area_fk200 (str): 연속조회검색조건200 - 초기조회 시 공백, 다음페이지 조회시 이전 조회 결과의 CTX_AREA_FK200값 ctx_area_nk200 (str): 연속조회키200 - 초기조회 시 공백, 다음페이지 조회시 이전 조회 결과의 CTX_AREA_NK200값 Returns: dict: - rt_cd: 응답코드 - msg_cd: 응답메시지코드 - msg1: 응답메시지1 - ctx_area_fk200: 연속조회검색조건200 - ctx_area_nk200: 연속조회키200 - tr_cont: 연속조회가능여부 - output1: 응답상세1 (list) - trad_day: 매매일 - ovrs_pdno: 해외상품번호 - ovrs_item_name: 해외종목명 - slcl_qty: 매도청산수량 - pchs_avg_pric: 매입평균가격 - frcr_pchs_amt1: 외화매입금액1 - avg_sll_unpr: 평균매도단가 - frcr_sll_amt_smtl1: 외화매도금액합계1 - stck_sll_tlex: 주식매도제비용 - ovrs_rlzt_pfls_amt: 해외실현손익금액 - pftrt: 수익률 - exrt: 환율 - ovrs_excg_cd: 해외거래소코드 - frst_bltn_exrt: 최초고시환율 - output2: 응답상세 (dict) - stck_sll_amt_smtl: 주식매도금액합계 - WCRC_FRCR_DVSN_CD(원화외화구분코드)가 01(외화)이고 OVRS_EXCG_CD(해외거래소코드)가 공란(전체)인 경우 출력값 무시 - stck_buy_amt_smtl: 주식매수금액합계 - WCRC_FRCR_DVSN_CD(원화외화구분코드)가 01(외화)이고 OVRS_EXCG_CD(해외거래소코드)가 공란(전체)인 경우 출력값 무시 - smtl_fee1: 합계수수료1 - WCRC_FRCR_DVSN_CD(원화외화구분코드)가 01(외화)이고 OVRS_EXCG_CD(해외거래소코드)가 공란(전체)인 경우 출력값 무시 - excc_dfrm_amt: 정산지급금액 - WCRC_FRCR_DVSN_CD(원화외화구분코드)가 01(외화)이고 OVRS_EXCG_CD(해외거래소코드)가 공란(전체)인 경우 출력값 무시 - ovrs_rlzt_pfls_tot_amt: 해외실현손익총금액 - WCRC_FRCR_DVSN_CD(원화외화구분코드)가 01(외화)이고 OVRS_EXCG_CD(해외거래소코드)가 공란(전체)인 경우 출력값 무시 - tot_pftrt: 총수익률 - bass_dt: 기준일자 - exrt: 환율 Raises: ValueError - API 호출 실패시 발생 ''' assert self.auth.paper_trading is False, "모의투자에서는 사용할 수 없는 API입니다." assert wcrc_frcr_dvsn_cd in ["01", "02"], "원화외화구분코드는 01(원화) 또는 02(외화)만 가능합니다." url_path = "/uapi/overseas-stock/v1/trading/inquire-period-profit" tr_id = "TTTS3039R" tr_cont = "" params = { "CANO": cano, "ACNT_PRDT_CD": acnt_prdt_cd, "OVRS_EXCG_CD": ovrs_excg_cd, "CRCY_CD": crcy_cd, "PDNO": pdno, "INQR_STRT_DT": inqr_strt_dt.strftime("%Y%m%d"), "INQR_END_DT": inqr_end_dt.strftime("%Y%m%d"), "WCRC_FRCR_DVSN_CD": wcrc_frcr_dvsn_cd, "NATN_CD": "", "CTX_AREA_FK200": ctx_area_fk200, "CTX_AREA_NK200": ctx_area_nk200, } res_body, res_header = self._tr_request(url_path, tr_id, tr_cont, 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']: copied = el.copy() copied['trad_day'] = dtm.datetime.strptime(copied['trad_day'], '%Y%m%d').date() copied['slcl_qty'] = int(copied['slcl_qty']) for k in ['pchs_avg_pric', 'frcr_pchs_amt1', 'avg_sll_unpr', 'frcr_sll_amt_smtl1', 'stck_sll_tlex', 'ovrs_rlzt_pfls_amt', 'pftrt', 'exrt', 'frst_bltn_exrt']: if copied.get(k) is not None and len(copied[k]) > 0: copied[k] = Decimal(copied[k]) output1.append(copied) output2 = res_body['output2'].copy() for k in ['stck_sll_amt_smtl', 'stck_buy_amt_smtl', 'smtl_fee1', 'excc_dfrm_amt', 'ovrs_rlzt_pfls_tot_amt', 'tot_pftrt', 'exrt']: if output2.get(k) is not None and len(output2[k]) > 0: output2[k] = Decimal(output2[k]) if output2.get('base_dt') is not None and len(output2['base_dt']) > 0: output2['base_dt'] = dtm.datetime.strptime(output2['base_dt'], '%Y%m%d').date() result = { 'rt_cd': res_body['rt_cd'], 'msg_cd': res_body['msg_cd'], 'msg1': res_body['msg1'], 'tr_cont': res_header['tr_cont'], 'output1': output1, 'output2': output2, 'ctx_area_fk200': res_body.get('ctx_area_fk200', ''), 'ctx_area_nk200': res_body.get('ctx_area_nk200', ''), } return result
def get_foreign_margin( self, cano: str, acnt_prdt_cd: str, ) -> Dict: """(해외증거금 통화별조회) 해외증거금 통화별 조회 [해외주식-035] Args: cano (str): 종합계좌번호 (8자리) acnt_prdt_cd (str): 계좌상품코드 (2자리) Returns: dict: 해외증거금 통화별 조회 정보 - rt_cd: 성공/실패 여부 - msg_cd: 응답 코드 - msg1: 응답 메시지 - output: 응답 상세 (Object Array) - natn_name: 국가명 - crcy_cd: 통화코드 - frcr_dncl_amt1: 외화예수금액 - ustl_buy_amt: 미결제 매수금액 - ustl_sll_amt: 미결제 매도금액 - frcr_rcvb_amt: 외화미수금액 - frcr_mgn_amt: 외화증거금액 - frcr_gnrl_ord_psbl_amt: 외화 일반주문 가능금액 - frcr_ord_psbl_amt1: 외화 주문 가능금액 - itgr_ord_psbl_amt: 통합 주문 가능금액 - bass_exrt: 기준환율 Raises: ValueError: API 호출 실패 시 발생 """ url_path = "/uapi/overseas-stock/v1/trading/foreign-margin" tr_id = "TTTC2101R" tr_cont = "" params = { "CANO": cano, "ACNT_PRDT_CD": acnt_prdt_cd, } res_body, _ = self._tr_request(url_path, tr_id, tr_cont, params) if res_body["rt_cd"] != "0": raise ValueError(f"Error: ({res_body['msg_cd']}) {res_body['msg1']}") return { "rt_cd": res_body["rt_cd"], "msg_cd": res_body["msg_cd"], "msg1": res_body["msg1"], "output": res_body["output"], } def inquire_paymt_stdr_balance( self, cano: str, acnt_prdt_cd: str, bass_dt: dtm.date, wcrc_frcr_dvsn_cd: str, inqr_dvsn_cd: str, ) -> Dict: """(해외주식 결제기준잔고) 해외주식 결제기준잔고 조회 [해외주식-064] Args: cano (str): 종합계좌번호 (계좌번호 체계 8-2의 앞 8자리) acnt_prdt_cd (str): 계좌상품코드 (계좌번호 체계 8-2의 뒤 2자리) bass_dt (str): 기준일자 (YYYYMMDD 형식) wcrc_frcr_dvsn_cd (str): 원화/외화 구분 코드 (01: 원화기준, 02: 외화기준) inqr_dvsn_cd (str): 조회 구분 코드 (00: 전체, 01: 일반, 02: 미니스탁) Returns: dict: 해외주식 결제기준잔고 조회 정보 - rt_cd: 성공/실패 여부 - msg_cd: 응답 코드 - msg1: 응답 메시지 - output1: 응답 상세 (Object Array) - pdno: 상품번호 - prdt_name: 상품명 - cblc_qty13: 잔고수량 - ord_psbl_qty1: 주문가능수량 - avg_unpr3: 평균단가 - ovrs_now_pric1: 해외 현재가격 - frcr_pchs_amt: 외화 매입금액 - frcr_evlu_amt2: 외화 평가금액 - evlu_pfls_amt2: 평가 손익금액 - bass_exrt: 기준환율 - oprt_dtl_dtime: 조작 상세일시 - buy_crcy_cd: 매수 통화코드 - thdt_sll_ccld_qty1: 당일 매도 체결수량 - thdt_buy_ccld_qty1: 당일 매수 체결수량 - evlu_pfls_rt1: 평가손익율 - tr_mket_name: 거래시장명 - natn_kor_name: 국가 한글명 - std_pdno: 표준 상품번호 - mgge_qty: 담보수량 - loan_rmnd: 대출잔액 - prdt_type_cd: 상품유형코드 - ovrs_excg_cd: 해외거래소 코드 - scts_dvsn_name: 유가증권 구분명 - output2: 응답 상세 (Object Array) - crcy_cd: 통화코드 - crcy_cd_name: 통화코드명 - frcr_dncl_amt_2: 외화 예수금액 - frst_bltn_exrt: 최초 고시환율 - frcr_evlu_amt2: 외화 평가금액 - output3: 응답 상세 (Object) - pchs_amt_smtl_amt: 매입금액 합계 - tot_evlu_pfls_amt: 총 평가 손익금액 - evlu_erng_rt1: 평가 수익율 - tot_dncl_amt: 총 예수금액 - wcrc_evlu_amt_smtl: 원화 평가금액 합계 - tot_asst_amt2: 총 자산금액 - frcr_cblc_wcrc_evlu_amt_smtl: 외화 잔고 원화 평가금액 합계 - tot_loan_amt: 총 대출금액 Raises: ValueError: API 호출 실패 시 발생 """ assert wcrc_frcr_dvsn_cd in ["01", "02"], "원화외화구분코드는 01(원화) 또는 02(외화)만 가능합니다." assert inqr_dvsn_cd in ["00", "01", "02"], "조회구분코드는 00(전체), 01(일반), 02(미니스탁)만 가능합니다." url_path = "/uapi/overseas-stock/v1/trading/inquire-paymt-stdr-balance" tr_id = "CTRP6010R" tr_cont = "" params = { "CANO": cano, "ACNT_PRDT_CD": acnt_prdt_cd, "BASS_DT": bass_dt.strftime("%Y%m%d"), "WCRC_FRCR_DVSN_CD": wcrc_frcr_dvsn_cd, "INQR_DVSN_CD": inqr_dvsn_cd, } res_body, _ = self._tr_request(url_path, tr_id, tr_cont, params) if res_body["rt_cd"] != "0": raise ValueError(f"Error: ({res_body['msg_cd']}) {res_body['msg1']}") return { "rt_cd": res_body["rt_cd"], "msg_cd": res_body["msg_cd"], "msg1": res_body["msg1"], "output1": res_body["output1"], "output2": res_body["output2"], "output3": res_body["output3"], }
[docs] def inquire_asking_price( self, excd: str, symb: str, ): """ 해외주식의 현재가 10호가 정보를 조회하는 API입니다. 미국 주식의 경우 실시간으로 10호가까지 무료로 제공됩니다. 다른 아시아 국가의 경우 지연 시세가 제공되며, 유료로 10호가까지 조회 가능합니다. Args: excd (str): 거래소 코드 (예: NYS: 뉴욕, NAS: 나스닥, AMS: 아멕스 등). symb (str): 종목 코드 (예: TSLA). Returns: dict: 조회된 10호가 정보. - output1: - rsym (str): 실시간 조회 종목 코드. - zdiv (str): 소수점 자리수. - curr (str): 통화 코드. - base (Decimal): 전일 종가. - open (Decimal): 시가. - high (Decimal): 고가. - low (Decimal): 저가. - last (Decimal): 현재가. - dymd (str): 호가 일자. - dhms (str): 호가 시간. - bvol (int): 매수 호가 총 잔량. - avol (int): 매도 호가 총 잔량. - output2: 각 호가의 가격 및 잔량 정보 (1호가부터 10호가까지). - pbid1~10 (Decimal): 매수 호가 가격 (1~10). - pask1~10 (Decimal): 매도 호가 가격 (1~10). - vbid1~10 (int): 매수 호가 잔량 (1~10). - vask1~10 (int): 매도 호가 잔량 (1~10). Raises: ValueError: 필수 인자가 없거나 잘못된 경우 발생. """ url_path = "/uapi/overseas-price/v1/quotations/inquire-asking-price" tr_id = "HHDFS76200100" tr_cont = "" params = { "AUTH": "", "EXCD": excd, "SYMB": symb, } res_body, _ = self._tr_request(url_path, tr_id, tr_cont, 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 ["base", "open", "high", "low", "last"]: output1[k] = Decimal(output1[k]) if k in ["bvol", "avol"]: output1[k] = int(output1[k]) output2 = res_body["output2"] for k in output2.keys(): if k[0] == "p": output2[k] = Decimal(output2[k]) if k[0] == "v": output2[k] = int(output2[k]) return { "rt_cd": res_body["rt_cd"], "msg_cd": res_body["msg_cd"], "msg1": res_body["msg1"], "output1": res_body["output1"], "output2": res_body["output2"], }