initial commit

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

View File

@@ -0,0 +1,31 @@
import sys
import logging
import pandas as pd
sys.path.extend(['..', '.'])
import kis_auth as ka
from auth_functions import *
# 로깅 설정
logging.basicConfig(level=logging.INFO, format='%(levelname)s - %(message)s')
logger = logging.getLogger(__name__)
# 인증
ka.auth()
trenv = ka.getTREnv()
##############################################################################################
# [인증] OAuth 접근토큰 발급
##############################################################################################
df = auth_token(grant_type="client_credentials", appkey=trenv.my_app, appsecret=trenv.my_sec, env_dv="real")
print(df)
##############################################################################################
# [인증] WebSocket 웹소켓 접속키 발급
##############################################################################################
df = auth_ws_token(grant_type="client_credentials", appkey=trenv.my_app, appsecret=trenv.my_sec, env_dv="real")
print(df)

View File

@@ -0,0 +1,216 @@
import logging
import time
import sys
from typing import Optional, Tuple
import pandas as pd
import requests
import json
sys.path.extend(['..', '.'])
import kis_auth as ka
# 로깅 설정
logging.basicConfig(level=logging.INFO, format='%(levelname)s - %(message)s')
logger = logging.getLogger(__name__)
##############################################################################################
# [인증] OAuth 접근토큰 발급
##############################################################################################
def auth_token(
grant_type: str,
appkey: str,
appsecret: str,
env_dv: str
) -> pd.DataFrame:
"""
OAuth 접근토큰 발급 API를 호출하여 DataFrame으로 반환합니다.
Args:
grant_type (str): [필수] 권한부여 Type (client_credentials)
appkey (str): [필수] 앱키 (한국투자증권 홈페이지에서 발급받은 appkey)
appsecret (str): [필수] 앱시크릿키 (한국투자증권 홈페이지에서 발급받은 appsecret)
env_dv (str): [필수] 환경구분 (real: 실전, demo: 모의)
Returns:
pd.DataFrame: OAuth 토큰 발급 결과
Example:
>>> df = auth_token(
... grant_type="client_credentials",
... appkey=trenv.my_app,
... appsecret=trenv.my_sec,
... env_dv="real"
... )
>>> print(df)
"""
api_url = "/oauth2/tokenP"
# 필수 파라미터 검증
if not grant_type:
logger.error("grant_type is required. (e.g. 'client_credentials')")
raise ValueError("grant_type is required. (e.g. 'client_credentials')")
if not appkey:
logger.error("appkey is required. (한국투자증권 홈페이지에서 발급받은 appkey)")
raise ValueError("appkey is required. (한국투자증권 홈페이지에서 발급받은 appkey)")
if not appsecret:
logger.error("appsecret is required. (한국투자증권 홈페이지에서 발급받은 appsecret)")
raise ValueError("appsecret is required. (한국투자증권 홈페이지에서 발급받은 appsecret)")
if not env_dv:
logger.error("env_dv is required. (real: 실전, demo: 모의)")
raise ValueError("env_dv is required. (real: 실전, demo: 모의)")
# 환경 구분에 따른 서버 URL 설정
config = ka.getEnv()
if env_dv == "real":
base_url = config.get("prod", "")
elif env_dv == "demo":
base_url = config.get("vps", "")
else:
logger.error("env_dv must be 'real' or 'demo'")
raise ValueError("env_dv must be 'real' or 'demo'")
url = f"{base_url}{api_url}"
# 헤더 설정
headers = {
"Content-Type": "application/json",
"Accept": "text/plain",
"charset": "UTF-8"
}
# 요청 데이터
data = {
"grant_type": grant_type,
"appkey": appkey,
"appsecret": appsecret,
}
try:
# POST 방식으로 직접 API 호출
response = requests.post(url, data=json.dumps(data), headers=headers)
if response.status_code == 200:
# 응답 데이터를 DataFrame으로 반환 (1개 row)
response_data = response.json()
current_data = pd.DataFrame([response_data])
logger.info("OAuth 토큰 발급 성공")
return current_data
else:
logger.error("API call failed: %s - %s", response.status_code, response.text)
return pd.DataFrame()
except requests.RequestException as e:
logger.error("Request failed: %s", str(e))
return pd.DataFrame()
except json.JSONDecodeError as e:
logger.error("JSON decode failed: %s", str(e))
return pd.DataFrame()
##############################################################################################
# [인증] WebSocket 웹소켓 접속키 발급
##############################################################################################
def auth_ws_token(
grant_type: str,
appkey: str,
appsecret: str,
env_dv: str,
token: Optional[str] = ""
) -> pd.DataFrame:
"""
WebSocket 웹소켓 접속키 발급 API를 호출하여 DataFrame으로 반환합니다.
Args:
grant_type (str): [필수] 권한부여 Type (client_credentials)
appkey (str): [필수] 고객 앱Key (한국투자증권 홈페이지에서 발급받은 appkey)
appsecret (str): [필수] 고객 앱Secret (한국투자증권 홈페이지에서 발급받은 appsecret)
env_dv (str): [필수] 환경구분 (real: 실전, demo: 모의)
token (Optional[str]): 접근토큰 (OAuth 토큰이 필요한 API 경우 발급한 Access token)
Returns:
pd.DataFrame: WebSocket 접속키 발급 결과
Example:
>>> df = auth_ws_token(
... grant_type="client_credentials",
... appkey=trenv.my_app,
... appsecret=trenv.my_sec,
... env_dv="real"
... )
>>> print(df)
"""
api_url = "/oauth2/Approval"
# 필수 파라미터 검증
if not grant_type:
logger.error("grant_type is required. (e.g. 'client_credentials')")
raise ValueError("grant_type is required. (e.g. 'client_credentials')")
if not appkey:
logger.error("appkey is required. (한국투자증권 홈페이지에서 발급받은 appkey)")
raise ValueError("appkey is required. (한국투자증권 홈페이지에서 발급받은 appkey)")
if not appsecret:
logger.error("appsecret is required. (한국투자증권 홈페이지에서 발급받은 appsecret)")
raise ValueError("appsecret is required. (한국투자증권 홈페이지에서 발급받은 appsecret)")
if not env_dv:
logger.error("env_dv is required. (real: 실전, demo: 모의)")
raise ValueError("env_dv is required. (real: 실전, demo: 모의)")
# 환경 구분에 따른 서버 URL 설정
config = ka.getEnv()
if env_dv == "real":
base_url = config.get("prod", "")
elif env_dv == "demo":
base_url = config.get("vps", "")
else:
logger.error("env_dv must be 'real' or 'demo'")
raise ValueError("env_dv must be 'real' or 'demo'")
url = f"{base_url}{api_url}"
# 헤더 설정
headers = {
"Content-Type": "application/json",
"Accept": "text/plain",
"charset": "UTF-8"
}
# 요청 데이터
data = {
"grant_type": grant_type,
"appkey": appkey,
"secretkey": appsecret,
}
# token이 있는 경우에만 data에 추가
if token:
data["token"] = token
try:
# POST 방식으로 직접 API 호출
response = requests.post(url, data=json.dumps(data), headers=headers)
if response.status_code == 200:
# 응답 데이터를 DataFrame으로 반환 (1개 row)
response_data = response.json()
current_data = pd.DataFrame([response_data])
logger.info("WebSocket 접속키 발급 성공")
return current_data
else:
logger.error("API call failed: %s - %s", response.status_code, response.text)
return pd.DataFrame()
except requests.RequestException as e:
logger.error("Request failed: %s", str(e))
return pd.DataFrame()
except json.JSONDecodeError as e:
logger.error("JSON decode failed: %s", str(e))
return pd.DataFrame()

View File

@@ -0,0 +1,165 @@
import sys
import logging
import pandas as pd
sys.path.extend(['..', '.'])
import kis_auth as ka
from domestic_bond_functions import *
# 로깅 설정
logging.basicConfig(level=logging.INFO, format='%(levelname)s - %(message)s')
logger = logging.getLogger(__name__)
# 인증
ka.auth()
trenv = ka.getTREnv()
##############################################################################################
# [장내채권] 기본시세 > 장내채권 평균단가조회 [국내채권-158]
##############################################################################################
df1, df2, df3 = avg_unit(inqr_strt_dt="20250101", inqr_end_dt="20250131", pdno="KR2033022D33", prdt_type_cd="302", vrfc_kind_cd="00")
print(df1)
print(df2)
print(df3)
##############################################################################################
# [장내채권] 주문/계좌 > 장내채권 매수주문 [국내주식-124]
##############################################################################################
result = buy(
cano=trenv.my_acct, # 종합계좌번호
acnt_prdt_cd=trenv.my_prod, # 계좌상품코드
pdno="KR6095572D81", # 상품번호
ord_qty2="10", # 주문수량
bond_ord_unpr="9900", # 채권주문단가
samt_mket_ptci_yn="N", # 소액시장참여여부
bond_rtl_mket_yn="N", # 채권소매시장여부
idcr_stfno="", # 유치자직원번호
mgco_aptm_odno="", # 운용사지정주문번호
ord_svr_dvsn_cd="0", # 주문서버구분코드
ctac_tlno="", # 연락전화번호
)
print(result)
##############################################################################################
# [장내채권] 기본시세 > 장내채권현재가(호가) [국내주식-132]
##############################################################################################
df = inquire_asking_price(fid_cond_mrkt_div_code="B", fid_input_iscd="KR2033022D33")
print(df)
##############################################################################################
# [장내채권] 주문/계좌 > 장내채권 잔고조회 [국내주식-198]
##############################################################################################
df = inquire_balance(cano=trenv.my_acct, acnt_prdt_cd=trenv.my_prod, inqr_cndt="00", pdno="", buy_dt="")
print(df)
##############################################################################################
# [장내채권] 기본시세 > 장내채권현재가(체결) [국내주식-201]
##############################################################################################
df = inquire_ccnl(fid_cond_mrkt_div_code="B", fid_input_iscd="KR2033022D33")
print(df)
##############################################################################################
# [장내채권] 주문/계좌 > 장내채권 일별체결조회 [국내주식-127]
##############################################################################################
df1, df2 = inquire_daily_ccld(cano=trenv.my_acct, acnt_prdt_cd=trenv.my_prod, inqr_strt_dt="20250601", inqr_end_dt="20250630", sll_buy_dvsn_cd="%", sort_sqn_dvsn="01", pdno="", nccs_yn="N", ctx_area_nk200="", ctx_area_fk200="")
print(df1)
print(df2)
##############################################################################################
# [장내채권] 기본시세 > 장내채권 기간별시세(일) [국내주식-159]
##############################################################################################
df = inquire_daily_itemchartprice(fid_cond_mrkt_div_code="B", fid_input_iscd="KR2033022D33")
print(df)
##############################################################################################
# [장내채권] 기본시세 > 장내채권현재가(일별) [국내주식-202]
##############################################################################################
df = inquire_daily_price(fid_cond_mrkt_div_code="B", fid_input_iscd="KR2033022D33")
print(df)
##############################################################################################
# [장내채권] 기본시세 > 장내채권현재가(시세) [국내주식-200]
##############################################################################################
df = inquire_price(fid_cond_mrkt_div_code="B", fid_input_iscd="KR2033022D33")
print(df)
##############################################################################################
# [장내채권] 주문/계좌 > 장내채권 매수가능조회 [국내주식-199]
##############################################################################################
df = inquire_psbl_order(cano=trenv.my_acct, acnt_prdt_cd=trenv.my_prod, pdno="KR2033022D33", bond_ord_unpr="1000")
print(df)
##############################################################################################
# [장내채권] 주문/계좌 > 채권정정취소가능주문조회 [국내주식-126]
##############################################################################################
df = inquire_psbl_rvsecncl(cano=trenv.my_acct, acnt_prdt_cd=trenv.my_prod, ord_dt="20250601", odno="", ctx_area_fk200="", ctx_area_nk200="")
print(df)
##############################################################################################
# [장내채권] 기본시세 > 장내채권 발행정보 [국내주식-156]
##############################################################################################
df = issue_info(pdno="KR6449111CB8", prdt_type_cd="302")
print(df)
##############################################################################################
# [장내채권] 주문/계좌 > 장내채권 정정취소주문 [국내주식-125]
##############################################################################################
result = order_rvsecncl(
cano=trenv.my_acct,
acnt_prdt_cd=trenv.my_prod,
pdno="KR6095572D81",
orgn_odno="0004357900", # 실제 테스트 시 유효한 원주문번호로 변경해야 합니다.
ord_qty2="1", # 정정/취소 수량
bond_ord_unpr="10470", # 정정 단가
qty_all_ord_yn="Y", # 잔량 전부 주문 여부
rvse_cncl_dvsn_cd="01", # 01: 정정, 02: 취소
mgco_aptm_odno="",
ord_svr_dvsn_cd="0",
ctac_tlno="",
)
print(result)
##############################################################################################
# [장내채권] 기본시세 > 장내채권 기본조회 [국내주식-129]
##############################################################################################
df = search_bond_info(pdno="KR2033022D33", prdt_type_cd="302")
print(df)
##############################################################################################
# [장내채권] 주문/계좌 > 장내채권 매도주문 [국내주식-123]
##############################################################################################
result = sell(
cano=trenv.my_acct, # 종합계좌번호
acnt_prdt_cd=trenv.my_prod, # 계좌상품코드
ord_dvsn="01", # 주문구분
pdno="KR6095572D81", # 상품번호
ord_qty2="1", # 주문수량
bond_ord_unpr="10000.0", # 채권주문단가
sprx_yn="N", # 분리과세여부
buy_dt="", # 매수일자
buy_seq="", # 매수순번
samt_mket_ptci_yn="N", # 소액시장참여여부
sll_agco_opps_sll_yn="N", # 매도대행사반대매도여부
bond_rtl_mket_yn="N", # 채권소매시장여부
mgco_aptm_odno="", # 운용사지정주문번호
ord_svr_dvsn_cd="0", # 주문서버구분코드
ctac_tlno="", # 연락전화번호
)
print(result)

View File

@@ -0,0 +1,53 @@
import sys
import logging
import pandas as pd
sys.path.extend(['..', '.'])
import kis_auth as ka
from domestic_bond_functions_ws import *
# 로깅 설정
logging.basicConfig(level=logging.INFO, format='%(levelname)s - %(message)s')
logger = logging.getLogger(__name__)
# 인증
ka.auth()
ka.auth_ws()
trenv = ka.getTREnv()
# 웹소켓 선언
kws = ka.KISWebSocket(api_url="/tryitout")
##############################################################################################
# [장내채권] 실시간시세 > 일반채권 실시간호가 [실시간-053]
##############################################################################################
kws.subscribe(request=bond_asking_price, data=["KR103502GA34", "KR6095572D81"])
##############################################################################################
# [장내채권] 실시간시세 > 일반채권 실시간체결가 [실시간-052]
##############################################################################################
kws.subscribe(request=bond_ccnl, data=["KR103502GA34", "KR6095572D81"])
##############################################################################################
# [장내채권] 실시간시세 > 채권지수 실시간체결가 [실시간-060]
##############################################################################################
kws.subscribe(request=bond_index_ccnl, data=[
# 한경채권지수
"KBPR01", "KBPR02", "KBPR03", "KBPR04",
# KIS채권지수
"KISR01", "MSBI07", "KTBL10", "MSBI09", "MSBI10", "CDIX01",
# 매경채권지수
"MKFR01", "MSBI01", "MSBI03", "MSBI10", "CORP01"
])
# 시작
def on_result(ws, tr_id, result, data_info):
print(result)
kws.start(on_result=on_result)

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,233 @@
import logging
import sys
sys.path.extend(['..', '.'])
import kis_auth as ka
# 로깅 설정
logging.basicConfig(level=logging.INFO, format='%(levelname)s - %(message)s')
logger = logging.getLogger(__name__)
##############################################################################################
# [장내채권] 실시간시세 > 일반채권 실시간호가 [실시간-053]
##############################################################################################
def bond_asking_price(
tr_type: str,
tr_key: str,
) -> tuple[dict, list[str]]:
"""
일반채권 실시간호가[실시간-053]
일반채권 실시간호가 API를 통해 실시간 데이터를 구독합니다.
Args:
tr_type (str): [필수] 구독 등록("1") 또는 해제("0") 여부를 나타냅니다.
tr_key (str): [필수] 종목코드. 빈 문자열일 수 없습니다.
Returns:
message (dict): 실시간 데이터 메시지.
columns (list[str]): 응답 데이터의 컬럼 정보.
Raises:
ValueError: tr_key가 빈 문자열인 경우 발생합니다.
Example:
>>> msg, columns = bond_asking_price("1", "005930")
>>> print(msg, columns)
[참고자료]
채권 종목코드 마스터파일은 "KIS포털 > API문서 > 종목정보파일 > 장내채권 - 채권코드" 참고 부탁드립니다.
"""
# 필수 파라미터 검증
if not tr_key:
raise ValueError("tr_key is required and cannot be an empty string")
tr_id = "H0BJASP0"
params = {
"tr_key": tr_key,
}
# 데이터 요청
msg = ka.data_fetch(tr_id, tr_type, params)
# 응답 데이터 컬럼 정보
columns = [
"stnd_iscd",
"stck_cntg_hour",
"askp_ert1",
"bidp_ert1",
"askp1",
"bidp1",
"askp_rsqn1",
"bidp_rsqn1",
"askp_ert2",
"bidp_ert2",
"askp2",
"bidp2",
"askp_rsqn2",
"bidp_rsqn2",
"askp_ert3",
"bidp_ert3",
"askp3",
"bidp3",
"askp_rsqn3",
"bidp_rsqn3",
"askp_ert4",
"bidp_ert4",
"askp4",
"bidp4",
"askp_rsqn4",
"bidp_rsqn4",
"askp_ert5",
"bidp_ert5",
"askp5",
"bidp5",
"askp_rsqn52",
"bidp_rsqn53",
"total_askp_rsqn",
"total_bidp_rsqn",
]
return msg, columns
##############################################################################################
# [장내채권] 실시간시세 > 일반채권 실시간체결가 [실시간-052]
##############################################################################################
def bond_ccnl(
tr_type: str,
tr_key: str,
) -> tuple[dict, list[str]]:
"""
일반채권 실시간체결가[H0BJCNT0] 구독 함수
한국투자증권 웹소켓 API를 통해 일반채권의 실시간 체결가 데이터를 구독합니다.
Args:
tr_type (str): [필수] 구독 등록("1") 또는 해제("0") 여부
tr_key (str): [필수] 종목코드 (빈 문자열 불가)
Returns:
message (dict): 실시간 데이터 구독 결과 메시지
columns (list[str]): 응답 데이터의 컬럼 정보
Raises:
ValueError: tr_key가 빈 문자열인 경우 발생
Example:
>>> msg, columns = bond_ccnl("1", "005930")
>>> print(msg, columns)
[참고자료]
채권 종목코드 마스터파일은 "KIS포털 > API문서 > 종목정보파일 > 장내채권 - 채권코드" 참고 부탁드립니다.
"""
# 필수 파라미터 검증
if not tr_key:
raise ValueError("tr_key는 빈 문자열일 수 없습니다.")
tr_id = "H0BJCNT0"
params = {
"tr_key": tr_key,
}
# 데이터 구독 요청
msg = ka.data_fetch(tr_id, tr_type, params)
# 응답 데이터 컬럼 정보
columns = [
"stnd_iscd", # 표준종목코드
"bond_isnm", # 채권종목명
"stck_cntg_hour", # 주식체결시간
"prdy_vrss_sign", # 전일대비부호
"prdy_vrss", # 전일대비
"prdy_ctrt", # 전일대비율
"stck_prpr", # 현재가
"cntg_vol", # 체결거래량
"stck_oprc", # 시가
"stck_hgpr", # 고가
"stck_lwpr", # 저가
"stck_prdy_clpr", # 전일종가
"bond_cntg_ert", # 현재수익률
"oprc_ert", # 시가수익률
"hgpr_ert", # 고가수익률
"lwpr_ert", # 저가수익률
"acml_vol", # 누적거래량
"prdy_vol", # 전일거래량
"cntg_type_cls_code", # 체결유형코드
]
return msg, columns
##############################################################################################
# [장내채권] 실시간시세 > 채권지수 실시간체결가 [실시간-060]
##############################################################################################
def bond_index_ccnl(
tr_type: str,
tr_key: str,
) -> tuple[dict, list[str]]:
"""
채권지수 실시간체결가[H0BICNT0]
채권지수 실시간체결가 API를 통해 실시간 데이터를 구독합니다.
Args:
tr_type (str): [필수] 구독 등록("1") 또는 해제("0") 여부를 나타냅니다.
tr_key (str): [필수] 구독할 종목코드. 빈 문자열이 아니어야 합니다.
Returns:
message (dict): 구독 요청에 대한 응답 메시지.
columns (list[str]): 실시간 데이터의 컬럼 정보.
Raises:
ValueError: tr_key가 빈 문자열인 경우 발생합니다.
Example:
>>> msg, columns = bond_index_ccnl("1", "005930")
>>> print(msg, columns)
[참고자료]
채권 종목코드 마스터파일은 "KIS포털 > API문서 > 종목정보파일 > 장내채권 - 채권코드" 참고 부탁드립니다.
"""
# 필수 파라미터 검증
if not tr_key:
raise ValueError("tr_key is required and cannot be an empty string")
tr_id = "H0BICNT0"
params = {
"tr_key": tr_key,
}
# 데이터 구독 요청
msg = ka.data_fetch(tr_id, tr_type, params)
# 응답 데이터 컬럼 정보
columns = [
"nmix_id", # 지수ID
"stnd_date1", # 기준일자1
"trnm_hour", # 전송시간
"totl_ernn_nmix_oprc", # 총수익지수시가지수
"totl_ernn_nmix_hgpr", # 총수익지수최고가
"totl_ernn_nmix_lwpr", # 총수익지수최저가
"totl_ernn_nmix", # 총수익지수
"prdy_totl_ernn_nmix", # 전일총수익지수
"totl_ernn_nmix_prdy_vrss", # 총수익지수전일대비
"totl_ernn_nmix_prdy_vrss_sign", # 총수익지수전일대비부호
"totl_ernn_nmix_prdy_ctrt", # 총수익지수전일대비율
"clen_prc_nmix", # 순가격지수
"mrkt_prc_nmix", # 시장가격지수
"bond_call_rnvs_nmix", # Call재투자지수
"bond_zero_rnvs_nmix", # Zero재투자지수
"bond_futs_thpr", # 선물이론가격
"bond_avrg_drtn_val", # 평균듀레이션
"bond_avrg_cnvx_val", # 평균컨벡서티
"bond_avrg_ytm_val", # 평균YTM
"bond_avrg_frdl_ytm_val", # 평균선도YTM
]
return msg, columns

