주식 자동매매 강의/기초반(모든 코딩의 뿌리)

주식자동매매 43강. 실시간 자동매매 구현(5), DB에 저장된 종목 가져오기

개발자(ALBA) 2022. 6. 9. 22:42
반응형

42강에서 KOA Studio를 이용해 원하는 종목의 실시간 데이터를 어떻게 키움 서버에 요청하는지 그리고 받아오는지에 대하여 설명드렸습니다. 이번에는 원하는 종목의 실시간 등록을 위해 DB를 읽어 들이겠습니다.

 

[유튜브 강의, 링크]와 같이 보시면 많은 도움이 되실 겁니다.

1. DB 데이터 읽어 들이기

38강에서 DB로 저장된 텍스트 데이터를 어떻게 불러 들이는지 아주 자세히 설명드렸습니다. 따라서 이 부분을 스킵하려고 했지만... 여러분들의 복습을 위해 다시 한 번 더 DB 데이터를 읽는 법을 강의해 드리겠습니다.

- 우선 37~38강에서 우리가 무엇을 저장햇는지 다시 리뷰 하도록 하겠습니다.
- 저장된 정보는 코드번호, 종목명, 현재가, 신용비율, 매수가, 매수수량, 익절가, 손절가입니다.

저장 데이터 확인
저장 데이터 확인

- 그러면 위에 저장된 데이터를 불러올 수 있는 Load_code() 함수를 실행합니다.

DB 데이터 로드 함수
DB 데이터 로드 함수

- Load_data 함수의 구성은 아래와 같습니다.

DB데이터 가져오기
DB데이터 가져오기

- if os.path.exisits : 원하는 폴더에 원하는 파일이 있다면 아래 코드를 실행합니다.
- f = open() : 원하는 파일을 읽어 들입니다.


