키움 OPEN API에 TR 요청하기(feat. 예수금과 계좌잔고 받아오기)

 

 

지난 글 보기

01_시작

02_기본설정

03_pykiwoom vs. 직접코딩

04_키움 open api 로그인 하기

 

 

 

지난 시간에 키움 api 자동 로그인까지 성공했다.

로그인을 했으니 나의 계좌 정보를 받아와야 하겠다. 대표적으로 예수금과 계좌평가잔고내역 받아오기를 해보았다.

코드 작성을 위한 전반적인 도움은 지난 글에서 설명한 유튜브 "프로그램 동산" 채널을 도움을 받았다.

 

 

조회하고자 하는 내용은 영웅문에서 다음의 내용이다.

나는 모의투자로 1,000만원을 신청해둔 상태이며, 아직 매매를 하지 않아 1,000만원이 모두 예수금 잔액으로 잡혀있다.

 

영웅문 예수금상세현황 조회

 

영웅문 계좌평가잔고내역 조회

 

 

영웅문에서 화면으로 조회되는 것을 OPEN API로 조회하기 위해서는 TR(Transaction)을 요청해야 하며, 어떤 요구사항들이 있는지 알아보기 위해 KOA를 실행한다.

 

 

키움 KOA TR 요청 - 예수금 검색

 

KOA에서 하단의 "TR목록"을 클릭하고, 상단 검색란에 "예수금"을 입력한 뒤 엔터키 말고 마우스로 "다음"을 클릭한다.

opw00001을 찾아 클릭하면 위와 같은 화면이 조회된다. 받을 수 있는 자료 목록이 왼쪽에 나열되고, C++ 기준 예제 코드가 중앙 상단에 위치하고 있다. 오른쪽에 있는 조회 창에 계좌번호 등의 정보를 입력하면, 하단에 출력된다.

 

나의 예수금이 1,000만원으로 조회되었지만, 앞에 0이 많이 붙어 숫자가 아닌 text 형식임을 추측할 수 있다.

 

 

키움 KOA TR 요청 - 예수금 검색

 

 

위에서 조회한 데이터를 요청하는 방법은 KOA 하단의 "개발가이드"에서 찾을 수 있다. 각종 조회와 실시간데이터처리 중 "OnReceiveTrData"를 활용할 수 있다. 함께 넘겨야하는 파라미터들도 확인할 수 있다.

 

 

 

 

이제 코드로 넘어간다.

지난 시간의 코드와 중복되는 코드는 생략하여 "def" 부분만 표기한다.

from PyQt5.QAxContainer import *
from PyQt5.QtCore import *
from config.errorCode import *

class Kiwoom(QAxWidget):
    def __init__(self):
        super().__init__()

        ### event loop 모음 ###############################
        self.login_event_loop = None
        self.detail_account_info_event_loop = None
        self.detail_account_info_event_loop_2 = None
        ##################################################

        ### 변수 모음 #####################################
        self.account_num = None
        self.account_pw = "********"
        ##################################################

        self.detail_account_info()
        self.detail_account_mystock()

    def get_ocx_instance(self):
    def event_slots(self):
        self.OnReceiveTrData.connect(self.trdata_slot) # 예수금 받기 이벤트 생성
    def signal_login_commConnect(self):
    def login_slot(self, errCode):
    def get_account_info(self):

    def detail_account_info(self):
        # 예수금 조회를 위한 Open API 조회 함수 입력값을 설정
        self.dynamicCall("SetInputValue(String, String)", "계좌번호", self.account_num)
        self.dynamicCall("SetInputValue(String, String)", "비밀번호", self.account_pw)
        self.dynamicCall("SetInputValue(String, String)", "비밀번호입력매체구분", "00")
        self.dynamicCall("SetInputValue(String, String)", "조회구분", "2")
        self.dynamicCall("CommRqData(String, String, int, String)", "예수금상세현황요청", "opw00001", "0", "2000")
        self.detail_account_info_event_loop = QEventLoop()
        self.detail_account_info_event_loop.exec_()

    def detail_account_mystock(self, sPrevNext="0"):
        # 계좌평가 잔고내역 요청
        # sPrevNext="0" : 싱글데이터 받아오기(종목합계 데이터)
        self.dynamicCall("SetInputValue(String, String)", "계좌번호", self.account_num)
        self.dynamicCall("SetInputValue(String, String)", "비밀번호", self.account_pw)
        self.dynamicCall("SetInputValue(String, String)", "비밀번호입력매체구분", "00")
        self.dynamicCall("SetInputValue(String, String)", "조회구분", "2")
        self.dynamicCall("CommRqData(String, String, int, String)", "계좌평가잔고내역요청", "opw00018", sPrevNext, "2000")
        self.detail_account_info_event_loop_2 = QEventLoop()
        self.detail_account_info_event_loop.exec_()

    def trdata_slot(self, sScrNo, sRQName, sTrCode, sRecordName, sPrevNext):
        # TR SLOT 만들기
        '''
        TR 요청을 받는 구역, slot임
        :param sScrNo: 스크린 번호
        :param sRQName: 내가 요청했을 때 지은 이름
        :param sTrCode: 요청 ID, TR코드
        :param sRecordName: 사용안함
        :param sPrevNext: 다음 페이지가 있는지
        :return:
        '''

        # 예수금 등 조회 하기
        if sRQName == "예수금상세현황요청":
            deposit = self.dynamicCall("GetCommData(String, String, int, String)", sTrCode, sRQName, 0, "예수금")
            print("예수금 %s" % int(deposit))

            ok_deposit = self.dynamicCall("GetCommData(String, String, int, String)", sTrCode, sRQName, 0, "출금가능금액")
            print("출금가능금액 %s" % int(ok_deposit))

            self.detail_account_info_event_loop.exit()

        # 계좌평가잔고 조회 하기
        if sRQName == "계좌평가잔고내역요청":
            total_buy_money = self.dynamicCall("GetCommData(String, String, int, String)", sTrCode, sRQName, 0, "총매입금액")
            print("총매입금액 %s" % int(total_buy_money))

            total_profit_loss_rate = self.dynamicCall("GetCommData(String, String, int, String)", sTrCode, sRQName, 0, "총수익률(%)")
            print("총수익률 %s" % float(total_profit_loss_rate))

            self.detail_account_info_event_loop_2.exit()

 

 

 

 