View File

@@ -0,0 +1,296 @@
import sys
import logging
import pandas as pd
sys.path.extend(['..', '.'])
import kis_auth as ka
from domestic_futureoption_functions import *
# 로깅 설정
logging.basicConfig(level=logging.INFO, format='%(levelname)s - %(message)s')
logger = logging.getLogger(__name__)
# 인증
ka.auth()
trenv = ka.getTREnv()
##############################################################################################
# [국내선물옵션] 기본시세 > 국내옵션전광판_콜풋[국내선물-022]
##############################################################################################
result1, result2 = display_board_callput(
fid_cond_mrkt_div_code="O",
fid_cond_scr_div_code="20503",
fid_mrkt_cls_code="CO",
fid_mtrt_cnt="202508",
fid_mrkt_cls_code1="PO"
)
print(result1)
print(result2)
##############################################################################################
# [국내선물옵션] 기본시세 > 국내옵션전광판_선물[국내선물-023]
##############################################################################################
result = display_board_futures(
fid_cond_mrkt_div_code="F",
fid_cond_scr_div_code="20503",
fid_cond_mrkt_cls_code="MKI"
)
print(result)
##############################################################################################
# [국내선물옵션] 기본시세 > 국내옵션전광판_옵션월물리스트[국내선물-020]
##############################################################################################
result = display_board_option_list(fid_cond_scr_div_code="509")
print(result)
##############################################################################################
# [국내선물옵션] 기본시세 > 국내선물 기초자산 시세[국내선물-021]
##############################################################################################
output1, output2 = display_board_top(fid_cond_mrkt_div_code="F", fid_input_iscd="101W09")
print(output1)
print(output2)
##############################################################################################
# [국내선물옵션] 기본시세 > 선물옵션 일중예상체결추이[국내선물-018]
##############################################################################################
result1, result2 = exp_price_trend(fid_input_iscd="101W09", fid_cond_mrkt_div_code="F")
print(result1)
print(result2)
##############################################################################################
# [국내선물옵션] 기본시세 > 선물옵션 시세호가[v1_국내선물-007]
##############################################################################################
result1, result2 = inquire_asking_price(fid_cond_mrkt_div_code="F", fid_input_iscd="101W09", env_dv="real")
print(result1)
print(result2)
##############################################################################################
# [국내선물옵션] 주문/계좌 > 선물옵션 잔고현황[v1_국내선물-004]
##############################################################################################
result1, result2 = inquire_balance(env_dv="real", cano=trenv.my_acct, acnt_prdt_cd=trenv.my_prod, mgna_dvsn="01",
excc_stat_cd="1")
print(result1)
print(result2)
##############################################################################################
# [국내선물옵션] 주문/계좌 > 선물옵션 잔고정산손익내역[v1_국내선물-013]
##############################################################################################
result1, result2 = inquire_balance_settlement_pl(cano=trenv.my_acct, acnt_prdt_cd=trenv.my_prod, inqr_dt="20230906")
print(result1)
print(result2)
##############################################################################################
# [국내선물옵션] 주문/계좌 > 선물옵션 잔고평가손익내역[v1_국내선물-015]
##############################################################################################
result1, result2 = inquire_balance_valuation_pl(cano=trenv.my_acct, acnt_prdt_cd=trenv.my_prod, mgna_dvsn="01",
excc_stat_cd="1")
print(result1)
print(result2)
##############################################################################################
# [국내선물옵션] 주문/계좌 > 선물옵션 주문체결내역조회[v1_국내선물-003]
##############################################################################################
result1, result2 = inquire_ccnl(
env_dv="real",
cano=trenv.my_acct,
acnt_prdt_cd=trenv.my_prod,
strt_ord_dt="20220730",
end_ord_dt="20220830",
sll_buy_dvsn_cd="00",
ccld_nccs_dvsn="00",
sort_sqn="DS"
)
print(result1)
print(result2)
##############################################################################################
# [국내선물옵션] 주문/계좌 > 선물옵션 기준일체결내역[v1_국내선물-016]
##############################################################################################
result1, result2 = inquire_ccnl_bstime(
cano=trenv.my_acct,
acnt_prdt_cd=trenv.my_prod,
ord_dt="20230920",
fuop_tr_strt_tmd="000000",
fuop_tr_end_tmd="240000"
)
print(result1)
print(result2)
##############################################################################################
# [국내선물옵션] 주문/계좌 > 선물옵션기간약정수수료일별[v1_국내선물-017]
##############################################################################################
result1, result2 = inquire_daily_amount_fee(
cano=trenv.my_acct,
acnt_prdt_cd=trenv.my_prod,
inqr_strt_day="20240401",
inqr_end_day="20240625"
)
print(result1)
print(result2)
##############################################################################################
# [국내선물옵션] 기본시세 > 선물옵션기간별시세(일/주/월/년)[v1_국내선물-008]
##############################################################################################
output1, output2 = inquire_daily_fuopchartprice(
fid_cond_mrkt_div_code="F",
fid_input_iscd="101W09",
fid_input_date_1="20250301",
fid_input_date_2="20250810",
fid_period_div_code="D",
env_dv="real"
)
print(output1)
print(output2)
##############################################################################################
# [국내선물옵션] 주문/계좌 > 선물옵션 총자산현황[v1_국내선물-014]
##############################################################################################
result = inquire_deposit(cano=trenv.my_acct, acnt_prdt_cd=trenv.my_prod)
print(result)
##############################################################################################
# [국내선물옵션] 주문/계좌 > (야간)선물옵션 잔고현황 [국내선물-010]
##############################################################################################
result1, result2 = inquire_ngt_balance(
cano=trenv.my_acct,
acnt_prdt_cd=trenv.my_prod,
mgna_dvsn="01",
excc_stat_cd="1"
)
print(result1)
print(result2)
##############################################################################################
# [국내선물옵션] 주문/계좌 > (야간)선물옵션 주문체결 내역조회 [국내선물-009]
##############################################################################################
result1, result2 = inquire_ngt_ccnl(cano=trenv.my_acct, acnt_prdt_cd=trenv.my_prod, strt_ord_dt="20250610",
end_ord_dt="20250613", sll_buy_dvsn_cd="00", ccld_nccs_dvsn="00")
print(result1)
print(result2)
##############################################################################################
# [국내선물옵션] 기본시세 > 선물옵션 시세[v1_국내선물-006]
##############################################################################################
result1, result2, result3 = inquire_price(
fid_cond_mrkt_div_code="F",
fid_input_iscd="101W09",
env_dv="real"
)
print(result1)
print(result2)
print(result3)
##############################################################################################
# [국내선물옵션] 주문/계좌 > (야간)선물옵션 주문가능 조회 [국내선물-011]
##############################################################################################
result = inquire_psbl_ngt_order(
cano=trenv.my_acct,
acnt_prdt_cd=trenv.my_prod,
pdno="101W09",
prdt_type_cd="301",
sll_buy_dvsn_cd="02",
unit_price="322",
ord_dvsn_cd="01"
)
print(result)
##############################################################################################
# [국내선물옵션] 주문/계좌 > 선물옵션 주문가능[v1_국내선물-005]
##############################################################################################
result = inquire_psbl_order(
env_dv="real",
cano=trenv.my_acct,
acnt_prdt_cd=trenv.my_prod,
pdno="101W09",
sll_buy_dvsn_cd="02",
unit_price="1",
ord_dvsn_cd="01"
)
print(result)
##############################################################################################
# [국내선물옵션] 기본시세 > 선물옵션 분봉조회[v1_국내선물-012]
##############################################################################################
result1, result2 = inquire_time_fuopchartprice(
fid_cond_mrkt_div_code="F",
fid_input_iscd="101T12",
fid_hour_cls_code="60",
fid_pw_data_incu_yn="Y",
fid_fake_tick_incu_yn="N",
fid_input_date_1="20230901",
fid_input_hour_1="100000"
)
print(result1)
print(result2)
##############################################################################################
# [국내선물옵션] 주문/계좌 > (야간)선물옵션 증거금 상세 [국내선물-024]
##############################################################################################
result1, result2, result3 = ngt_margin_detail(cano=trenv.my_acct, acnt_prdt_cd=trenv.my_prod, mgna_dvsn_cd="01")
print(result1)
print(result2)
print(result3)
##############################################################################################
# [국내선물옵션] 주문/계좌 > 선물옵션 주문[v1_국내선물-001]
##############################################################################################
result = order(
env_dv="real",
ord_dv="day",
ord_prcs_dvsn_cd="02",
cano=trenv.my_acct,
acnt_prdt_cd=trenv.my_prod,
sll_buy_dvsn_cd="02",
shtn_pdno="101W09",
ord_qty="1",
unit_price="0",
nmpr_type_cd="02",
krx_nmpr_cndt_cd="0",
ord_dvsn_cd="02"
)
print(result)
##############################################################################################
# [국내선물옵션] 주문/계좌 > 선물옵션 정정취소주문[v1_국내선물-002]
##############################################################################################
result = order_rvsecncl(
env_dv="real",
day_dv="day",
ord_prcs_dvsn_cd="02",
cano=trenv.my_acct,
acnt_prdt_cd=trenv.my_prod,
rvse_cncl_dvsn_cd="02",
orgn_odno="0000004018",
ord_qty="0",
unit_price="0",
nmpr_type_cd="02",
krx_nmpr_cndt_cd="0",
rmn_qty_yn="Y",
ord_dvsn_cd="01"
)
print(result)

View File

