Files
KisStock0/한국투자증권(API)/legacy/rest/get_ovsfut_chart_price.py
2026-02-04 00:16:34 +09:00

150 lines
6.0 KiB
Python

## 해외선물분봉조회: 해외선물 상품의 특정 기간동안의 분봉을 받아서 엑셀로 저장하는 파이썬 샘플코드
## config.yaml 파일을 설정한 뒤 get_ovsfut_chart_price.py를 실행해서 분봉 데이터 저장 가능
## 해외선물 종목정보 마스터파일 다운로드 : https://new.real.download.dws.co.kr/common/master/ffcode.mst.zip
# (0) 필요 모듈 임포트
import pandas as pd
import requests
import json
import yaml
import time
# (1) 개인정보 파일 가져오기
with open('config.yaml', encoding='UTF-8') as f:
_cfg = yaml.load(f, Loader=yaml.FullLoader)
APP_KEY = _cfg['APP_KEY']
APP_SECRET = _cfg['APP_SECRET']
ACCESS_TOKEN = ""
ACCESS_TOKEN_EXPIRED = ""
CANO = _cfg['CANO']
ACNT_PRDT_CD = _cfg['ACNT_PRDT_CD']
URL_BASE = _cfg['URL_BASE']
HTS_ID = _cfg['HTS_ID']
# (2) 함수 정의
def get_access_token():
""" OAuth 인증 > 접근토큰발급 """
headers = {"content-type": "application/json"}
body = {"grant_type": "client_credentials",
"appkey": APP_KEY,
"appsecret": APP_SECRET}
PATH = "oauth2/tokenP"
URL = f"{URL_BASE}/{PATH}"
res = requests.post(URL, headers=headers, data=json.dumps(body))
time.sleep(0.1)
try:
ACCESS_TOKEN = res.json()["access_token"]
ACCESS_TOKEN_EXPIRED = res.json()["access_token_token_expired"]
return ACCESS_TOKEN, ACCESS_TOKEN_EXPIRED
except:
print("접근 토큰 발급이 불가능합니다")
print(res.json())
def get_overseas_future_time_price(SRS="6AZ23", EXCH="CME", STRT_DT="",END_DT="", CNT="100", GAP="1", dataframe=None, file_name=None): # 해외선물옵션시세 > 해외선물 분봉조회
"""
해외선물옵션시세 > 해외선물 분봉조회를 위한 함수
Parameters:
- SRS: 종목 코드
- EXCH: 거래소 코드
- STRT_DT: 조회 시작일
- END_DT: 조회 종료일
- CNT: 호출건당 조회 갯수
- GAP: 조회 간격
- dataframe: 초기 데이터프레임
- file_name: 저장할 파일 이름
Returns"":
- 최종 데이터프레임
"""
PATH = "/uapi/overseas-futureoption/v1/quotations/inquire-time-futurechartprice"
URL = f"{URL_BASE}/{PATH}"
headers = {"Content-Type":"application/json",
"authorization":f"Bearer {ACCESS_TOKEN}",
"appKey":APP_KEY,
"appSecret":APP_SECRET,
"tr_id":"HHDFC55020400", # 실전투자
"custtype":"P"
}
params = {
"SRS_CD": SRS,
"EXCH_CD": EXCH,
"START_DATE_TIME": "",
"CLOSE_DATE_TIME": END_DT,
"QRY_TP": "",
"QRY_CNT": CNT,
"QRY_GAP": GAP,
"INDEX_KEY": ""
}
res = requests.get(URL, headers=headers, params=params)
time.sleep(0.1) # 유량제한 예방 (REST: 1초당 20건 제한)
output = res.json()['output1']
# 파일 이름이 제공되지 않은 경우에만 생성
if file_name is None:
file_name = f"{SRS}_{EXCH}_{STRT_DT}_{END_DT}"
# 초기 dataframe 생성
if dataframe is None:
dataframe = pd.DataFrame()
current_dataframe = pd.DataFrame(output)
# 이전 응답값이 존재하고, 이전 응답값과 현재 응답값이 동일하면
if not dataframe.empty and dataframe.iloc[-1,0] == current_dataframe.iloc[-1,0] and dataframe.iloc[-1,1] == current_dataframe.iloc[-1,1]:
# 이전 데이터프레임에 현재 데이터프레임 추가
dataframe = pd.concat([dataframe, current_dataframe], ignore_index=True)
# STRT_DT와 END_DT가 같은 경우 현재 dataframe을 return
if STRT_DT == END_DT:
dataframe = dataframe.drop_duplicates(ignore_index=True)
# 최종 데이터프레임 정제 작업(이상치 삭제 및 date, time으로 정렬)
## 'data_date'와 'data_time'을 문자열로 변환하여 문자열을 합쳐 datetime 형식으로 만들기
dataframe['datetime'] = pd.to_datetime(dataframe['data_date'].astype(str) + dataframe['data_time'].astype(str).str.zfill(6), errors='coerce', format='%Y%m%d%H%M%S')
## 유효한 datetime이 아닌 행 삭제
dataframe = dataframe.dropna(subset=['datetime'])
## 'datetime'을 기준으로 정렬 후 'datetime' 열 삭제
dataframe = dataframe.sort_values(by=['datetime']).drop(columns=['datetime']).reset_index(drop=True)
# 현재 위치에 엑셀파일로 저장
dataframe.to_excel(f"{file_name}.xlsx",index=False)
print("File Saved")
# 최종 데이터프레임 return
return dataframe
else:
# END_DT를 하루 이전으로 설정하고 재귀호출
END_DT = pd.to_datetime(END_DT) - pd.DateOffset(days=1)
END_DT = END_DT.strftime("%Y%m%d")
return get_overseas_future_time_price(SRS, EXCH, STRT_DT, END_DT, "100", GAP, dataframe, file_name)
else:
# 이전 데이터프레임에 현재 데이터프레임 추가
dataframe = pd.concat([dataframe, current_dataframe], ignore_index=True)
# 이전 응답값과 현재 응답값이 다르면 CNT를 100늘려서 재호출
CNT = str(int(CNT) + 100)
# print(SRS, EXCH, STRT_DT, END_DT, CNT, GAP)
return get_overseas_future_time_price(SRS, EXCH, STRT_DT, END_DT, CNT, GAP, dataframe, file_name)
# (3) 함수 실행
# 접근토큰 발급
ACCESS_TOKEN, ACCESS_TOKEN_EXPIRED = get_access_token()
# 사용자 입력 받기
SRS = input("종목 코드를 입력하세요(ex. 6AZ23): ")
EXCH = input("거래소 코드를 입력하세요(ex. CME): ")
STRT_DT = input("조회 시작일을 입력하세요 (YYYYMMDD 형식): ")
END_DT = input("조회 종료일을 입력하세요 (YYYYMMDD 형식): ")
GAP = input("조회 간격(분)을 입력하세요 (ex. 1) : ")
# 해외선물분봉조회 호출
print("Downloading...")
result_dataframe = get_overseas_future_time_price(SRS=SRS, EXCH=EXCH, STRT_DT=STRT_DT, END_DT=END_DT, CNT="100", GAP=GAP)
result_dataframe[:3]