조회 요청을 한 뒤, 응답이 오기 전에 다음 라인의 코드가 실행되지 않도록 이벤트 루프를 __init__안에 생성한다.

"self.detail_account_info_event_loop = None"
"self.detail_account_info_event_loop_2 = None"

 

예수금과 계좌잔고 조회를 실행할 수 있도록 __init__안에 마련한다.

"self.detail_account_info()"

"self.detail_account_mystock()"

 

"def event_slots"에 예수금을 받기 위한 이벤트를 만들어 준다(self.OnReceiveTrData.connect(self.trdata_slot)). "OnReceiveTrData"는 위 KOA에서 살펴봤다.

 

 

"def detail_account_info(self):"는 예수금 TR 요청을 위한 공간이다.

SetInputValue로 넘길 값을 형태를 지정해주고 dynamicCall로 데이터를 전송한다. 넘겨야 하는 데이터는 위 KOA에서 예수금 조회할 때 넘긴 것과 동일하다.

 

넘길 데이터를 다 입력했으면, 조회할 데이터는 이벤트 내부에서 OPEN API 조회 함수인 "CommRqData()"를 호출해서 서버로 전송한다. 이때 함께 전송할 자료는 요청이름(각자 네이밍 가능), TR번호, preNext, 화면번호(스크린넘버-하단에 별도 설명)이다.

 

조회 후 결과가 도착하기 전에 다음 코드가 실행되지 않도록 PyQt의 Event Loop를 열어준다.

 

 

"def detail_account_mystock(self, sPrevNext="0"):"는 예수금 조회와 같은 내용이다. 다만, 계좌평가잔고내역을 요청하는 코드이다.

 

 

"def trdata_slot(self, sScrNo, sRQName, sTrCode, sRecordName, sPrevNext):"로 TR 데이터 슬롯을 열어준다. 예수금과 계좌평가잔고 코드를 입력한다. 각 요청한 TR을 받은 뒤 열어둔 Event Loop를 닫아준다.

 

 

코드 실행 결과

 

 

 

 

 

아.... 길다....

 

위에서 넘어간 화면번호(스크린넘버)는 키움 OPEN API가 TR 요청에 의해 데이터를 넘겨주면서 그룹을 지어서 넘겨준다. 그 그룹의 이름을 "화면번호(스크린넘버)"라고 부른다. [1]

 

화면번호(스크린넘버)는 0과 0000을 제외한 4자리 숫자로 구성하여 200개까지 만들 수 있다.

그리고 각 화면번호(스크린넘버)에는 100개의 TR 요청 결과를 담을 수 있다.

 

TR 요청을 중구난방으로 하게 되면, 관리가 안되니 일종의 grouping 기능을 넣어준 것이라 해석된다.

 

예를 들어, 코스피200의 일봉을 요청하는데

화면번호 1000번 : 전자통신 30 종목

화면번호 2000번 : 화학 40 종목

화면번호 3000번 : 바이오 60 종목

화면번호 4000번 : 제조 70개 종목

등으로 그룹을 지어 결과를 저장할 수 있는 방식이다. 

 

화면번호(스크린넘버)는 삭제할 수 있고, 삭제되면 거기에 포함된 TR 요청은 모두 삭제되는 등 관리적 기능도 포함되어 있다.

 

 

 

도움받은 곳

[1] www1.kiwoom.com/nkw.templateFrameSet.do?m=m1408000000

    : 위 고객 문의 게시판에서 "스크린번호"를 검색하면 관련 내용을 찾아볼 수 있다.

 

 

 

파이썬을 학습하며 남기는 블로그입니다.
질문, 지적, 조언은 항상 환영합니다.

 

 

2021.01.05. 코리.

 

04. 키움 open api 로그인 하기

 

이전 글 보러 가기

01_시작

02_기본설정

03_pykiwoom vs. 직접코딩

 

 

하루 사이에 대문이 조금 바뀌었다.

IDE를 vs code에서 pycharm으로 변경했다. vs code가 전반적으로 많은 사람들이 사용하지만, python 사용자들은 pycharm을 더 많이 사용한다는 글을 보았다. 그리고, pycharm이 python 문법을 작성하는게 더 편리했다. 

 

 

키움 open api에 로그인하기 위한 코드는 다음과 같다.

코드 작성을 위한 전반적인 도움은 지난 글에서 설명한 유튜브 "프로그램 동산" 채널을 도움을 받았다.

 

 

from PyQt5.QAxContainer import *
from PyQt5.QtCore import *
from config.errorCode import *

필요한 패키지를 import 한다.

"PyQt5.QAxContainer"는 ActiveX를 비롯한 OCX에 대한 관리를 위한 것이고 [1]

"PyQt5.QtCore"는 event loop를 사용하기 위함이고  [2]

세 번째 라인은 에러 메시지를 관리하기 위함이다. 이건 아래에서 다시 설명한다.

 

 

 

