PYTHON/AUTO TRADE SYSTEM

[자동 매매 시스템 구축하기] 실시간 해제하기 (1) - self.setrealreg 업데이트

  • -

지난 게시글까지 특정 종목을 실시간으로 등록하고 tableWidget 내에 데이터를 추가하고 self.setrealreg 변수에 종목코드를 입력하는 기능을 구현했다. 하지만 실시간 등록의 경우 실사간으로 등록할 수 있는 종목의 개수를 100개로 제한하고 있다. 따라서 등록한 종목의 개수가 100개가 되기 전에 매수 조건에 이탈하여 필요가 없어진 종목을 실시간 해제를 하거나 또는 100개가 될 경우 가장 이전에 등록된 종목은 제거하는 등의 기능을 구현하는 게 필요하다.

 

 

실시간 해제 함수 구현하기

이전에 다른 함수들도 모두 캡슐화를 이용해서 제작해주었던 것처럼, 실시간 해제 함수도 하나의 캡슐로 생성해줘야 사용하고자 하는 지점에서 적절하게 호출해서 사용할 수 있게 된다. 사실 이쯤 되면 함수 하나 만들어내는 것 정도는 별 어려움 없이 만들어낼 수 있어야 한다. 반환값에서 "통신결과" 데이터를 전달해주고 있으니, 이 함수도   return  을 사용해주자.

    """실시간 해제 함수"""
    def __setrealremove(self, scrno, item_code):
        return self.kiwoom.dynamicCall("SetRealRemove(QString, QString)", [scrno, item_code])

 

추후에 다시 다룰 일이 없을 것 같아, 실시간 해제 함수를 사용하는 방법을 여기서 소개하고자 한다. 예를 들어, 우리가 "005930" 종목을 "0101"화면으로 실시간 등록을 걸었다고 가정했을 때, 이 종목에 대해 실시간 등록을 해제하는 방법은 마찬가지로 화면번호(  scrno  ) 인자에는 "0101"을, 종목코드(  item_code  ) 인자에는 "005930"을 전달해주면 된다. 하지만 간혹 너무 많은 종목이 실시간으로 등록되어 있어 관리하기가 어려운 경우가 있을 수도 있는데, 이런 경우에는 화면번호(scrno) 인자와 종목코드(item_code) 인자 모두에 "ALL"을 전달해주면 실시간으로 등록되어 있는 모든 데이터에 대해 수신을 중지하게 된다. 즉, 모두 해제한 이후 다시 새롭게 등록하는 방법도 있는 것이다. 아래의 예제를 살펴보자.

## 실시간 등록 방법
self.__setrealreg("005930")

## 특정 종목의 모든 화면 실시간 해제 방법
self.__setrealremove("ALL", "005930")

## 모든 종목의 모든 화면 실시간 해제 방법
self.__setrealremove("ALL", "ALL")

## 특정 종목의 특정 화면 실시간 해제 방법
self.__setrealremove("0101", "005930")

 

사실 여기서 실시간으로 등록할 수 있는 화면 번호가 "0101" 현재가 화면만 있냐는 의문이 들 수도 있긴 한데, 꼭 그렇지는 않다. 다만 우리가 이전에 제작한 실시간 등록 함수(  def __setrealreg(self, item_code)  ) 내 코드를 보면 return 부분의 함수 내에서 첫 번째 인자로 "0101"을 전달해주고 있기 때문이다. 즉, 우리가 제작한 실시간 등록 함수는 종목코드만 전달해주면 "0101" 화면에 대해서만 실시간으로 등록하기 때문에, 실시간 해제 시에도 "0101"만 전달해주면 된다는 것이다.(따라서 화면번호 인자로 "0101"을 입력하든 "ALL"을 입력하든 간에 차이는 없다.)

 

 


728x90

 

 

등록도 어려웠는데 해제라고 쉬울까?

우리가 등록할 때 해줬던 모든 작업들은 해제 시에도 함께 이루어져야 한다. 이전 게시글에서 실시간으로 등록할 때 아래와 같은 두 가지 작업을 위주로 진행하겠다는 설명을 했었는데, 기억할지 모르겠다.

  1. self.setrealreg 변수에 종목코드 추가하기
  2. tableWidget에 데이터 입력하기