- f.readlines() : 원하는 파일에 적힌 글의 행에 있는 모든 데이터를 넣습니다. 다시 말씀드리지만 행으로 구분합니다.
1행 : 삼성전자 11111
2행 : 바이넥스 22222
- screen : 실시간 주문 전송을 위한 스크린 번호입니다. 종목마다 스크린 번호를 다르게 하며, 시작은 4000부터 입니다. 아래 코드를 보시면 screen += 1 이 있는데 이는 4000이 끝나면 screen을 4001로 만들고 4001이 끝나면 4002로 만드는 코드입니다.
- for line in lines : lines에 입력된 각 종목에 대한 특정 값들이 하나의 행 순서로 line에 입력됩니다.
- line에 입력된 코드번호, 종목명, 현재가, 신용비율, 매수가, 매수수량, 익절가, 손절가 값들은 Tab으로 구분되어 있기 때문에 구분자를 \t로 없애 줍니다. 그러면 [코드번호 종목명….]으로 구분되어 있던 값이 [코드번호, 종목명….]으로 바뀌게 됩니다.
- t.code = ls[0] : 0은 파이썬에서 첫 번째를 의미하고 t_code에는 ls의 첫 번째 코드번호가 들어가게 됩니다. 나머지 코드도 동일합니다.
- selfk.k.portpolio_stock_dict.update({t_code: {"종목명 : t_name}}) : 메타 클래스 기반의 싱글턴에 있는 portpolio_stock_dict에 우리가 원하는 종목의 모든 정보를 입력하겠습니다. slff.k를 사용해서 실글턴에 접속 후 portpolio_stock_dict에 원하는 종목 코드와 종목명을 입력하기 위해 update라는 함수를 사용합니다. 그리고 저장 형식은 딕셔너리 형태이며 A = B와 동일합니다. {}는 딕셔너리를 의미 합니다.
딕셔너리 구성 시 {A : B}이며, B에 딕셔너리를 한번 더 적용하여 {A : {B : C}}라고 하였습니다. 차 후에 C값을 확인하기 위해서는 A[B]라고 코딩하시몀 C가 나오게 됩니다. 이 부분이 이해가 어렵다면, 차후에 업로드되는 유튜브 영상을 보시거나 파이썬 딕셔너리를 공부해 보세요. 저도 자동매매 기초반이 끝나면 파이썬 주요 함수들에서 설명할 수 있는 기회를 가지겠습니다.
- 위의 코드에서 t_code에 대한 정의가 portpolio_stock_dict에 저장되었으므로 이제부터 우리가 원하는 값을 계속 붙여 넣기 하면 됩니다.
- self.k.portpolio_stock_dict[t_code].update({"현재가" : int(current_price}) : portpolio_stock_dict에 t_code로 구성된 딕셔너리를 생성합니다. 그리고 update를 이용해 원하는 값들을 딕셔너리러 계속 저장하시면 됩니다. 이때 현재가 같은 경우는 int를 사용하려 문자에서 숫자로 변경하였으며, 차 후 사칙연산 등에 사용될 예정입니다.
- 나머지 코드들도 다 동일하고 별도의 주문용 스크린 번호도 저장해 줌으로써 차 후에 매수/매도를 위한 종목마다의 스크린 번호를 할당해 놓습니다.

반응형

2. 코드 공개

Load_code 함수 부분에 대한 코드를 아래와 같이 공개해 드리니 많은 연습하시기 바랍니다. 다음 강의에서는 읽어 들인 DB 파일을 기초로 실시간 종목 등록을 해보도록 하겠습니다.

import os                                   # 현재 디렉토리 확인 기능
from PyQt5.QtCore import *                  # 쓰레드 함수를 불러온다.
from kiwoom import Kiwoom                   # 로그인을 위한 클래스
from kiwoomType import *


class Thread3(QThread):
    def __init__(self, parent):   # 부모의 윈도우 창을 가져올 수 있다.
        super().__init__(parent)  # 부모의 윈도우 창을 초기화 한다.
        self.parent = parent      # 부모의 윈도우를 사용하기 위한 조건

        ################## 키움서버 함수를 사용하기 위해서 kiwoom의 능력을 상속 받는다.
        self.k = Kiwoom()
        ##################

        ################## 사용되는 변수
        account = self.parent.accComboBox.currentText()  # 콤보박스 안에서 가져오는 부분
        self.account_num = account
        # 계좌번호 가져오는 부분은 Qthread_3 분리 시 로그인 후 계좌번호를 가져오는 함수로 교체된다. Lecture_0529.py

        ################# 매수관련 변수
        self.Load_code()         # 매수 종목/금액/수량 가져오기

    def Load_code(self):

        if os.path.exists("dist/Selected_code.txt"):
            f = open("dist/Selected_code.txt", "r", encoding="utf8")
            lines = f.readlines()  # 여러 종목이 저장되어 있다면 모든 항목을 가져온다.
            screen = 4000
            for line in lines:
                if line != "":                     # 만약에 line이 비어 있지 않다면
                    ls = line.split("\t")  # \t(tap)로 구분을 지어 놓는다.
                    t_code = ls[0]
                    t_name = ls[1]
                    curren_price = ls[2]
                    dept = ls[3]
                    mesu = ls[4]
                    n_o_stock = ls[5]
                    profit = ls[6]
                    loss = ls[7].split("\n")[0]

                    self.k.portfolio_stock_dict.update({t_code: {"종목명": t_name}})
                    self.k.portfolio_stock_dict[t_code].update({"현재가": int(curren_price)})
                    self.k.portfolio_stock_dict[t_code].update({"신용비율": dept})
                    self.k.portfolio_stock_dict[t_code].update({"매수가": int(mesu)})
                    self.k.portfolio_stock_dict[t_code].update({"매수수량": int(n_o_stock)})
                    self.k.portfolio_stock_dict[t_code].update({"익절가": int(profit)})
                    self.k.portfolio_stock_dict[t_code].update({"손절가": int(loss)})
                    self.k.portfolio_stock_dict[t_code].update({"주문용스크린번호": screen})  # 아래 내용을 업데이트
                    screen += 1
            f.close()
반응형