class Kiwoom(QAxWidget):
    def __init__(self):
        super().__init__()

        ### event loop 모음 ###############################
        self.login_event_loop = None
        ##################################################

        ### 변수 모음 #####################################
        self.account_num = None
        ##################################################

        self.get_ocx_instance()
        self.event_slots()
        self.signal_login_commConnect()
        self.get_account_info()

    def get_ocx_instance(self):
        self.setControl("KHOPENAPI.KHOpenAPICtrl.1")

    def event_slots(self):
        self.OnEventConnect.connect(self.login_slot)

    def signal_login_commConnect(self):
        self.dynamicCall("CommConnect()")
        self.login_event_loop = QEventLoop()
        self.login_event_loop.exec()

    def login_slot(self, errCode):
        print(errors(errCode))
        self.login_event_loop.exit()

    def get_account_info(self):
        account_list = self.dynamicCall("GetLogininfo(String)", "ACCNO")
        self.account_num = account_list.split(';')[0]
        print("나의 보유 계좌번호 %s" % self.account_num)

 

"get_ocx_instance"는 QAxWidget에 있는 setControl 사용하여, 설치된 경로(레지스트리)를 지정("KHOPENAPI.KHOpenAPICtrl.1")하여야 한다.

 

"event_slots"은 자동로그인 이벤트를 생성하기 위함이다.

 

"signal_login_commConnect"는 네트워크에 데이터를 전송하고(dynamicCall), 자동 로그인하기 위함이다.

 

키움 KOA CommConnect 설명

 

"self.login_event_loop = QEventLoop()" 가 실행되면, 아이디와 비밀번호를 입력하라는 창이 출력된다. 자동 로그인을 하기 위해서는 다음의 조치가 필요하다.

 

 

키움 open api 자동 로그인 설정

 

윈도우 작업표시줄 오른쪽 아래에 빨간색 상자로 표기된 아이콘에 마우스 우클릭하여 자동로그인을 설정한다.

 

처음 로그인을 하거나, 버전 업데이트 등으로 버전 처리가 필요한 경우, 버전처리 알림 창이 뜨는데 다음을 잘 읽어보고 순서대로 해야 성공한다.

1. 알림창을 그대로 둔다. (확인을 눌러 닫지 않는다.)

2. 키움 관련 프로그램을 모두 종료한다.(KOA, OPEN API 등)

3. 알림창을 "확인"을 눌러 닫는다.

4. 코드를 다시 실행한다.

 

키움 open api 버전처리 알림창

 

"login_event_loop.exec()"는 로그인이 완료될 때까지 다음 코드 실행을 막기 위함이다. 로그인하는 과정은 필요한 파일 등을 다운로드하기 위해 시간이 다소 소요되는데, 이 코드 없이는 아직 로그인 준비가 진행 중인 상황에서 다음 코드를 실행해버리는 결과가 나타난다. 

 

 

 

"login_slot"은  로그인 상태를 확인하고, 로그인 완료 시 위에서 생성한 event loop를 종료(login_event_loop.exit())하는 코드이다.

 

가장 위에 있는 import 단계에서 "config.errorCode"를 import 했다.

현재 나의 작업 폴더에 config 폴더를 만들고 그 안에 errorCode.py 파일을 하나 만들어서 다음의 코드를 입력해 두어야 한다.

 

 

def errors(err_code):
    err_dic = {
        0: ("OP_ERR_NONE", "정상처리"),
        -10: ("OP_ERR_FAIL", "실패"),
        -100: ("OP_ERR_LOGIN", "사용자정보교환실패"),
        -101: ("OP_ERR_CONNECT", "서버접속실패"),
        -102: ("OP_ERR_VERSION", "버전처리실패"),
        -103: ("OP_ERR_FIREWALL", "개인방화벽실패"),
        -104: ("OP_ERR_MEMORY", "메모리보호실패"),
        -105: ("OP_ERR_INPUT", "함수입력값오류"),
        -106: ("OP_ERR_SOCKET_CLOSED", "통신연결종료"),
        -200: ("OP_ERR_SISE_OVERFLOW", "시세조회과부하"),
        -201: ("OP_ERR_RQ_STRUCT_FAIL", "전문작성초기화실패"),
        -202: ("OP_ERR_RQ_STRING_FAIL", "전문작성입력값오류"),
        -203: ("OP_ERR_NO_DATA", "데이터없음"),
        -204: ("OP_ERR_OVER_MAX_DATA", "조회가능한종목수초과"),
        -205: ("OP_ERR_DATA_RCV_FAIL", "데이터수신실패"),
        -206: ("OP_ERR_OVER_MAX_FID", "조회가능한FID수초과"),
        -207: ("OP_ERR_REAL_CANCEL", "실시간해제오류"),
        -300: ("OP_ERR_ORD_WRONG_INPUT", "입력값오류"),
        -301: ("OP_ERR_ORD_WRONG_ACCTNO", "계좌비밀번호없음"),
        -302: ("OP_ERR_OTHER_ACC_USE", "타인계좌사용오류"),
        -303: ("OP_ERR_MIS_2BILL_EXC", "주문가격이20억원을초과"),
        -304: ("OP_ERR_MIS_5BILL_EXC", "주문가격이50억원을초과"),
        -305: ("OP_ERR_MIS_1PER_EXC", "주문수량이총발행주수의1%초과오류"),
        -306: ("OP_ERR_MIS_3PER_EXC", "주문수량은총발행주수의3%초과오류"),
        -307: ("OP_ERR_SEND_FAIL", "주문전송실패"),
        -308: ("OP_ERR_ORD_OVERFLOW", "주문전송과부하"),
        -309: ("OP_ERR_MIS_300CNT_EXC", "주문수량300계약초과"),
        -310: ("OP_ERR_MIS_500CNT_EXC", "주문수량500계약초과"),
        -340: ("OP_ERR_ORD_WRONG_ACCTINFO", "계좌정보없음"),
        -500: ("OP_ERR_ORD_SYMCODE_EMPTY", "종목코드없음")
        }

    result = err_dic[err_code]

    return result

 

