본문 바로가기

파이썬으로 퀀트 프로그램 만들기 project

한국투자증권 api 사용하기_1

728x90

#모의투자 신청

먼저 한국투자증권 홈페이지 로그인하여 모의투자를 신청해줍니다. 그리고 모의투자 계좌번호를 기억해둡니다.

 

 

#api 신청

api 신청해줍니다. [트레이딩] -> [Open API] -> [KIS Developers] -> [KIS Developers 서비스 신청하기]

모의투자 계좌, 국내주식에 5억원 신청해줍니다.

 

 

#keyring 패키지를 통한 app key, app secret 기억하기

vscode를 키고 다음을 입력합니다.

 

import keyring

#종합계좌
real_app_key = keyring.set_password('real_app_key', 'User Name', 'App key') # 'App key' 자리에 발급받은 app key 입력
real_app_secret = keyring.set_password('real_app_secret', 'User Name', 'App secret')# 'App secret' 자리에 발급받은 app secret 입력

#모의계좌
mock_app_key = keyring.set_password('mock_app_key', 'User Name', 'App key')# 'App key' 자리에 발급받은 app key 입력
mock_app_secret = keyring.set_password('mock_app_secret', 'User Name', 'App secret')# 'App secret' 자리에 발급받은 app secret 입력

 

해당 app key와 app secret은 유출되지 않도록 조심합니다.

 

 

 

#접근토크와 해쉬키 발급받기

API를 이용해 조회 및 주문을 하기 위해서는 접근토큰과 해쉬키가 필요합니다. 앞서 발급받은 App key와 App secret을 이용해 접근토큰을 받을 수 있습니다. 이 접근 토큰을 통해 계좌에 접근할 수 있습니다.

홈페이지에서 [트레이딩] -> [Open API] -> [KIS Developers] -> [서비스 안내] 로 들어가줍니다.

여기서 [API 문서] -> [접근토큰발급(P)] 를 클릭해줍니다.

모의투자와 실전투자의 도메인 주소를 알 수 있고 POST방식임을 알 수 있습니다.

여기서 다시 [도구] -> [Wikidocs] ->[파이썬으로 배우는 오픈 api예제]를 눌러보시면 이것을 통해 api 사용 예시를 알 수 있습니다. 이것을 참조하여 파이썬 코드를 작성해보겠습니다. 이전 파이썬 코드에 이어서 작성해주시면 됩니다.

 

import json
import requests
import keyring

#key
app_key = keyring.get_password('mock_app_key', 'User name')
app_secret = keyring.get_password('mock_app_secret', 'User name')

#base url
url_base = "https://openapivts.koreainvestment.com:29443" #모의투자

#information
path = "oauth2/tokenP"
body = {"grant_type":"client_credentials",
        "appkey":app_key, 
        "appsecret":app_secret}

url = f"{url_base}/{path}"
res = requests.post(url, headers=headers, data=json.dumps(body)) # url에 데이터 전송
access_tocken = res.json()['access_token']

 

 

이렇게 하면 접근 토큰을 받을 수 있습니다. 이제 해쉬키를 받아야합니다.

조회가 아닌 주문이나 정정, 취소등을 할 때에는 추가적으로 해쉬키가 필요합니다.

해쉬키란 보안을 위한 요소로 사용자가 보낸 요청 값을 중간에 탈취하여 변조하지 못하도록 하는데 사용됩니다.

해쉬키는 요청하는 데이터마다 변하므로 함수로 만드는 것이 편합니다. 그 방법 역시 wikidocs에 나와 있습니다.

 

# 해쉬키 발급받기
def hashkey(datas):
  path = "uapi/hashkey"
  url = f"{url_base}/{path}"
  headers = {
    'content-Type' : 'application/json',
    'appKey' : app_key,
    'appSecret' : app_secret,
    }
  res = requests.post(url, headers=headers, data=json.dumps(datas))
  hashkey = res.json()["HASH"]

  return hashkey

 

 

#주식 현재가 시세 조회하기

먼저 삼성전자의 현재가를 조회해보도록 하겠습니다.

홈페이제에서 KIS Developers 에서 '국내주식시세' -> '주식현재가 시세' 를 보시면 방법이 나와 있습니다.

get 방식을 쓰고 입력값으로 어떤게 필요한지가 나와 있습니다. 법인에 해당하는 부분은 입력하지 않아도 됩니다.

이것의 사용법 역시 wikidocs에 제공되어 있습니다.

 

#주식 현재가 시세 조회하기
path = "uapi/domestic-stock/v1/quotations/inquire-price"
url = f"{url_base}/{path}"

headers = {"Content-Type":"application/json", 
           "authorization": f"Bearer {access_tocken}",
           "appKey":app_key,
           "appSecret":app_secret,
           "tr_id":"FHKST01010100"}
#tr_id는 거래 id에 해당하며, 원하는 작업마다 tr_id가 다름
params = {
    "fid_cond_mrkt_div_code":"J",
    "fid_input_iscd":"005930"
}

res = requests.get(url, headers=headers, params=params)
res.json()['output']['stck_prpr']

 

 

#매수 주문하기

시장가로 삼성전자를 매수해보겠습니다.

#시장가 매수 주문하기
path = "uapi/domestic-stock/v1/trading/order-cash"
url = f"{url_base}/{path}"