그렇다면 반대로, 실시간 해제 시에도 역시 마찬가지로 두 가지 작업이 함께 이루어져야 한다. 1번 작업의 경우에는   self.setrealreg  변수에서 종목코드 제거하기가 될 것이고, 2번 작업의 경우에는 tableWidget에서 종목코드 데이터 해제하기가 될 것이다. 하나하나 해보자. 막상 해보면 그렇게 어렵지도 않다.

 

 

self.setrealreg 업데이트

실시간으로 등록되어 있는 종목 데이터가 입력되어 있는   self.setrealreg  변수 내에서 종목코드를 삭제하는 시점은 언제가 될까? 간단하게도 실시간 해제 요청이 있는 시점이다. 실시간 해제가 요청되면 변수 내에서 종목코드를 삭제하고, 실시간을 해제해주면 된다. 여기서   self.setrealreg  변수의 데이터형은 데이터프레임 형이었는데, 이전에 데이터프레임 변수 중 원하는 위치에 데이터를 입력하는 방법을 살펴본 적이 있었다. 거기서 가장 먼저 우리가 입력하고자 하는 데이터의 인덱스 값을 얻어오는 것이 가장 우선시되었는데, 데이터를 삭제하는 것 역시 마찬가지이다.
※ Line : 3

    """실시간 해제 함수"""
    def __setrealremove(self, scrno, item_code):
        idx = self.setrealreg.index[self.setrealreg['item_code'] == item_code].item()
        return self.kiwoom.dynamicCall("SetRealRemove(QString, QString)", [scrno, item_code])

 

이제 우리가 사용하고자 하는 인덱스 값을 얻어왔다면 그 인덱스에 해당하는 데이터를 삭제하면 되는데, 데이터프레임 자료형에서의 데이터 삭제는   .drop()   메서드를 사용한다. 우리가 삭제하고자 하는 데이터에 대해 알고 있는 정보는 인덱스 번호(  idx  ) 뿐이니,   .drop()  메서드 내에   index   파라미터의 인자로   idx  를 전달해주도록 하자.
※ Line : 4

    """실시간 해제 함수"""
    def __setrealremove(self, scrno, item_code):
        idx = self.setrealreg.index[self.setrealreg['item_code'] == item_code].item()
        self.setrealreg = self.setrealreg.drop(index=idx)
        return self.kiwoom.dynamicCall("SetRealRemove(QString, QString)", [scrno, item_code])

 

그리고 나서 우리가 해야 할 일이 하나가 있는데, 바로   self.setrealreg  데이터의 인덱스 번호를 새롭게 정렬해주는 것이다. 이 내용은 반드시 tableWidget을 변경하는 것과 함께 이루어져야 하는데, tableWidget을 수정하는 내용은 다음 게시글에서 살펴볼 내용이므로 여기서는 간단하게만 살펴보고 넘어가도록 하자.

아래의 사진 중 맨 왼쪽의 사진이 현재 우리가 실시간 등록을 해 둔 종목의 데이터라고 가정해보자.(변수는   self.setrealreg  이다.) 이 때 "005930"이라는 종목의 데이터를 삭제하고자 할 때, 해당 종목이 변수 내에서 갖는 인덱스(idx) 번호는 2이다. 따라서 우리는 .drop()메서드를 사용해서 2번 인덱스의 데이터를 삭제(  .drop(index=2)  )할텐데, 그 결과로 얻게 되는 데이터는 가운데에 있는 데이터이다. 즉, 가운데 한 칸이 비어 있는 데이터인 것이다. 따라서 우리는 이 데이터를 맨 오른쪽에 있는 데이터와 같은 상태로 만들어주어야 하는데, 이 방법은   .reset_index()  메서드를 사용하면 된다!

 

  .reset_index()  메서드의 경우 그 안에서 drop이라는 파라미터의 인자를 전달해줄 수 있는데, drop=True는 기존의 인덱스 정보를 삭제하라는 의미이다.(drop=의 기본값은 False로, drop=True를 하지 않으면 추후에 인덱스가 여러 개가 되는 문제점이 발생할 수 있다.)
※ Line : 4

    """실시간 해제 함수"""
    def __setrealremove(self, scrno, item_code):
        idx = self.setrealreg.index[self.setrealreg['item_code'] == item_code].item()
        self.setrealreg = self.setrealreg.drop(index=idx).reset_index(drop=True)
        return self.kiwoom.dynamicCall("SetRealRemove(QString, QString)", [scrno, item_code])

 

 


728x90
반응형
Contents

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

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