위 코드에서는 로그인을 포함한 모든 오류 코드를 담아 두고, 필요시 가져다 쓰고자 함이다.

 

자동로그인에서 정상적으로 로그인이 되면, "print(errors(errCode))"에 의해 다음과 같은 출력물이 나타난다. 

"('OP_ERR_NONE', '정상처리')"

 

오류코드는 KOA에서 확인할 수 있다.

KOA OPEN API 오류코드

 

 

"get_account_info"는 로그인이 되었으니, 사용자 정보를 가져오기 위한 부분이다.

"dynamicCall("GetLogininfo(String)", "ACCNO")" 코드로 사용자 정보를 호출한다.

 

이렇게 호출된 계좌번호는 "8154749111;" 와 같이 끝에 세미콜론이 붙어있다. 아마 아이디가 2개 이상인 경우 구분하기 위한 목적으로 보인다. 

 

"account_list.split(';')[0]"으로 콜론을 지워주고, 첫 번째 값을 가져와서 사용한다.

 

 

 

이제 키움 OPEN API에 로그인하고, 계좌정보까지 가지고 왔다.

 

 

 

도움받은 감사한 글들

[1] docs.huihoo.com/pyqt/PyQt5/QAxContainer.html

[2] docs.huihoo.com/pyqt/PyQt5/QtCore.html

 

 

 

2020.01.04. 코리.

 

 

pykiwoom vs. 직접코딩

 

 

이전 글 보기

2020/12/31 - [Bigdata_tips] - [python] 머신러닝 주가 예측 및 자동 매매 - 01_시작

2020/12/31 - [분류 전체보기] - [python] 머신러닝 주가 예측 및 자동 매매 - 02_기본설정

 

 

 

어제 4시간 동안 삽질을 하며, 기본설정을 마쳤다고 좋아했다.

import pykiwoom 이 완료 되었으니 이제 큰 어려움이 없다고 기쁜마음으로 새벽 4시 경에 잠에 들었다.

 

우선, pykiwoom을 import 하려고 노력한 이유는 참고하던 사이트를 따라하고 있었기 때문이다. [1] 그리고 패키지 이름도 pykiwoom으로 키움에서 만들었는 듯하게(?) 무작정 받아 들였다. 

 

하지만, pykiwoom 패키지는 "퀀트투자를 위한 키움 API" 책을 집필한 필자들이 만든 모듈이다. 그래서 몇가지 단점이랄까, 우려할 점이 있다. 

   - 기능이 제한적이다. 즉, pykiwoom에 없는 조회나 기능을 추가하려면 직접 코딩해야 한다.

   - 개인이 관리하는 모듈이다 보니, 모듈 업데이트 등 관리가 얼마나 될지 조금은 걱정된다. 

 

 

pykiwoom

나는 출판사, 출판사 관계자, 저자, 저자 관계자 등과 일체 관련이 없다. 책 광고가 아님을 밝혀 둔다. 광고 문의는 댓글로;;;

 

당연히 pykiwoom 모듈을 활용하여 키움API 접근 및 데이터 다운로드 등 초기 진입장벽이 낮다는 매우 강력한 장점이 있다.

 

 

 

하지만, 나는 부족한 파이썬 학습과 광활한 API 기능을 느껴보고 싶어서 직접코딩을 하기로 마음을 방금;; 먹었다.

맨바닥에 할 수는 없고, 참고할 좋은 youtube 채널을 발견했다. [2]

 

유튜브 프로그램 동산 채널

이 곳 역시 나와 아무런 관련이 없다. 광고 문의는 댓글로;;;

 

 

주식 매매 자동화와 관련하여 1~71강까지 강의가 있다. 몇개 봤는데 괜찮아 보였다.

여기서 주식 매매 자동화에 대해 배우면서, 코딩하면서, 진행할 예정이다.

다른 큰 축인 주가 예측은 내가 따로 개발을 해야한다.

 

 

도움 받은 곳들

[1] wikidocs.net/book/1173

[2] www.youtube.com/channel/UCq7fsrxP6oi6vnYgPkw92jg/featured

 

 

 

2020.01.01. 코리.

 

 

폭스바겐 제타 배터리 교체

 

제타를 탄지 벌써 5.5년이나 되었다.

배터리를 이번에 처음 교체했는데, 배터리가 5.5년이나 버틴게 놀라웠다.

서비스센터에서는 배터리 수명이 2년이라고 했는데, 그건 너무 하고;;;

 

 

폭스바겐 디젤게이트 여파로 모든 오너에게 지급된 WCC(We Care Campaign) 100만원 바우처가 아직 많이 남아 있어서, 공식 서비스 센터에서 배터리를 교환하고자 방문했다.

 

2020년 12월 말, 그러니깐 오늘, 까지 대폭 할인도 한다길래 방문했다.

참고로 배터리 교환은 센터에 예약없이 방문해도 진행해 준다. 이건 문제가 되면 시동이 걸리지 않는 것이니 예약없이 방문해도 처리가 된다고 하였다.

 

오전 일찍 방문해서 대기 손님이 거의 없는 수준이었다.

 

작업시간은 1시간 남짓 소요되었다.

비용은 할인해서 총 264,726원 들었다.

 

 

폭스바겐 서비스센터 제타 AMG 배터리 교체 견적

 

폭스바겐 서비스센터 제타 AMG 배터리 교체 명세서

 

견적과 명세서로는 전체 세부 비용이 드러나지 않는다.

 

AMG배터리가 할인해서 96,125원이고, 총 비용이 264,726원 나왔으니, 공임이 168,601원으로 계산된다.

