PYTHON/AUTO TRADE SYSTEM

[자동 매매 시스템 구축하기] 주문 정보 관리하기 (7) - 정정 주문 데이터 로직 확인하기 ②

  • -

지난 게시글에서는 정정 주문이 발생했을 때 어떠한 절차에 따라 데이터가 발생하는지에 대해 살펴보고 프로그램이 그 순서에 따라 오류 없이 동작하도록 구현하기 위해 고려해야 하는 부분에 대해 살펴보았다. 그러면서 원주문 번호가 0000000일 때 해당 종목 코드 데이터가   self.order_info  변수 내에 입력되어 있는지 아닌지를 기준으로 신규 주문인가 정정 주문인가를 구분하여 각각 데이터를 다르게 입력하도록 구현하였다.

이번 게시글에서는 지난 번에 다루지 않은 원주문 번호가 000000이 아닌 경우에는 어떻게 데이터를 입력할 것인지에 대해 살펴보고, 마찬가지로 오류 없이 데이터를 입력하도록 하기 위한 코드를 구현할 계획이다.

 

 

원주문번호가 0000000이 아닌 경우

앞서 설명했듯이, 원주문번호가 0000000인 경우는 단순하게 ①신규로 접수된 주문이거나 ②정정 주문으로부터 발생하는 미체결 클리어 데이터인 경우 둘 중 하나라고 설명했었다. 그렇다면 원주문번호가 0000000이 아닌 경우는 어떠한 경우들이 해당할까? 결론부터 이야기하자면, 정정 주문으로 인해 발생하는 데이터이다. 크게 고려할 사항 없이 단순하게 정정 주문 데이터가 발생했음을 확인한 후에 해당 데이터를 기존의   self.order_info  변수에 덮어씌우면 된다. 아래의 사진은 지난 게시글에서 [미체결 클리어] 데이터와 [신규 주문] 데이터를 구분할 수 있는 방법 중 하나로, self.order_info 변수 내에 해당 종목 코드가 있는지 없는지를 설명하면서 사용했던 도표인데, 그 도표 뒤에 체결량 등의 데이터를 추가적으로 입력해서 살펴보도록 하자.

  self.order_info  변수 내의 데이터가 위의 도표와 동일하고, 000020 종목에 대해 주문량인 500주는 유지한 채 주문 가격을 1,500원에서 1,600원으로 변경하는 정정 주문을 접수했다고 가정해보자. 이 때 데이터는 어떠한 형태로 발생할까?

  • [접수] 종목코드:000020, 주문번호:0200002, 원주문번호:0200001, 주문가격:1,600, 주문량:500, 체결량:0
  • [확인] 종목코드:000020, 주문번호:0200002, 원주문번호:0200001, 주문가격:1,600, 주문량:500, 체결량:0
  • [접수] 종목코드:000020, 주문번호:0200001, 원주문번호:0000000, 주문가격:1,500, 주문량:500, 체결량:0

위 세 가지 순서에 따라 데이터가 발생하게 되는데, 이 때 우리가 처리해야 할 데이터는 바로 맨 첫 번째로 발생한 딱 하나의 데이터이다. 왜냐하면 우리는 애시당초 접수 데이터만 처리하고 있으며, 추가적으로 현재는 원주문번호가 000000이 아닌 경우에 대해서만 고려하면 되기 때문이다. 원주문번호가 0000000인 데이터는 이미 지난 게시글에서 모두 처리했다. 

그렇다면 이 데이터를 어떻게 처리해야 할까? 결론부터 말하자면 간단하다. 원주문번호가 000000이 아닌 경우에도 역시 마찬가지로 종목코드가   self.order_info  변수 내에 포함되어 있는가 아닌가를 판단하고, 그 결과에 따라 데이터를 입력하면 되기 때문이다.

 

 


728x90

 

 

이 때 원주문번호가 0000000이 아니면서 해당 종목에 대한 주문 정보가 self.order_info 변수 내에 있는 경우(사전 주문 정보가 있는 경우)는 바로 정정 주문에 해당한다고 볼 수 있는데, 그렇다면 반대로 원주문번호가 0000000이 아니면서 self.order_info 변수에 데이터가 입력되어 있지 않은 경우는 어떤 경우에 해당한다고 볼 수 있을까?

  • 원주문번호가 0000000이 아닌데 사전 주문 정보가 없는 경우 : 오류 상황
  • 원주문번호가 0000000이 아닌데 사전 주문 정보가 있는 경우 : 정정 주문