data = {
    "CANO": "계좌번호 앞 8자리", # 계좌번호 앞 8 자리
    "ACNT_PRDT_CD": "계좌번호 뒤 2자리", # 계좌번호 뒤 2자리
    "PDNO": "005930", # 종목코드
    "ORD_DVSN": "01", # 주문방법 (시장가의 경우 01)
    "ORD_QTY": "10", # 주문 수량
    "ORD_UNPR": "0", #주문 단가(시장가의 경우 0)
}

headers = {"Content-Type":"application/json", 
           "authorization":f"Bearer {access_tocken}",
           "appKey":app_key,
           "appSecret":app_secret,
           "tr_id":"VTTC0802U",
           "custtype":"P",
           "hashkey" : hashkey(data)}

res = requests.post(url, headers=headers, data=json.dumps(data))
res.json()

 

 

# 정정 주문하기

먼저 위의 코드에서 지정가로 낮은 가격으로 매수하는 코드로 수정하겠습니다.

#매수 주문하기
path = "uapi/domestic-stock/v1/trading/order-cash"
url = f"{url_base}/{path}"

data = {
    "CANO": "계좌번호 앞 8자리", # 계좌번호 앞 8 자리
    "ACNT_PRDT_CD": "계좌번호 뒤 2자리", # 계좌번호 뒤 2자리
    "PDNO": "005930", # 종목코드
    "ORD_DVSN": "00", # 주문방법 (시장가의 경우 01, 지정가의 경우 00)
    "ORD_QTY": "10", # 주문 수량
    "ORD_UNPR": "50000", #주문 단가(시장가의 경우 0)
}

headers = {"Content-Type":"application/json", 
           "authorization":f"Bearer {access_tocken}",
           "appKey":app_key,
           "appSecret":app_secret,
           "tr_id":"VTTC0802U",
           "custtype":"P",
           "hashkey" : hashkey(data)}

res = requests.post(url, headers=headers, data=json.dumps(data))
res.json()

50000원의 가격에 매수를 걸었습니다. hts로 확인해 보시면 현재가 보다 낮은 가격으로 매수를 걸었기 때문에 채결은 안되고 미채결 상태로 남아있습니다.

다시 매수 가격에 정정 주문을 하기 위해서는 '한국거래소전송주문조직번호' 와 '주문번호' 정보를 알아야 합니다.

이전 코드의 res.json()의 출력값에서 'KRX_FWDG_ORD_ORGNO' 가 '한국거래소전송주문조직번호'에 해당합니다.

주문번호는 'ODNO'에 해당하는 값입니다.

해당 정보를 이용해 미체결된 주문을 '최유리 지정가'로 변경하여 정정 주문을 해보겠습니다.

 

KRX_FWDG_ORD_ORGNO = res.json()["output"]["KRX_FWDG_ORD_ORGNO"] #한국거래소전송주문조직번호
ODNO = res.json()["output"]["ODNO"]

#정정주문
path = "uapi/domestic-stock/v1/trading/order-rvsencl"
url = f"{url_base}/{path}"

data ={
    "CANO": "계좌번호 앞 8자리",
    "ACNT_PRDT_CD": "계좌번호 뒤 2자리",
    "KRX_FWDG_ORD_ORGNO":KRX_FWDG_ORD_ORGNO, #한국거래소전송주문조직번호
    "ORGN_ODNO":ODNO, #주문번호
    "RVSE_CNCL_DVSN_CD":"03", #주문방법 | 최유리 지정가 03
    "ORD_DVSN":"01", #정정 01 (취소는 02)
    "ORD_QTY":"10", #주문수량
    "ORD_UNPR":"0", #주문 단가 (시장가의 경우 0)
    "QTY_ALL_ORD_YN": "Y", #잔량 전부(잔량 일부는 N)
}

headers = {"Content-Type":"application/json", 
          "authorization":f"Bearer {access_tocken}",
          "appKey": app_key,
          "appSecret":app_secret,
          "tr_id":"VTTC0803U",
          "custtype":"P", 
          "hashkey" : hashkey(data)}

res = requests.post(url, headers=headers, data=json.dumps(data))
res.json()

 

 

# 시장가 매도 주문하기

시장가 매수하기와 거의 비슷합니다.  tr_id 부분만 다릅니다.

#시장가 매도 주문하기
path = "uapi/domestic-stock/v1/trading/order-cash"
url = f"{url_base}/{path}"

data = {
    "CANO": "50095584", # 계좌번호 앞 8 자리
    "ACNT_PRDT_CD": "84", # 계좌번호 뒤 2자리
    "PDNO": "005930", # 종목코드
    "ORD_DVSN": "01", # 주문방법 | 시장가: 01 , 지정가 : 00 
    "ORD_QTY": "10", # 주문 수량
    "ORD_UNPR": "0", #주문 단가(시장가의 경우0)
}

headers = {"Content-Type":"application/json", 
           "authorization":f"Bearer {access_tocken}",
           "appKey":app_key,
           "appSecret":app_secret,
           "tr_id":"VTTC0801U",
           "custtype":"P",
           "hashkey" : hashkey(data)}

res = requests.post(url, headers=headers, data=json.dumps(data))
res.json()