배터리 할인이 없었다면, 배터리 336,100*1.1 + 공임 168, 601 = 538,311원이 나오는데.... 여튼 계산과정이 투명하지 않아 잘 모르겠다.

 

공임도 이상한 것이, 명세서를 보면 작업시간이 60분(탈착 50분 + 확인 10분)에 단가 780(아마도 원/분)이면 시간당 46,800원이 되는데, 총 공임이 168,000원 정도이니 작업을 3.5명이 했다는 것인가? 3명이 했으면 수량이 총 60분이 아니라 180분이 되어야 할거 같은데...

 

결론은, 서비스센터에서 배터리교환은 비싸다.

 

배터리 교환 후 엔진오일 교환은 시중 수입차 전문점에서 했는데, 사장님께 여쭤보니 동일한 델코 AMG 배터리가 교환 비용이 15만원 이하였다.

 

 

2020.12.31. 코리. 

 

ps. 배터리와 관련 없는 이야기지만, 서비스센터에 금호타이어 3+1 이벤트 중이라는 베너가 보이길래 가격이 얼마인지 물어보았더니 90만원 이란다.

 

 

 

머신러닝 주가예측 및 자동매매를 위해 사용할 환경은 다음과 같다.

 

1. 하드웨어

   - CPU : 인텔 i5-6400

   - 램 : 8기가

   - OS : 윈도우 10

   - no GPU

 

2. 소프트웨어

   - Anaconda3_2020.11 (python 3.8.5) 64bit

   - Anaconda 가상환경 (python 3.7.9) 32bit

   - Visual Studio Code 1.52.1 

   - 영웅문4, 번개3

 

 

 

우선....

 

장장 4시간에 걸친 삽질에 대해 남겨야 하겠다. 같은 삽질을 반복하면 안되니깐.

   - python 단독으로 깔지 말고 anaconda 깔아라. 정신에 이롭다. 64bit에 32bit 가상환경 설정하는게 맞다. [1]

   - 파이썬 아키텍쳐 2개가 필요하다. 머신러닝 모델링을 위해 64bit로 돌려야 하고, 증권사 api 구동을 위해 32bit가 필요하기 때문이다.

   - python이나 anaconda 64비트 32비트를 하나의 pc에 깔 수는 있지만 정신건강에 매우 해롭다. 64비트에 깔린  ipykernel이 32비트에서 인식되는 바람에 아무것도 할 수 없었다.

   - 64비트 anaconda를 설치한 후 32비트 가상환경을 만들어 구동하는 것이 "아직까지는" 성공적이다.

   - 64비트는 python 3.8.5 버전을, 32비트 기상환경에는 python 3.7.9 버전을 설치했다. 똑같은 버전을 설치해 보니, 헷갈린다.

   - 64비트에서 32비트 가상환경 만들고 잘만들어졌는지 확인하는 거는 vs code에서 하지말고, anaconda prompt 에서 하는 것이 바람직하다. vs code 터미널에서 작업하다가 2시간 이상 날려먹었다.

   - vs code나 anaconda prompt는 관리자 권한으로 실행해야 한다. 안그럼, 권한으로 귀찮게 한다.

 

 

 

 

 

 

from  pykiwoom.kiwoom  import *

 

"from pykiwoom.kiwoom import *"

이 코드가 오류없이 구동되는 모습을 보는데 4시간이 걸렸다. 패키지가 잘 import 되자, 눈물이 날거 같았다.

 

 

첫번째 코드 오류 : ModuleNotFoundError: No module named 'PyQt5.QAxContainer'

이것은 PyQt5 모듈을 찾을 수 없다는 것인데, "pip install pyqt5" 하면, 이미 패키지가 설치되어 있다는 말을 들려준다. 

 

해결방법은 "pip install pyqt5==5.13" 이다.

32비트 가상환경에는 python 3.7.9 버전이 깔려 있는데, 3.7.9는 PyQt5 최신버전인 5.15와 맞지 않기 때문이다. [2]

 

 

두번째 코드 오류 : ImportError: DLL load failed while importing QAxContainer: %1은(는) 올바른 Win32 응용 프로그램이 아닙니다.

 

이건 정확히 원인을 찾지 못했는데, 64비트과 32비트 가상환경 사이에 뭔가 맞지 않은게 있다는 의미로 이해했다. 해결방법은 vs code에서 만든 32비트 가상 환경을 삭제하고, anaconda prompt에서 다시 만들었다. 

 

 

 

32비트 가상환경 오류

 

vs code에서 만든 32비트 가상환경은 자기가 계속 64비트라고 말한다. 

anaconda prompt에서 32비트 가상환경을 만들고 확인하면 자신이 32비트라고 솔직히 말한다.

 

 

 

 

 

ipykernel 설치 오류 (캡처 못해서 구글링 펌)

 

 

별거 아닌거 같았지만 내 정신을 많으 갉아먹은 오류다.

"python requires ipykernel to be installed"  그래그래, 설치해봐 하고 install 누르면

"ipykernel not installed into interpreter python" 안된다고 대답한다.

 

이 오류는 64bit 파이썬을 깔때 ipykernel이 64비트에 맞게 설치가 되었는데,

32비트 가상환경도 ipykernel 쓰고 싶어서 깔아달라하는데,

32비트에서 pip install 하면 이미 설치되어 있다고 설치가 안되는 무한루프 오류이다.

 

해결방법은 아나콘다(64비트) 삭제 후 재설치 -_-;;

방법을 찾다가 재설치가 빠를거 같아서 재설치 했다.

 

 

 

 

기억나는 것들 적어놓고 보니 별거 없는데, 4시간을 날려먹었다.