@@ -0,0 +1,148 @@
import sys
import logging
import pandas as pd
sys.path.extend(['..', '.'])
import kis_auth as ka
from domestic_futureoption_functions_ws import *
# 로깅 설정
logging.basicConfig(level=logging.INFO, format='%(levelname)s - %(message)s')
logger = logging.getLogger(__name__)
# 인증
ka.auth()
ka.auth_ws()
trenv = ka.getTREnv()
# 웹소켓 선언
kws = ka.KISWebSocket(api_url="/tryitout")
##############################################################################################
# [국내선물옵션] 실시간시세 > 상품선물 실시간체결가[실시간-022]
##############################################################################################
kws.subscribe(request=commodity_futures_realtime_conclusion, data=["165W09"])
##############################################################################################
# [국내선물옵션] 실시간시세 > 상품선물 실시간호가[실시간-023]
##############################################################################################
kws.subscribe(request=commodity_futures_realtime_quote, data=["165W09"])
##############################################################################################
# [국내선물옵션] 실시간시세 > 선물옵션 실시간체결통보[실시간-012]
##############################################################################################
kws.subscribe(request=fuopt_ccnl_notice, data=[trenv.my_htsid])
##############################################################################################
# [국내선물옵션] 실시간시세 > 주식선물 실시간예상체결 [실시간-031]
##############################################################################################
kws.subscribe(request=futures_exp_ccnl, data=["111W07"])
##############################################################################################
# [국내선물옵션] 실시간시세 > 지수선물 실시간체결가[실시간-010]
##############################################################################################
kws.subscribe(request=index_futures_realtime_conclusion, data=["101W09"])
##############################################################################################
# [국내선물옵션] 실시간시세 > 지수선물 실시간호가[실시간-011]
##############################################################################################
kws.subscribe(request=index_futures_realtime_quote, data=["101W09"])
##############################################################################################
# [국내선물옵션] 실시간시세 > 지수옵션 실시간체결가[실시간-014]
##############################################################################################
kws.subscribe(request=index_option_realtime_conclusion, data=["201W08427"])
##############################################################################################
# [국내선물옵션] 실시간시세 > 지수옵션 실시간호가[실시간-015]
##############################################################################################
kws.subscribe(request=index_option_realtime_quote, data=["201W08427"])
##############################################################################################
# [국내선물옵션] 실시간시세 > KRX야간선물 실시간호가 [실시간-065]
##############################################################################################
kws.subscribe(request=krx_ngt_futures_asking_price, data=["101W09"])
##############################################################################################
# [국내선물옵션] 실시간시세 > KRX야간선물 실시간종목체결 [실시간-064]
##############################################################################################
kws.subscribe(request=krx_ngt_futures_ccnl, data=["101W9000"])
##############################################################################################
# [국내선물옵션] 실시간시세 > KRX야간선물 실시간체결통보 [실시간-066]
##############################################################################################
kws.subscribe(request=krx_ngt_futures_ccnl_notice, data=[trenv.my_htsid])
##############################################################################################
# [국내선물옵션] 실시간시세 > KRX야간옵션 실시간호가 [실시간-033]
##############################################################################################
kws.subscribe(request=krx_ngt_option_asking_price, data=["101W9000"])
##############################################################################################
# [국내선물옵션] 실시간시세 > KRX야간옵션 실시간체결가 [실시간-032]
##############################################################################################
kws.subscribe(request=krx_ngt_option_ccnl, data=["101W9000"])
##############################################################################################
# [국내선물옵션] 실시간시세 > KRX야간옵션실시간예상체결 [실시간-034]
##############################################################################################
kws.subscribe(request=krx_ngt_option_exp_ccnl, data=["101W9000"])
##############################################################################################
# [국내선물옵션] 실시간시세 > KRX야간옵션실시간체결통보 [실시간-067]
##############################################################################################
kws.subscribe(request=krx_ngt_option_notice, data=[trenv.my_htsid])
##############################################################################################
# [국내선물옵션] 실시간시세 > 주식옵션 실시간예상체결 [실시간-046]
##############################################################################################
kws.subscribe(request=option_exp_ccnl, data=["339W08088"])
##############################################################################################
# [국내선물옵션] 실시간시세 > 주식선물 실시간체결가 [실시간-029]
##############################################################################################
kws.subscribe(request=stock_futures_realtime_conclusion, data=["111W08"])
##############################################################################################
# [국내선물옵션] 실시간시세 > 주식선물 실시간호가 [실시간-030]
##############################################################################################
kws.subscribe(request=stock_futures_realtime_quote, data=["111W08"])
##############################################################################################
# [국내선물옵션] 실시간시세 > 주식옵션 실시간호가 [실시간-045]
##############################################################################################
kws.subscribe(request=stock_option_asking_price, data=["239W08090"])
##############################################################################################
# [국내선물옵션] 실시간시세 > 주식옵션 실시간체결가 [실시간-044]
##############################################################################################
kws.subscribe(request=stock_option_ccnl, data=["339W08088"])
# 시작
def on_result(ws, tr_id, result, data_info):
print(result)
kws.start(on_result=on_result)

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,181 @@
import sys
import logging
import pandas as pd
sys.path.extend(['..', '.'])
import kis_auth as ka
from domestic_stock_functions_ws import *
# 로깅 설정
logging.basicConfig(level=logging.INFO, format='%(levelname)s - %(message)s')
logger = logging.getLogger(__name__)
# 인증
ka.auth()
ka.auth_ws()
trenv = ka.getTREnv()
# 웹소켓 선언
kws = ka.KISWebSocket(api_url="/tryitout")
##############################################################################################
# [국내주식] 실시간시세 > 국내주식 실시간호가 (KRX) [실시간-004]
##############################################################################################
kws.subscribe(request=asking_price_krx, data=["005930", "000660"])
##############################################################################################
# [국내주식] 실시간시세 > 국내주식 실시간호가 (NXT)
##############################################################################################
kws.subscribe(request=asking_price_nxt, data=["005930", "000660"])
##############################################################################################
# [국내주식] 실시간시세 > 국내주식 실시간호가 (통합)
##############################################################################################
kws.subscribe(request=asking_price_total, data=["005930", "000660"])
##############################################################################################
# [국내주식] 실시간시세 > 국내주식 실시간체결가(KRX) [실시간-003]
##############################################################################################
kws.subscribe(request=ccnl_krx, data=["005930", "000660"])
##############################################################################################
# [국내주식] 실시간시세 > 국내주식 주식체결통보 [실시간-005]
##############################################################################################
kws.subscribe(request=ccnl_notice, data=[trenv.my_htsid])
##############################################################################################
# [국내주식] 실시간시세 > 국내주식 실시간체결가 (NXT)
##############################################################################################
kws.subscribe(request=ccnl_nxt, data=["005930", "000660"])
##############################################################################################
# [국내주식] 실시간시세 > 국내주식 실시간체결가 (통합)
##############################################################################################
kws.subscribe(request=ccnl_total, data=["005930", "000660"])
##############################################################################################
# [국내주식] 실시간시세 > 국내주식 실시간예상체결 (KRX) [실시간-041]
##############################################################################################
kws.subscribe(request=exp_ccnl_krx, data=["005930", "000660"])
##############################################################################################
# [국내주식] 실시간시세 > 국내주식 실시간예상체결 (NXT)
##############################################################################################
kws.subscribe(
request=exp_ccnl_nxt,
data=["005930", "000660", "005380"]
)
##############################################################################################
# [국내주식] 실시간시세 > 국내주식 실시간예상체결(통합)
##############################################################################################
kws.subscribe(request=exp_ccnl_total, data=["005930", "000660"])
##############################################################################################
# [국내주식] 실시간시세 > 국내지수 실시간체결 [실시간-026]
##############################################################################################
kws.subscribe(request=index_ccnl, data=["0001", "0128"])
##############################################################################################
# [국내주식] 실시간시세 > 국내지수 실시간예상체결 [실시간-027]
##############################################################################################
kws.subscribe(request=index_exp_ccnl, data=["0001"])
##############################################################################################
# [국내주식] 실시간시세 > 국내지수 실시간프로그램매매 [실시간-028]
##############################################################################################
kws.subscribe(request=index_program_trade, data=["0001", "0128"])
##############################################################################################
# [국내주식] 실시간시세 > 국내주식 장운영정보 (KRX) [실시간-049]
##############################################################################################
kws.subscribe(request=market_status_krx, data=["417450", "308100"])
##############################################################################################
# [국내주식] 실시간시세 > 국내주식 장운영정보(NXT)
##############################################################################################
kws.subscribe(request=market_status_nxt, data=["006220"])
##############################################################################################
# [국내주식] 실시간시세 > 국내주식 장운영정보(통합)
##############################################################################################
kws.subscribe(request=market_status_total, data=["158430"])
##############################################################################################
# [국내주식] 실시간시세 > 국내주식 실시간회원사 (KRX) [실시간-047]
##############################################################################################
kws.subscribe(request=member_krx, data=["005930", "000660"])
##############################################################################################
# [국내주식] 실시간시세 > 국내주식 실시간회원사 (NXT)
##############################################################################################
kws.subscribe(request=member_nxt, data=["005930", "000660"])
##############################################################################################
# [국내주식] 실시간시세 > 국내주식 실시간회원사 (통합)
##############################################################################################
kws.subscribe(request=member_total, data=["005930", "000660"])
##############################################################################################
# [국내주식] 실시간시세 > 국내주식 시간외 실시간호가 (KRX) [실시간-025]
##############################################################################################
kws.subscribe(request=overtime_asking_price_krx, data=["023460"])
##############################################################################################
# [국내주식] 실시간시세 > 국내주식 시간외 실시간체결가 (KRX) [실시간-042]
##############################################################################################
kws.subscribe(request=overtime_ccnl_krx, data=["023460", "199480", "462860", "440790", "000660"])
##############################################################################################
# [국내주식] 실시간시세 > 국내주식 시간외 실시간예상체결 (KRX) [실시간-024]
##############################################################################################
kws.subscribe(request=overtime_exp_ccnl_krx, data=["023460"])
##############################################################################################
# [국내주식] 실시간시세 > 국내주식 실시간프로그램매매 (KRX) [실시간-048]
##############################################################################################
kws.subscribe(request=program_trade_krx, data=["005930", "000660"])
##############################################################################################
# [국내주식] 실시간시세 > 국내주식 실시간프로그램매매 (NXT)
##############################################################################################
kws.subscribe(request=program_trade_nxt, data=["032640", "010950"])
##############################################################################################
# [국내주식] 실시간시세 > 국내주식 실시간프로그램매매 (통합)
##############################################################################################
kws.subscribe(request=program_trade_total, data=["005930", "000660"])
# 시작
def on_result(ws, tr_id, result, data_info):
print(result)
kws.start(on_result=on_result)

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,165 @@
import sys
import logging
import pandas as pd
sys.path.extend(['..', '.'])
import kis_auth as ka
from elw_functions import *
# 로깅 설정
logging.basicConfig(level=logging.INFO, format='%(levelname)s - %(message)s')
logger = logging.getLogger(__name__)
# 인증
ka.auth()
trenv = ka.getTREnv()
##############################################################################################
# [국내주식] ELW시세 - ELW 비교대상종목조회[국내주식-183]
##############################################################################################
df = compare_stocks(fid_cond_scr_div_code="11517", fid_input_iscd="005930")
print(df)
##############################################################################################
# [국내주식] ELW시세 - ELW 종목검색[국내주식-166]
##############################################################################################
df = cond_search(fid_cond_mrkt_div_code="W", fid_cond_scr_div_code="11510", fid_rank_sort_cls_code="0", fid_input_cnt_1="100")
print(df)
##############################################################################################
# [국내주식] ELW시세 - ELW 만기예정/만기종목[국내주식-184]
##############################################################################################
df = expiration_stocks(fid_cond_mrkt_div_code="W", fid_cond_scr_div_code="11547", fid_input_date_1="20240402", fid_input_date_2="20240408", fid_div_cls_code="2", fid_etc_cls_code="", fid_unas_input_iscd="000000", fid_input_iscd_2="00000", fid_blng_cls_code="0", fid_input_option_1="")
print(df)
##############################################################################################
# [국내주식] ELW시세 - ELW 지표순위[국내주식-169]
##############################################################################################
df = indicator(fid_cond_mrkt_div_code="W", fid_cond_scr_div_code="20279", fid_unas_input_iscd="000000", fid_input_iscd="00000", fid_div_cls_code="0", fid_input_price_1="", fid_input_price_2="", fid_input_vol_1="", fid_input_vol_2="", fid_rank_sort_cls_code="0", fid_blng_cls_code="0")
print(df)
##############################################################################################
# [국내주식] ELW시세 - ELW 투자지표추이(체결)[국내주식-172]
##############################################################################################
df = indicator_trend_ccnl(fid_cond_mrkt_div_code="W", fid_input_iscd="58J297")
print(df)
##############################################################################################
# [국내주식] ELW시세 - ELW 투자지표추이(일별)[국내주식-173]
##############################################################################################
df = indicator_trend_daily(fid_cond_mrkt_div_code="W", fid_input_iscd="57K281")
print(df)
##############################################################################################
# [국내주식] ELW시세 - ELW 투자지표추이(분별)[국내주식-174]
##############################################################################################
df = indicator_trend_minute(fid_cond_mrkt_div_code="W", fid_input_iscd="58J297", fid_hour_cls_code="60", fid_pw_data_incu_yn="N")
print(df)
##############################################################################################
# [국내주식] ELW시세 - ELW LP매매추이 [국내주식-182]
##############################################################################################
df1, df2 = lp_trade_trend(fid_cond_mrkt_div_code="W", fid_input_iscd="52K577")
print(df1)
print(df2)
##############################################################################################
# [국내주식] ELW시세 - ELW 신규상장종목[국내주식-181]
##############################################################################################
df = newly_listed(fid_cond_mrkt_div_code="W", fid_cond_scr_div_code="11548", fid_div_cls_code="02", fid_unas_input_iscd="000000", fid_input_iscd_2="00003", fid_input_date_1="20240402", fid_blng_cls_code="0")
print(df)
##############################################################################################
# [국내주식] ELW시세 - ELW 당일급변종목[국내주식-171]
##############################################################################################
df = quick_change(fid_cond_mrkt_div_code="W", fid_cond_scr_div_code="20287", fid_unas_input_iscd="000000", fid_input_iscd="00000", fid_mrkt_cls_code="A", fid_input_price_1="", fid_input_price_2="", fid_input_vol_1="", fid_input_vol_2="", fid_hour_cls_code="1", fid_input_hour_1="", fid_input_hour_2="", fid_rank_sort_cls_code="1", fid_blng_cls_code="0")
print(df)
##############################################################################################
# [국내주식] ELW시세 - ELW 민감도 순위[국내주식-170]
##############################################################################################
df = sensitivity(fid_cond_mrkt_div_code="W", fid_cond_scr_div_code="20285", fid_unas_input_iscd="000000", fid_input_iscd="00000", fid_div_cls_code="0", fid_input_price_1="", fid_input_price_2="", fid_input_vol_1="", fid_input_vol_2="", fid_rank_sort_cls_code="0", fid_input_rmnn_dynu_1="", fid_input_date_1="", fid_blng_cls_code="0")
print(df)
##############################################################################################
# [국내주식] ELW시세 - ELW 민감도 추이(체결)[국내주식-175]
##############################################################################################
df = sensitivity_trend_ccnl(fid_cond_mrkt_div_code="W", fid_input_iscd="58J297")
print(df)
##############################################################################################
# [국내주식] ELW시세 - ELW 민감도 추이(일별)[국내주식-176]
##############################################################################################
df = sensitivity_trend_daily(fid_cond_mrkt_div_code="W", fid_input_iscd="58J438")
print(df)
##############################################################################################
# [국내주식] ELW시세 - ELW 기초자산 목록조회[국내주식-185]
##############################################################################################
df = udrl_asset_list(fid_cond_scr_div_code="11541", fid_rank_sort_cls_code="0", fid_input_iscd="00000")
print(df)
##############################################################################################
# [국내주식] ELW시세 - ELW 기초자산별 종목시세[국내주식-186]
##############################################################################################
df = udrl_asset_price(fid_cond_mrkt_div_code="W", fid_cond_scr_div_code="11541", fid_mrkt_cls_code="A", fid_input_iscd="00000", fid_unas_input_iscd="005930", fid_vol_cnt="1000", fid_trgt_exls_cls_code="0", fid_input_price_1="1000", fid_input_price_2="5000", fid_input_vol_1="100", fid_input_vol_2="1000", fid_input_rmnn_dynu_1="30", fid_input_rmnn_dynu_2="90", fid_option="0", fid_input_option_1="", fid_input_option_2="")
print(df)
##############################################################################################
# [국내주식] ELW시세 - ELW 상승률순위[국내주식-167]
##############################################################################################
df = updown_rate(fid_cond_mrkt_div_code="W", fid_cond_scr_div_code="20277", fid_unas_input_iscd="000000", fid_input_iscd="00000", fid_input_rmnn_dynu_1="0", fid_div_cls_code="0", fid_input_price_1="", fid_input_price_2="", fid_input_vol_1="", fid_input_vol_2="", fid_input_date_1="", fid_rank_sort_cls_code="0", fid_blng_cls_code="0", fid_input_date_2="")
print(df)
##############################################################################################
# [국내주식] ELW시세 - ELW 변동성추이(체결)[국내주식-177]
##############################################################################################
df = volatility_trend_ccnl(fid_cond_mrkt_div_code="W", fid_input_iscd="58J297")
print(df)
##############################################################################################
# [국내주식] ELW시세 - ELW 변동성추이(일별)[국내주식-178]
##############################################################################################
df = volatility_trend_daily(fid_cond_mrkt_div_code="W", fid_input_iscd="58J297")
print(df)
##############################################################################################
# [국내주식] ELW시세 - ELW 변동성추이(분별)[국내주식-179]
##############################################################################################
df = volatility_trend_minute(fid_cond_mrkt_div_code="W", fid_input_iscd="58J297", fid_hour_cls_code="60", fid_pw_data_incu_yn="N")
print(df)
##############################################################################################
# [국내주식] ELW시세 - ELW 변동성추이(틱)[국내주식-180]
##############################################################################################
df = volatility_trend_tick(fid_cond_mrkt_div_code="W", fid_input_iscd="58J297")
print(df)
##############################################################################################
# [국내주식] ELW시세 - ELW 거래량순위[국내주식-168]
##############################################################################################
df = volume_rank(fid_cond_mrkt_div_code="W", fid_cond_scr_div_code="20278", fid_unas_input_iscd="000000", fid_input_iscd="00000", fid_input_rmnn_dynu_1="", fid_div_cls_code="0", fid_input_price_1="0", fid_input_price_2="100000", fid_input_vol_1="0", fid_input_vol_2="1000000", fid_input_date_1="20250101", fid_rank_sort_cls_code="0", fid_blng_cls_code="0", fid_input_iscd_2="0000", fid_input_date_2="")
print(df)

View File

