본문 바로가기
System Trading

바이낸스 페어 아비트라지 봇 빌딩하기 - 현재 거래 중 정보 목록을 파일로 실시간 관리하기

by raacers 2022. 12. 23.

바이낸스 페어 아비트라지 봇 빌딩하기 - 현재 거래 중 정보 목록을 파일로 실시간 관리하기

 

 

현재 봇의 인터페이스입니다. 큰 창이 공적분(Co-Integration) 분석 결과이고 작은 창이 현재 거래 중인 정보입니다.

바이낸스, 업비트 아비트라지 봇 빌딩하기 - 현재 거래 중 정보 목록을 파일로 실시간 관리하기(현재 인터페이스)

 

지금까지는 직접 변수로 거래 중인 정보들을 관리했는데, 거래를 시작하면 json 파일에 자동으로 추가하고 거래를 종료하면 삭제하는 기능을 추가하려고 합니다. 봇을 멈추고 다시 작동해도 저장되어 있는 파일을 로드하면 되므로 편리하게 사용할 수 있게 됩니다.

 

1. 거래를 시작할 때 거래 정보를 json 파일에 자동으로 추가하기

현재 저장된 파일을 불러와서 메인 쓰레드에서 전달받은 종목명과 표준점수를 아래와 같이 추가합니다. 거래 정보는 List 형식의 json 파일로 저장되어 있기 때문에 append 함수로 정보를 쉽게 추가할 수 있습니다.

def append_new_position_to_json(sym_1, sym_2, z_score):
    with open("open_position_data.json") as json_file:
        open_position_data = json.load(json_file)

    new_order = {
        "sym_1": sym_1,
        "sym_2": sym_2,
        "opening_z_score": z_score,
        "opening_date": 0,
        "closing_date": 0,
        "closing_PNL": 0,
        "closing_ROE": 0,
    }
    open_position_data.append(new_order)

    with open("open_position_data.json", 'w') as json_file:
        json_file.write(json.dumps(open_position_data, indent=4))

 

2. 거래 정보 json 파일을 주기적으로 읽어서 정보 창에 입력하기

저장한 json 파일을 5초 마다 불러와서 List 변수에 저장 후 메인 쓰레드로 전달해 주는 쓰레드를 작성합니다. QThread 클래스를 상속받는 클래스를 생성하여 아래와 같이 작성합니다.

class GetOpenPositionData(QThread):
    dataSent = pyqtSignal(list)

    def __init__(self):
        super().__init__()
        self.alive = True

    def run(self):
        while self.alive:
            with open("open_position_data.json") as json_file:
                open_position_data = json.load(json_file)

            self.dataSent.emit(open_position_data)
            time.sleep(5)

    def close(self):
        self.alive = False

 

메인 쓰레드에서는 List 형식의 데이터를 넘겨받아, 이 데이터를 필요로 하는 모든 함수들을 한 군데에 묶어서 아래처럼 처리합니다.

class OpenPositionWindow(QMainWindow):

    def __init__(self):
        super().__init__()
        self.setupUI()

        self.go = GetOpenPositionData()
        self.go.dataSent.connect(self.get_open_position_data)
        self.go.start()
        
    def get_open_position_data(self, open_position_data):
        self.open_position_data = open_position_data


        self.gz = GetZScore(self.open_position_data)
        self.gz.dataSent.connect(self.set_latest_z_score)
        self.gz.start()

        self.gp = GetPnlRoe(self.open_position_data)
        self.gp.dataSent.connect(self.set_pnl_roe)
        self.gp.start()

        self.pc = Get24hrPriceChange(self.open_position_data)
        self.pc.dataSent.connect(self.close_price_change_position)
        self.pc.start()

        self.tableWidget.cellClicked.connect(self.cell_clicked_event)

        self.set_starting_z_score()
        self.setTableWidgetData()

 

json파일의 데이터가 잘 전달되고 있음을 확인할 수 있습니다.

바이낸스, 업비트 아비트라지 봇 빌딩하기 - 현재 거래 중 정보 목록을 파일로 실시간 관리하기(json 파일)
바이낸스, 업비트 아비트라지 봇 빌딩하기 - 현재 거래 중 정보 목록을 파일로 실시간 관리하기(json 파일 출력)

 

3. 거래를 종료할 때 거래 정보를 json 파일에서 자동으로 삭제하기

현재 봇에서 거래 종료는 세 부분에서 작동하고 있습니다. 사용자가 거래 종료 버튼을 누를 때 작동하고, 가격이 급변할 때 2가지 알고리즘으로 자동으로 작동합니다. 세 부분에 아래와 같이 삭제 함수를 호출하는 부분을 작성합니다. 삭제할 데이터는 List의 일부분이고 테이블 행 번호와 List 인덱스 번호가 동일하기 때문에 테이블 행 번호만 함수에 전달하면 됩니다.

delete_close_position_from_json(item.row())

 

삭제 함수에서는 전달받은 행 번호를 List 인덱스 번호로 사용하여 간단히 삭제할 수 있습니다.

def delete_close_position_from_json(index):
    with open("open_position_data.json") as json_file:
        open_position_data = json.load(json_file)

    del open_position_data[index]

    with open("open_position_data.json", 'w') as json_file:
        json_file.write(json.dumps(open_position_data, indent=4))

댓글