오늘 키움 API로 로그인해서 삼성전자 일봉 정보 다운로드까지 받고 싶었는데

달랑 "from pykiwoom.kiwoom import *" 이거 성공했다.

 

 

 

파이썬 32비트 가상환경 설정 완료

 

 

 

내일은 또 어떤 에러가 날 기다리고 있을까....

 

 

 

도움주신 좋은 글들

[1] lazyblue.tistory.com/9

[2] m.blog.naver.com/oneaview/221997472226

 

 

 

 

2020.12.31. 코리.

 

 

 

 

머신러닝은 과거 데이터를 이용해서 insight를 찾고 미래를 예측할 수 있다.

 

그래서 머신러닝으로 주가를 예측하는 머신러닝 모델을 구축하고, 

그 모델이 예측한 결과(매매가격)에 따라 주식 자동매매가 이뤄지도록 하는

"딸래미 학원비 벌기" project를 시작한다.

 

목표는 다음과 같다.

1. 대상 종목을 하나만 선정한다.

   - 삼성전자 한놈만 팬다

2. 오늘 주식시장 종료 후 내일 삼성전자의 시가, 고가, 저가, 종가를 예측하는 모델을 구축한다.

   - 머신러닝, 딥러닝, 강화학습, 유전 알고리즘 뭐든 다 해본다.

3. 증권사 API를 이용해서 조건에 따라 자동매매가 이뤄지도록 한다.

   - 나는 낮에 일하고, 집에서 노는 컴퓨터는 자기 혼자 주식을 매매한다.

   - 매매 현황을 나에게 메시지로 보고한다.

4. 1단계 목표수익: 1일 평균 5천원

 

 

화이팅

2020.12.31. 코리.

 

 

 

평소 업무에서 엑셀을 많이 사용하며, 엑셀만큼 훌륭한 프로그램이 없다고 생각했었다. 메모리를 많이 먹어서 계산이 느린 경우는 종종 있지만, 내가 원하는 계산은 뭐든지 막힘 없이 다 해주었다.

 

예전에 근무한 직장에서는 MS WORD나 한컴의 한글로 작업하는 문서 작업을 엑셀로 하기도 했다.

 

15여 년에 걸친 직장생활 중 처음으로 엑셀의 한계를 발견했다.

엑셀이 처리할 수 있는 숫자의 자릿수가 15개로 제한이 있다. 

 

15자리 숫자는 123,456,789,012,345 이런 숫자이며, 100조 단위이다. 일상생활과 업무에서 100조까지의 숫자를 처리할 일이 없으니 몰랐다. 

 

그런데, 15자리 이상의 긴 숫자로 구성된 코드번호의 중복값을 처리하면서 문제가 발생했다. 

 

아마 평생 100조 이상의 숫자를 엑셀로 처리할 일은 없겠지만, 16자리 숫자로 구성된 코드는 업무에서 얼마든지 등장할 수 있다. 매일 사용하는 신용카드 번호도 16자리 숫자로 구성되어 있다.

 

 

엑셀의 숫자 자릿수 제한, countif 오류

 

위 그림에서와 같이 22자리로 구성된 코드를 다루던 중 이상한 현상이 발견되었다. 모든 코드는 중복 값이 없다. "중복된 항목 제거"를 했기 때문이다.

 

그런데, B열의 값(코드)을 COUNTIF 함수로 확인하는 과정에서 "5"라는 숫자가 나타났다. 눈으로 봐도 끝자리가 1, 2, 3, 4, 5로 모두 다른데, 완벽한 엑셀은 나에게 "5"개가 중복이라는 결과를 보여주었다. 컴퓨터를 껐다가 켜서 다시 해봤지만, 결과는 바뀌지 않았다.

 

검색 결과, 엑셀이 처리할 수 있는 숫자 자릿수가 15개 라는 것을 알게 되었다. 

 

 

엑셀의 숫자 자릿수 제한, countif 오류

 

COUNTIF 함수가 15자리까지는 잘 작동을 하는데, 16자리부터는 모두 "같은 값"으로 인식을 한다.

 

그 이유는 엑셀이 숫자 15자리를 초과하는 숫자는 모두 0으로 바꿔버리기 때문이다. 위 16자리 코드의 끝자리가 2001, 2002, 2003, 2004, 2005로 보이지만, 엑셀은 모두 "2000"으로 인식하기 때문에 COUNTIF 함수가 모두 같다는 결과를 반환하는 것이다.

 

 

엑셀의 숫자 자릿수 제한, countif 오류

 

위 그림에서 19~23번 행에서는 B열(코드)의 값이 "텍스트" 형식이라 끝자리가 2001, 2002, 2003, 2004, 2005로 보이지만, 이를 숫자로 바꾸면 26~30번 행과 같이 끝자리가 모두 "2000"이 돼버린다. 

 

 

 

 

해결방법

 

해결방법에는 여러가지가 있을 수 있다. 대전제는 15자리를 초과하는 숫자를 연산할 수는 없다. 1,000조 단위 숫자를 더하고, 빼고, 곱하고, 나누고 할 수 없다는 것이다. 연산을 하지 않고 위 예시와 같이 "텍스트(코드)"로만 사용하려면 다양한 방법이 있다.

 

 

첫 번째 방법은 긴 숫자를 자르는 것이다.

 

엑셀의 숫자 자릿수 제한, countif 오류 해결 방법

 

22자리의 텍스트인 숫자를 LEFT와 RIGHT 함수를 이용해서 자른 후, COUNTIFS 함수로 카운트를 해보면 다른 값으로 인식한다. 

 

 

 

두 번째 방법은 텍스트인 숫자를 텍스트로 바꿔주는 방법이다.

 