@@ -0,0 +1,46 @@
import sys
import logging
import pandas as pd
sys.path.extend(['..', '.'])
import kis_auth as ka
from elw_functions_ws import *
# 로깅 설정
logging.basicConfig(level=logging.INFO, format='%(levelname)s - %(message)s')
logger = logging.getLogger(__name__)
# 인증
ka.auth()
ka.auth_ws()
trenv = ka.getTREnv()
# 웹소켓 선언
kws = ka.KISWebSocket(api_url="/tryitout")
##############################################################################################
# [국내주식] 실시간시세 - ELW 실시간호가[실시간-062]
##############################################################################################
kws.subscribe(request=elw_asking_price, data=["57LA24", "57L739", "57L650", "57L966", "52L181", "57LB38"])
##############################################################################################
# [국내주식] 실시간시세 - ELW 실시간체결가[실시간-061]
##############################################################################################
kws.subscribe(request=elw_ccnl, data=["57LA24", "57L739", "57L650", "57L966", "52L181", "57LB38"])
##############################################################################################
# [국내주식] 실시간시세 - ELW 실시간예상체결[실시간-063]
##############################################################################################
kws.subscribe(request=elw_exp_ccnl, data=["57LA24", "57L739", "57L650", "57L966", "52L181", "57LB38"])
# 시작
def on_result(ws, tr_id, result, data_info):
print(result)
kws.start(on_result=on_result)

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,307 @@
import logging
import sys
sys.path.extend(['..', '.'])
import kis_auth as ka
# 로깅 설정
logging.basicConfig(level=logging.INFO, format='%(levelname)s - %(message)s')
logger = logging.getLogger(__name__)
##############################################################################################
# [국내주식] 실시간시세 - ELW 실시간호가[실시간-062]
##############################################################################################
def elw_asking_price(
tr_type: str,
tr_key: str,
) -> tuple[dict, list[str]]:
"""
ELW 실시간호가[H0EWASP0]
ELW 실시간 호가 정보를 실시간으로 구독하는 웹소켓 API입니다.
Args:
tr_type (str): [필수] 구독 등록("1") 또는 해제("0") 여부를 나타냅니다.
tr_key (str): [필수] 종목코드. 빈 문자열일 수 없습니다.
Returns:
message (dict): 실시간 데이터 구독에 대한 응답 메시지.
columns (list[str]): 실시간 데이터의 컬럼 정보.
Raises:
ValueError: tr_key가 빈 문자열인 경우 발생합니다.
Example:
>>> msg, columns = elw_asking_price("1", "005930")
>>> print(msg, columns)
[참고자료]
종목코드 마스터파일 파이썬 정제코드는 한국투자증권 Github 참고 부탁드립니다.
https://github.com/koreainvestment/open-trading-api/tree/main/stocks_info
"""
# 필수 파라미터 검증
if not tr_key:
raise ValueError("tr_key is required and cannot be an empty string")
tr_id = "H0EWASP0"
params = {
"tr_key": tr_key,
}
# 데이터 구독 요청
msg = ka.data_fetch(tr_id, tr_type, params)
# 응답 데이터 컬럼 정보
columns = [
"mksc_shrn_iscd",
"bsop_hour",
"hour_cls_code",
"askp1",
"askp2",
"askp3",
"askp4",
"askp5",
"askp6",
"askp7",
"askp8",
"askp9",
"askp10",
"bidp1",
"bidp2",
"bidp3",
"bidp4",
"bidp5",
"bidp6",
"bidp7",
"bidp8",
"bidp9",
"bidp10",
"askp_rsqn1",
"askp_rsqn2",
"askp_rsqn3",
"askp_rsqn4",
"askp_rsqn5",
"askp_rsqn6",
"askp_rsqn7",
"askp_rsqn8",
"askp_rsqn9",
"askp_rsqn10",
"bidp_rsqn1",
"bidp_rsqn2",
"bidp_rsqn3",
"bidp_rsqn4",
"bidp_rsqn5",
"bidp_rsqn6",
"bidp_rsqn7",
"bidp_rsqn8",
"bidp_rsqn9",
"bidp_rsqn10",
"total_askp_rsqn",
"total_bidp_rsqn",
"antc_cnpr",
"antc_cnqn",
"antc_cntg_vrss_sign",
"antc_cntg_vrss",
"antc_cntg_prdy_ctrt",
"lp_askp_rsqn1",
"lp_askp_rsqn2",
"lp_askp_rsqn3",
"lp_bidp_rsqn4",
"lp_askp_rsqn4",
"lp_bidp_rsqn5",
"lp_askp_rsqn5",
"lp_bidp_rsqn6",
"lp_askp_rsqn6",
"lp_bidp_rsqn7",
"lp_askp_rsqn7",
"lp_askp_rsqn8",
"lp_bidp_rsqn8",
"lp_askp_rsqn9",
"lp_bidp_rsqn9",
"lp_askp_rsqn10",
"lp_bidp_rsqn10",
"lp_bidp_rsqn1",
"lp_total_askp_rsqn",
"lp_bidp_rsqn2",
"lp_total_bidp_rsqn",
"lp_bidp_rsqn3",
"antc_vol",
]
return msg, columns
##############################################################################################
# [국내주식] 실시간시세 - ELW 실시간체결가[실시간-061]
##############################################################################################
def elw_ccnl(
tr_type: str,
tr_key: str,
) -> tuple[dict, list[str]]:
"""
ELW 실시간체결가[H0EWCNT0] 구독 함수
ELW 실시간체결가 API를 통해 실시간 데이터를 구독합니다.
Args:
tr_type (str): [필수] 구독 등록("1") 또는 해제("0") 여부를 나타냅니다.
tr_key (str): [필수] 종목코드를 입력합니다. 빈 문자열이 아니어야 합니다.
Returns:
message (dict): 메시지 데이터
columns (list[str]): 실시간 데이터의 컬럼 정보
Example:
>>> msg, columns = elw_ccnl("1", "005930")
>>> print(msg, columns)
[참고자료]
종목코드 마스터파일 파이썬 정제코드는 한국투자증권 Github 참고 부탁드립니다.
https://github.com/koreainvestment/open-trading-api/tree/main/stocks_info
"""
# 필수 파라미터 검증
if not tr_key:
raise ValueError("tr_key는 필수 입력값입니다.")
tr_id = "H0EWCNT0"
params = {
"tr_key": tr_key,
}
# 데이터 구독 요청
msg = ka.data_fetch(tr_id, tr_type, params)
# 응답 데이터 컬럼 정보
columns = [
"mksc_shrn_iscd", "stck_cntg_hour", "stck_prpr", "prdy_vrss_sign",
"prdy_vrss", "prdy_ctrt", "wghn_avrg_stck_prc", "stck_oprc",
"stck_hgpr", "stck_lwpr", "askp1", "bidp1", "cntg_vol", "acml_vol",
"acml_tr_pbmn", "seln_cntg_csnu", "shnu_cntg_csnu", "ntby_cntg_csnu",
"cttr", "seln_cntg_smtn", "shnu_cntg_smtn", "cntg_cls_code",
"shnu_rate", "prdy_vol_vrss_acml_vol_rate", "oprc_hour",
"oprc_vrss_prpr_sign", "oprc_vrss_prpr", "hgpr_hour",
"hgpr_vrss_prpr_sign", "hgpr_vrss_prpr", "lwpr_hour",
"lwpr_vrss_prpr_sign", "lwpr_vrss_prpr", "bsop_date",
"new_mkop_cls_code", "trht_yn", "askp_rsqn1", "bidp_rsqn1",
"total_askp_rsqn", "total_bidp_rsqn", "tmvl_val", "prit", "prmm_val",
"gear", "prls_qryr_rate", "invl_val", "prmm_rate", "cfp", "lvrg_val",
"delta", "gama", "vega", "theta", "rho", "hts_ints_vltl", "hts_thpr",
"vol_tnrt", "prdy_smns_hour_acml_vol", "prdy_smns_hour_acml_vol_rate",
"apprch_rate", "lp_hvol", "lp_hldn_rate", "lp_ntby_qty"
]
return msg, columns
##############################################################################################
# [국내주식] 실시간시세 - ELW 실시간예상체결[실시간-063]
##############################################################################################
def elw_exp_ccnl(
tr_type: str,
tr_key: str,
) -> tuple[dict, list[str]]:
"""
ELW 실시간예상체결[H0EWANC0]
ELW 실시간예상체결 API입니다. 이 함수는 웹소켓을 통해 실시간 데이터를 구독합니다.
Args:
tr_type (str): [필수] 구독 등록("1") 또는 해제("0") 여부를 나타냅니다.
tr_key (str): [필수] 종목코드. 빈 문자열일 수 없습니다.
Returns:
message (dict): 메시지 데이터
columns (list[str]): 응답 데이터의 컬럼 정보
Raises:
ValueError: tr_key가 빈 문자열인 경우 발생합니다.
Example:
>>> msg, columns = elw_exp_ccnl("1", "005930")
>>> print(msg, columns)
[참고자료]
종목코드 마스터파일 파이썬 정제코드는 한국투자증권 Github 참고 부탁드립니다.
https://github.com/koreainvestment/open-trading-api/tree/main/stocks_info
"""
# 필수 파라미터 검증
if not tr_key:
raise ValueError("tr_key is required and cannot be an empty string")
tr_id = "H0EWANC0"
params = {
"tr_key": tr_key,
}
# 데이터 구독 요청
msg = ka.data_fetch(tr_id, tr_type, params)
# 응답 데이터의 컬럼 정보
columns = [
"mksc_shrn_iscd",
"stck_cntg_hour",
"stck_prpr",
"prdy_vrss_sign",
"prdy_vrss",
"prdy_ctrt",
"wghn_avrg_stck_prc",
"stck_oprc",
"stck_hgpr",
"stck_lwpr",
"askp1",
"bidp1",
"cntg_vol",
"acml_vol",
"acml_tr_pbmn",
"seln_cntg_csnu",
"shnu_cntg_csnu",
"ntby_cntg_csnu",
"cttr",
"seln_cntg_smtn",
"shnu_cntg_smtn",
"cntg_cls_code",
"shnu_rate",
"prdy_vol_vrss_acml_vol_rate",
"oprc_hour",
"oprc_vrss_prpr_sign",
"oprc_vrss_prpr",
"hgpr_hour",
"hgpr_vrss_prpr_sign",
"hgpr_vrss_prpr",
"lwpr_hour",
"lwpr_vrss_prpr_sign",
"lwpr_vrss_prpr",
"bsop_date",
"new_mkop_cls_code",
"trht_yn",
"askp_rsqn1",
"bidp_rsqn1",
"total_askp_rsqn",
"total_bidp_rsqn",
"tmvl_val",
"prit",
"prmm_val",
"gear",
"prls_qryr_rate",
"invl_val",
"prmm_rate",
"cfp",
"lvrg_val",
"delta",
"gama",
"vega",
"theta",
"rho",
"hts_ints_vltl",
"hts_thpr",
"vol_tnrt",
"lp_hvol",
"lp_hldn_rate",
]
return msg, columns

View File

@@ -0,0 +1,54 @@
import sys
import logging
import pandas as pd
sys.path.extend(['..', '.'])
import kis_auth as ka
from etfetn_functions import *
# 로깅 설정
logging.basicConfig(level=logging.INFO, format='%(levelname)s - %(message)s')
logger = logging.getLogger(__name__)
# 인증
ka.auth()
trenv = ka.getTREnv()
##############################################################################################
# [국내주식] 기본시세 > ETF 구성종목시세[국내주식-073]
##############################################################################################
result1, result2 = inquire_component_stock_price(fid_cond_mrkt_div_code="J", fid_input_iscd="069500", fid_cond_scr_div_code="11216")
print(result1)
print(result2)
##############################################################################################
# [국내주식] 기본시세 > ETF/ETN 현재가[v1_국내주식-068]
##############################################################################################
result = inquire_price(fid_cond_mrkt_div_code="J", fid_input_iscd="005930")
print(result)
##############################################################################################
# [국내주식] 기본시세 > NAV 비교추이(일)[v1_국내주식-071]
##############################################################################################
result = nav_comparison_daily_trend(fid_cond_mrkt_div_code="J", fid_input_iscd="069500", fid_input_date_1="20240101", fid_input_date_2="20240220")
print(result)
##############################################################################################
# [국내주식] 기본시세 > NAV 비교추이(분)[v1_국내주식-070]
##############################################################################################
result = nav_comparison_time_trend(fid_cond_mrkt_div_code="E", fid_input_iscd="069500", fid_hour_cls_code="60")
print(result)
##############################################################################################
# [국내주식] 기본시세 > NAV 비교추이(종목)[v1_국내주식-069]
##############################################################################################
result1, result2 = nav_comparison_trend(fid_cond_mrkt_div_code="J", fid_input_iscd="069500")
print(result1)
print(result2)

View File

@@ -0,0 +1,34 @@
import sys
import logging
import pandas as pd
sys.path.extend(['..', '.'])
import kis_auth as ka
from etfetn_functions_ws import *
# 로깅 설정
logging.basicConfig(level=logging.INFO, format='%(levelname)s - %(message)s')
logger = logging.getLogger(__name__)
# 인증
ka.auth()
ka.auth_ws()
trenv = ka.getTREnv()
# 웹소켓 선언
kws = ka.KISWebSocket(api_url="/tryitout")
##############################################################################################
# [국내주식] 실시간시세 > 국내ETF NAV추이[실시간-051]
##############################################################################################
kws.subscribe(request=etf_nav_trend, data=["069500"])
# 시작
def on_result(ws, tr_id, result, data_info):
print(result)
kws.start(on_result=on_result)

View File

@@ -0,0 +1,317 @@
import logging
import time
import sys
from typing import Optional, Tuple
import pandas as pd
sys.path.extend(['..', '.'])
import kis_auth as ka
# 로깅 설정
logging.basicConfig(level=logging.INFO, format='%(levelname)s - %(message)s')
logger = logging.getLogger(__name__)
##############################################################################################
# [국내주식] 기본시세 > ETF 구성종목시세[국내주식-073]
##############################################################################################
def inquire_component_stock_price(
fid_cond_mrkt_div_code: str,
fid_input_iscd: str,
fid_cond_scr_div_code: str
) -> Tuple[pd.DataFrame, pd.DataFrame]:
"""
ETF 구성종목시세 API입니다.
한국투자 HTS(eFriend Plus) > [0245] ETF/ETN 구성종목시세 화면의 기능을 API로 개발한 사항으로, 해당 화면을 참고하시면 기능을 이해하기 쉽습니다.
Args:
fid_cond_mrkt_div_code (str): [필수] 조건시장분류코드 (ex. J: 주식/ETF/ETN)
fid_input_iscd (str): [필수] 입력종목코드 (ex. 123456)
fid_cond_scr_div_code (str): [필수] 조건화면분류코드 (ex. 11216)
Returns:
Tuple[pd.DataFrame, pd.DataFrame]: (output1 데이터프레임, output2 데이터프레임)
Raises:
ValueError: 필수 파라미터가 누락된 경우
Examples:
>>> df1, df2 = inquire_component_stock_price("J", "069500", "11216")
>>> print(df1) # ETF 기본 정보
>>> print(df2) # ETF 구성종목 상세정보
"""
# 필수 파라미터 검증
if fid_cond_mrkt_div_code == "":
raise ValueError("fid_cond_mrkt_div_code is required (e.g. 'J: 주식/ETF/ETN')")
if fid_input_iscd == "":
raise ValueError("fid_input_iscd is required (e.g. '123456')")
if fid_cond_scr_div_code == "":
raise ValueError("fid_cond_scr_div_code is required (e.g. '11216')")
# API 호출 설정
tr_id = "FHKST121600C0"
# 파라미터 설정
api_url = "/uapi/etfetn/v1/quotations/inquire-component-stock-price"
params = {
"FID_COND_MRKT_DIV_CODE": fid_cond_mrkt_div_code,
"FID_INPUT_ISCD": fid_input_iscd,
"FID_COND_SCR_DIV_CODE": fid_cond_scr_div_code
}
# API 호출
res = ka._url_fetch(api_url, tr_id, "", params)
if res.isOK():
# output1 (object) -> DataFrame 변환
output1_data = res.getBody().output1
df1 = pd.DataFrame([output1_data]) if output1_data else pd.DataFrame()
# output2 (array) -> DataFrame 변환
output2_data = res.getBody().output2
df2 = pd.DataFrame(output2_data) if output2_data else pd.DataFrame()
return df1, df2
else:
res.printError(url=api_url)
return pd.DataFrame(), pd.DataFrame()
##############################################################################################
# [국내주식] 기본시세 > ETF/ETN 현재가[v1_국내주식-068]
##############################################################################################
def inquire_price(
fid_cond_mrkt_div_code: str, # 조건 시장 분류 코드
fid_input_iscd: str, # 입력 종목코드
) -> pd.DataFrame:
"""
ETF/ETN 현재가 API입니다.
한국투자 HTS(eFriend Plus) > [0240] ETF/ETN 현재가 화면의 기능을 API로 개발한 사항으로, 해당 화면을 참고하시면 기능을 이해하기 쉽습니다.
Args:
fid_cond_mrkt_div_code (str): [필수] 조건 시장 분류 코드 (ex. J:KRX, NX:NXT, UN:통합)
fid_input_iscd (str): [필수] 입력 종목코드 (ex. 123456)
Returns:
pd.DataFrame: ETF/ETN 현재가 데이터
Example:
>>> df = inquire_price("J", "123456")
>>> print(df)
"""
if fid_cond_mrkt_div_code == "":
raise ValueError("fid_cond_mrkt_div_code is required (e.g. 'J:KRX, NX:NXT, UN:통합')")
if fid_input_iscd == "":
raise ValueError("fid_input_iscd is required (e.g. '123456')")
tr_id = "FHPST02400000" # ETF/ETN 현재가
api_url = "/uapi/etfetn/v1/quotations/inquire-price"
params = {
"FID_COND_MRKT_DIV_CODE": fid_cond_mrkt_div_code, # 조건 시장 분류 코드
"FID_INPUT_ISCD": fid_input_iscd, # 입력 종목코드
}
res = ka._url_fetch(api_url, tr_id, "", params)
if res.isOK():
current_data = pd.DataFrame(res.getBody().output, index=[0])
return current_data
else:
res.printError(url=api_url)
return pd.DataFrame()
##############################################################################################
# [국내주식] 기본시세 > NAV 비교추이(일)[v1_국내주식-071]
##############################################################################################
def nav_comparison_daily_trend(
fid_cond_mrkt_div_code: str, # 조건시장분류코드
fid_input_iscd: str, # 입력종목코드
fid_input_date_1: str, # 조회시작일자
fid_input_date_2: str # 조회종료일자
) -> pd.DataFrame:
"""
NAV 비교추이(일) API입니다.
한국투자 HTS(eFriend Plus) > [0244] ETF/ETN 비교추이(NAV/IIV) 좌측 화면 "일별" 비교추이 기능을 API로 개발한 사항으로, 해당 화면을 참고하시면 기능을 이해하기 쉽습니다.
실전계좌의 경우, 한 번의 호출에 최대 100건까지 확인 가능합니다.
Args:
fid_cond_mrkt_div_code (str): [필수] 조건시장분류코드 (ex. J:주식)
fid_input_iscd (str): [필수] 입력종목코드 (ex. 123456)
fid_input_date_1 (str): [필수] 조회시작일자 (ex. 20240101)
fid_input_date_2 (str): [필수] 조회종료일자 (ex. 20240220)
Returns:
pd.DataFrame: NAV 비교추이(일) 데이터
Example:
>>> df = nav_comparison_daily_trend("J", "069500", "20240101", "20240220")
>>> print(df)
"""
# 필수 파라미터 검증
if fid_cond_mrkt_div_code == "":
raise ValueError("fid_cond_mrkt_div_code is required (e.g. 'J:주식')")
if fid_input_iscd == "":
raise ValueError("fid_input_iscd is required (e.g. '123456')")
if fid_input_date_1 == "":
raise ValueError("fid_input_date_1 is required (e.g. '20240101')")
if fid_input_date_2 == "":
raise ValueError("fid_input_date_2 is required (e.g. '20240220')")
tr_id = "FHPST02440200" # NAV 비교추이(일)
api_url = "/uapi/etfetn/v1/quotations/nav-comparison-daily-trend"
params = {
"FID_COND_MRKT_DIV_CODE": fid_cond_mrkt_div_code, # 조건시장분류코드
"FID_INPUT_ISCD": fid_input_iscd, # 입력종목코드
"FID_INPUT_DATE_1": fid_input_date_1, # 조회시작일자
"FID_INPUT_DATE_2": fid_input_date_2 # 조회종료일자
}
res = ka._url_fetch(api_url, tr_id, "", params)
if res.isOK():
current_data = pd.DataFrame(res.getBody().output)
logging.info("Data fetch complete.")
return current_data
else:
res.printError(url=api_url)
return pd.DataFrame()
##############################################################################################
# [국내주식] 기본시세 > NAV 비교추이(분)[v1_국내주식-070]
##############################################################################################
def nav_comparison_time_trend(
fid_cond_mrkt_div_code: str, # [필수] 조건시장분류코드 (ex. E)
fid_input_iscd: str, # [필수] 입력종목코드 (ex. 123456)
fid_hour_cls_code: str # [필수] 시간구분코드 (ex. 60:1분,180:3분,...,7200:120분)
) -> pd.DataFrame:
"""
NAV 비교추이(분) API입니다.
한국투자 HTS(eFriend Plus) > [0244] ETF/ETN 비교추이(NAV/IIV) 좌측 화면 "분별" 비교추이 기능을 API로 개발한 사항으로, 해당 화면을 참고하시면 기능을 이해하기 쉽습니다.
실전계좌의 경우, 한 번의 호출에 최근 30건까지 확인 가능합니다.
Args:
fid_cond_mrkt_div_code (str): [필수] 조건시장분류코드 (ex. E)
fid_input_iscd (str): [필수] 입력종목코드 (ex. 123456)
fid_hour_cls_code (str): [필수] 시간구분코드 (ex. 60:1분,180:3분,...,7200:120분)
Returns:
pd.DataFrame: NAV 비교추이(분) 데이터
Example:
>>> df = nav_comparison_time_trend("E", "069500", "60")
>>> print(df)
"""
# 필수 파라미터 검증
if fid_cond_mrkt_div_code == "" or fid_cond_mrkt_div_code is None:
raise ValueError("fid_cond_mrkt_div_code is required (e.g. 'E')")
if fid_input_iscd == "" or fid_input_iscd is None:
raise ValueError("fid_input_iscd is required (e.g. '123456')")
if fid_hour_cls_code == "" or fid_hour_cls_code is None:
raise ValueError("fid_hour_cls_code is required (e.g. '60:1분,180:3분,...,7200:120분')")
tr_id = "FHPST02440100"
api_url = "/uapi/etfetn/v1/quotations/nav-comparison-time-trend"
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
}
res = ka._url_fetch(api_url, tr_id, "", params)
if res.isOK():
# output (array) -> pd.DataFrame
current_data = pd.DataFrame(res.getBody().output)
return current_data
else:
res.printError(url=api_url)
return pd.DataFrame()
##############################################################################################
# [국내주식] 기본시세 > NAV 비교추이(종목)[v1_국내주식-069]
##############################################################################################
def nav_comparison_trend(
fid_cond_mrkt_div_code: str, # [필수] 조건 시장 분류 코드 (ex. J)
fid_input_iscd: str, # [필수] 입력 종목코드
) -> Tuple[pd.DataFrame, pd.DataFrame]:
"""
NAV 비교추이(종목) API입니다.
한국투자 HTS(eFriend Plus) > [0244] ETF/ETN 비교추이(NAV/IIV) 좌측 화면의 기능을 API로 개발한 사항으로, 해당 화면을 참고하시면 기능을 이해하기 쉽습니다.
Args:
fid_cond_mrkt_div_code (str): [필수] 조건 시장 분류 코드 (ex. J)
fid_input_iscd (str): [필수] 입력 종목코드
Returns:
Tuple[pd.DataFrame, pd.DataFrame]: output1, output2 데이터프레임
Example:
>>> output1, output2 = nav_comparison_trend("J", "069500")
>>> print(output1)
>>> print(output2)
"""
if fid_cond_mrkt_div_code == "":
raise ValueError("fid_cond_mrkt_div_code is required (e.g. 'J')")
if fid_input_iscd == "":
raise ValueError("fid_input_iscd is required")
tr_id = "FHPST02440000" # NAV 비교추이(종목)
api_url = "/uapi/etfetn/v1/quotations/nav-comparison-trend"
params = {
"FID_COND_MRKT_DIV_CODE": fid_cond_mrkt_div_code, # 조건 시장 분류 코드
"FID_INPUT_ISCD": fid_input_iscd, # 입력 종목코드
}
res = ka._url_fetch(api_url, tr_id, "", params)
if res.isOK():
output1_data = pd.DataFrame(res.getBody().output1, index=[0])
output2_data = pd.DataFrame(res.getBody().output2, index=[0])
logging.info("Data fetch complete.")
return output1_data, output2_data
else:
res.printError(url=api_url)
return pd.DataFrame(), pd.DataFrame()

