PYTHON/AUTO TRADE SYSTEM

[자동 매매 시스템 구축하기] 실시간 해제하기 (3) - 오류 처리

  • -

 

지난 게시글까지의 내용은 실시간을 등록하고 해제하는 기능을 구현하는 것이었다. 하지만 아직 발생할 수 있는 오류가 남아 있는데, 바로 동일한 종목을 실시간으로 등록하거나 실시간으로 등록되어 있지 않은 종목을 대상으로 실시간 해제를 했을 경우에 발생할 수 있는 오류이다.

이러한 문제를 해결하는 것은 의외로 단순하게 처리할 수 있다.

 

 

실시간 등록 시 오류 처리 : def add_to_setrealreg(self, item_code)

일단 어떤 오류가 발생하는지에 대해 먼저 살펴보자면, 아래와 같은   ValueError  가 발생한다. 이는   .item()  메서드를 원인으로 발생하는 것인데, 애당초 그 앞 부분의 코드에서 얻어온 값이 없기 때문에 빈 데이터에 대고   .item()  메서드를 적용했을 때 발생하는 오류이다.

Traceback (most recent call last):
  File "main.py", line 222, in _pushbtn_4
    self.__setrealremove("ALL", item_code)
  File "main.py", line 227, in __setrealremove
    idx = self.setrealreg.index[self.setrealreg['item_code'] == item_code].item()
  File "py36\lib\site-packages\pandas\core\base.py", line 660, in item
    raise ValueError("can only convert an array of size 1 to a Python scalar")
ValueError: can only convert an array of size 1 to a Python scalar

다만, 이 오류는 앞서 처리했던 오류 처리 방법인   try:  와   except:  문을 사용하지 않고, 다른 방법으로 처리할 것이다. 왜냐하면 이전에 다루었듯이 실시간 등록과 해제라는 작업이 동작하는 사이에   self.setrealreg  변수와 tableWidget의 데이터가 일치하지 않는 현상처럼 필수불가결하게 발생하는 오류가 아닌, 당연히 우리가 체크해줘야 하는 오류이기 때문이다. 
※ Line : 8

## 기존의 코드
    def add_to_setrealreg(self, item_code):
        idx = len(self.setrealreg)
        self.setrealreg.loc[idx, 'item_code'] = item_code
        
## 변경된 코드
    def add_to_setrealreg(self, item_code):
        if item_code not in self.setrealreg['item_code']:
            idx = len(self.setrealreg)
            self.setrealreg.loc[idx, 'item_code'] = item_code

 

 

 

실시간 해제 버튼 생성하기

예전 게시글에서 실시간 등록은 별도의 버튼을 만들어서 기능이 동작하도록 구현했지만, 실시간 해제는 아직 별도의 버튼을 생성하지 않았다. 실시간 해제 버튼은 이전에 실시간 등록 기능을 구현할 때 제작했던 GUI 기능과 동일한 방식으로 종목코드 변수를 입력받는   lineEdit  객체와 함수를 실행할   pushButton  객체를 생성해주도록 하자. (본인의 경우 실시간 해제 시 사용할 lineEdit의 객체이름은   lineEdit_2  이고 pushButton의 객체이름은   pushButton_4  이다.)

 

이제   pushButton_4  버튼을 눌렀을 때 별도의 함수로 연결되도록 하는 이벤트를 구현해보자.
※ Line : 16

class tradesystem(QMainWindow, form_class):
    def __init__(self):
        super().__init__()
        self.setupUi(self)  ## GUI 켜기
        self.setWindowTitle("주식 프로그램")  ## 프로그램 화면 이름 설정

        self.kiwoom = QAxWidget("KHOPENAPI.KHOpenAPICtrl.1")  ## OpenAPI 시작
        self.kiwoom.dynamicCall("CommConnect()")  ## 로그인 요청

        self.setrealreg = _df.setrealreg()

        """데이터 요청 구간"""
        self.pushButton.clicked.connect(self.request_opt10016)
        self.pushButton_2.clicked.connect(self.request_opt10080)
        self.pushButton_3.clicked.connect(self._pushbtn_3)
        self.pushButton_4.clicked.connect(self._pushbtn_4)

        """이벤트 처리 구간"""
        self.kiwoom.OnReceiveTrData.connect(self.receive_trdata)        ## 데이터 조회 요청 처리 함수
        self.kiwoom.OnEventConnect.connect(self.process_login)          ## 로그인 반환값 처리 함수
        self.kiwoom.OnReceiveRealData.connect(self.receive_realdata)    ## 실시간 데이터 수신 처리 함수

 

  pushButton_4  가 클릭됐을 때   def pushbtn_4  라는 함수로 연결되도록 했으니,   def pushbtn_4  라는 함수 내에서는   lineEdit_2  에 입력되어 있는 값을 얻어다가 실시간 해제 함수에서 요구하는   item_code  의 인자로 전달해주는 구조를 갖추면 된다.
※ Line : 1~4

    def _pushbtn_4(self):
        item_code = self.lineEdit_2.text()
        self.__setrealremove("ALL", item_code)
        print(self.setrealreg)

 

그 후에 코드를 실행해보면 정상적으로 실시간 등록과 해제가 이루어지는 것을 확인할 수 있다. 하지만 우리가 기존에 하려고 구현하려 했던 내용은   self.setrealreg  변수 내에 있는 종목은 중복으로 추가되지 않도록 하고, 없는 종목에 대해서는 실시간 해제 요청이 이루어지지 않도록 하는 것이었다. 실시간 등록 시에 발생하는 오류는 처리했으니, 해제 시레 발생하는 오류만 처리해주면 된다. 실시간 해제 시에도 구현할 코드에 있어 기본적인 메커니즘은 실시간 등록 시에 사용했던 구조와 동일하다. 

조금 다르게 작동하는 부분이 있다면   not in  인가   in  인가를 구분해줘야 한다는 것이다. 실시간 등록 시에는 중복 여부를 판단하는 것이기 때문에   if item_code not in self.setrealreg['item_code']  를 사용했지만, 해제 시에는 존재 여부를 판단하는 것이기 때문에   if item_code in self.setrealreg['item_code']  를 사용해야 한다.
※ Line : 4

    def _pushbtn_4(self):
        item_code = self.lineEdit_2.text()

        if item_code in self.setrealreg['item_code']:
            self.__setrealremove("ALL", item_code)
            print(self.setrealreg)

 

 

 


728x90
반응형
Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.