엑셀에서 숫자를 텍스트로 표시 형식을 바꿔도 숫자의 성격을 가지고 있기 때문에 이런 문제가 발생한다. 그럼 숫자를 완전히 텍스트로 바꿔버리면 이런 문제를 해결할 수 있다.

 

엑셀의 숫자 자릿수 제한, countif 오류 해결 방법

 

위 그림에서와 같이 22자리 텍스트 숫자의 중간이나 끝부분에 "_"를 추가하면 더 이상 숫자의 성격을 갖지 못한 "텍스트"가 되면서, 15자리 한계를 벗어나게 된다.

 

"_" 말고 문자라면 뭐든지 추가해도 된다.

 

 

 

또 다른 엑셀의 한계가 궁금하다.

 

2020.07.30. 코리.

 

 

 

 

 

 

 

2020/05/19 - [Bigdata_tips] - ADsP - 독학 3주 도전기

2020/06/10 - [Bigdata_tips] - ADsP - 제25회 시험 후기

 

 

 

아.... 가슴이 아프다. 

나이가 먹어갈 수록 "불합격"이라는 글자가 가슴을 더 후벼파고 머릿속에 더 오래 남아 있는 기분이다.

 

불합격이니 할말은 없지만... 참 아깝다.

전체 점수는 68점으로 합격 기준 점수인 60점을 넘겼는데, 2과목에서 과락이 발생했다. 딱 1문제가 부족했다. 

 

딱 1문제 이지만, 하나하나 준비해가던 단계에서 삐끗해버려서 심적 타격이 상당하다.

 

시험 후기 포스팅에서 "2과목 과락나면 어쩌지?" 라고 했는데, 현실이 되어 버렸다. 안좋은 예감은 항상 맞아 들어간다.

 

 

ADsP 2과목 과락(1문제 부족ㅠㅠ)으로 불합격이다.

 

 

자체 진단해 보자면....

3과목(데이터 분석)은 어렵다는 말을 많이 들어서 집중해서 많이 봤고,

1과목(데이터 이해)은 책 제일 앞에 나오고, 개념적인 부분이라 크게 어렵지 않았다.

 

그 사이에 낀 2과목(데이터 분석 기획)은 상대적으로 관심을 덜 기울인거 같다. 1과목과 3과목에 비해 2과목의 용어들이 낯설게 느껴지기도 했다. 

 

2과목은 "과락만 면하자" 라는 생각으로 접근했다가 이런일이 난거 같다. 

 

반성하는 마음으로 도서관에 반납한 책들을 다시 빌려야 하겠다. 

반성하는 마음으로 응시료 5만원을 또 내야하겠다.

반성하는 마음으로 또 몇날며칠을 스트레스 받으면서 공부해야겠다.

 

제26회 ADsP 시험 일정은 다음과 같다.

접수 : 6/15 ~ 8/3

시험 : 8/29

발표 : 9/29

 

 

2020.07.09. 코리.

 

 

 

 

 

말도 많고 탈도 많던 "국가교육위원회 설치 및 운영에 관한 법률안"이 마련되었다. 더불어민주당 안민석 의원이 대표발의 하였다.

 

 

교육부를 없애고 국가교육위원회를 설치해야 한다는 등 과거 관련 논란이 다수 있었다. 법률안을 살펴보니 생각보다는 강한 법률이었다.

 

 

★명칭 : 국가교육위원회의 설치 및 운영에 관한 법률안

의안번호 : 190

발의연월일 : 2020.06.05.

발의자 : 안민석(대표발의), 서영교, 박정, 도종환, 송갑석, 김민기, 문진석, 고용진, 김병욱, 이동주, 전혜숙 의원, 이상 더불어민주당 의원 11명

 

 

주요내용

★ 교육정책의 기본방향과 중장기 정책목표 수립 등의 업무를 수행하기 위하여 국가교육위원회를 설치

★ 위원 15명(상임 5명 포함)으로 구성(국회 선출 11명, 대통령 지명 4명)

위원 임기 3년, 1회에 한해 연임 가능

★ 위원장은 국회 인사청문 거치도록 하며, 국회에 출석하여 소관 사무에 관한 의견 진술

★ 위원은 의사에 반하여 면직되지 않고, 정치활동에 관여할 수 없음

★ 위원회 사무처리를 위해 사무처를 둠

★ 교육부장관은 위원회의 업무에 관하여는 그 집행에 앞서 위원회의 심의의결을 거치도록 함

 

 

 

국가교육위원회가 설치되면, 위원회와 교육부의 관계는 어떻게 될지 궁금했다. 법률안에 몇가지 내용이 있는데, 위원회가 상위 기관처럼 보인다.

 

 

제15조(교육부장관과의 관계) ① 교육부장관은 「정부조직법」 제28조에도 불구하고 위원회의 업무에 관하여는 대통령령으로 정하는 바에 따라 그 집행에 앞서 위원회의 심의․의결을 거쳐야 한다.
  ② 위원회는 필요하다고 인정하는 경우 그 의결로 교육부장관에게 업무에 관한 사항을 위원회에 보고하게 할 수 있다.

 

 

 

교육부는 국가교육위원회 관련 업무는 그 집행에 앞서 위원회의 심의의결을 거쳐야 한다.

국가교육위원회는 교육부장관에게 위원회에 보고하게 할 수 있다.

 

 

 

위 두 문장만 봐도 국가교육위원회가 교육부보다 상위기관으로 보인다.

너무 멀리간 추측이지만, "국가교육위원회 사무처 = 교육부" 가 되는건 아닌지 모르겠다.

 

 

 

아직 법률안 수준이고, 여러 곳의 의견수렴과 검토를 거친 후, 최종적으로 국회를 통과해야 하겠지만, 생각보다 막강한 위원회가 만들어지는 것으로 보인다.

 

 