View File

@@ -0,0 +1,72 @@
import logging
import sys
sys.path.extend(['..', '.'])
import kis_auth as ka
# 로깅 설정
logging.basicConfig(level=logging.INFO, format='%(levelname)s - %(message)s')
logger = logging.getLogger(__name__)
##############################################################################################
# [국내주식] 실시간시세 > 국내ETF NAV추이[실시간-051]
##############################################################################################
def etf_nav_trend(
tr_type: str,
tr_key: str,
) -> tuple[dict, list[str]]:
"""
국내ETF NAV추이[H0STNAV0] 실시간 데이터 구독 함수
이 함수는 한국투자증권의 웹소켓 API를 통해 실시간으로 국내 ETF의 NAV 추이를 구독합니다.
구독을 시작하거나 해제할 수 있으며, 실시간 데이터를 수신합니다.
Args:
tr_type (str): [필수] 구독 등록("1") 또는 해제("0") 여부를 나타내는 문자열
tr_key (str): [필수] 종목코드 (빈 문자열 불가)
Returns:
message (dict): 수신된 메시지 데이터
columns (list[str]): 수신된 데이터의 컬럼 정보
Raises:
ValueError: tr_key가 빈 문자열인 경우 발생
Example:
>>> msg, columns = etf_nav_trend("1", "005930")
>>> print(msg, columns)
"""
# 필수 파라미터 검증
if not tr_key:
raise ValueError("tr_key is required and cannot be an empty string")
tr_id = "H0STNAV0"
params = {
"tr_key": tr_key,
}
# 데이터 수신
msg = ka.data_fetch(tr_id, tr_type, params)
# 응답 컬럼 정보
columns = [
"rt_cd", # 성공 실패 여부
"msg_cd", # 응답코드
"output1", # 응답상세
"msg1", # 응답메세지
"mksc_shrn_iscd", # 유가증권단축종목코드
"nav", # NAV
"nav_prdy_vrss_sign", # NAV전일대비부호
"nav_prdy_vrss", # NAV전일대비
"nav_prdy_ctrt", # NAV전일대비율
"oprc_nav", # NAV시가
"hprc_nav", # NAV고가
"lprc_nav", # NAV저가
]
return msg, columns

View File

@@ -0,0 +1,799 @@
# -*- coding: utf-8 -*-
# ====| (REST) 접근 토큰 / (Websocket) 웹소켓 접속키 발급 에 필요한 API 호출 샘플 아래 참고하시기 바랍니다. |=====================
# ====| API 호출 공통 함수 포함 |=====================
import asyncio
import copy
import json
import logging
import os
import time
from base64 import b64decode
from collections import namedtuple
from collections.abc import Callable
from datetime import datetime
from io import StringIO
import pandas as pd
# pip install requests (패키지설치)
import requests
# 웹 소켓 모듈을 선언한다.
import websockets
# pip install PyYAML (패키지설치)
import yaml
from Crypto.Cipher import AES
# pip install pycryptodome
from Crypto.Util.Padding import unpad
clearConsole = lambda: os.system("cls" if os.name in ("nt", "dos") else "clear")
key_bytes = 32
config_root = os.path.join(os.path.expanduser("~"), "KIS", "config")
# config_root = "$HOME/KIS/config/" # 토큰 파일이 저장될 폴더, 제3자가 찾기 어렵도록 경로 설정하시기 바랍니다.
# token_tmp = config_root + 'KIS000000' # 토큰 로컬저장시 파일 이름 지정, 파일이름을 토큰값이 유추가능한 파일명은 삼가바랍니다.
# token_tmp = config_root + 'KIS' + datetime.today().strftime("%Y%m%d%H%M%S") # 토큰 로컬저장시 파일명 년월일시분초
token_tmp = os.path.join(
config_root, f"KIS{datetime.today().strftime("%Y%m%d")}"
) # 토큰 로컬저장시 파일명 년월일
# 접근토큰 관리하는 파일 존재여부 체크, 없으면 생성
if os.path.exists(token_tmp) == False:
f = open(token_tmp, "w+")
# 앱키, 앱시크리트, 토큰, 계좌번호 등 저장관리, 자신만의 경로와 파일명으로 설정하시기 바랍니다.
# pip install PyYAML (패키지설치)
with open(os.path.join(config_root, "kis_devlp.yaml"), encoding="UTF-8") as f:
_cfg = yaml.load(f, Loader=yaml.FullLoader)
_TRENV = tuple()
_last_auth_time = datetime.now()
_autoReAuth = False
_DEBUG = False
_isPaper = False
_smartSleep = 0.1
# 기본 헤더값 정의
_base_headers = {
"Content-Type": "application/json",
"Accept": "text/plain",
"charset": "UTF-8",
"User-Agent": _cfg["my_agent"],
}
# 토큰 발급 받아 저장 (토큰값, 토큰 유효시간,1일, 6시간 이내 발급신청시는 기존 토큰값과 동일, 발급시 알림톡 발송)
def save_token(my_token, my_expired):
# print(type(my_expired), my_expired)
valid_date = datetime.strptime(my_expired, "%Y-%m-%d %H:%M:%S")
# print('Save token date: ', valid_date)
with open(token_tmp, "w", encoding="utf-8") as f:
f.write(f"token: {my_token}\n")
f.write(f"valid-date: {valid_date}\n")
# 토큰 확인 (토큰값, 토큰 유효시간_1일, 6시간 이내 발급신청시는 기존 토큰값과 동일, 발급시 알림톡 발송)
def read_token():
try:
# 토큰이 저장된 파일 읽기
with open(token_tmp, encoding="UTF-8") as f:
tkg_tmp = yaml.load(f, Loader=yaml.FullLoader)
# 토큰 만료 일,시간
exp_dt = datetime.strftime(tkg_tmp["valid-date"], "%Y-%m-%d %H:%M:%S")
# 현재일자,시간
now_dt = datetime.today().strftime("%Y-%m-%d %H:%M:%S")
# print('expire dt: ', exp_dt, ' vs now dt:', now_dt)
# 저장된 토큰 만료일자 체크 (만료일시 > 현재일시 인경우 보관 토큰 리턴)
if exp_dt > now_dt:
return tkg_tmp["token"]
else:
# print('Need new token: ', tkg_tmp['valid-date'])
return None
except Exception:
# print('read token error: ', e)
return None
# 토큰 유효시간 체크해서 만료된 토큰이면 재발급처리
def _getBaseHeader():
if _autoReAuth:
reAuth()
return copy.deepcopy(_base_headers)
# 가져오기 : 앱키, 앱시크리트, 종합계좌번호(계좌번호 중 숫자8자리), 계좌상품코드(계좌번호 중 숫자2자리), 토큰, 도메인
def _setTRENV(cfg):
nt1 = namedtuple(
"KISEnv",
["my_app", "my_sec", "my_acct", "my_prod", "my_htsid", "my_token", "my_url", "my_url_ws"],
)
d = {
"my_app": cfg["my_app"], # 앱키
"my_sec": cfg["my_sec"], # 앱시크리트
"my_acct": cfg["my_acct"], # 종합계좌번호(8자리)
"my_prod": cfg["my_prod"], # 계좌상품코드(2자리)
"my_htsid": cfg["my_htsid"], # HTS ID
"my_token": cfg["my_token"], # 토큰
"my_url": cfg[
"my_url"
], # 실전 도메인 (https://openapi.koreainvestment.com:9443)
"my_url_ws": cfg["my_url_ws"],
} # 모의 도메인 (https://openapivts.koreainvestment.com:29443)
# print(cfg['my_app'])
global _TRENV
_TRENV = nt1(**d)
def isPaperTrading(): # 모의투자 매매
return _isPaper
# 실전투자면 'prod', 모의투자면 'vps'를 셋팅 하시기 바랍니다.
def changeTREnv(token_key, svr="prod", product=_cfg["my_prod"]):
cfg = dict()
global _isPaper
if svr == "prod": # 실전투자
ak1 = "my_app" # 실전투자용 앱키
ak2 = "my_sec" # 실전투자용 앱시크리트
_isPaper = False
_smartSleep = 0.05
elif svr == "vps": # 모의투자
ak1 = "paper_app" # 모의투자용 앱키
ak2 = "paper_sec" # 모의투자용 앱시크리트
_isPaper = True
_smartSleep = 0.5
cfg["my_app"] = _cfg[ak1]
cfg["my_sec"] = _cfg[ak2]
if svr == "prod" and product == "01": # 실전투자 주식투자, 위탁계좌, 투자계좌
cfg["my_acct"] = _cfg["my_acct_stock"]
elif svr == "prod" and product == "03": # 실전투자 선물옵션(파생)
cfg["my_acct"] = _cfg["my_acct_future"]
elif svr == "prod" and product == "08": # 실전투자 해외선물옵션(파생)
cfg["my_acct"] = _cfg["my_acct_future"]
elif svr == "prod" and product == "22": # 실전투자 개인연금저축계좌
cfg["my_acct"] = _cfg["my_acct_stock"]
elif svr == "prod" and product == "29": # 실전투자 퇴직연금계좌
cfg["my_acct"] = _cfg["my_acct_stock"]
elif svr == "vps" and product == "01": # 모의투자 주식투자, 위탁계좌, 투자계좌
cfg["my_acct"] = _cfg["my_paper_stock"]
elif svr == "vps" and product == "03": # 모의투자 선물옵션(파생)
cfg["my_acct"] = _cfg["my_paper_future"]
cfg["my_prod"] = product
cfg["my_htsid"] = _cfg["my_htsid"]
cfg["my_url"] = _cfg[svr]
try:
my_token = _TRENV.my_token
except AttributeError:
my_token = ""
cfg["my_token"] = my_token if token_key else token_key
cfg["my_url_ws"] = _cfg["ops" if svr == "prod" else "vops"]
# print(cfg)
_setTRENV(cfg)
def _getResultObject(json_data):
_tc_ = namedtuple("res", json_data.keys())
return _tc_(**json_data)
# Token 발급, 유효기간 1일, 6시간 이내 발급시 기존 token값 유지, 발급시 알림톡 무조건 발송
# 모의투자인 경우 svr='vps', 투자계좌(01)이 아닌경우 product='XX' 변경하세요 (계좌번호 뒤 2자리)
def auth(svr="prod", product=_cfg["my_prod"], url=None):
p = {
"grant_type": "client_credentials",
}
# 개인 환경파일 "kis_devlp.yaml" 파일을 참조하여 앱키, 앱시크리트 정보 가져오기
# 개인 환경파일명과 위치는 고객님만 아는 위치로 설정 바랍니다.
if svr == "prod": # 실전투자
ak1 = "my_app" # 앱키 (실전투자용)
ak2 = "my_sec" # 앱시크리트 (실전투자용)
elif svr == "vps": # 모의투자
ak1 = "paper_app" # 앱키 (모의투자용)
ak2 = "paper_sec" # 앱시크리트 (모의투자용)
# 앱키, 앱시크리트 가져오기
p["appkey"] = _cfg[ak1]
p["appsecret"] = _cfg[ak2]
# 기존 발급된 토큰이 있는지 확인
saved_token = read_token() # 기존 발급 토큰 확인
# print("saved_token: ", saved_token)
if saved_token is None: # 기존 발급 토큰 확인이 안되면 발급처리
url = f"{_cfg[svr]}/oauth2/tokenP"
res = requests.post(
url, data=json.dumps(p), headers=_getBaseHeader()
) # 토큰 발급
rescode = res.status_code
if rescode == 200: # 토큰 정상 발급
my_token = _getResultObject(res.json()).access_token # 토큰값 가져오기
my_expired = _getResultObject(
res.json()
).access_token_token_expired # 토큰값 만료일시 가져오기
save_token(my_token, my_expired) # 새로 발급 받은 토큰 저장
else:
print("Get Authentification token fail!\nYou have to restart your app!!!")
return
else:
my_token = saved_token # 기존 발급 토큰 확인되어 기존 토큰 사용
# 발급토큰 정보 포함해서 헤더값 저장 관리, API 호출시 필요
changeTREnv(my_token, svr, product)
_base_headers["authorization"] = f"Bearer {my_token}"
_base_headers["appkey"] = _TRENV.my_app
_base_headers["appsecret"] = _TRENV.my_sec
global _last_auth_time
_last_auth_time = datetime.now()
if _DEBUG:
print(f"[{_last_auth_time}] => get AUTH Key completed!")
# end of initialize, 토큰 재발급, 토큰 발급시 유효시간 1일
# 프로그램 실행시 _last_auth_time에 저장하여 유효시간 체크, 유효시간 만료시 토큰 발급 처리
def reAuth(svr="prod", product=_cfg["my_prod"]):
n2 = datetime.now()
if (n2 - _last_auth_time).seconds >= 86400: # 유효시간 1일
auth(svr, product)
def getEnv():
return _cfg
def smart_sleep():
if _DEBUG:
print(f"[RateLimit] Sleeping {_smartSleep}s ")
time.sleep(_smartSleep)
def getTREnv():
return _TRENV
# 주문 API에서 사용할 hash key값을 받아 header에 설정해 주는 함수
# 현재는 hash key 필수 사항아님, 생략가능, API 호출과정에서 변조 우려를 하는 경우 사용
# Input: HTTP Header, HTTP post param
# Output: None
def set_order_hash_key(h, p):
url = f"{getTREnv().my_url}/uapi/hashkey" # hashkey 발급 API URL
res = requests.post(url, data=json.dumps(p), headers=h)
rescode = res.status_code
if rescode == 200:
h["hashkey"] = _getResultObject(res.json()).HASH
else:
print("Error:", rescode)
# API 호출 응답에 필요한 처리 공통 함수
class APIResp:
def __init__(self, resp):
self._rescode = resp.status_code
self._resp = resp
self._header = self._setHeader()
self._body = self._setBody()
self._err_code = self._body.msg_cd
self._err_message = self._body.msg1
def getResCode(self):
return self._rescode
def _setHeader(self):
fld = dict()
for x in self._resp.headers.keys():
if x.islower():
fld[x] = self._resp.headers.get(x)
_th_ = namedtuple("header", fld.keys())
return _th_(**fld)
def _setBody(self):
_tb_ = namedtuple("body", self._resp.json().keys())
return _tb_(**self._resp.json())
def getHeader(self):
return self._header
def getBody(self):
return self._body
def getResponse(self):
return self._resp
def isOK(self):
try:
if self.getBody().rt_cd == "0":
return True
else:
return False
except:
return False
def getErrorCode(self):
return self._err_code
def getErrorMessage(self):
return self._err_message
def printAll(self):
print("<Header>")
for x in self.getHeader()._fields:
print(f"\t-{x}: {getattr(self.getHeader(), x)}")
print("<Body>")
for x in self.getBody()._fields:
print(f"\t-{x}: {getattr(self.getBody(), x)}")
def printError(self, url):
print(
"-------------------------------\nError in response: ",
self.getResCode(),
" url=",
url,
)
print(
"rt_cd : ",
self.getBody().rt_cd,
"/ msg_cd : ",
self.getErrorCode(),
"/ msg1 : ",
self.getErrorMessage(),
)
print("-------------------------------")
# end of class APIResp
class APIRespError(APIResp):
def __init__(self, status_code, error_text):
# 부모 생성자 호출하지 않고 직접 초기화
self.status_code = status_code
self.error_text = error_text
self._error_code = str(status_code)
self._error_message = error_text
def isOK(self):
return False
def getErrorCode(self):
return self._error_code
def getErrorMessage(self):
return self._error_message
def getBody(self):
# 빈 객체 리턴 (속성 접근 시 AttributeError 방지)
class EmptyBody:
def __getattr__(self, name):
return None
return EmptyBody()
def getHeader(self):
# 빈 객체 리턴
class EmptyHeader:
tr_cont = ""
def __getattr__(self, name):
return ""
return EmptyHeader()
def printAll(self):
print(f"=== ERROR RESPONSE ===")
print(f"Status Code: {self.status_code}")
print(f"Error Message: {self.error_text}")
print(f"======================")
def printError(self, url=""):
print(f"Error Code : {self.status_code} | {self.error_text}")
if url:
print(f"URL: {url}")
########### API call wrapping : API 호출 공통
def _url_fetch(
api_url, ptr_id, tr_cont, params, appendHeaders=None, postFlag=False, hashFlag=True
):
url = f"{getTREnv().my_url}{api_url}"
headers = _getBaseHeader() # 기본 header 값 정리
# 추가 Header 설정
tr_id = ptr_id
if ptr_id[0] in ("T", "J", "C"): # 실전투자용 TR id 체크
if isPaperTrading(): # 모의투자용 TR id 식별
tr_id = "V" + ptr_id[1:]
headers["tr_id"] = tr_id # 트랜젝션 TR id
headers["custtype"] = "P" # 일반(개인고객,법인고객) "P", 제휴사 "B"
headers["tr_cont"] = tr_cont # 트랜젝션 TR id
if appendHeaders is not None:
if len(appendHeaders) > 0:
for x in appendHeaders.keys():
headers[x] = appendHeaders.get(x)
if _DEBUG:
print("< Sending Info >")
print(f"URL: {url}, TR: {tr_id}")
print(f"<header>\n{headers}")
print(f"<body>\n{params}")
if postFlag:
# if (hashFlag): set_order_hash_key(headers, params)
res = requests.post(url, headers=headers, data=json.dumps(params))
else:
res = requests.get(url, headers=headers, params=params)
if res.status_code == 200:
ar = APIResp(res)
if _DEBUG:
ar.printAll()
return ar
else:
print("Error Code : " + str(res.status_code) + " | " + res.text)
return APIRespError(res.status_code, res.text)
# auth()
# print("Pass through the end of the line")
########### New - websocket 대응
_base_headers_ws = {
"content-type": "utf-8",
}
def _getBaseHeader_ws():
if _autoReAuth:
reAuth_ws()
return copy.deepcopy(_base_headers_ws)
def auth_ws(svr="prod", product=_cfg["my_prod"]):
p = {"grant_type": "client_credentials"}
if svr == "prod":
ak1 = "my_app"
ak2 = "my_sec"
elif svr == "vps":
ak1 = "paper_app"
ak2 = "paper_sec"
p["appkey"] = _cfg[ak1]
p["secretkey"] = _cfg[ak2]
url = f"{_cfg[svr]}/oauth2/Approval"
res = requests.post(url, data=json.dumps(p), headers=_getBaseHeader()) # 토큰 발급
rescode = res.status_code
if rescode == 200: # 토큰 정상 발급
approval_key = _getResultObject(res.json()).approval_key
else:
print("Get Approval token fail!\nYou have to restart your app!!!")
return
changeTREnv(None, svr, product)
_base_headers_ws["approval_key"] = approval_key
global _last_auth_time
_last_auth_time = datetime.now()
if _DEBUG:
print(f"[{_last_auth_time}] => get AUTH Key completed!")
def reAuth_ws(svr="prod", product=_cfg["my_prod"]):
n2 = datetime.now()
if (n2 - _last_auth_time).seconds >= 86400:
auth_ws(svr, product)
def data_fetch(tr_id, tr_type, params, appendHeaders=None) -> dict:
headers = _getBaseHeader_ws() # 기본 header 값 정리
headers["tr_type"] = tr_type
headers["custtype"] = "P"
if appendHeaders is not None:
if len(appendHeaders) > 0:
for x in appendHeaders.keys():
headers[x] = appendHeaders.get(x)
if _DEBUG:
print("< Sending Info >")
print(f"TR: {tr_id}")
print(f"<header>\n{headers}")
inp = {
"tr_id": tr_id,
}
inp.update(params)
return {"header": headers, "body": {"input": inp}}
# iv, ekey, encrypt 는 각 기능 메소드 파일에 저장할 수 있도록 dict에서 return 하도록
def system_resp(data):
isPingPong = False
isUnSub = False
isOk = False
tr_msg = None
tr_key = None
encrypt, iv, ekey = None, None, None
rdic = json.loads(data)
tr_id = rdic["header"]["tr_id"]
if tr_id != "PINGPONG":
tr_key = rdic["header"]["tr_key"]
encrypt = rdic["header"]["encrypt"]
if rdic.get("body", None) is not None:
isOk = True if rdic["body"]["rt_cd"] == "0" else False
tr_msg = rdic["body"]["msg1"]
# 복호화를 위한 key 를 추출
if "output" in rdic["body"]:
iv = rdic["body"]["output"]["iv"]
ekey = rdic["body"]["output"]["key"]
isUnSub = True if tr_msg[:5] == "UNSUB" else False
else:
isPingPong = True if tr_id == "PINGPONG" else False
nt2 = namedtuple(
"SysMsg",
[
"isOk",
"tr_id",
"tr_key",
"isUnSub",
"isPingPong",
"tr_msg",
"iv",
"ekey",
"encrypt",
],
)
d = {
"isOk": isOk,
"tr_id": tr_id,
"tr_key": tr_key,
"tr_msg": tr_msg,
"isUnSub": isUnSub,
"isPingPong": isPingPong,
"iv": iv,
"ekey": ekey,
"encrypt": encrypt,
}
return nt2(**d)
def aes_cbc_base64_dec(key, iv, cipher_text):
if key is None or iv is None:
raise AttributeError("key and iv cannot be None")
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))
#####
open_map: dict = {}
def add_open_map(
name: str,
request: Callable[[str, str, ...], (dict, list[str])],
data: str | list[str],
kwargs: dict = None,
):
if open_map.get(name, None) is None:
open_map[name] = {
"func": request,
"items": [],
"kwargs": kwargs,
}
if type(data) is list:
open_map[name]["items"] += data
elif type(data) is str:
open_map[name]["items"].append(data)
data_map: dict = {}
def add_data_map(
tr_id: str,
columns: list = None,
encrypt: str = None,
key: str = None,
iv: str = None,
):
if data_map.get(tr_id, None) is None:
data_map[tr_id] = {"columns": [], "encrypt": False, "key": None, "iv": None}
if columns is not None:
data_map[tr_id]["columns"] = columns
if encrypt is not None:
data_map[tr_id]["encrypt"] = encrypt
if key is not None:
data_map[tr_id]["key"] = key
if iv is not None:
data_map[tr_id]["iv"] = iv
class KISWebSocket:
api_url: str = ""
on_result: Callable[
[websockets.ClientConnection, str, pd.DataFrame, dict], None
] = None
result_all_data: bool = False
retry_count: int = 0
amx_retries: int = 0
# init
def __init__(self, api_url: str, max_retries: int = 3):
self.api_url = api_url
self.max_retries = max_retries
# private
async def __subscriber(self, ws: websockets.ClientConnection):
async for raw in ws:
logging.info("received message >> %s" % raw)
show_result = False
df = pd.DataFrame()
if raw[0] in ["0", "1"]:
d1 = raw.split("|")
if len(d1) < 4:
raise ValueError("data not found...")
tr_id = d1[1]
dm = data_map[tr_id]
d = d1[3]
if dm.get("encrypt", None) == "Y":
d = aes_cbc_base64_dec(dm["key"], dm["iv"], d)
df = pd.read_csv(
StringIO(d), header=None, sep="^", names=dm["columns"], dtype=object
)
show_result = True
else:
rsp = system_resp(raw)
tr_id = rsp.tr_id
add_data_map(
tr_id=rsp.tr_id, encrypt=rsp.encrypt, key=rsp.ekey, iv=rsp.iv
)
if rsp.isPingPong:
print(f"### RECV [PINGPONG] [{raw}]")
await ws.pong(raw)
print(f"### SEND [PINGPONG] [{raw}]")
if self.result_all_data:
show_result = True
if show_result is True and self.on_result is not None:
self.on_result(ws, tr_id, df, data_map[tr_id])
async def __runner(self):
if len(open_map.keys()) > 40:
raise ValueError("Subscription's max is 40")
url = f"{getTREnv().my_url_ws}{self.api_url}"
while self.retry_count < self.max_retries:
try:
async with websockets.connect(url) as ws:
# request subscribe
for name, obj in open_map.items():
await self.send_multiple(
ws, obj["func"], "1", obj["items"], obj["kwargs"]
)
# subscriber
await asyncio.gather(
self.__subscriber(ws),
)
except Exception as e:
print("Connection exception >> ", e)
self.retry_count += 1
await asyncio.sleep(1)
# func
@classmethod
async def send(
cls,
ws: websockets.ClientConnection,
request: Callable[[str, str, ...], (dict, list[str])],
tr_type: str,
data: str,
kwargs: dict = None,
):
k = {} if kwargs is None else kwargs
msg, columns = request(tr_type, data, **k)
add_data_map(tr_id=msg["body"]["input"]["tr_id"], columns=columns)
logging.info("send message >> %s" % json.dumps(msg))
await ws.send(json.dumps(msg))
smart_sleep()
async def send_multiple(
self,
ws: websockets.ClientConnection,
request: Callable[[str, str, ...], (dict, list[str])],
tr_type: str,
data: list | str,
kwargs: dict = None,
):
if type(data) is str:
await self.send(ws, request, tr_type, data, kwargs)
elif type(data) is list:
for d in data:
await self.send(ws, request, tr_type, d, kwargs)
else:
raise ValueError("data must be str or list")
@classmethod
def subscribe(
cls,
request: Callable[[str, str, ...], (dict, list[str])],
data: list | str,
kwargs: dict = None,
):
add_open_map(request.__name__, request, data, kwargs)
def unsubscribe(
self,
ws: websockets.ClientConnection,
request: Callable[[str, str, ...], (dict, list[str])],
data: list | str,
):
self.send_multiple(ws, request, "2", data)
# start
def start(
self,
on_result: Callable[
[websockets.ClientConnection, str, pd.DataFrame, dict], None
],
result_all_data: bool = False,
):
self.on_result = on_result
self.result_all_data = result_all_data
try:
asyncio.run(self.__runner())
except KeyboardInterrupt:
print("Closing by KeyboardInterrupt")