사전 주문 정보가 없는데 원주문번호가 0000000이 아닐 수가 없다. 다시 말해, 사전 주문 정보가 없는 경우(신규 주문인 경우)에는 해당 주문의 원주문번호는 반드시 0000000이어야 한다는 것이다. 따라서 그 경우는 오류가 발생한 경우라고 판단할 수 있기 때문에 우리는 사전 주문 정보가 있는 경우, 즉 종목 코드 변수가   self.order_info  변수 내에 있는 경우에만 데이터를 덮어 씌우면 된다는 것이다. 아래의 도표를 확인해보자.

정정 주문 발생 전 후 self.order_info 변수 값의 변화

위와 같이, 정정 주문에 해당하는 경우에는 해당 데이터의 인덱스 번호를 얻어온 후 해당 인덱스 번호의 열에 데이터를 덮어 씌우면 된다는 것이다. 
※ Line : 4~32

## 정정 주문 접수
elif origin_ordno != "0000000":

    ## 종목코드 데이터가 없고 원주문번호가 0000000이 아님 = 오류가 있는 유형
    if item_code not in self.order_info['item_code']:
        pass

    ## 종목코드 데이터가 있고 원주문번호가 0000000이 아님 = 정정 주문 접수
    elif item_code in self.order_info['item_code']:
        idx = int(self.order_info.index[self.order_info['item_code'] == item_code].to_list()[0])

        self.order_info.loc[idx, 'item_code'] = item_code
        self.order_info.loc[idx, 'item_name'] = item_name
        self.order_info.loc[idx, 'bns'] = order_bns
        self.order_info.loc[idx, 'origin_code'] = origin_ordno
        self.order_info.loc[idx, 'order_gubun'] = order_gubun
        self.order_info.loc[idx, 'trade_gubun'] = trade_gubun
        self.order_info.loc[idx, 'order_quan'] = order_quan
        self.order_info.loc[idx, 'signed_quan'] = signed_quan
        self.order_info.loc[idx, 'remained_quan'] = remained_quan
        self.order_info.loc[idx, 'order_info'] = ""
        print("self.order_info")
        print(self.order_info)

        self.tableWidget_2.setRowCount(idx)
        self.tableWidget_2.setItem(idx, dv.tableWidget_2_item_code, QTableWidgetItem(str(item_code)))
        self.tableWidget_2.setItem(idx, dv.tableWidget_2_item_name, QTableWidgetItem(str(item_name)))
        self.tableWidget_2.setItem(idx, dv.tableWidget_2_origin_code, QTableWidgetItem(str(origin_ordno)))
        self.tableWidget_2.setItem(idx, dv.tableWidget_2_order_price, QTableWidgetItem(str(order_pri)))
        self.tableWidget_2.setItem(idx, dv.tableWidget_2_order_quan, QTableWidgetItem(str(order_quan)))
        self.tableWidget_2.setItem(idx, dv.tableWidget_2_trade_quan, QTableWidgetItem(str(signed_quan)))
        self.tableWidget_2.setItem(idx, dv.tableWidget_2_remained_quan, QTableWidgetItem(str(remained_quan)))

Line 4~6 구간은 원주문번호가 0000000이 아님에도 불구하고 사전 주문 정보가 없는, 즉 일어나서는 안 되는 상황이었기 때문에 어떠한 동작도 수행하지 않도록 구현한다(오류가 있음을 확인하고 싶다면 오류가 있음을 출력하도록 구현해도 된다).

다음으로 Line 8~32 구간은 원주문번호가 0000000이 아니면서 사전 주문 정보가 있는 경우에 해당하므로 Line 10에서 해당 종목 코드(  _item_code  )가   self.order_info  변수 내에서 갖는 인덱스 번호를 얻어와서   idx  에 저장하고, Line 12~21에서는   self.order_info  변수에 데이터를 입력하고 Line 25~32에서는 GUI 상에서 확인할 수 있도록   tableWidget_2  객체에 데이터를 입력하도록 한다.

여기까지의 코드가 정정 주문이 발생했을 때 데이터를 처리하는 방법에 관한 내용이다.

 

 


728x90
반응형
Contents

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

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