국가교육위원회의 설치 및 운영에 관한 법률안.hwp
0.04MB

 

 

 

2020.06.17. 코리.

 

 

 

ADsP 시험 후기

 

2020/05/19 - [Bigdata_tips] - ADsP - 독학 3주 도전기

 

 

3주가 지났고, 지난 6/7 제25회 ADsP 시험을 치렀다.

 

시험 문제를 받아 들고 주관식부터 풀기 시작했다. 주관식 답을 몇 개 적으면서 "생각보다 쉬운데?" 라는 생각이 잠시 머리를 스치고 지나갔다.

 

하지만 2과목(데이터 분석 기획)이 걱정이다. 한번에 풀지 못하고 건너뛰는 객관식 문제들이 늘어나면서 "이거 2과목 과락 나오면 어쩌지?" 라는 걱정이 다시 머리를 스치고 지나갔다.

 

시험시간 1:30분을 모두 쓰고서야 퇴실할 수 있었다. 자신있게 적었던 주관식 2개 정도가 틀린 거 같아 마음이 불안하다. 

   - 정답이 "odds" 인데, 문제집에는 "odds"라 적고 답안지에는 "오즈비"라고 적었다. 무슨 생각이었을까...

 

 

관련 카페에 올라오는 후기들도 이번 시험은 "대체적으로 쉬었다" 라는 말이 많았다. 기출문제에서 많이 나왔다는 반응도 있었고, 특히 3과목에서 R 코드 관련 질문이 하나도 나오지 않았다. 

 

ADsP 시험은 비전공자가 3주만에 준비하기에는 무리가 있다는 생각이다. 빅데이터 MBA 과정에서 들었던 내용들이 ADsP에 많이 등장해서 나는 비교적 수월했다. 이론을 깊게는 몰랐지만, 몇 번씩 들어봤던 내용들이니 그래도 이해가 빨랐다. 이해가 빨랐다고 모두 기억하는건 아니다.

 

 

ADsP 시험 준비 책

 

위 3권으로 시험을 준비했다. 한 번에 붙을 생각이었으니 책은 모두 도서관에서 빌렸다. 우리 다시 만나지 말자 ㅠㅠ

 

왼쪽책은 거의 ADsP, ADP 준비의 바이블 격인 책이다. 시험 준비를 위한 목적으로는 펴보지 않았다. 펴서 공부해봐야겠다는 생각이 드는 책이 아니다.

 

중간책은 인터넷에 가장 많이 등장하는 책이라서 빌렸다. 인터넷에 가장 많이 등장하는 이유는 저 책을 만든 회사의 온라인 강좌를 듣고 후기를 올리면 수강료를 50% 할인해주기 때문이다. 책의 품질은 별로 마음에 들지 않았다. 오타, 틀린 설명 등이 중간중간에 등장해서 난감했던 적이 몇 번이나 된다.

 

오른쪽 책은 기출문제집이다. 2017년에 한국데이터산업진흥원(ADsP 시험 주관기관)에서 펴낸 책이지만 충분히 도움이 된다.

 

ADsP를 준비하고자 한다면, 일단 오른쪽 기출문제집은 꼭 풀어봐야 한다. 그리고 중간 책을 산다면, 이론 부분은 2~3번 볼 생각으로 천천히 잘 읽어야 한다. 그림으로 설명된 것들도 그냥 넘기지 않고 찬찬히 잘 살펴봐야 한다. 다음과 같은 책의 오류는 알아서 잘 발견하고 이해햐야 한다. 한 두 개가 아니다.

 

 

ADsP 책 오류

 

 

 

대구에서 치뤄지는 한국데이터산업진흥원 시험은 과거엔 영남이공대학에서 진행되었다. 하지만 이번 시험은 코로나-19 때문인지 시험 장소가 대구엑스코로 되어 있었다. 교통편이 마땅치 않기에, 그리고 대중교통을 이용하기 탐탁지 않기에 자차로 이동했다. 주차비는 지원되지 않아서 5천원 정도 내가 부담해야 했다.

 

 

제25호 ADsP 시험 장소 - 대구 엑스코

 

 

제25호 ADsP 시험 고가실 안내 - 대구 엑스코

 

 

제25호 ADsP 시험 장소 - 대구 엑스코 소독기

 

건물 안으로 입장하면 위 사진과 같은 소독기가 있다. 공항 탐색기와 비슷하게 생긴 "몸 소독기"를 통화하면 되는데, 생각보다 소리가 크다. 내 앞에 있던 여자분은 경험이 있는지 귀를 막고 지나갔다. 몸 소독기를 지나면 열화상 카메라로 체온을 측정한다.

 

 

 

제25호 ADsP 시험 장소 - 대구 엑스코

 

위 사진에서 오른쪽에 갈색문으로 보이는 곳이 고사장이다. 8시 조금 넘어서 도착했더니 생각보다 한산했다.

 

 

제25호 ADsP 시험 장소 - 대구 엑스코

 

내가 친 시험은 제25회 ADsP 이지만, 찍다 보니 ADP 고사장 알림 모니터를 찍었다.

 

 

제25호 ADsP 시험 장소 - 대구 엑스코

 

 

내가 시험을 친 고사장의 모습이다. 책상이 80~90개 정도 있어 보였다. 사회적 거리두기가 가능할 정도의 공간이었다.

 

 

ADsP, 더 나아가 ADP는 따고 싶은 자격증이다. 하지만 ADsP 자격증 시험을 다시 치는 그런 일은 없으면 참 좋겠다. 한 달 뒤인 7월 7일 결과 발표가 기다려진다.

 

 

 

2020.06.10. 코리. 

 

 

+ Recent posts