View File

@@ -0,0 +1,250 @@
import sys
import logging
import pandas as pd
sys.path.extend(['..', '.'])
import kis_auth as ka
from overseas_futureoption_functions import *
# 로깅 설정
logging.basicConfig(level=logging.INFO, format='%(levelname)s - %(message)s')
logger = logging.getLogger(__name__)
# 인증
ka.auth()
trenv = ka.getTREnv()
##############################################################################################
# [해외선물옵션] 기본시세 > 해외선물 체결추이(일간) [해외선물-018]
##############################################################################################
df1, df2 = daily_ccnl(srs_cd="6AM24", exch_cd="CME", start_date_time="", close_date_time="20240402", qry_tp="Q", qry_cnt="30", qry_gap="", index_key="")
print(df1)
print(df2)
##############################################################################################
# [해외선물옵션] 기본시세 > 해외선물 호가 [해외선물-031]
##############################################################################################
df1, df2 = inquire_asking_price(srs_cd="ESZ23")
print(df1)
print(df2)
##############################################################################################
# [해외선물옵션] 주문/계좌 > 해외선물옵션 당일주문내역조회 [v1_해외선물-004]
##############################################################################################
df = inquire_ccld(cano=trenv.my_acct, acnt_prdt_cd=trenv.my_prod, ccld_nccs_dvsn="01", sll_buy_dvsn_cd="%%", fuop_dvsn="00", ctx_area_fk200="", ctx_area_nk200="")
print(df)
##############################################################################################
# [해외선물옵션] 주문/계좌 > 해외선물옵션 일별체결내역[해외선물-011]
##############################################################################################
df1, df2 = inquire_daily_ccld(cano=trenv.my_acct, acnt_prdt_cd=trenv.my_prod, strt_dt="20250101", end_dt="20250131", fuop_dvsn_cd="00", fm_pdgr_cd="", crcy_cd="%%%", fm_item_ftng_yn="N", sll_buy_dvsn_cd="%%", ctx_area_fk200="", ctx_area_nk200="")
print(df1)
print(df2)
##############################################################################################
# [해외선물옵션] 주문/계좌 > 해외선물옵션 일별 주문내역 [해외선물-013]
##############################################################################################
df = inquire_daily_order(cano=trenv.my_acct, acnt_prdt_cd=trenv.my_prod, strt_dt="20250601", end_dt="20250703", fm_pdgr_cd="", ccld_nccs_dvsn="01", sll_buy_dvsn_cd="%%", fuop_dvsn="00", ctx_area_fk200="", ctx_area_nk200="")
print(df)
##############################################################################################
# [해외선물옵션] 주문/계좌 > 해외선물옵션 예수금현황 [해외선물-012]
##############################################################################################
df = inquire_deposit(cano=trenv.my_acct, acnt_prdt_cd=trenv.my_prod, crcy_cd="TUS", inqr_dt="20250630")
print(df)
##############################################################################################
# [해외선물옵션] 주문/계좌 > 해외선물옵션 기간계좌손익 일별 [해외선물-010]
##############################################################################################
df1, df2 = inquire_period_ccld(inqr_term_from_dt="20250601", inqr_term_to_dt="20250630", cano=trenv.my_acct, acnt_prdt_cd=trenv.my_prod, crcy_cd="%%%", whol_trsl_yn="N", fuop_dvsn="00", ctx_area_fk200="", ctx_area_nk200="")
print(df1)
print(df2)
##############################################################################################
# [해외선물옵션] 주문/계좌 > 해외선물옵션 기간계좌거래내역 [해외선물-014]
##############################################################################################
df = inquire_period_trans(inqr_term_from_dt="20250101", inqr_term_to_dt="20250131", cano=trenv.my_acct, acnt_prdt_cd=trenv.my_prod, acnt_tr_type_cd="1", crcy_cd="%%%", ctx_area_fk100="", ctx_area_nk100="", pwd_chk_yn="")
print(df)
##############################################################################################
# [해외선물옵션] 기본시세 > 해외선물종목현재가 [v1_해외선물-009]
##############################################################################################
df = inquire_price(srs_cd="BONU25")
print(df)
##############################################################################################
# [해외선물옵션] 주문/계좌 > 해외선물옵션 주문가능조회 [v1_해외선물-006]
##############################################################################################
df = inquire_psamount(cano=trenv.my_acct, acnt_prdt_cd=trenv.my_prod, ovrs_futr_fx_pdno="6AU22", sll_buy_dvsn_cd="02", fm_ord_pric="", ecis_rsvn_ord_yn="")
print(df)
##############################################################################################
# [해외선물옵션] 기본시세 > 해외선물 분봉조회[해외선물-016]
##############################################################################################
df1, df2 = inquire_time_futurechartprice(srs_cd="BONU25", exch_cd="EUREX", start_date_time="20250101", close_date_time="20250701", qry_tp="Q", qry_cnt="120", qry_gap="1", index_key="")
print(df1)
print(df2)
##############################################################################################
# [해외선물옵션] 기본시세 > 해외옵션 분봉조회 [해외선물-040]
##############################################################################################
result1, result2 = inquire_time_optchartprice(srs_cd="DXM24", exch_cd="ICE", qry_cnt="30")
print(result1)
print(result2)
##############################################################################################
# [해외선물옵션] 주문/계좌 > 해외선물옵션 미결제내역조회(잔고) [v1_해외선물-005]
##############################################################################################
df = inquire_unpd(cano=trenv.my_acct, acnt_prdt_cd=trenv.my_prod, fuop_dvsn="00", ctx_area_fk100="", ctx_area_nk100="")
print(df)
##############################################################################################
# [해외선물옵션] 기본시세 > 해외선물 미결제추이 [해외선물-029]
##############################################################################################
df1, df2 = investor_unpd_trend(prod_iscd="GE", bsop_date="20240513", upmu_gubun="0", cts_key="")
print(df1)
print(df2)
##############################################################################################
# [해외선물옵션] 주문/계좌 > 해외선물옵션 증거금상세 [해외선물-032]
##############################################################################################
df = margin_detail(cano=trenv.my_acct, acnt_prdt_cd=trenv.my_prod, crcy_cd="USD", inqr_dt="20250701")
print(df)
##############################################################################################
# [해외선물옵션] 기본시세 > 해외선물옵션 장운영시간 [해외선물-030]
##############################################################################################
df = market_time(fm_pdgr_cd="", fm_clas_cd="", fm_excg_cd="CME", opt_yn="N", ctx_area_nk200="", ctx_area_fk200="")
print(df)
##############################################################################################
# [해외선물옵션] 기본시세 > 해외선물 체결추이(월간)[해외선물-020]
##############################################################################################
df1, df2 = monthly_ccnl(srs_cd="6AM24", exch_cd="CME", start_date_time="", close_date_time="20240402", qry_tp="Q", qry_cnt="30", qry_gap="", index_key="")
print(df1)
print(df2)
##############################################################################################
# [해외선물옵션] 기본시세 > 해외옵션 호가 [해외선물-033]
##############################################################################################
df1, df2 = opt_asking_price(srs_cd="OESM24 C5340")
print(df1)
print(df2)
##############################################################################################
# [해외선물옵션] 기본시세 > 해외옵션 체결추이(일간) [해외선물-037]
##############################################################################################
result1, result2 = opt_daily_ccnl(srs_cd="DXM24", exch_cd="ICE", qry_cnt="30")
print(result1)
print(result2)
##############################################################################################
# [해외선물옵션] 기본시세 > 해외옵션종목상세 [해외선물-034]
##############################################################################################
result = opt_detail(srs_cd="C5500")
print(result)
##############################################################################################
# [해외선물옵션] 기본시세 > 해외옵션 체결추이(월간) [해외선물-039]
##############################################################################################
result1, result2 = opt_monthly_ccnl(srs_cd="DXM24", exch_cd="ICE", qry_cnt="30")
print(result1)
print(result2)
##############################################################################################
# [해외선물옵션] 기본시세 > 해외옵션종목현재가 [해외선물-035]
##############################################################################################
result = opt_price(srs_cd="DXM24")
print(result)
##############################################################################################
# [해외선물옵션] 기본시세 > 해외옵션 체결추이(틱) [해외선물-038]
##############################################################################################
result1, result2 = opt_tick_ccnl(srs_cd="DXM24", exch_cd="ICE", qry_cnt="30")
print(result1)
print(result2)
##############################################################################################
# [해외선물옵션] 기본시세 > 해외옵션 체결추이(주간) [해외선물-036]
##############################################################################################
result1, result2 = opt_weekly_ccnl(srs_cd="DXM24", exch_cd="ICE", qry_cnt="30")
print(result1)
print(result2)
##############################################################################################
# [해외선물옵션] 주문/계좌 > 해외선물옵션 주문[v1_해외선물-001]
##############################################################################################
df = order(cano=trenv.my_acct, acnt_prdt_cd=trenv.my_prod, ovrs_futr_fx_pdno="1AALN25 C10.0", sll_buy_dvsn_cd="02", fm_lqd_ustl_ccld_dt="", fm_lqd_ustl_ccno="", pric_dvsn_cd="1", fm_limit_ord_pric="1.17", fm_stop_ord_pric="", fm_ord_qty="1", fm_lqd_lmt_ord_pric="", fm_lqd_stop_ord_pric="", ccld_cndt_cd="6", cplx_ord_dvsn_cd="0", ecis_rsvn_ord_yn="N", fm_hdge_ord_scrn_yn="N")
print(df)
##############################################################################################
# [해외선물옵션] 주문/계좌 > 해외선물옵션 정정취소주문[v1_해외선물-002, 003]
##############################################################################################
df = order_rvsecncl(cano=trenv.my_acct, ord_dv="0", acnt_prdt_cd=trenv.my_prod, orgn_ord_dt="20250630", orgn_odno="00123456", fm_limit_ord_pric="10.0", fm_stop_ord_pric="", fm_lqd_lmt_ord_pric="", fm_lqd_stop_ord_pric="", fm_hdge_ord_scrn_yn="N", fm_mkpr_cvsn_yn="")
print(df)
##############################################################################################
# [해외선물옵션] 기본시세 > 해외선물 상품기본정보[해외선물-023]
##############################################################################################
df = search_contract_detail(qry_cnt="1", srs_cd_01="BONU25", srs_cd_02="BONU25", srs_cd_03="BONU25")
print(df)
##############################################################################################
# [해외선물옵션] 기본시세 > 해외옵션 상품기본정보 [해외선물-041]
##############################################################################################
result = search_opt_detail(qry_cnt="1", srs_cd_01="6AM24")
print(result)
##############################################################################################
# [해외선물옵션] 기본시세 > 해외선물종목상세[v1_해외선물-008]
##############################################################################################
df = stock_detail(srs_cd="BONU25")
print(df)
##############################################################################################
# [해외선물옵션] 기본시세 > 해외선물 체결추이(틱)[해외선물-019]
##############################################################################################
df1, df2 = tick_ccnl(srs_cd="BONU25", exch_cd="EUREX", start_date_time="", close_date_time="20250630", qry_tp="Q", qry_cnt="30", qry_gap="", index_key="")
print(df1)
print(df2)
##############################################################################################
# [해외선물옵션] 기본시세 > 해외선물 체결추이(주간)[해외선물-017]
##############################################################################################
df1, df2 = weekly_ccnl(srs_cd="6AM24", exch_cd="CME", start_date_time="", close_date_time="20240402", qry_tp="Q", qry_cnt="30", qry_gap="", index_key="")
print(df1)
print(df2)

