국내주식에 대한 일봉/주봉/월봉, 분봉 데이터를 뽑아보자.
mojito2
모듈에서는 fetch-ohlcv
메서드를 통해서 데이터를 얻을 수 있는데, 리턴되는 값의 형식은 output2에 dictionary 타입으로 출력된다.
0. 객체 생성
import mojito
import pprint
key = "PStmW7....t"
secret = "7gPSHO....="
acc_no = "12345678-0"
# 객체 생성
broker = mojito.KoreaInvestment(
api_key=key,
api_secret=secret,
acc_no=acc_no # 모의투자계좌라면 mock=True 추가
)
1. 분봉 조회
result = broker.fetch_today_1m_ohlcv("005930")
df = pd.DataFrame(result['output2'])
dt = pd.to_datetime(df['stck_bsop_date'] + ' ' + df['stck_cntg_hour'], format="%Y%m%d %H%M%S")
df.set_index(dt, inplace=True)
df = df[['stck_oprc', 'stck_hgpr', 'stck_lwpr', 'stck_prpr', 'cntg_vol']]
df.columns = ['open', 'high', 'low', 'close', 'volume']
df.index.name = "datetime"
df = df[::-1]
print(df)
위에 있는 코드는 현재 https://wikidocs.net/178242 에 있는 코드로, 파이썬에서 해당 코드를 그대로 실행해보면 Keyerror가 발생한다…
문제를 찾기 위해서 fetch_today_1m_ohlcv
의 코드 일부분을 수정해서 원인을 찾을 수 있었다. while loop를 통해서 _fetch_today_1m_ohlcv
에서 api로 분봉 데이터를 계속해서 polling을 하는데, 신한투자증권의 해당 API의 경우에는 가상투자계좌(Mock)의 경우에는 초당 5건으로 제한이 되어있다.
while last_hour > "090100":
# last minute
dt1 = datetime.datetime(
year=now.year,
month=now.month,
day=now.day,
hour=int(last_hour[:2]),
minute=int(last_hour[2:4])
)
delta = datetime.timedelta(minutes=1)
# 1 minute ago
dt2 = dt1 - delta
to = dt2.strftime("%H%M%S")
# request 1minute ohlcv
output = self._fetch_today_1m_ohlcv(symbol, to)
# 코드 수정한 부분 ###########################################
if 'output2' in output:
print(output['output2'])
output2 = output['output2']
last_hour = output2[-1]['stck_cntg_hour']
result['output2'].extend(output2)
else:
print("output2가 응답에 없습니다.")
# 코드 수정한 부분 ###########################################
# output2 = output['output2']
# last_hour = output2[-1]['stck_cntg_hour']
# result['output2'].extend(output2)
return result
** fetch_today_1m_ohlcv **
def fetch_today_1m_ohlcv(self, symbol: str, to: str=""):
"""국내주식시세/주식당일분봉조회
Args:
symbol (str): 6자리 종목코드
to (str, optional): "HH:MM:00". Defaults to "".
"""
result = {}
now = datetime.datetime.now()
if to == "":
to = now.strftime("%H%M%S")
# kospi market end time
if to > "153000":
to = "153000"
output = self._fetch_today_1m_ohlcv(symbol, to)
output2 = output['output2']
last_hour = output2[-1]['stck_cntg_hour']
result['output1'] = output['output1']
result['output2'] = output2
while last_hour > "090100":
# last minute
dt1 = datetime.datetime(
year=now.year,
month=now.month,
day=now.day,
hour=int(last_hour[:2]),
minute=int(last_hour[2:4])
)
delta = datetime.timedelta(minutes=1)
# 1 minute ago
dt2 = dt1 - delta
to = dt2.strftime("%H%M%S")
# request 1minute ohlcv
output = self._fetch_today_1m_ohlcv(symbol, to)
if 'output2' in output:
print(output['output2'])
output2 = output['output2']
last_hour = output2[-1]['stck_cntg_hour']
result['output2'].extend(output2)
else:
print("output2가 응답에 없습니다.")
# output2 = output['output2']
# last_hour = output2[-1]['stck_cntg_hour']
# result['output2'].extend(output2)
return result
def _fetch_today_1m_ohlcv(self, symbol: str, to: str):
"""국내주식시세/주식당일분봉조회
Args:
symbol (str): 6자리 종목코드
to (str): "HH:MM:SS"
"""
path = "/uapi/domestic-stock/v1/quotations/inquire-time-itemchartprice"
url = f"{self.base_url}/{path}"
headers = {
"content-type": "application/json; charset=utf-8",
"authorization": self.access_token,
"appKey": self.api_key,
"appSecret": self.api_secret,
"tr_id": "FHKST03010200",
"tr_cont": "",
}
params = {
"fid_etc_cls_code": "",
"fid_cond_mrkt_div_code": "J",
"fid_input_iscd": symbol,
"fid_input_hour_1": to,
"fid_pw_data_incu_yn": "Y"
}
res = requests.get(url, headers=headers, params=params)
return res.json()
2. API 직접 분봉 데이터 호출해보기
import pickle
import requests
import pprint
url = "https://openapivts.koreainvestment.com:29443//uapi/domestic-stock/v1/quotations/inquire-time-itemchartprice"
with open("token.dat", "rb") as f:
data = pickle.load(f)
access_token = f'Bearer {data["access_token"]}'
headers = {
"content-type": "application/json; charset=utf-8",
"authorization": access_token,
"appKey": key,
"appSecret": secret,
"tr_id": "FHKST03010200",
"tr_cont": "",
}
params = {
"fid_etc_cls_code": "",
"fid_cond_mrkt_div_code": "J",
"fid_input_iscd": "005930",
"fid_input_hour_1": "",
"fid_pw_data_incu_yn": "Y"
}
res = requests.get(url, headers=headers, params=params)
data = res.json()
pprint.pprint(data)