1. 국내주식/1-3. 키움 OpenAPI (기타)

(주식 자동 매매) 키움증권 OpenAPI - 주식외국인요청(opt10008)

봄이오네 2022. 11. 26. 08:13
반응형
목 차
1. 들어가며
2. 사전설명
3. 코드설명
4. 전체 코드 및 결과
5. 마치며

1. 들어가며

이번 글에서는 키움증권에서

주식외국인요청(opt10008)을 통해 외국인 보유주식수 등을 받아오는 방법을 알아보자.

키움증권 영웅문에서는 화면번호 0240(외국인정보)에 해당한다.

그림1. 삼성전자의 외국인정보-종목별 매매동향 현황


2. 사전 설명

1) 화면번호 0240(외국인 관련 정보)

먼저 KOA Studio에서 외국인정보를 받아오는 화면을 알아보자.

KOA Studio의 화면목록에서는

화면번호 0240에서 외국인 관련 정보를 제공한다.

그림2-1. KOA Studio의 화면목록

 

2) TR목록은 opt10008을 활용한다.

그림2-2. KOA Studio의 외국인 보유 주식 등을 나타낸다.

① 외국인 보유주식을 알아보기 위해, 입력/출력 정보를 확인한다.

② 키움증권의 SetInputvalue와 CommRqData를 활용한다.

③ 삼성전자 종목코드를 입력한다.

④ 수신받는 정보는 일자, 종가, 전일대비 변경가격 등이다.


3. 코드설명

키움증권 OpenAPI를 통해 로그인/데이터를 수신받는다.

그림3-1. 로그인을 통해 데이터를 입력/요청한다.

 

1줄~4줄 : 동시성 처리, 로그인 등을 위해 sys모듈, PyQt5 모듈을 임포트한다.

8줄~23줄 : 로그인을 요청 및 실행한다.

27줄 : 종목코드를 키움서버 OpenAPI에 입력한다.

28줄 : 종목코드를 키움서버 OpenAPI에 요청한다.

 

그림3-2. 데이터를 수신받는다.

 

32줄 : 데이터 수신을 위해 임의의 trdata_get 함수를 선언한다.

33줄 : 28줄에서 요청한 데이터가 opt_10008이면,

34줄~44줄 : 날짜, 종가, 전일대비, 거래량 등의 데이터를 받아온다.

46줄~56줄 : 일자, 종가, (외국인)보유주식수 등을 출력한다.

67줄 : 삼성전자(005930) 종목코드를 입력하여, 25줄의 함수를 실행한다.


4. 전체 코드 및 결과

import sys
from PyQt5.QAxContainer import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *

class btl_system():
    def __init__(self):
        self.kiwoom = QAxWidget("KHOPENAPI.KHOpenAPICtrl.1")

        self.kiwoom.OnEventConnect.connect(self.login_Connect)
        self.kiwoom.OnReceiveTrData.connect(self.trdata_get)

        print("로그인 요청!")
        self.kiwoom.dynamicCall("CommConnect()")
        self.login_event_loop = QEventLoop()
        self.login_event_loop.exec_()

    def login_Connect(self, nErrCode):
        if nErrCode == 0:
            print('로그인 성공하였습니다!')
        else:
            print('로그인 실패하였습니다!')
        self.login_event_loop.exit()

    def rq_data_opt10008(self, stock_code):
        print("67줄에서 입력받은 종목코드를 키움서버에 요청합니다.""\n")
        self.kiwoom.dynamicCall("SetInputValue(QString, QString)", "종목코드", stock_code)
        self.kiwoom.dynamicCall("CommRqData(QString, QString, int, QString)", "opt_10008", "opt10008", 0, "1022")
        self.tr_event_loop = QEventLoop()
        self.tr_event_loop.exec_()

    def trdata_get(self, sScrNo, rqname, strcode, sRecordName, sPreNext, nDataLength, sErrorCode, sMessage, sSplmMsg):
        if rqname == "opt_10008":
            date = self.kiwoom.dynamicCall("GetCommData(QString, QString, int, QString)", "opt10008", "주식외국인요청", 0, "일자").strip()
            close_price = self.kiwoom.dynamicCall("GetCommData(QString, QString, int, QString)", "opt10008", "주식외국인요청", 0, "종가").strip()
            yesterday_updown = self.kiwoom.dynamicCall("GetCommData(QString, QString, int, QString)", "opt10008", "주식외국인요청", 0, "전일대비").strip()
            qty = self.kiwoom.dynamicCall("GetCommData(QString, QString, int, QString)", "opt10008", "주식외국인요청", 0, "거래량").strip()
            changing_qty = self.kiwoom.dynamicCall("GetCommData(QString, QString, int, QString)", "opt10008", "주식외국인요청", 0, "변동수량").strip()
            bou_stock_qty = self.kiwoom.dynamicCall("GetCommData(QString, QString, int, QString)", "opt10008", "주식외국인요청", 0, "보유주식수").strip()
            bijung = self.kiwoom.dynamicCall("GetCommData(QString, QString, int, QString)", "opt10008", "주식외국인요청", 0, "비중").strip()
            able_stocks = self.kiwoom.dynamicCall("GetCommData(QString, QString, int, QString)", "opt10008", "주식외국인요청", 0, "취득가능주식수").strip()
            foreinger_limit = self.kiwoom.dynamicCall("GetCommData(QString, QString, int, QString)", "opt10008", "주식외국인요청", 0, "외국인한도").strip()
            foreinger_updown = self.kiwoom.dynamicCall("GetCommData(QString, QString, int, QString)", "opt10008", "주식외국인요청", 0, "외국인한도증감").strip()
            limit_per = self.kiwoom.dynamicCall("GetCommData(QString, QString, int, QString)", "opt10008", "주식외국인요청", 0, "한도소진률").strip()

            print(f"일자는 {date} 입니다.")
            print(f"종가는 {close_price}원 입니다.""\n")
            print(f"전일대비 가격은 {yesterday_updown}원 입니다.")
            print(f"거래량은 {qty}주 입니다.")
            print(f"변동수량은 {changing_qty}주 입니다.")
            print(f"보유주식수는 {bou_stock_qty}주 입니다.""\n")
            print(f"비중은 {bijung}% 입니다.")
            print(f"취식가능주식수는 {able_stocks}주 입니다.""\n")
            print(f"외국인한도는 {foreinger_limit}주 입니다.")
            print(f"외국인한도증감은 {foreinger_updown}주 입니다.")
            print(f"한도소진률은 {limit_per}% 입니다.""\n")

            try:
                self.tr_event_loop.exit()
            except AttributeError:
                pass

if __name__ == "__main__":
    app = QApplication(sys.argv)
    btl = btl_system()

    btl.rq_data_opt10008("005930")

    app.exec_()
    
    
# (expected result)
# 일자는 20221118 입니다.
# 종가는 +61800원 입니다.

# 전일대비 가격은 +400원 입니다.
# 거래량은 12236503주 입니다.
# 변동수량은 857248주 입니다.
# 보유주식수는 2979841397주 입니다.

# 비중은 +49.92% 입니다.
# 취식가능주식수는 2989941153주 입니다.

# 외국인한도는 5969782550주 입니다.
# 외국인한도증감은 0주 입니다.
# 한도소진률은 +49.92% 입니다.

5. 마치며

외국인 보유수량, 외국인 보유주식수, 비중 등을 알아보았다.

주식 체결을 할 때, 외국인의 매매 동향을 알아야 할 때가 있다.

외국인 보유 수량 등 시황 파악을 통해 지혜롭게 투자하는 안목을 가지자.

반응형