View File

@@ -0,0 +1,52 @@
import sys
import logging
import pandas as pd
sys.path.extend(['..', '.'])
import kis_auth as ka
from overseas_futureoption_functions_ws import *
# 로깅 설정
logging.basicConfig(level=logging.INFO, format='%(levelname)s - %(message)s')
logger = logging.getLogger(__name__)
# 인증
ka.auth()
ka.auth_ws()
trenv = ka.getTREnv()
# 웹소켓 선언
kws = ka.KISWebSocket(api_url="/tryitout")
##############################################################################################
# [해외선물옵션]실시간시세 > 해외선물옵션 실시간호가[실시간-018]
##############################################################################################
kws.subscribe(request=asking_price, data=["SPIU25"])
##############################################################################################
# [해외선물옵션]실시간시세 > 해외선물옵션 실시간체결가[실시간-017]
##############################################################################################
kws.subscribe(request=ccnl, data=["1OZQ25"])
##############################################################################################
# [해외선물옵션]실시간시세 > 해외선물옵션 실시간체결내역통보[실시간-020]
##############################################################################################
kws.subscribe(request=ccnl_notice, data=[trenv.my_htsid])
##############################################################################################
# [해외선물옵션]실시간시세 > 해외선물옵션 실시간주문내역통보[실시간-019]
##############################################################################################
kws.subscribe(request=order_notice, data=[trenv.my_htsid])
# 시작
def on_result(ws, tr_id, result, data_info):
print(result)
kws.start(on_result=on_result)

View File

@@ -0,0 +1,324 @@
import logging
import sys
sys.path.extend(['..', '.'])
import kis_auth as ka
# 로깅 설정
logging.basicConfig(level=logging.INFO, format='%(levelname)s - %(message)s')
logger = logging.getLogger(__name__)
##############################################################################################
# [해외선물옵션]실시간시세 > 해외선물옵션 실시간호가[실시간-018]
##############################################################################################
def asking_price(
tr_type: str,
tr_key: str,
) -> tuple[dict, list[str]]:
"""
[해외선물옵션]실시간시세 > 해외선물옵션 실시간호가[실시간-018]
※ CME, SGX 실시간시세 유료시세 신청 필수 (KIS포털 > FAQ > 자주 묻는 질문 > 해외선물옵션 API 유료시세 신청방법(CME, SGX 거래소))
- CME, SGX 거래소 실시간시세는 유료시세 신청 후 이용하시는 모든 계좌에 대해서 접근토큰발급 API 호출하셔야 하며,
접근토큰발급 이후 2시간 이내로 신청정보가 동기화되어 유료시세 수신이 가능해집니다.
- CME, SGX 거래소 종목은 유료시세 신청되어 있지 않으면 실시간시세 종목등록이 불가하며,
등록 시도 시 "SUBSCRIBE ERROR : mci send failed" 에러가 발생합니다.
(중요) 해외선물옵션시세 출력값을 해석하실 때 ffcode.mst(해외선물종목마스터 파일)에 있는 sCalcDesz(계산 소수점) 값을 활용하셔야 정확한 값을 받아오실 수 있습니다.
Args:
tr_type (str): [필수] 등록/해제
tr_key (str): [필수] 종목코드
Returns:
message (dict): 메시지 데이터
columns (list[str]): 컬럼 정보
Example:
>>> msg, columns = asking_price("1", "DNASAAPL")
>>> print(msg, columns)
"""
# 필수 파라미터 검증
if tr_type == "":
raise ValueError("tr_type is required")
if tr_key == "":
raise ValueError("tr_key is required")
tr_id = "HDFFF010"
params = {
"tr_key": tr_key,
}
msg = ka.data_fetch(tr_id, tr_type, params)
columns = [
"series_cd",
"recv_date",
"recv_time",
"prev_price",
"bid_qntt_1",
"bid_num_1",
"bid_price_1",
"ask_qntt_1",
"ask_num_1",
"ask_price_1",
"bid_qntt_2",
"bid_num_2",
"bid_price_2",
"ask_qntt_2",
"ask_num_2",
"ask_price_2",
"bid_qntt_3",
"bid_num_3",
"bid_price_3",
"ask_qntt_3",
"ask_num_3",
"ask_price_3",
"bid_qntt_4",
"bid_num_4",
"bid_price_4",
"ask_qntt_4",
"ask_num_4",
"ask_price_4",
"bid_qntt_5",
"bid_num_5",
"bid_price_5",
"ask_qntt_5",
"ask_num_5",
"ask_price_5",
"sttl_price"
]
return msg, columns
##############################################################################################
# [해외선물옵션]실시간시세 > 해외선물옵션 실시간체결가[실시간-017]
##############################################################################################
def ccnl(
tr_type: str,
tr_key: str,
) -> tuple[dict, list[str]]:
"""
※ CME, SGX 실시간시세 유료시세 신청 필수 (포럼 > FAQ > 해외선물옵션 API 유료시세 신청방법(CME, SGX 거래소))
- CME, SGX 거래소 실시간시세는 유료시세 신청 후 이용하시는 모든 계좌에 대해서 접근토큰발급 API 호출하셔야 하며,
접근토큰발급 이후 2시간 이내로 신청정보가 동기화되어 유료시세 수신이 가능해집니다.
- CME, SGX 거래소 종목은 유료시세 신청되어 있지 않으면 실시간시세 종목등록이 불가하며,
등록 시도 시 "SUBSCRIBE ERROR : mci send failed" 에러가 발생합니다.
Args:
tr_type (str): [필수] 등록/해제
tr_key (str): [필수] 종목코드
Returns:
message (dict): 메시지 데이터
columns (list[str]): 컬럼 정보
Example:
>>> msg, columns = ccnl("1", "DNASAAPL")
>>> print(msg, columns)
"""
# 필수 파라미터 검증
if tr_type == "":
raise ValueError("tr_type is required")
if tr_key == "":
raise ValueError("tr_key is required")
tr_id = "HDFFF020"
params = {
"tr_key": tr_key,
}
msg = ka.data_fetch(tr_id, tr_type, params)
columns = [
"series_cd",
"bsns_date",
"mrkt_open_date",
"mrkt_open_time",
"mrkt_close_date",
"mrkt_close_time",
"prev_price",
"recv_date",
"recv_time",
"active_flag",
"last_price",
"last_qntt",
"prev_diff_price",
"prev_diff_rate",
"open_price",
"high_price",
"low_price",
"vol",
"prev_sign",
"quotsign",
"recv_time2",
"psttl_price",
"psttl_sign",
"psttl_diff_price",
"psttl_diff_rate"
]
return msg, columns
##############################################################################################
# [해외선물옵션]실시간시세 > 해외선물옵션 실시간체결내역통보[실시간-020]
##############################################################################################
def ccnl_notice(
tr_type: str,
tr_key: str,
) -> tuple[dict, list[str]]:
"""
해외선물옵션 실시간체결내역통보 API입니다.
Args:
tr_type (str): [필수] 등록/해제
tr_key (str): [필수] 종목코드
Returns:
message (dict): 메시지 데이터
columns (list[str]): 컬럼 정보
Example:
>>> msg, columns = ccnl_notice("1", trenv.my_htsid)
>>> print(msg, columns)
"""
# 필수 파라미터 검증
if tr_type == "":
raise ValueError("tr_type is required")
if tr_key == "":
raise ValueError("tr_key is required")
tr_id = "HDFFF2C0"
params = {
"tr_key": tr_key,
}
msg = ka.data_fetch(tr_id, tr_type, params)
columns = [
"acct_no",
"ord_dt",
"odno",
"orgn_ord_dt",
"orgn_odno",
"series",
"rvse_cncl_dvsn_cd",
"sll_buy_dvsn_cd",
"cplx_ord_dvsn_cd",
"prce_tp",
"fm_excg_rcit_dvsn_cd",
"ord_qty",
"fm_lmt_pric",
"fm_stop_ord_pric",
"tot_ccld_qty",
"tot_ccld_uv",
"ord_remq",
"fm_ord_grp_dt",
"ord_grp_stno",
"ord_dtl_dtime",
"oprt_dtl_dtime",
"work_empl",
"ccld_dt",
"ccno",
"api_ccno",
"ccld_qty",
"fm_ccld_pric",
"crcy_cd",
"trst_fee",
"ord_mdia_online_yn",
"fm_ccld_amt",
"fuop_item_dvsn_cd"
]
return msg, columns
##############################################################################################
# [해외선물옵션]실시간시세 > 해외선물옵션 실시간주문내역통보[실시간-019]
##############################################################################################
def order_notice(
tr_type: str,
tr_key: str,
) -> tuple[dict, list[str]]:
"""
[참고자료]
종목코드 마스터파일 파이썬 정제코드는 한국투자증권 Github 참고 부탁드립니다.
https://github.com/koreainvestment/open-trading-api/tree/main/stocks_info
Args:
tr_type (str): [필수] 등록/해제
tr_key (str): [필수] HTS ID
Returns:
message (dict): 메시지 데이터
columns (list[str]): 컬럼 정보
Example:
>>> msg, columns = order_notice("1", trenv.my_htsid)
>>> print(msg, columns)
"""
# 필수 파라미터 검증
if tr_type == "":
raise ValueError("tr_type is required")
if tr_key == "":
raise ValueError("tr_key is required")
tr_id = "HDFFF1C0"
params = {
"tr_key": tr_key,
}
msg = ka.data_fetch(tr_id, tr_type, params)
columns = [
"acct_no",
"ord_dt",
"odno",
"orgn_ord_dt",
"orgn_odno",
"series",
"rvse_cncl_dvsn_cd",
"sll_buy_dvsn_cd",
"cplx_ord_dvsn_cd",
"prce_tp",
"fm_excg_rcit_dvsn_cd",
"ord_qty",
"fm_lmt_pric",
"fm_stop_ord_pric",
"tot_ccld_qty",
"tot_ccld_uv",
"ord_remq",
"fm_ord_grp_dt",
"ord_grp_stno",
"ord_dtl_dtime",
"oprt_dtl_dtime",
"work_empl",
"crcy_cd",
"lqd_yn",
"lqd_lmt_pric",
"lqd_stop_pric",
"trd_cond",
"term_ord_vald_dtime",
"spec_tp",
"ecis_rsvn_ord_yn",
"fuop_item_dvsn_cd",
"auto_ord_dvsn_cd"
]
return msg, columns

View File

@@ -0,0 +1,414 @@
import sys
import logging
import pandas as pd
sys.path.extend(['..', '.'])
import kis_auth as ka
from overseas_stock_functions import *
# 로깅 설정
logging.basicConfig(level=logging.INFO, format='%(levelname)s - %(message)s')
logger = logging.getLogger(__name__)
# 인증
ka.auth()
trenv = ka.getTREnv()
##############################################################################################
# [해외주식] 주문/계좌 > 해외주식 지정가주문번호조회 [해외주식-071]
##############################################################################################
result = algo_ordno(cano=trenv.my_acct, acnt_prdt_cd=trenv.my_prod, trad_dt="20250619")
print(result)
##############################################################################################
# [해외주식] 주문/계좌 > 해외주식 미국주간주문 [v1_해외주식-026]
##############################################################################################
df = daytime_order(cano=trenv.my_acct, acnt_prdt_cd=trenv.my_prod, order_dv="buy", ovrs_excg_cd="NASD", pdno="AAPL",
ord_qty="10", ovrs_ord_unpr="150.50", ctac_tlno="", mgco_aptm_odno="", ord_svr_dvsn_cd="0",
ord_dvsn="00")
print(df)
##############################################################################################
# [해외주식] 주문/계좌 > 해외주식 미국주간정정취소 [v1_해외주식-027]
##############################################################################################
df = daytime_order_rvsecncl(cano=trenv.my_acct, acnt_prdt_cd=trenv.my_prod, ovrs_excg_cd="NASD", pdno="AAPL",
orgn_odno="1234567890", rvse_cncl_dvsn_cd="01", ord_qty="10", ovrs_ord_unpr="150.25",
ctac_tlno="", mgco_aptm_odno="", ord_svr_dvsn_cd="0")
print(df)
##############################################################################################
# [해외주식] 주문/계좌 - 해외증거금 통화별조회 [해외주식-035]
##############################################################################################
df = foreign_margin(cano=trenv.my_acct, acnt_prdt_cd=trenv.my_prod)
print(df)
##############################################################################################
# [해외주식] 주문/계좌 > 해외주식 지정가체결내역조회 [해외주식-070]
##############################################################################################
result, result3 = inquire_algo_ccnl(cano=trenv.my_acct, acnt_prdt_cd=trenv.my_prod, )
print(result)
print(result3)
##############################################################################################
# [해외주식] 주문/계좌 > 해외주식 잔고 [v1_해외주식-006]
##############################################################################################
df = inquire_balance(cano=trenv.my_acct, acnt_prdt_cd=trenv.my_prod, ovrs_excg_cd="NASD", tr_crcy_cd="USD")
print(df)
##############################################################################################
# [해외주식] 주문/계좌 > 해외주식 주문체결내역 [v1_해외주식-007]
##############################################################################################
df = inquire_ccnl(cano=trenv.my_acct, acnt_prdt_cd=trenv.my_prod, pdno="", ord_strt_dt="20250101",
ord_end_dt="20250131", sll_buy_dvsn="00", ccld_nccs_dvsn="00", ovrs_excg_cd="NASD", sort_sqn="DS",
ord_dt="", ord_gno_brno="", odno="", env_dv="real")
print(df)
##############################################################################################
# [해외주식] 주문/계좌 > 해외주식 미체결내역 [v1_해외주식-005]
##############################################################################################
df = inquire_nccs(cano=trenv.my_acct, acnt_prdt_cd=trenv.my_prod, ovrs_excg_cd="NASD", sort_sqn="DS", FK200="",
NK200="", env_dv="real")
print(df)
##############################################################################################
# [해외주식] 주문/계좌 > 해외주식 결제기준잔고 [해외주식-064]
##############################################################################################
df1, df2, df3 = inquire_paymt_stdr_balance(cano=trenv.my_acct, acnt_prdt_cd=trenv.my_prod, bass_dt="20250630",
wcrc_frcr_dvsn_cd="01", inqr_dvsn_cd="00")
print(df1)
print(df2)
print(df3)
##############################################################################################
# [해외주식] 주문/계좌 > 해외주식 기간손익 [v1_해외주식-032]
##############################################################################################
df1, df2 = inquire_period_profit(cano=trenv.my_acct, acnt_prdt_cd=trenv.my_prod, ovrs_excg_cd="NASD", natn_cd="",
crcy_cd="USD", pdno="", inqr_strt_dt="20230101", inqr_end_dt="20231231",
wcrc_frcr_dvsn_cd="01", FK200="", NK200="")
print(df1)
print(df2)
##############################################################################################
# [해외주식] 주문/계좌 > 해외주식 일별거래내역 [해외주식-063]
##############################################################################################
df1, df2 = inquire_period_trans(cano=trenv.my_acct, acnt_prdt_cd=trenv.my_prod, erlm_strt_dt="20240420",
erlm_end_dt="20240520", ovrs_excg_cd="NAS", pdno="", sll_buy_dvsn_cd="00",
loan_dvsn_cd="", FK100="", NK100="")
print(df1)
print(df2)
##############################################################################################
# [해외주식] 주문/계좌 > 해외주식 체결기준현재잔고 [v1_해외주식-008]
##############################################################################################
df1, df2, df3 = inquire_present_balance(cano=trenv.my_acct, acnt_prdt_cd=trenv.my_prod, wcrc_frcr_dvsn_cd="02",
natn_cd="000", tr_mket_cd="00", inqr_dvsn_cd="00", env_dv="real")
print(df1)
print(df2)
print(df3)
##############################################################################################
# [해외주식] 주문/계좌 > 해외주식 매수가능금액조회 [v1_해외주식-014]
##############################################################################################
df = inquire_psamount(cano=trenv.my_acct, acnt_prdt_cd=trenv.my_prod, ovrs_excg_cd="NASD", ovrs_ord_unpr="1.4",
item_cd="QQQ", env_dv="real")
print(df)
##############################################################################################
# [해외주식] 시세분석 > 해외주식 시가총액순위[해외주식-047]
##############################################################################################
result1, result2 = market_cap(excd="SZS", vol_rang="1")
print(result1)
print(result2)
##############################################################################################
# [해외주식] 시세분석 > 해외주식 신고/신저가[해외주식-042]
##############################################################################################
result1, result2 = new_highlow(excd="AMS", mixn="0", vol_rang="0", gubn="1", gubn2="1")
print(result1)
print(result2)
##############################################################################################
# [해외주식] 주문/계좌 > 해외주식 주문 [v1_해외주식-001]
##############################################################################################
df = order(cano=trenv.my_acct, acnt_prdt_cd=trenv.my_prod, ovrs_excg_cd="NASD", pdno="AAPL", ord_qty="10",
ovrs_ord_unpr="150.00", ord_dv="sell", ctac_tlno="", mgco_aptm_odno="", ord_svr_dvsn_cd="0", ord_dvsn="00",
env_dv="real")
print(df)
##############################################################################################
# [해외주식] 주문/계좌 > 해외주식 예약주문접수[v1_해외주식-002]
##############################################################################################
result = order_resv(env_dv="real", ord_dv="usBuy", cano=trenv.my_acct, acnt_prdt_cd=trenv.my_prod,
pdno="TSLA", ovrs_excg_cd="NASD", ft_ord_qty="1", ft_ord_unpr3="900")
print(result)
##############################################################################################
# [해외주식] 주문/계좌 > 해외주식 예약주문접수취소[v1_해외주식-004]
##############################################################################################
result = order_resv_ccnl(
env_dv="real",
nat_dv="us",
cano=trenv.my_acct,
acnt_prdt_cd=trenv.my_prod,
rsvn_ord_rcit_dt="20250610",
ovrs_rsvn_odno="0030008244"
)
print(result)
##############################################################################################
# [해외주식] 주문/계좌 > 해외주식 예약주문조회[v1_해외주식-013]
##############################################################################################
df = order_resv_list(nat_dv="us", cano=trenv.my_acct, acnt_prdt_cd=trenv.my_prod, inqr_strt_dt="20220809",
inqr_end_dt="20220830", inqr_dvsn_cd="00", ovrs_excg_cd="NASD")
print(df)
################################################################################
# [해외주식] 주문/계좌 > 해외주식 정정취소주문[v1_해외주식-003]
################################################################################
df = order_rvsecncl(cano=trenv.my_acct, acnt_prdt_cd=trenv.my_prod, ovrs_excg_cd="NYSE", pdno="BA",
orgn_odno="1234567890", rvse_cncl_dvsn_cd="01", ord_qty="100", ovrs_ord_unpr="0", mgco_aptm_odno="",
ord_svr_dvsn_cd="0", env_dv="real")
print(df)
##############################################################################################
# [해외주식] 시세분석 > 해외주식 가격급등락[해외주식-038]
##############################################################################################
result1, result2 = price_fluct(excd="NAS", gubn="0", mixn="0", vol_rang="0")
print(result1)
print(result2)
##############################################################################################
# [해외주식] 시세분석 > 해외주식 거래증가율순위[해외주식-045]
##############################################################################################
result1, result2 = trade_growth(excd="NAS", nday="0", vol_rang="0")
print(result1)
print(result2)
##############################################################################################
# [해외주식] 시세분석 > 해외주식 거래대금순위[해외주식-044]
##############################################################################################
result1, result2 = trade_pbmn(excd="NAS", nday="0", vol_rang="0")
print(result1)
print(result2)
##############################################################################################
# [해외주식] 시세분석 > 해외주식 거래회전율순위[해외주식-046]
##############################################################################################
result1, result2 = trade_turnover(excd="SHS", nday="0", vol_rang="0")
print(result1)
print(result2)
##############################################################################################
# [해외주식] 시세분석 > 해외주식 거래량순위[해외주식-043]
##############################################################################################
result1, result2 = trade_vol(excd="HNX", nday="0", vol_rang="0")
print(result1)
print(result2)
##############################################################################################
# [해외주식] 시세분석 > 해외주식 상승률/하락률[해외주식-041]
##############################################################################################
result1, result2 = updown_rate(excd="SHS", gubn="1", nday="0", vol_rang="0")
print(result1)
print(result2)
##############################################################################################
# [해외주식] 시세분석 > 해외주식 매수체결강도상위[해외주식-040]
##############################################################################################
result1, result2 = volume_power(excd="HKS", nday="0", vol_rang="0")
print(result1)
print(result2)
##############################################################################################
# [해외주식] 시세분석 > 해외주식 거래량급증[해외주식-039]
##############################################################################################
result1, result2 = volume_surge(excd="NYS", mixn="0", vol_rang="0")
print(result1)
print(result2)
##############################################################################################
# [해외주식] 시세분석 > 해외속보(제목) [해외주식-055]
##############################################################################################
result = brknews_title(fid_news_ofer_entp_code="0", fid_cond_scr_div_code="11801")
print(result)
##############################################################################################
# [해외주식] 시세분석 > 당사 해외주식담보대출 가능 종목 [해외주식-051]
##############################################################################################
result1, result2 = colable_by_company(pdno="AMD", natn_cd="840", inqr_sqn_dvsn="01")
print(result1)
print(result2)
##############################################################################################
# [해외주식] 기본시세 > 해외결제일자조회[해외주식-017]
##############################################################################################
df = countries_holiday(trad_dt="20250131", NK="", FK="")
print(df)
##############################################################################################
# [해외주식] 기본시세 > 해외주식 기간별시세[v1_해외주식-010]
##############################################################################################
df1, df2 = dailyprice(auth="", excd="NAS", symb="TSLA", gubn="0", bymd="", modp="1", env_dv="real")
print(df1)
print(df2)
##############################################################################################
# [해외주식] 기본시세 > 해외주식 업종별코드조회[해외주식-049]
##############################################################################################
result1, result2 = industry_price(excd="NAS")
print(result1)
print(result2)
##############################################################################################
# [해외주식] 기본시세 > 해외주식 업종별시세[해외주식-048]
##############################################################################################
result1, result2 = industry_theme(excd="NAS", icod="010", vol_rang="0")
print(result1)
print(result2)
##############################################################################################
# [해외주식] 기본시세 > 해외주식 현재가 1호가[해외주식-033]
##############################################################################################
df1, df2, df3 = inquire_asking_price(auth="", excd="NAS", symb="TSLA")
print(df1)
print(df2)
print(df3)
##############################################################################################
# [해외주식] 기본시세 > 해외주식 체결추이[해외주식-037]
##############################################################################################
result = quot_inquire_ccnl(excd="NAS", tday="0", symb="TSLA")
print(result)
##############################################################################################
# [해외주식] 기본시세 > 해외주식 종목_지수_환율기간별시세(일_주_월_년)[v1_해외주식-012]
##############################################################################################
df1, df2 = inquire_daily_chartprice(fid_cond_mrkt_div_code="N", fid_input_iscd=".DJI", fid_input_date_1="20250101",
fid_input_date_2="20250131", fid_period_div_code="D", env_dv="real")
print(df1)
print(df2)
##############################################################################################
# [해외주식] 시세분석 > 해외주식조건검색[v1_해외주식-015]
##############################################################################################
df1, df2 = inquire_search(auth="", excd="NYS", co_yn_pricecur="1", co_st_pricecur="100", co_en_pricecur="200",
co_yn_rate="1", co_st_rate="5", co_en_rate="10", co_yn_valx="1", co_st_valx="1000",
co_en_valx="5000", co_yn_shar="1", co_st_shar="100", co_en_shar="500", co_yn_volume="1",
co_st_volume="1000", co_en_volume="5000", co_yn_amt="1", co_st_amt="1000", co_en_amt="5000",
co_yn_eps="1", co_st_eps="1", co_en_eps="5", co_yn_per="1", co_st_per="10", co_en_per="20",
keyb="")
print(df1)
print(df2)
##############################################################################################
# [해외주식] 기본시세 > 해외지수분봉조회[v1_해외주식-031]
##############################################################################################
df1, df2 = inquire_time_indexchartprice(fid_cond_mrkt_div_code="N", fid_input_iscd="TSLA", fid_hour_cls_code="0",
fid_pw_data_incu_yn="Y")
print(df1)
print(df2)
##############################################################################################
# [해외주식] 기본시세 > 해외주식분봉조회[v1_해외주식-030]
##############################################################################################
df1, df2 = inquire_time_itemchartprice(auth="", excd="NAS", symb="TSLA", nmin="5", pinc="1", next="", nrec="120",
fill="", keyb="")
print(df1)
print(df2)
##############################################################################################
# [해외주식] 시세분석 > 해외뉴스종합(제목) [해외주식-053]
##############################################################################################
result = news_title(
info_gb="",
class_cd="",
nation_cd="",
exchange_cd="",
symb="",
data_dt="",
data_tm="",
cts=""
)
print(result)
##############################################################################################
# [해외주식] 시세분석 > 해외주식 기간별권리조회 [해외주식-052]
##############################################################################################
result = period_rights(
rght_type_cd="%%",
inqr_dvsn_cd="02",
inqr_strt_dt="20240417",
inqr_end_dt="20240417"
)
print(result)
##############################################################################################
# [해외주식] 기본시세 > 해외주식 현재체결가[v1_해외주식-009]
##############################################################################################
df = price(auth="", excd="NAS", symb="AAPL", env_dv="real")
print(df)
##############################################################################################
# [해외주식] 기본시세 > 해외주식 현재가상세[v1_해외주식-029]
##############################################################################################
df = price_detail(auth="", excd="NAS", symb="TSLA")
print(df)
##############################################################################################
# [해외주식] 시세분석 > 해외주식 권리종합 [해외주식-050]
##############################################################################################
result = rights_by_ice(ncod="US", symb="NVDL")
print(result)
##############################################################################################
# [해외주식] 시세분석 > 해외주식 상품기본정보[v1_해외주식-034]
##############################################################################################
df = search_info(prdt_type_cd="512", pdno="AAPL")
print(df)

View File

@@ -0,0 +1,52 @@
import sys
import logging
import pandas as pd
sys.path.extend(['..', '.'])
import kis_auth as ka
from overseas_stock_functions_ws import *
# 로깅 설정
logging.basicConfig(level=logging.INFO, format='%(levelname)s - %(message)s')
logger = logging.getLogger(__name__)
# 인증
ka.auth()
ka.auth_ws()
trenv = ka.getTREnv()
# 웹소켓 선언
kws = ka.KISWebSocket(api_url="/tryitout")
##############################################################################################
# [해외주식] 실시간시세 > 해외주식 실시간호가[실시간-021]
##############################################################################################
kws.subscribe(request=asking_price, data=["RBAQAAPL"])
##############################################################################################
# [해외주식] 실시간시세 > 해외주식 실시간체결통보[실시간-009]
##############################################################################################
kws.subscribe(request=ccnl_notice, data=[trenv.my_htsid], kwargs={"env_dv": "real"})
##############################################################################################
# [해외주식] 실시간시세 > 해외주식 지연호가(아시아)[실시간-008]
##############################################################################################
kws.subscribe(request=delayed_asking_price_asia, data=["DHKS00003"])
##############################################################################################
# [해외주식] 실시간시세 > 해외주식 실시간지연체결가[실시간-007]
##############################################################################################
kws.subscribe(request=delayed_ccnl, data=["DHKS00003"])
# 시작
def on_result(ws, tr_id, result, data_info):
print(result)
kws.start(on_result=on_result)

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,295 @@
import logging
import sys
sys.path.extend(['..', '.'])
import kis_auth as ka
# 로깅 설정
logging.basicConfig(level=logging.INFO, format='%(levelname)s - %(message)s')
logger = logging.getLogger(__name__)
##############################################################################################
# [해외주식] 실시간시세 > 해외주식 실시간호가[실시간-021]
##############################################################################################
def asking_price(
tr_type: str,
tr_key: str,
) -> tuple[dict, list[str]]:
"""
해외주식 실시간호가를 이용하여 미국시세 실시간 1호가(매수/매도) 시세가 무료로 제공됩니다. (미국은 유료시세 제공 X)
아시아 국가의 경우, HTS(efriend Plus) [7781] 시세신청(실시간) 화면에서 유료 서비스 신청 시,
"해외주식 실시간호가 HDFSASP0" 을 이용하여 아시아국가 유료시세(실시간호가)를 받아보실 수 있습니다. (24.11.29 반영)
(아시아 국가 무료시세는 "해외주식 지연호가(아시아) HDFSASP1" 를 이용하시기 바랍니다.)
Args:
tr_type (str): [필수] 등록/해제
tr_key (str): [필수] 종목코드
Returns:
message (dict): 메시지 데이터
columns (list[str]): 컬럼 정보
Example:
>>> msg, columns = asking_price("1", "DNASAAPL")
>>> print(msg, columns)
"""
# 필수 파라미터 검증
if tr_type == "":
raise ValueError("tr_type is required")
if tr_key == "":
raise ValueError("tr_key is required")
tr_id = "HDFSASP0"
params = {
"tr_key": tr_key,
}
msg = ka.data_fetch(tr_id, tr_type, params)
columns = [
"symb",
"zdiv",
"xymd",
"xhms",
"kymd",
"khms",
"bvol",
"avol",
"bdvl",
"advl",
"pbid1",
"pask1",
"vbid1",
"vask1",
"dbid1",
"dask1"
]
return msg, columns
##############################################################################################
# [해외주식] 실시간시세 > 해외주식 실시간체결통보[실시간-009]
##############################################################################################
def ccnl_notice(
tr_type: str,
tr_key: str,
env_dv: str,
) -> tuple[dict, list[str]]:
"""
해외주식 실시간체결통보 API입니다.
Args:
tr_type (str): [필수] 등록/해제
tr_key (str): [필수] 종목코드
env_dv (str): [필수] 실전모의구분 (ex. real:실전, demo:모의)
Returns:
message (dict): 메시지 데이터
columns (list[str]): 컬럼 정보
Example:
>>> msg, columns = ccnl_notice("1", trenv.my_htsid, "real")
>>> print(msg, columns)
"""
# 필수 파라미터 검증
if tr_type == "":
raise ValueError("tr_type is required")
if tr_key == "":
raise ValueError("tr_key is required")
if env_dv == "":
raise ValueError("env_dv is required (e.g. 'real', 'demo')")
# tr_id 구분
if env_dv == "real":
tr_id = "H0GSCNI0"
elif env_dv == "demo":
tr_id = "H0GSCNI9"
else:
raise ValueError("env_dv can only be real or demo")
params = {
"tr_key": tr_key,
}
msg = ka.data_fetch(tr_id, tr_type, params)
columns = [
"CUST_ID",
"ACNT_NO",
"ODER_NO",
"OODER_NO",
"SELN_BYOV_CLS",
"RCTF_CLS",
"ODER_KIND2",
"STCK_SHRN_ISCD",
"CNTG_QTY",
"CNTG_UNPR",
"STCK_CNTG_HOUR",
"RFUS_YN",
"CNTG_YN",
"ACPT_YN",
"BRNC_NO",
"ODER_QTY",
"ACNT_NAME",
"CNTG_ISNM",
"ODER_COND",
"DEBT_GB",
"DEBT_DATE",
"START_TM",
"END_TM",
"TM_DIV_TP",
"CNTG_UNPR12"
]
return msg, columns
##############################################################################################
# [해외주식] 실시간시세 > 해외주식 지연호가(아시아)[실시간-008]
##############################################################################################
def delayed_asking_price_asia(
tr_type: str,
tr_key: str,
) -> tuple[dict, list[str]]:
"""
해외주식 지연호가(아시아)의 경우 아시아 무료시세(지연호가)가 제공됩니다.
HTS(efriend Plus) [7781] 시세신청(실시간) 화면에서 유료 서비스 신청 시,
"해외주식 실시간호가 HDFSASP0" 을 이용하여 아시아국가 유료시세(실시간호가)를 받아보실 수 있습니다. (24.11.29 반영)
※ 지연시세 지연시간 : 홍콩, 베트남, 중국, 일본 - 15분지연
Args:
tr_type (str): [필수] 등록/해제
tr_key (str): [필수] 종목코드
Returns:
message (dict): 메시지 데이터
columns (list[str]): 컬럼 정보
Example:
>>> msg, columns = delayed_asking_price_asia("1", "DHKS00003")
>>> print(msg, columns)
"""
# 필수 파라미터 검증
if tr_type == "":
raise ValueError("tr_type is required")
if tr_key == "":
raise ValueError("tr_key is required")
tr_id = "HDFSASP1"
params = {
"tr_key": tr_key,
}
msg = ka.data_fetch(tr_id, tr_type, params)
columns = [
"symb",
"zdiv",
"xymd",
"xhms",
"kymd",
"khms",
"bvol",
"avol",
"bdvl",
"advl",
"pbid1",
"pask1",
"vbid1",
"vask1",
"dbid1",
"dask1"
]
return msg, columns
##############################################################################################
# [해외주식] 실시간시세 > 해외주식 실시간지연체결가[실시간-007]
##############################################################################################
def delayed_ccnl(
tr_type: str,
tr_key: str,
) -> tuple[dict, list[str]]:
"""
해외주식 실시간지연체결가의 경우 기본적으로 무료시세(지연체결가)가 제공되며,
아시아국가의 경우 HTS(efriend Plus) [7781] 시세신청(실시간) 화면에서 유료 서비스 신청 시 API로도 유료시세(실시간체결가)를 받아보실 수 있습니다. (24.11.29 반영)
※ 지연시세 지연시간 : 미국 - 실시간무료(0분지연) / 홍콩, 베트남, 중국, 일본 - 15분지연 (중국은 실시간시세 신청 시 무료실시간시세 제공)
미국의 경우 0분지연시세로 제공되나, 장중 당일 시가는 상이할 수 있으며, 익일 정정 표시됩니다.
해당 API로 미국주간거래(10:00~16:00) 시세 조회도 가능합니다.
※ 미국주간거래 실시간 조회 시, 맨 앞자리(R), tr_key 중 시장구분 값을 다음과 같이 입력 → 나스닥: BAQ, 뉴욕: BAY, 아멕스: BAA
Args:
tr_type (str): [필수] 등록/해제
tr_key (str): [필수] 종목코드
Returns:
message (dict): 메시지 데이터
columns (list[str]): 컬럼 정보
Example:
>>> msg, columns = delayed_ccnl("1", "DNASAAPL")
>>> print(msg, columns)
"""
# 필수 파라미터 검증
if tr_type == "":
raise ValueError("tr_type is required")
if tr_key == "":
raise ValueError("tr_key is required")
tr_id = "HDFSCNT0"
params = {
"tr_key": tr_key,
}
msg = ka.data_fetch(tr_id, tr_type, params)
columns = [
"SYMB",
"ZDIV",
"TYMD",
"XYMD",
"XHMS",
"KYMD",
"KHMS",
"OPEN",
"HIGH",
"LOW",
"LAST",
"SIGN",
"DIFF",
"RATE",
"PBID",
"PASK",
"VBID",
"VASK",
"EVOL",
"TVOL",
"TAMT",
"BIVL",
"ASVL",
"STRN",
"MTYP"
]
return msg, columns