Skip to content
조회 수 3820 추천 수 0 댓글 3
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄

키움 증권 API를 이용하여 주식 자동 매매 프로그램 개발

 

 

https://github.com/kdseo/PyTrader/blob/master/Kiwoom.py

 

import sys
import os
from PyQt5.QtWidgets import *
from PyQt5.QAxContainer import *
from PyQt5.QtCore import *
from beautifultable import BeautifulTable
from PyQt5.QtTest import *

TR_REQ_TIME_INTERVAL = 0.2
class Kiwoom(QAxWidget):
    def __init__(self):
        self.app = QApplication(sys.argv)
        print("Ui_class 입니다.")
        super().__init__()
        # 이벤트 루프 관련 변수
        self.login_event_loop = QEventLoop()
        self.account_event_loop = QEventLoop()
        self.calculator_event_loop = QEventLoop()

        # 계좌 관련 변수
        self.account_number = None
        self.total_buy_money = None
        self.total_evaluation_money = None
        self.total_evaluation_profit_and_loss_money = None
        self.total_yield = None
        self.account_stock_dict = {}
        self.not_signed_account_dict = {}

        # 예수금 관련 변수
        self.deposit = None
        self.withdraw_deposit = None
        self.order_deposit = None

        # 종목 분석 관련 변수
        self.calculator_list = []

        # 화면 번호
        self.screen_my_account = "1000"
        self.screen_calculation_stock = "2000"

        # 초기 작업
        print("초기작업시작")
        self.create_kiwoom_instance()
        self.event_collection()  # 이벤트와 슬롯을 메모리에 먼저 생성.
        self.login()
        print("계좌정보시작")
        input()
        self.get_account_info()  # 계좌 번호만 얻어오기
        self.get_deposit_info()  # 예수금 관련된 정보 얻어오기
        self.get_account_evaluation_balance()  # 계좌평가잔고내역 얻어오기
        self.not_signed_account()  # 미체결내역 얻어오기
        #self.calculator()
        self.menu()

        print("스케쥴링시작")
###########[스케쥴링]############
        self.kiwoom = QAxWidget("KHOPENAPI.KHOpenAPICtrl.1")
        self.kiwoom.OnEventConnect.connect(self.kiwoom_OnEventConnect)  # 로그인 결과를 받을 콜백함수 연결
        self.get_ocx_instance() # OCX 방식을 파이썬에 사용할 수 있게 반환해 주는 함수 실행
        self.event_slots()
        self.signal_login_commConnect() #접속
        self.get_account_info()  # 계좌정보



###########[스케쥴링]############


    # COM 오브젝트 생성.
    def create_kiwoom_instance(self):
        # 레지스트리에 저장된 키움 openAPI 모듈 불러오기
        self.setControl("KHOPENAPI.KHOpenAPICtrl.1")

    def event_collection(self):
        self.OnEventConnect.connect(self.login_slot)  # 로그인 관련 이벤트
        self.OnReceiveTrData.connect(self.tr_slot)  # 트랜잭션 요청 관련 이벤트

    def login(self):
        self.dynamicCall("CommConnect()")  # 시그널 함수 호출.
        self.login_event_loop.exec_()

    def login_slot(self, err_code):
        if err_code == 0:
            print("로그인에 성공하였습니다.")
        else:
            os.system('cls')
            print("에러 내용 :", errors(err_code)[1])
            sys.exit(0)
        self.login_event_loop.exit()

    def get_account_info(self):
        account_list = self.dynamicCall("GetLoginInfo(QString)", "ACCNO")
        account_number = account_list.split(';')[0]
        self.account_number = account_number

    def menu(self):
        sel = ""
        while True:
            os.system('cls')
            print("1. 현재 로그인 상태 확인")
            print("2. 사용자 정보 조회")
            print("3. 예수금 조회")
            print("4. 계좌 잔고 조회")
            print("5. 미체결 내역 조회")
            print("Q. 프로그램 종료")
            sel = input("=> ")

            if sel == "Q" or sel == "q":
                sys.exit(0)

            if sel == "1":
                self.print_login_connect_state()
            elif sel == "2":
                self.print_my_info()
            elif sel == "3":
                self.print_get_deposit_info()
            elif sel == "4":
                self.print_get_account_evaulation_balance_info()
            elif sel == "5":
                self.print_not_signed_account()

    def print_login_connect_state(self):
        os.system('cls')
        isLogin = self.dynamicCall("GetConnectState()")
        if isLogin == 1:
            print("\n현재 계정은 로그인 상태입니다.")
        else:
            print("\n현재 계정은 로그아웃 상태입니다.")
        input()

    def print_my_info(self):
        os.system('cls')
        user_name = self.dynamicCall("GetLoginInfo(QString)", "USER_NAME")
        user_id = self.dynamicCall("GetLoginInfo(QString)", "USER_ID")
        account_count = self.dynamicCall(
            "GetLoginInfo(QString)", "ACCOUNT_CNT")

        print(f"\n이름 : {user_name}")
        print(f"ID : {user_id}")
        print(f"보유 계좌 수 : {account_count}")
        print(f"계좌번호 : {self.account_number}")
        input()

    def print_get_deposit_info(self):
        os.system('cls')
        print(f"\n예수금 : {self.deposit}")
        print(f"출금 가능 금액 : {self.withdraw_deposit}")
        print(f"주문 가능 금액 : {self.order_deposit}")
        input()

    def print_get_account_evaulation_balance_info(self):
        os.system('cls')
        print("\n<싱글 데이터>")
        print(f"총 매입 금액 : {self.total_buy_money}")
        print(f"총 평가 금액 : {self.total_evaluation_money}")
        print(f"총 평가 손익 금액 : {self.total_evaluation_profit_and_loss_money}")
        print(f"총 수익률 : {self.total_yield}%\n")

        table = self.make_table("계좌평가잔고내역요청")
        print("<멀티 데이터>")
        if len(self.account_stock_dict) == 0:
            print("보유한 종목이 없습니다!")
        else:
            print(f"보유 종목 수 : {len(self.account_stock_dict)}")
            print(table)
        input()

    def make_table(self, sRQName):
        table = BeautifulTable()
        table = BeautifulTable(maxwidth=150)

        if sRQName == "계좌평가잔고내역요청":
            for stock_code in self.account_stock_dict:
                stock = self.account_stock_dict[stock_code]
                stockList = []
                for key in stock:
                    output = None

                    if key == "종목명":
                        output = stock[key]
                    elif key == "수익률(%)":
                        output = str(stock[key]) + "%"
                    elif key == "보유수량" or key == "매매가능수량":
                        output = str(stock[key]) + ""
                    else:
                        output = str(stock[key]) + ""
                    stockList.append(output)
                table.rows.append(stockList)
            table.columns.header = ["종목명", "평가손익",
                                    "수익률", "매입가", "보유수량", "매매가능수량", "현재가"]
            table.rows.sort('종목명')

        elif sRQName == "실시간미체결요청":
            for stock_order_number in self.not_signed_account_dict:
                stock = self.not_signed_account_dict[stock_order_number]
                stockList = [stock_order_number]
                for key in stock:
                    output = None
                    if key == "주문가격" or key == "현재가":
                        output = str(stock[key]) + ""
                    elif '' in key:
                        output = str(stock[key]) + ""
                    elif key == "종목코드":
                        continue
                    else:
                        output = stock[key]
                    stockList.append(output)
                table.rows.append(stockList)
            table.columns.header = ["주문번호", "종목명", "주문구분", "주문가격", "주문수량",
                                    "미체결수량", "체결량", "현재가", "주문상태"]
            table.rows.sort('주문번호')
        return table

    def print_not_signed_account(self):
        os.system('cls')
        print()
        table = self.make_table("실시간미체결요청")
        if len(self.not_signed_account_dict) == 0:
            print("미체결 내역이 없습니다!")
        else:
            print(table)
        input()

    def get_deposit_info(self, nPrevNext=0):
        self.dynamicCall("SetInputValue(QString, QString)",
                         "계좌번호", self.account_number)
        self.dynamicCall("SetInputValue(QString, QString)", "비밀번호", " ")
        self.dynamicCall("SetInputValue(QString, QString)", "비밀번호입력매체구분", "00")
        self.dynamicCall("SetInputValue(QString, QString)", "조회구분", "2")
        self.dynamicCall("CommRqData(QString, QString, int, QString)",
                         "예수금상세현황요청", "opw00001", nPrevNext, self.screen_my_account)

        self.account_event_loop.exec_()

    def get_account_evaluation_balance(self, nPrevNext=0):
        self.dynamicCall("SetInputValue(QString, QString)",
                         "계좌번호", self.account_number)
        self.dynamicCall("SetInputValue(QString, QString)", "비밀번호", " ")
        self.dynamicCall("SetInputValue(QString, QString)", "비밀번호입력매체구분", "00")
        self.dynamicCall("SetInputValue(QString, QString)", "조회구분", "1")
        self.dynamicCall("CommRqData(QString, QString, int, QString)",
                         "계좌평가잔고내역요청", "opw00018", nPrevNext, self.screen_my_account)

        if not self.account_event_loop.isRunning():
            self.account_event_loop.exec_()

    def not_signed_account(self, nPrevNext=0):
        self.dynamicCall("SetInputValue(QString, QString)",
                         "계좌번호", self.account_number)
        self.dynamicCall("SetInputValue(QString, QString)", "전체종목구분", "0")
        self.dynamicCall("SetInputValue(QString, QString)", "매매구분", "0")
        self.dynamicCall("SetInputValue(QString, QString)", "체결구분", "1")
        self.dynamicCall("CommRqData(QString, QString, int, QString)",
                         "실시간미체결요청", "opt10075", nPrevNext, self.screen_my_account)

        if not self.account_event_loop.isRunning():
            self.account_event_loop.exec_()

    def tr_slot(self, sScrNo, sRQName, sTrCode, sRecordName, sPrevNext):
        if sRQName == "예수금상세현황요청":
            deposit = self.dynamicCall(
                "GetCommData(QString, QString, int, QString)", sTrCode, sRQName, 0, "예수금")
            self.deposit = int(deposit)

            withdraw_deposit = self.dynamicCall(
                "GetCommData(QString, QString, int, QString)", sTrCode, sRQName, 0, "출금가능금액")
            self.withdraw_deposit = int(withdraw_deposit)

            order_deposit = self.dynamicCall(
                "GetCommData(QString, QString, int, QString)", sTrCode, sRQName, 0, "주문가능금액")
            self.order_deposit = int(order_deposit)
            self.cancel_screen_number(self.screen_my_account)
            self.account_event_loop.exit()

        elif sRQName == "계좌평가잔고내역요청":
            if (self.total_buy_money == None or self.total_evaluation_money == None
                    or self.total_evaluation_profit_and_loss_money == None or self.total_yield == None):
                total_buy_money = self.dynamicCall(
                    "GetCommData(QString, QString, int, QString)", sTrCode, sRQName, 0, "총매입금액")
                self.total_buy_money = int(total_buy_money)

                total_evaluation_money = self.dynamicCall(
                    "GetCommData(QString, QString, int, QString)", sTrCode, sRQName, 0, "총평가금액")
                self.total_evaluation_money = int(total_evaluation_money)

                total_evaluation_profit_and_loss_money = self.dynamicCall(
                    "GetCommData(QString, QString, int, QString)", sTrCode, sRQName, 0, "총평가손익금액")
                self.total_evaluation_profit_and_loss_money = int(
                    total_evaluation_profit_and_loss_money)

                total_yield = self.dynamicCall(
                    "GetCommData(QString, QString, int, QString)", sTrCode, sRQName, 0, "총수익률(%)")
                self.total_yield = float(total_yield)

            cnt = self.dynamicCall(
                "GetRepeatCnt(QString, QString)", sTrCode, sRQName)

            for i in range(cnt):
                stock_code = self.dynamicCall(
                    "GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "종목번호")
                stock_code = stock_code.strip()[1:]

                stock_name = self.dynamicCall(
                    "GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "종목명")
                stock_name = stock_name.strip()  # 필요 없는 공백 제거.

                stock_evaluation_profit_and_loss = self.dynamicCall(
                    "GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "평가손익")
                stock_evaluation_profit_and_loss = int(
                    stock_evaluation_profit_and_loss)

                stock_yield = self.dynamicCall(
                    "GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "수익률(%)")
                stock_yield = float(stock_yield)

                stock_buy_money = self.dynamicCall(
                    "GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "매입가")
                stock_buy_money = int(stock_buy_money)

                stock_quantity = self.dynamicCall(
                    "GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "보유수량")
                stock_quantity = int(stock_quantity)

                stock_trade_quantity = self.dynamicCall(
                    "GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "매매가능수량")
                stock_trade_quantity = int(stock_trade_quantity)

                stock_present_price = self.dynamicCall(
                    "GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "현재가")
                stock_present_price = int(stock_present_price)

                if not stock_code in self.account_stock_dict:
                    self.account_stock_dict[stock_code] = {}

                self.account_stock_dict[stock_code].update({'종목명': stock_name})
                self.account_stock_dict[stock_code].update(
                    {'평가손익': stock_evaluation_profit_and_loss})
                self.account_stock_dict[stock_code].update(
                    {'수익률(%)': stock_yield})
                self.account_stock_dict[stock_code].update(
                    {'매입가': stock_buy_money})
                self.account_stock_dict[stock_code].update(
                    {'보유수량': stock_quantity})
                self.account_stock_dict[stock_code].update(
                    {'매매가능수량': stock_trade_quantity})
                self.account_stock_dict[stock_code].update(
                    {'현재가': stock_present_price})

            if sPrevNext == "2":
                self.get_account_evaluation_balance(2)
            else:
                self.cancel_screen_number(self.screen_my_account)
                self.account_event_loop.exit()

        elif sRQName == "실시간미체결요청":
            cnt = self.dynamicCall(
                "GetRepeatCnt(QString, QString)", sTrCode, sRQName)

            for i in range(cnt):
                stock_code = self.dynamicCall(
                    "GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "종목코드")
                stock_code = stock_code.strip()

                stock_order_number = self.dynamicCall(
                    "GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "주문번호")
                stock_order_number = int(stock_order_number)

                stock_name = self.dynamicCall(
                    "GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "종목명")
                stock_name = stock_name.strip()

                stock_order_type = self.dynamicCall(
                    "GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "주문구분")
                stock_order_type = stock_order_type.strip().lstrip('+').lstrip('-')

                stock_order_price = self.dynamicCall(
                    "GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "주문가격")
                stock_order_price = int(stock_order_price)

                stock_order_quantity = self.dynamicCall(
                    "GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "주문수량")
                stock_order_quantity = int(stock_order_quantity)

                stock_not_signed_quantity = self.dynamicCall(
                    "GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "미체결수량")
                stock_not_signed_quantity = int(stock_not_signed_quantity)

                stock_signed_quantity = self.dynamicCall(
                    "GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "체결량")
                stock_signed_quantity = int(stock_signed_quantity)

                stock_present_price = self.dynamicCall(
                    "GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "현재가")
                stock_present_price = int(
                    stock_present_price.strip().lstrip('+').lstrip('-'))

                stock_order_status = self.dynamicCall(
                    "GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "주문상태")
                stock_order_status = stock_order_status.strip()

                if not stock_order_number in self.not_signed_account_dict:
                    self.not_signed_account_dict[stock_order_number] = {}

                self.not_signed_account_dict[stock_order_number].update(
                    {'종목코드': stock_code})
                self.not_signed_account_dict[stock_order_number].update(
                    {'종목명': stock_name})
                self.not_signed_account_dict[stock_order_number].update(
                    {'주문구분': stock_order_type})
                self.not_signed_account_dict[stock_order_number].update(
                    {'주문가격': stock_order_price})
                self.not_signed_account_dict[stock_order_number].update(
                    {'주문수량': stock_order_quantity})
                self.not_signed_account_dict[stock_order_number].update(
                    {'미체결수량': stock_not_signed_quantity})
                self.not_signed_account_dict[stock_order_number].update(
                    {'체결량': stock_signed_quantity})
                self.not_signed_account_dict[stock_order_number].update(
                    {'현재가': stock_present_price})
                self.not_signed_account_dict[stock_order_number].update(
                    {'주문상태': stock_order_status})

            if sPrevNext == "2":
                self.not_signed_account(2)
            else:
                self.cancel_screen_number(sScrNo)
                self.account_event_loop.exit()

        elif sRQName == "주식일봉차트조회요청":
            stock_code = self.dynamicCall(
                "GetCommData(QString, QString, int, QString)", sTrCode, sRQName, 0, "종목코드")
            #six_hundred_data = self.dynamicCall("GetCommDataEx(QString, QString)", sTrCode, sRQName)

            stock_code = stock_code.strip()
            cnt = self.dynamicCall(
                "GetRepeatCnt(QString, QString)", sTrCode, sRQName)  # 최대 600
            for i in range(cnt):
                calculator_list = []

                current_price = self.dynamicCall(
                    "GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "현재가")
                volume = self.dynamicCall(
                    "GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "거래량")
                trade_price = self.dynamicCall(
                    "GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "거래대금")
                date = self.dynamicCall(
                    "GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "일자")
                start_price = self.dynamicCall(
                    "GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "시가")
                high_price = self.dynamicCall(
                    "GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "고가")
                low_price = self.dynamicCall(
                    "GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "저가")

                calculator_list.append("")
                calculator_list.append(int(current_price))
                calculator_list.append(int(volume))
                calculator_list.append(int(trade_price))
                calculator_list.append(int(date))
                calculator_list.append(int(start_price))
                calculator_list.append(int(high_price))
                calculator_list.append(int(low_price))
                calculator_list.append("")

                self.calculator_list.append(calculator_list.copy())

            if sPrevNext == "2":
                self.day_kiwoom_db(stock_code, None, 2)
            else:
                self.calculator_event_loop.exit()

    def cancel_screen_number(self, sScrNo):
        self.dynamicCall("DisconnectRealData(QString)", sScrNo)

    def get_code_list_by_market(self, market_code):
        code_list = self.dynamicCall(
            "GetCodeListByMarket(QString)", market_code)
        code_list = code_list.split(";")[:-1]
        return code_list

    def calculator(self):
        kosdaq_list = self.get_code_list_by_market("10")

        for idx, stock_code in enumerate(kosdaq_list):
            self.dynamicCall("DisconnectRealData(QString)",
                             self.screen_calculation_stock)

            print(
                f"{idx + 1} / {len(kosdaq_list)} : KOSDAQ Stock Code : {stock_code} is updating...")
            self.day_kiwoom_db(stock_code)

    def day_kiwoom_db(self, stock_code=None, date=None, nPrevNext=0):
        QTest.qWait(3600)  # 3.6초마다 딜레이

        self.dynamicCall("SetInputValue(QString, QString)", "종목코드", stock_code)
        self.dynamicCall("SetInputValue(QString, QString)", "수정주가구분", 1)

        if date != None:  # date None일 경우 date는 오늘 날짜 기준
            self.dynamicCall("SetInputValue(QString, QString)", "기준일자", date)

        self.dynamicCall("CommRqData(QString, QString, int, QString)",
                         "주식일봉차트조회요청", "opt10081", nPrevNext, self.screen_calculation_stock)

        if not self.calculator_event_loop.isRunning():
            self.calculator_event_loop.exec_()

    def errors(err_code):

        err_dic = {0: ('OP_ERR_NONE', '정상처리'),
                   -10: ('OP_ERR_FAIL', '실패'),
                   -100: ('OP_ERR_LOGIN', '사용자정보교환실패'),
                   -101: ('OP_ERR_CONNECT', '서버접속실패'),
                   -102: ('OP_ERR_VERSION', '버전처리실패'),
                   -103: ('OP_ERR_FIREWALL', '개인방화벽실패'),
                   -104: ('OP_ERR_MEMORY', '메모리보호실패'),
                   -105: ('OP_ERR_INPUT', '함수입력값오류'),
                   -106: ('OP_ERR_SOCKET_CLOSED', '통신연결종료'),
                   -200: ('OP_ERR_SISE_OVERFLOW', '시세조회과부하'),
                   -201: ('OP_ERR_RQ_STRUCT_FAIL', '전문작성초기화실패'),
                   -202: ('OP_ERR_RQ_STRING_FAIL', '전문작성입력값오류'),
                   -203: ('OP_ERR_NO_DATA', '데이터없음'),
                   -204: ('OP_ERR_OVER_MAX_DATA', '조회가능한종목수초과'),
                   -205: ('OP_ERR_DATA_RCV_FAIL', '데이터수신실패'),
                   -206: ('OP_ERR_OVER_MAX_FID', '조회가능한FID수초과'),
                   -207: ('OP_ERR_REAL_CANCEL', '실시간해제오류'),
                   -300: ('OP_ERR_ORD_WRONG_INPUT', '입력값오류'),
                   -301: ('OP_ERR_ORD_WRONG_ACCTNO', '계좌비밀번호없음'),
                   -302: ('OP_ERR_OTHER_ACC_USE', '타인계좌사용오류'),
                   -303: ('OP_ERR_MIS_2BILL_EXC', '주문가격이20억원을초과'),
                   -304: ('OP_ERR_MIS_5BILL_EXC', '주문가격이50억원을초과'),
                   -305: ('OP_ERR_MIS_1PER_EXC', '주문수량이총발행주수의1 % 초과오류'),
                   -306: ('OP_ERR_MIS_3PER_EXC', '주문수량은총발행주수의3 % 초과오류'),
                   -307: ('OP_ERR_SEND_FAIL', '주문전송실패'),
                   -308: ('OP_ERR_ORD_OVERFLOW', '주문전송과부하'),
                   -309: ('OP_ERR_MIS_300CNT_EXC', '주문수량300계약초과'),
                   -310: ('OP_ERR_MIS_500CNT_EXC', '주문수량500계약초과'),
                   -340: ('OP_ERR_ORD_WRONG_ACCTINFO', '계좌정보없음'),
                   -500: ('OP_ERR_ORD_SYMCODE_EMPTY', '종목코드없음')
                   }

        result = err_dic[err_code]

        return result


######################## 시작
if __name__=="__main__":

    kiwoom = Kiwoom()

 

 

위의 소스를 가지고 하나씩 뜯어봐야겠다.

 

input() 함수로 사용자가 어떤 값을 입력하게 하고, 그 값을 변수에 저장할 수 있습니다.

 

중간중간에 input() 함수가 있어서 이게 뭔가 싶어 조회를 해보니, 

그냥 입력값 전달받는 함수였다.

입력하고 엔터를 누르면 되겠다.

 

 

 

 

로그인 후 댓글쓰기가 가능합니다.

?
  • ?
    nanumi 2021.09.08 08:20
    def test를 만들었다.
    그리고 내가 보유한 모든 종목을 추출해서 현재가 대비 피라미드 매수, 역피라미드 매도 주문을 하게 만들었는데,
    첫번째 종목이 예약 되고 난 뒤, 두번째 종목에서 멈춘다.

    trvalue = self.dynamicCall("GetCommData(QString, QString, int, QString)", sTrCode, "OPT10001", 0, "현재가")

    위의 코드에서 코류가 나는데 sTrCode는 뭘까?



    import sys
    import os
    import time
    from PyQt5.QtWidgets import *
    from PyQt5.QAxContainer import *
    from PyQt5.QtCore import *
    from beautifultable import BeautifulTable
    from PyQt5.QtTest import *

    TR_REQ_TIME_INTERVAL = 0.2
    class Kiwoom(QAxWidget):
    def __init__(self):
    self.app = QApplication(sys.argv)
    print("Ui_class 입니다.")
    super().__init__()
    # 이벤트 루프 관련 변수
    self.login_event_loop = QEventLoop()
    self.account_event_loop = QEventLoop()
    self.calculator_event_loop = QEventLoop()

    # 계좌 관련 변수
    self.account_number = None
    self.total_buy_money = None
    self.total_evaluation_money = None
    self.total_evaluation_profit_and_loss_money = None
    self.total_yield = None
    self.account_stock_dict = {}
    self.not_signed_account_dict = {}

    # 예수금 관련 변수
    self.deposit = None
    self.withdraw_deposit = None
    self.order_deposit = None

    # 종목 분석 관련 변수
    self.calculator_list = []

    # 화면 번호
    self.screen_my_account = "1000"
    self.screen_calculation_stock = "2000"

    # 초기 작업
    print("로그인-초기작업시작")
    self.create_kiwoom_instance()
    self.event_collection() # 이벤트와 슬롯을 메모리에 먼저 생성.
    self.login()
    print("계좌정보시작")
    # input()
    #
    self.get_account_info() # 계좌 번호만 얻어오기
    self.get_deposit_info() # 예수금 관련된 정보 얻어오기
    self.get_account_evaluation_balance() # 계좌평가잔고내역 얻어오기
    self.not_signed_account() # 미체결내역 얻어오기
    #self.calculator()
    # self.menu()

    print("스케쥴링시작")
    ###########[스케쥴링]############
    #self.kiwoom = QAxWidget("KHOPENAPI.KHOpenAPICtrl.1")
    #self.kiwoom.OnEventConnect.connect(self.kiwoom_OnEventConnect) # 로그인 결과를 받을 콜백함수 연결
    #self.get_ocx_instance() # OCX 방식을 파이썬에 사용할 수 있게 반환해 주는 함수 실행
    #self.event_slots()
    #self.signal_login_commConnect() #접속
    #self.get_account_info() # 계좌정보
    self.test()


    ###########[스케쥴링]############

    def test(self):
    account_list = self.dynamicCall("GetLoginInfo(QString)", "ACCNO")
    account_number = account_list.split(';')[0]
    self.account_number = account_number ##계좌정보 획득!

    user_name = self.dynamicCall("GetLoginInfo(QString)", "USER_NAME")
    user_id = self.dynamicCall("GetLoginInfo(QString)", "USER_ID")
    account_count = self.dynamicCall(
    "GetLoginInfo(QString)", "ACCOUNT_CNT")

    print(f"\n이름 : {user_name}")
    print(f"ID : {user_id}")
    print(f"보유 계좌 수 : {account_count}")
    print(f"계좌번호 : {self.account_number}")

    print(f"\n예수금 : {self.deposit}원")
    print(f"출금 가능 금액 : {self.withdraw_deposit}원")
    print(f"주문 가능 금액 : {self.order_deposit}원")


    print("\n<싱글 데이터>")
    print(f"총 매입 금액 : {self.total_buy_money}원")
    print(f"총 평가 금액 : {self.total_evaluation_money}원")
    print(f"총 평가 손익 금액 : {self.total_evaluation_profit_and_loss_money}원")
    print(f"총 수익률 : {self.total_yield}%\n")

    #############[보유종목과 매매가능수량확인 ]#############
    self.item_nums=list(self.account_stock_dict.keys())
    self.item_values=list(self.account_stock_dict.values())
    print(self.item_nums)
    print(self.item_values)
    #for index,value in enumerate(self.item_nums):
    # print("[%s] 종목번호[%s] 종목명[%s] 매매가능수량 : %s" % (index,self.item_nums[index],self.item_values[index]['종목명'],self.item_values[index]['매매가능수량']))

    #############[호가 및 매수주문]#############
    for index, value in enumerate(self.item_nums):
    self.item_num=self.item_nums[index] #종목코드 담기
    self.item_value=self.item_values[index]['매매가능수량'] #종목 값 담기
    self.item_name = self.item_values[index]['종목명'] # 종목 값 담기
    print("종목명 %s,종목코드 %s, 매매가능수량 : %s" % (self.item_name,self.item_num,self.item_value))

    self.trcode_buy04() #종목현재가로 0~4호가 피라미드매수
    time.sleep(5)
    self.trcode_sell04() #종목현재가로 0~4호가 피라미드매도
    time.sleep(5)
    self.trcode_buy59() #종목현재가로 5~9호가 피라미드매수
    time.sleep(3)
    self.trcode_sell59() #종목현재가로 5~9호가 피라미드매도
    time.sleep(5)

    ##################################################
    # COM 오브젝트 생성.
    def create_kiwoom_instance(self):
    # 레지스트리에 저장된 키움 openAPI 모듈 불러오기
    self.setControl("KHOPENAPI.KHOpenAPICtrl.1")

    def event_collection(self):
    self.OnEventConnect.connect(self.login_slot) # 로그인 관련 이벤트
    self.OnReceiveTrData.connect(self.tr_slot) # 트랜잭션 요청 관련 이벤트

    def login(self):
    self.dynamicCall("CommConnect()") # 시그널 함수 호출.
    self.login_event_loop.exec_()

    def login_slot(self, err_code):
    if err_code == 0:
    print("로그인에 성공하였습니다.")
    else:
    os.system('cls')
    print("에러 내용 :", errors(err_code)[1])
    sys.exit(0)
    self.login_event_loop.exit()

    def get_account_info(self):
    account_list = self.dynamicCall("GetLoginInfo(QString)", "ACCNO")
    account_number = account_list.split(';')[0]
    self.account_number = account_number

    def menu(self):
    sel = ""
    while True:
    os.system('cls')
    print("1. 현재 로그인 상태 확인")
    print("2. 사용자 정보 조회")
    print("3. 예수금 조회")
    print("4. 계좌 잔고 조회")
    print("5. 미체결 내역 조회")
    print("Q. 프로그램 종료")
    sel = input("=> ")

    if sel == "Q" or sel == "q":
    sys.exit(0)

    if sel == "1":
    self.print_login_connect_state()
    elif sel == "2":
    self.print_my_info()
    elif sel == "3":
    self.print_get_deposit_info()
    elif sel == "4":
    self.print_get_account_evaulation_balance_info()
    elif sel == "5":
    self.print_not_signed_account()

    def print_login_connect_state(self):
    os.system('cls')
    isLogin = self.dynamicCall("GetConnectState()")
    if isLogin == 1:
    print("\n현재 계정은 로그인 상태입니다.")
    else:
    print("\n현재 계정은 로그아웃 상태입니다.")
    input()

    def print_my_info(self):
    os.system('cls')
    user_name = self.dynamicCall("GetLoginInfo(QString)", "USER_NAME")
    user_id = self.dynamicCall("GetLoginInfo(QString)", "USER_ID")
    account_count = self.dynamicCall(
    "GetLoginInfo(QString)", "ACCOUNT_CNT")

    print(f"\n이름 : {user_name}")
    print(f"ID : {user_id}")
    print(f"보유 계좌 수 : {account_count}")
    print(f"계좌번호 : {self.account_number}")
    input()

    def print_get_deposit_info(self):
    os.system('cls')
    print(f"\n예수금 : {self.deposit}원")
    print(f"출금 가능 금액 : {self.withdraw_deposit}원")
    print(f"주문 가능 금액 : {self.order_deposit}원")
    input()

    def print_get_account_evaulation_balance_info(self):
    os.system('cls')
    print("\n<싱글 데이터>")
    print(f"총 매입 금액 : {self.total_buy_money}원")
    print(f"총 평가 금액 : {self.total_evaluation_money}원")
    print(f"총 평가 손익 금액 : {self.total_evaluation_profit_and_loss_money}원")
    print(f"총 수익률 : {self.total_yield}%\n")

    table = self.make_table("계좌평가잔고내역요청")
    print("<멀티 데이터>")
    if len(self.account_stock_dict) == 0:
    print("보유한 종목이 없습니다!")
    else:
    print(f"보유 종목 수 : {len(self.account_stock_dict)}개")
    print(table)
    input()

    def make_table(self, sRQName):
    table = BeautifulTable()
    table = BeautifulTable(maxwidth=150)

    if sRQName == "계좌평가잔고내역요청":
    for stock_code in self.account_stock_dict:
    stock = self.account_stock_dict[stock_code]
    stockList = []
    for key in stock:
    output = None

    if key == "종목명":
    output = stock[key]
    elif key == "수익률(%)":
    output = str(stock[key]) + "%"
    elif key == "보유수량" or key == "매매가능수량":
    output = str(stock[key]) + "개"
    else:
    output = str(stock[key]) + "원"
    stockList.append(output)
    table.rows.append(stockList)
    table.columns.header = ["종목명", "평가손익",
    "수익률", "매입가", "보유수량", "매매가능수량", "현재가"]
    table.rows.sort('종목명')

    elif sRQName == "실시간미체결요청":
    for stock_order_number in self.not_signed_account_dict:
    stock = self.not_signed_account_dict[stock_order_number]
    stockList = [stock_order_number]
    for key in stock:
    output = None
    if key == "주문가격" or key == "현재가":
    output = str(stock[key]) + "원"
    elif '량' in key:
    output = str(stock[key]) + "개"
    elif key == "종목코드":
    continue
    else:
    output = stock[key]
    stockList.append(output)
    table.rows.append(stockList)
    table.columns.header = ["주문번호", "종목명", "주문구분", "주문가격", "주문수량",
    "미체결수량", "체결량", "현재가", "주문상태"]
    table.rows.sort('주문번호')
    return table

    def print_not_signed_account(self):
    os.system('cls')
    print()
    table = self.make_table("실시간미체결요청")
    if len(self.not_signed_account_dict) == 0:
    print("미체결 내역이 없습니다!")
    else:
    print(table)
    input()

    def get_deposit_info(self, nPrevNext=0):
    self.dynamicCall("SetInputValue(QString, QString)",
    "계좌번호", self.account_number)
    self.dynamicCall("SetInputValue(QString, QString)", "비밀번호", " ")
    self.dynamicCall("SetInputValue(QString, QString)", "비밀번호입력매체구분", "00")
    self.dynamicCall("SetInputValue(QString, QString)", "조회구분", "2")
    self.dynamicCall("CommRqData(QString, QString, int, QString)",
    "예수금상세현황요청", "opw00001", nPrevNext, self.screen_my_account)

    self.account_event_loop.exec_()

    def get_account_evaluation_balance(self, nPrevNext=0):
    self.dynamicCall("SetInputValue(QString, QString)",
    "계좌번호", self.account_number)
    self.dynamicCall("SetInputValue(QString, QString)", "비밀번호", " ")
    self.dynamicCall("SetInputValue(QString, QString)", "비밀번호입력매체구분", "00")
    self.dynamicCall("SetInputValue(QString, QString)", "조회구분", "1")
    self.dynamicCall("CommRqData(QString, QString, int, QString)",
    "계좌평가잔고내역요청", "opw00018", nPrevNext, self.screen_my_account)

    if not self.account_event_loop.isRunning():
    self.account_event_loop.exec_()

    def not_signed_account(self, nPrevNext=0):
    self.dynamicCall("SetInputValue(QString, QString)",
    "계좌번호", self.account_number)
    self.dynamicCall("SetInputValue(QString, QString)", "전체종목구분", "0")
    self.dynamicCall("SetInputValue(QString, QString)", "매매구분", "0")
    self.dynamicCall("SetInputValue(QString, QString)", "체결구분", "1")
    self.dynamicCall("CommRqData(QString, QString, int, QString)",
    "실시간미체결요청", "opt10075", nPrevNext, self.screen_my_account)

    if not self.account_event_loop.isRunning():
    self.account_event_loop.exec_()




    def send_order(self, rqname, screen_no, acc_no, order_type, code, quantity, price, hoga, order_no):
    self.dynamicCall("SendOrder(QString, QString, QString, int, QString, int, int, QString, QString)",
    [rqname, screen_no, acc_no, order_type, code, quantity, price, hoga, order_no])

    def send_order1(self, rqname, screen_no, acc_no, order_type, code, quantity, price, hoga, order_no):
    self.dynamicCall("SendOrder(QString, QString, QString, int, QString, int, int, QString, QString)",
    [rqname, screen_no, acc_no, order_type, code, quantity, price, hoga, order_no])

    def trcode_buy04(self,sPrevNext="0"): ##현재가로 피라미드 0~4까지 매수
    self.dynamicCall("SetInputValue(QString, QString)", "종목코드", self.item_num)
    self.dynamicCall("CommRqData(QString, QString, int, QString)", "buy04", "opt10001", sPrevNext, "2000")

    def trcode_buy59(self,sPrevNext="0"): ##현재가로 피라미드 5~9까지 매수
    self.dynamicCall("SetInputValue(QString, QString)", "종목코드", self.item_num)
    self.dynamicCall("CommRqData(QString, QString, int, QString)", "buy59", "opt10001", sPrevNext, "2000")

    def trcode_sell04(self,sPrevNext="0"): ##현재가로 피라미드 0~4까지 매도
    self.dynamicCall("SetInputValue(QString, QString)", "종목코드", self.item_num)
    self.dynamicCall("CommRqData(QString, QString, int, QString)", "sell04", "opt10001", sPrevNext, "2000")

    def trcode_sell59(self,sPrevNext="0"): ##현재가로 피라미드 5~9까지 매도
    self.dynamicCall("SetInputValue(QString, QString)", "종목코드", self.item_num)
    self.dynamicCall("CommRqData(QString, QString, int, QString)", "sell59", "opt10001", sPrevNext, "2000")






    def tr_slot(self, sScrNo, sRQName, sTrCode, sRecordName, sPrevNext):

    if sRQName == "buy04":
    print("현재가피라미드매수-buy04%s",self.item_num)
    self.dynamicCall("SetInputValue(QString, QString)", "종목코드", self.item_num)
    print("종목코드입력")
    self.dynamicCall("CommRqData(QString, QString, int, QS tring)", "OPT10001", "opt10001", 0, "0101")
    print("종목코드전달")
    trvalue = self.dynamicCall("GetCommData(QString, QString, int, QString)", sTrCode, "OPT10001", 0, "현재가")
    print("현재가 : %s" % abs(int(trvalue.strip())))
    order_money = abs(int(trvalue.strip().replace(",", ""))) # 현재가를 변수에 담기

    max_order_money = 1000000
    mom_ea = abs(int(max_order_money / order_money)) # 총매매금액 나누기 현재가 = 총매매 수량
    if self.item_value < mom_ea :
    mom_ea = self.item_value #매매가능수량이 총매매수량보다 작으면 매매가능수량을 총매매수량에 넣는다.
    rate = 0.01
    sb_sum = 0
    sellbuy_ea = []

    print("총매매금액 : %s, 현재가 : %s, 총수량 %s" % (max_order_money, order_money, mom_ea))
    for i in range(0, 5):
    sellbuy_ea.append(int(mom_ea * rate))
    rate = rate + 0.02
    sb_sum = int(int(mom_ea * rate) + sb_sum)

    sellbuy_ea = sellbuy_ea
    print("총매매 주식수 : ", mom_ea)
    print("총매매금액 : ", max_order_money)

    print("실제매수수량 %s, 매매가능수량 %s" % (order_money * sb_sum, sellbuy_ea))
    # 0.5% ~ 10%까지의 매수호가/매도호가 생성
    sell_m = []
    buy_m = []
    rate_v = 0.005
    for i in range(0, 40): ## 20 = 10%에 대한 매도호가 생성 / 40 = 20%에 대한 매도호가 생성
    sell_m.append(order_money + (order_money * rate_v))
    buy_m.append(order_money - (order_money * rate_v))
    rate_v = rate_v + 0.005
    #print("매도호가",sell_m)
    # 0.5% ~ 10%까지의 폭

    ## 호가를 자리수에따라 반올림하면서 정수화 함.
    buyQ = []
    sellQ = []
    for i in range(0, len(buy_m)):
    if buy_m[i] < 1000:
    buyQ.append(abs(int(round(buy_m[i], 0))))
    elif buy_m[i] < 5000:
    buyQ.append(abs(int(round(buy_m[i], -1))))
    elif buy_m[i] < 10000:
    buyQ.append(abs(int(round(buy_m[i], -1))))
    elif buy_m[i] < 50000:
    buyQ.append(abs(int(round(buy_m[i], -2))))
    elif buy_m[i] < 100000:
    buyQ.append(abs(int(round(buy_m[i], -2))))
    elif buy_m[i] < 500000:
    buyQ.append(abs(int(round(buy_m[i], -3))))
    elif buy_m[i] < 1000000:
    buyQ.append(abs(int(round(buy_m[i], -3))))
    print("매수호가 %s " % buyQ)

    print("계좌번호:%s, 종목번호:%s\n총매수수량:%s\n매수금액:%s" % (self.account_number, self.item_num, sellbuy_ea, buyQ)) # buyQ는 40호가 까지 / sellbuy_ea는 10개까지)
    # (1:신규매수, 2:신규매도, 3:매수취소, 4:매도취소, 5:매수정정, 6:매도정정)

    if sellbuy_ea[0] != 0:
    self.send_order("buy04", "0101", self.account_number, 1, self.item_num, sellbuy_ea[0], buyQ[0], "00", "")
    time.sleep(0.3)
    print("1번성공")

    if sellbuy_ea[1] != 0:
    self.send_order("buy04", "0101", self.account_number, 1, self.item_num, sellbuy_ea[1], buyQ[3], "00", "")
    time.sleep(0.3)
    print("2번성공")

    if sellbuy_ea[2] != 0:
    self.send_order("buy04", "0101", self.account_number, 1, self.item_num, sellbuy_ea[2], buyQ[6], "00", "")
    time.sleep(0.3)
    print("3번성공")

    if sellbuy_ea[3] != 0:
    self.send_order("buy04", "0101", self.account_number, 1, self.item_num, sellbuy_ea[3], buyQ[9], "00", "")
    time.sleep(0.3)
    print("4번성공")

    if sellbuy_ea[4] != 0:
    self.send_order("buy04", "0101", self.account_number, 1, self.item_num, sellbuy_ea[4], buyQ[12], "00", "")
    print("5번성공")
    print("buyQ 지정가 매수완료")

    ####################[현재가 확인후 피라미드 매수 0~4번]
    if sRQName == "buy59":
    print("현재가피라미드매수-buy59 %s", self.item_num)
    self.dynamicCall("SetInputValue(QString, QString)", "종목코드", self.item_num)
    print("종목코드입력")
    self.dynamicCall("CommRqData(QString, QString, int, QS tring)", "OPT10001", "opt10001", 0, "0101")
    print("종목코드전달")
    trvalue = self.dynamicCall("GetCommData(QString, QString, int, QString)", sTrCode, "OPT10001", 0, "현재가")
    print("현재가 : %s" % abs(int(trvalue.strip())))
    order_money = abs(int(trvalue.strip().replace(",", ""))) # 현재가를 변수에 담기

    max_order_money = 500000
    mom_ea = abs(int(max_order_money / order_money)) # 총매매금액 나누기 현재가 = 총매매 수량
    if self.item_value < mom_ea :
    mom_ea = self.item_value #매매가능수량이 총매매수량보다 작으면 매매가능수량을 총매매수량에 넣는다.
    rate = 0.01
    sb_sum = 0
    sellbuy_ea = []

    print("총매매금액 : %s, 현재가 : %s, 총수량 %s" % (max_order_money, order_money, mom_ea))
    for i in range(0, 5):
    sellbuy_ea.append(int(mom_ea * rate))
    rate = rate + 0.02
    sb_sum = int(int(mom_ea * rate) + sb_sum)

    sellbuy_ea = sellbuy_ea
    print("총매매 주식수 : ", mom_ea)
    print("총매매금액 : ", max_order_money)

    print(order_money * sb_sum, sellbuy_ea)

    # 0.5% ~ 10%까지의 매수호가/매도호가 생성
    sell_m = []
    buy_m = []
    rate_v = 0.005
    for i in range(0, 40): ## 20 = 10%에 대한 매도호가 생성 / 40 = 20%에 대한 매도호가 생성
    sell_m.append(order_money + (order_money * rate_v))
    buy_m.append(order_money - (order_money * rate_v))
    rate_v = rate_v + 0.005
    # print("매도호가",sell_m)
    # 0.5% ~ 10%까지의 폭

    ## 호가를 자리수에따라 반올림하면서 정수화 함.
    buyQ = []
    sellQ = []
    for i in range(0, len(buy_m)):
    if buy_m[i] < 1000:
    buyQ.append(abs(int(round(buy_m[i], 0))))
    elif buy_m[i] < 5000:
    buyQ.append(abs(int(round(buy_m[i], -1))))
    elif buy_m[i] < 10000:
    buyQ.append(abs(int(round(buy_m[i], -1))))
    elif buy_m[i] < 50000:
    buyQ.append(abs(int(round(buy_m[i], -2))))
    elif buy_m[i] < 100000:
    buyQ.append(abs(int(round(buy_m[i], -2))))
    elif buy_m[i] < 500000:
    buyQ.append(abs(int(round(buy_m[i], -3))))
    elif buy_m[i] < 1000000:
    buyQ.append(abs(int(round(buy_m[i], -3))))
    # print("매수호가 %s " % buyQ)

    print("계좌번호:%s, 종목번호:%s\n총매수수량:%s\n매수호가:%s" % (
    self.account_number, self.item_num, sellbuy_ea, buyQ)) # buyQ는 40호가 까지 / sellbuy_ea는 10개까지)
    # (1:신규매수, 2:신규매도, 3:매수취소, 4:매도취소, 5:매수정정, 6:매도정정)

    if sellbuy_ea[5] != 0:
    self.send_order("buy59", "0101", self.account_number, 1, self.item_num, sellbuy_ea[5], buyQ[5], "00", "")
    time.sleep(0.3)
    print("1번성공")

    if sellbuy_ea[6] != 0:
    self.send_order("buy59", "0101", self.account_number, 1, self.item_num, sellbuy_ea[6], buyQ[8], "00", "")
    time.sleep(0.3)
    print("2번성공")

    if sellbuy_ea[7] != 0:
    self.send_order("buy59", "0101", self.account_number, 1, self.item_num, sellbuy_ea[7], buyQ[12], "00", "")
    time.sleep(0.3)
    print("3번성공")

    if sellbuy_ea[8] != 0:
    self.send_order("buy59", "0101", self.account_number, 1, self.item_num, sellbuy_ea[8], buyQ[17], "00", "")
    time.sleep(0.3)
    print("4번성공")

    if sellbuy_ea[9] != 0:
    self.send_order("buy59", "0101", self.account_number, 1, self.item_num, sellbuy_ea[9], buyQ[20], "00", "")
    time.sleep(0.3)
    print("5번성공")

    print("지정가 매수완료")

    ####################[현재가 확인후 피라미드 매도 0~4번]
    if sRQName == "sell04":
    print("현재가피라미드매도-sell04 %s",self.item_num)
    self.dynamicCall("SetInputValue(QString, QString)", "종목코드", self.item_num)
    print("종목코드입력")
    self.dynamicCall("CommRqData(QString, QString, int, QS tring)", "OPT10001", "opt10001", 0, "0101")
    print("종목코드전달")
    trvalue = self.dynamicCall("GetCommData(QString, QString, int, QString)", sTrCode, "OPT10001", 0, "현재가")
    print("현재가 : %s" % abs(int(trvalue.strip())))
    order_money = abs(int(trvalue.strip().replace(",", ""))) # 현재가를 변수에 담기

    max_order_money = 500000
    mom_ea = abs(int(max_order_money / order_money)) # 총매매금액 나누기 현재가 = 총매매 수량
    if self.item_value < mom_ea :
    mom_ea = self.item_value #매매가능수량이 총매매수량보다 작으면 매매가능수량을 총매매수량에 넣는다.
    rate = 0.01
    sb_sum = 0
    sellbuy_ea = []

    print("총매매금액 : %s, 현재가 : %s, 총수량 %s" % (max_order_money, order_money, mom_ea))
    for i in range(0, 5):
    sellbuy_ea.append(int(mom_ea * rate))
    rate = rate + 0.02
    sb_sum = int(int(mom_ea * rate) + sb_sum)

    sellbuy_ea = sellbuy_ea
    print("총매매 주식수 : ", mom_ea)
    print("총매매금액 : ", max_order_money)

    print(order_money * sb_sum, sellbuy_ea)

    # 0.5% ~ 10%까지의 매수호가/매도호가 생성
    sell_m = []
    buy_m = []
    rate_v = 0.005
    for i in range(0, 40): ## 20 = 10%에 대한 매도호가 생성 / 40 = 20%에 대한 매도호가 생성
    sell_m.append(order_money + (order_money * rate_v))
    buy_m.append(order_money - (order_money * rate_v))
    rate_v = rate_v + 0.005
    # print("매도호가",sell_m)
    # 0.5% ~ 10%까지의 폭

    ## 호가를 자리수에따라 반올림하면서 정수화 함.
    buyQ = []
    sellQ = []

    for i in range(0, len(sell_m)):
    if sell_m[i] < 1000:
    sellQ.append(abs(int(round(sell_m[i], 0))))
    elif sell_m[i] < 5000:
    sellQ.append(abs(int(round(sell_m[i], -1))))
    elif sell_m[i] < 10000:
    sellQ.append(abs(int(round(sell_m[i], -1))))
    elif sell_m[i] < 50000:
    sellQ.append(abs(int(round(sell_m[i], -2))))
    elif sell_m[i] < 100000:
    sellQ.append(abs(int(round(sell_m[i], -2))))
    elif sell_m[i] < 500000:
    sellQ.append(abs(int(round(sell_m[i], -3))))
    elif sell_m[i] < 1000000:
    sellQ.append(abs(int(round(sell_m[i], -3))))

    # print("매도호가:%s \n매수호가:%s", (sellQ,buyQ))

    print("계좌번호:%s, 종목번호:%s\n총매수수량:%s\n매수금액:%s" % (
    self.account_number, self.item_num, sellbuy_ea, buyQ)) # buyQ는 40호가 까지 / sellbuy_ea는 10개까지)
    # (1:신규매수, 2:신규매도, 3:매수취소, 4:매도취소, 5:매수정정, 6:매도정정)
    if sellbuy_ea[0] != 0:
    self.send_order("sell04", "0101", self.account_number, 2, self.item_num, sellbuy_ea[0], sellQ[5], "00", "")
    time.sleep(0.3)
    print("1번성공")

    if sellbuy_ea[1] != 0:
    self.send_order("sell04", "0101", self.account_number, 2, self.item_num, sellbuy_ea[1], sellQ[10], "00", "")
    time.sleep(0.3)
    print("2번성공")

    if sellbuy_ea[2] != 0:
    self.send_order("sell04", "0101", self.account_number, 2, self.item_num, sellbuy_ea[2], sellQ[15], "00", "")
    time.sleep(0.3)
    print("3번성공")

    if sellbuy_ea[3] != 0:
    self.send_order("sell04", "0101", self.account_number, 2, self.item_num, sellbuy_ea[3], sellQ[20], "00", "")
    time.sleep(0.3)
    print("4번성공")

    if sellbuy_ea[4] != 0:
    self.send_order("sell04", "0101", self.account_number, 2, self.item_num, sellbuy_ea[4], sellQ[25], "00", "")
    time.sleep(0.3)
    print("5번성공")
    print("5,10,15,20,25호가 지정가 매도완료")

    ####################[현재가 확인후 피라미드 매도 5~9번]
    if sRQName == "sell59":
    print("현재가피라미드매도-sell59 시작! %s" % self.item_num)
    self.dynamicCall("SetInputValue(QString, QString)", "종목코드", self.item_num)
    print("종목코드입력")
    self.dynamicCall("CommRqData(QString, QString, int, QS tring)", "OPT10001", "opt10001", 0, "0101")
    print("종목코드전달")
    trvalue = self.dynamicCall("GetCommData(QString, QString, int, QString)", sTrCode, "OPT10001", 0, "현재가")
    print("현재가 : %s" % abs(int(trvalue.strip())))
    order_money = abs(int(trvalue.strip().replace(",", ""))) # 현재가를 변수에 담기

    max_order_money = 1000000
    mom_ea = abs(int(max_order_money / order_money)) # 총매매금액 나누기 현재가 = 총매매 수량
    if self.item_value < mom_ea :
    mom_ea = self.item_value #매매가능수량이 총매매수량보다 작으면 매매가능수량을 총매매수량에 넣는다.
    rate = 0.01
    sb_sum = 0
    sellbuy_ea = []

    print("총매매금액 : %s, 현재가 : %s, 총수량 %s" % (max_order_money, order_money, mom_ea))
    for i in range(0, 5):
    sellbuy_ea.append(int(mom_ea * rate))
    rate = rate + 0.02
    sb_sum = int(int(mom_ea * rate) + sb_sum)

    sellbuy_ea = sellbuy_ea
    print("총매매 주식수 : ", mom_ea)
    print("총매매금액 : ", max_order_money)

    print(order_money * sb_sum, sellbuy_ea)

    # 0.5% ~ 10%까지의 매수호가/매도호가 생성
    sell_m = []
    buy_m = []
    rate_v = 0.005
    for i in range(0, 40): ## 20 = 10%에 대한 매도호가 생성 / 40 = 20%에 대한 매도호가 생성
    sell_m.append(order_money + (order_money * rate_v))
    buy_m.append(order_money - (order_money * rate_v))
    rate_v = rate_v + 0.005
    # print("매도호가",sell_m)
    # 0.5% ~ 10%까지의 폭

    ## 호가를 자리수에따라 반올림하면서 정수화 함.
    buyQ = []
    sellQ = []
    for i in range(0, len(sell_m)):
    if sell_m[i] < 1000:
    sellQ.append(abs(int(round(sell_m[i], 0))))
    elif sell_m[i] < 5000:
    sellQ.append(abs(int(round(sell_m[i], -1))))
    elif sell_m[i] < 10000:
    sellQ.append(abs(int(round(sell_m[i], -1))))
    elif sell_m[i] < 50000:
    sellQ.append(abs(int(round(sell_m[i], -2))))
    elif sell_m[i] < 100000:
    sellQ.append(abs(int(round(sell_m[i], -2))))
    elif sell_m[i] < 500000:
    sellQ.append(abs(int(round(sell_m[i], -3))))
    elif sell_m[i] < 1000000:
    sellQ.append(abs(int(round(sell_m[i], -3))))

    # print("매도호가:%s \n매수호가:%s", (sellQ,buyQ))

    print("계좌번호:%s, 종목번호:%s\n총매수수량:%s\n매수금액:%s" % (
    self.account_number, self.item_num, sellbuy_ea, buyQ)) # buyQ는 40호가 까지 / sellbuy_ea는 10개까지)
    # (1:신규매수, 2:신규매도, 3:매수취소, 4:매도취소, 5:매수정정, 6:매도정정)

    if sellbuy_ea[5] != 0:
    self.send_order("sell59", "0101", self.account_number, 2, self.item_num, sellbuy_ea[5], sellQ[28], "00", "")
    time.sleep(0.3)
    print("1번성공")

    if sellbuy_ea[6] != 0:
    self.send_order("sell59", "0101", self.account_number, 2, self.item_num, sellbuy_ea[6], sellQ[33], "00", "")
    time.sleep(0.3)
    print("2번성공")

    if sellbuy_ea[7] != 0:
    self.send_order("sell59", "0101", self.account_number, 2, self.item_num, sellbuy_ea[7], sellQ[35], "00", "")
    time.sleep(0.3)
    print("3번성공")

    if sellbuy_ea[8] != 0:
    self.send_order("sell59", "0101", self.account_number, 2, self.item_num, sellbuy_ea[8], sellQ[38], "00", "")
    time.sleep(0.3)
    print("4번성공")

    if sellbuy_ea[9] != 0:
    self.send_order("sell59", "0101", self.account_number, 2, self.item_num, sellbuy_ea[9], sellQ[40], "00", "")
    time.sleep(0.3)
    print("5번성공")
    print("28,33,35,38,40호가 지정가 매도완료")


    if sRQName == "예수금상세현황요청":
    deposit = self.dynamicCall(
    "GetCommData(QString, QString, int, QString)", sTrCode, sRQName, 0, "예수금")
    self.deposit = int(deposit)

    withdraw_deposit = self.dynamicCall(
    "GetCommData(QString, QString, int, QString)", sTrCode, sRQName, 0, "출금가능금액")
    self.withdraw_deposit = int(withdraw_deposit)

    order_deposit = self.dynamicCall(
    "GetCommData(QString, QString, int, QString)", sTrCode, sRQName, 0, "주문가능금액")
    self.order_deposit = int(order_deposit)
    self.cancel_screen_number(self.screen_my_account)
    self.account_event_loop.exit()

    elif sRQName == "계좌평가잔고내역요청":
    if (self.total_buy_money == None or self.total_evaluation_money == None
    or self.total_evaluation_profit_and_loss_money == None or self.total_yield == None):
    total_buy_money = self.dynamicCall(
    "GetCommData(QString, QString, int, QString)", sTrCode, sRQName, 0, "총매입금액")
    self.total_buy_money = int(total_buy_money)

    total_evaluation_money = self.dynamicCall(
    "GetCommData(QString, QString, int, QString)", sTrCode, sRQName, 0, "총평가금액")
    self.total_evaluation_money = int(total_evaluation_money)

    total_evaluation_profit_and_loss_money = self.dynamicCall(
    "GetCommData(QString, QString, int, QString)", sTrCode, sRQName, 0, "총평가손익금액")
    self.total_evaluation_profit_and_loss_money = int(
    total_evaluation_profit_and_loss_money)

    total_yield = self.dynamicCall(
    "GetCommData(QString, QString, int, QString)", sTrCode, sRQName, 0, "총수익률(%)")
    self.total_yield = float(total_yield)

    cnt = self.dynamicCall(
    "GetRepeatCnt(QString, QString)", sTrCode, sRQName)

    for i in range(cnt):
    stock_code = self.dynamicCall(
    "GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "종목번호")
    stock_code = stock_code.strip()[1:]

    stock_name = self.dynamicCall(
    "GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "종목명")
    stock_name = stock_name.strip() # 필요 없는 공백 제거.

    stock_evaluation_profit_and_loss = self.dynamicCall(
    "GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "평가손익")
    stock_evaluation_profit_and_loss = int(
    stock_evaluation_profit_and_loss)

    stock_yield = self.dynamicCall(
    "GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "수익률(%)")
    stock_yield = float(stock_yield)

    stock_buy_money = self.dynamicCall(
    "GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "매입가")
    stock_buy_money = int(stock_buy_money)

    stock_quantity = self.dynamicCall(
    "GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "보유수량")
    stock_quantity = int(stock_quantity)

    stock_trade_quantity = self.dynamicCall(
    "GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "매매가능수량")
    stock_trade_quantity = int(stock_trade_quantity)

    stock_present_price = self.dynamicCall(
    "GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "현재가")
    stock_present_price = int(stock_present_price)

    if not stock_code in self.account_stock_dict:
    self.account_stock_dict[stock_code] = {}

    self.account_stock_dict[stock_code].update({'종목명': stock_name})
    self.account_stock_dict[stock_code].update(
    {'평가손익': stock_evaluation_profit_and_loss})
    self.account_stock_dict[stock_code].update(
    {'수익률(%)': stock_yield})
    self.account_stock_dict[stock_code].update(
    {'매입가': stock_buy_money})
    self.account_stock_dict[stock_code].update(
    {'보유수량': stock_quantity})
    self.account_stock_dict[stock_code].update(
    {'매매가능수량': stock_trade_quantity})
    self.account_stock_dict[stock_code].update(
    {'현재가': stock_present_price})

    if sPrevNext == "2":
    self.get_account_evaluation_balance(2)
    else:
    self.cancel_screen_number(self.screen_my_account)
    self.account_event_loop.exit()

    elif sRQName == "실시간미체결요청":
    cnt = self.dynamicCall(
    "GetRepeatCnt(QString, QString)", sTrCode, sRQName)

    for i in range(cnt):
    stock_code = self.dynamicCall(
    "GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "종목코드")
    stock_code = stock_code.strip()

    stock_order_number = self.dynamicCall(
    "GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "주문번호")
    stock_order_number = int(stock_order_number)

    stock_name = self.dynamicCall(
    "GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "종목명")
    stock_name = stock_name.strip()

    stock_order_type = self.dynamicCall(
    "GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "주문구분")
    stock_order_type = stock_order_type.strip().lstrip('+').lstrip('-')

    stock_order_price = self.dynamicCall(
    "GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "주문가격")
    stock_order_price = int(stock_order_price)

    stock_order_quantity = self.dynamicCall(
    "GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "주문수량")
    stock_order_quantity = int(stock_order_quantity)

    stock_not_signed_quantity = self.dynamicCall(
    "GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "미체결수량")
    stock_not_signed_quantity = int(stock_not_signed_quantity)

    stock_signed_quantity = self.dynamicCall(
    "GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "체결량")
    stock_signed_quantity = int(stock_signed_quantity)

    stock_present_price = self.dynamicCall(
    "GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "현재가")
    stock_present_price = int(
    stock_present_price.strip().lstrip('+').lstrip('-'))

    stock_order_status = self.dynamicCall(
    "GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "주문상태")
    stock_order_status = stock_order_status.strip()

    if not stock_order_number in self.not_signed_account_dict:
    self.not_signed_account_dict[stock_order_number] = {}

    self.not_signed_account_dict[stock_order_number].update(
    {'종목코드': stock_code})
    self.not_signed_account_dict[stock_order_number].update(
    {'종목명': stock_name})
    self.not_signed_account_dict[stock_order_number].update(
    {'주문구분': stock_order_type})
    self.not_signed_account_dict[stock_order_number].update(
    {'주문가격': stock_order_price})
    self.not_signed_account_dict[stock_order_number].update(
    {'주문수량': stock_order_quantity})
    self.not_signed_account_dict[stock_order_number].update(
    {'미체결수량': stock_not_signed_quantity})
    self.not_signed_account_dict[stock_order_number].update(
    {'체결량': stock_signed_quantity})
    self.not_signed_account_dict[stock_order_number].update(
    {'현재가': stock_present_price})
    self.not_signed_account_dict[stock_order_number].update(
    {'주문상태': stock_order_status})

    if sPrevNext == "2":
    self.not_signed_account(2)
    else:
    self.cancel_screen_number(sScrNo)
    self.account_event_loop.exit()

    elif sRQName == "주식일봉차트조회요청":
    stock_code = self.dynamicCall(
    "GetCommData(QString, QString, int, QString)", sTrCode, sRQName, 0, "종목코드")
    #six_hundred_data = self.dynamicCall("GetCommDataEx(QString, QString)", sTrCode, sRQName)

    stock_code = stock_code.strip()
    cnt = self.dynamicCall(
    "GetRepeatCnt(QString, QString)", sTrCode, sRQName) # 최대 600일

    for i in range(cnt):
    calculator_list = []

    current_price = self.dynamicCall(
    "GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "현재가")
    volume = self.dynamicCall(
    "GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "거래량")
    trade_price = self.dynamicCall(
    "GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "거래대금")
    date = self.dynamicCall(
    "GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "일자")
    start_price = self.dynamicCall(
    "GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "시가")
    high_price = self.dynamicCall(
    "GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "고가")
    low_price = self.dynamicCall(
    "GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "저가")

    calculator_list.append("")
    calculator_list.append(int(current_price))
    calculator_list.append(int(volume))
    calculator_list.append(int(trade_price))
    calculator_list.append(int(date))
    calculator_list.append(int(start_price))
    calculator_list.append(int(high_price))
    calculator_list.append(int(low_price))
    calculator_list.append("")

    self.calculator_list.append(calculator_list.copy())

    if sPrevNext == "2":
    self.day_kiwoom_db(stock_code, None, 2)
    else:
    self.calculator_event_loop.exit()

    def cancel_screen_number(self, sScrNo):
    self.dynamicCall("DisconnectRealData(QString)", sScrNo)

    def get_code_list_by_market(self, market_code):
    code_list = self.dynamicCall(
    "GetCodeListByMarket(QString)", market_code)
    code_list = code_list.split(";")[:-1]
    return code_list

    def calculator(self):
    kosdaq_list = self.get_code_list_by_market("10")

    for idx, stock_code in enumerate(kosdaq_list):
    self.dynamicCall("DisconnectRealData(QString)",
    self.screen_calculation_stock)

    print(
    f"{idx + 1} / {len(kosdaq_list)} : KOSDAQ Stock Code : {stock_code} is updating...")
    self.day_kiwoom_db(stock_code)

    def day_kiwoom_db(self, stock_code=None, date=None, nPrevNext=0):
    QTest.qWait(3600) # 3.6초마다 딜레이

    self.dynamicCall("SetInputValue(QString, QString)", "종목코드", stock_code)
    self.dynamicCall("SetInputValue(QString, QString)", "수정주가구분", 1)

    if date != None: # date가 None일 경우 date는 오늘 날짜 기준
    self.dynamicCall("SetInputValue(QString, QString)", "기준일자", date)

    self.dynamicCall("CommRqData(QString, QString, int, QString)",
    "주식일봉차트조회요청", "opt10081", nPrevNext, self.screen_calculation_stock)

    if not self.calculator_event_loop.isRunning():
    self.calculator_event_loop.exec_()

    def errors(err_code):

    err_dic = {0: ('OP_ERR_NONE', '정상처리'),
    -10: ('OP_ERR_FAIL', '실패'),
    -100: ('OP_ERR_LOGIN', '사용자정보교환실패'),
    -101: ('OP_ERR_CONNECT', '서버접속실패'),
    -102: ('OP_ERR_VERSION', '버전처리실패'),
    -103: ('OP_ERR_FIREWALL', '개인방화벽실패'),
    -104: ('OP_ERR_MEMORY', '메모리보호실패'),
    -105: ('OP_ERR_INPUT', '함수입력값오류'),
    -106: ('OP_ERR_SOCKET_CLOSED', '통신연결종료'),
    -200: ('OP_ERR_SISE_OVERFLOW', '시세조회과부하'),
    -201: ('OP_ERR_RQ_STRUCT_FAIL', '전문작성초기화실패'),
    -202: ('OP_ERR_RQ_STRING_FAIL', '전문작성입력값오류'),
    -203: ('OP_ERR_NO_DATA', '데이터없음'),
    -204: ('OP_ERR_OVER_MAX_DATA', '조회가능한종목수초과'),
    -205: ('OP_ERR_DATA_RCV_FAIL', '데이터수신실패'),
    -206: ('OP_ERR_OVER_MAX_FID', '조회가능한FID수초과'),
    -207: ('OP_ERR_REAL_CANCEL', '실시간해제오류'),
    -300: ('OP_ERR_ORD_WRONG_INPUT', '입력값오류'),
    -301: ('OP_ERR_ORD_WRONG_ACCTNO', '계좌비밀번호없음'),
    -302: ('OP_ERR_OTHER_ACC_USE', '타인계좌사용오류'),
    -303: ('OP_ERR_MIS_2BILL_EXC', '주문가격이20억원을초과'),
    -304: ('OP_ERR_MIS_5BILL_EXC', '주문가격이50억원을초과'),
    -305: ('OP_ERR_MIS_1PER_EXC', '주문수량이총발행주수의1 % 초과오류'),
    -306: ('OP_ERR_MIS_3PER_EXC', '주문수량은총발행주수의3 % 초과오류'),
    -307: ('OP_ERR_SEND_FAIL', '주문전송실패'),
    -308: ('OP_ERR_ORD_OVERFLOW', '주문전송과부하'),
    -309: ('OP_ERR_MIS_300CNT_EXC', '주문수량300계약초과'),
    -310: ('OP_ERR_MIS_500CNT_EXC', '주문수량500계약초과'),
    -340: ('OP_ERR_ORD_WRONG_ACCTINFO', '계좌정보없음'),
    -500: ('OP_ERR_ORD_SYMCODE_EMPTY', '종목코드없음')
    }

    result = err_dic[err_code]

    return result


    ######################## 시작
    if __name__=="__main__":

    kiwoom = Kiwoom()
  • ?
    nanumi 2021.09.09 12:20
    처음부터 다시 봐야겠다.
    갑자기 매수주문도 안되네?
    https://wikidocs.net/82380



    from pykiwoom.kiwoom import *

    kiwoom = Kiwoom()
    kiwoom.CommConnect(block=True)

    # 주식계좌
    accounts = kiwoom.GetLoginInfo("ACCNO")
    stock_account = accounts[0]

    # 매수
    kiwoom.SendOrder("시장가매수", "0101", stock_account, 1, "130660", 10, 0, "03", "") # 시장가주문 매수
    kiwoom.SendOrder("시장가매수", "0101", stock_account, 1, "130660", 10, 15800, "00", "") # 지정가주문 매수
    print("주문완료")
  • ?
    김치찌게 2021.09.10 18:28
    어쨋든
    보유종목들의 현재가 기준으로 분할 매수/매도주문이 가능하게 되었다.




    import sys
    import os
    import time
    #import logging.conf
    from PyQt5.QtWidgets import *
    from PyQt5.QAxContainer import *
    from PyQt5.QtCore import *
    from beautifultable import BeautifulTable
    from PyQt5.QtTest import *
    from pandas import DataFrame

    TR_REQ_TIME_INTERVAL = 0.2
    class Kiwoom(QAxWidget):
    def __init__(self):
    self.app = QApplication(sys.argv)
    print("Ui_class 입니다.")
    super().__init__()
    # 이벤트 루프 관련 변수
    self.login_event_loop = QEventLoop()
    self.account_event_loop = QEventLoop()
    self.calculator_event_loop = QEventLoop()

    # 계좌 관련 변수
    self.account_number = None
    self.total_buy_money = None
    self.total_evaluation_money = None
    self.total_evaluation_profit_and_loss_money = None
    self.total_yield = None
    self.account_stock_dict = {}
    self.not_signed_account_dict = {}

    # 예수금 관련 변수
    self.deposit = None
    self.withdraw_deposit = None
    self.order_deposit = None

    # 종목 분석 관련 변수
    self.calculator_list = []

    # 화면 번호
    self.screen_my_account = "1000"
    self.screen_calculation_stock = "2000"

    # 초기 작업
    print("로그인-초기작업시작")
    self.create_kiwoom_instance()
    self.event_collection() # 이벤트와 슬롯을 메모리에 먼저 생성.
    self.login()
    print("계좌정보시작")
    # input()
    #
    self.get_account_info() # 계좌 번호만 얻어오기
    self.get_deposit_info() # 예수금 관련된 정보 얻어오기
    self.get_account_evaluation_balance() # 계좌평가잔고내역 얻어오기
    self.not_signed_account() # 미체결내역 얻어오기
    #self.calculator()
    # self.menu()

    print("스케쥴링시작")
    ###########[스케쥴링]############

    self.test()


    ###########[스케쥴링]############

    def test(self):
    account_list = self.dynamicCall("GetLoginInfo(QString)", "ACCNO")
    account_number = account_list.split(';')[0]
    self.account_number = account_number ##계좌정보 획득!

    user_name = self.dynamicCall("GetLoginInfo(QString)", "USER_NAME")
    user_id = self.dynamicCall("GetLoginInfo(QString)", "USER_ID")
    account_count = self.dynamicCall(
    "GetLoginInfo(QString)", "ACCOUNT_CNT")

    #############[보유종목과 매매가능수량확인 ]#############
    self.item_nums = list(self.account_stock_dict.keys()) # dict key값을 self.item_nums 변수에 담기
    self.item_values = list(self.account_stock_dict.values()) # dict value값을 self.item_nums 변수에 담기
    print(self.item_nums) # 리스트 출력
    print(self.item_values) # 리스트 출력
    #for index, value in enumerate(self.item_nums):
    # print("[%s] 종목번호[%s] 종목명[%s] 현재가[%s] 매매가능수량 : [%s]" % (
    # index, self.item_nums[index], self.item_values[index]['종목명'], self.item_values[index]['현재가'],
    # self.item_values[index]['매매가능수량']))

    #############[호가 및 매수주문]#############
    for index, value in enumerate(self.item_nums):
    print("[%s]번째 종목을 매수주문 시도합니다." % index)
    self.item_num = self.item_nums[index] # 종목코드 담기
    self.item_value = self.item_values[index]['매매가능수량'] # 종목 값 담기
    self.item_name = self.item_values[index]['종목명'] # 종목 값 담기
    self.item_nowvalue = self.item_values[index]['현재가'] # 종목 값 담기

    if '(폐)' in self.item_name:
    print('[%s]는 상장폐지된 종목입니다.' % self.item_name)

    else:
    #print("[%s] 종목번호[%s] 종목명[%s] 현재가[%s] 매매가능수량 : [%s]" % (index, self.item_nums[index], self.item_values[index]['종목명'], self.item_values[index]['현재가'],self.item_values[index]['매매가능수량']))
    print("[%s] 종목번호[%s] 종목명[%s] 현재가[%s] 매매가능수량 : [%s]" % (index, self.item_num, self.item_name, self.item_nowvalue,self.item_value))

    ############################################## 현재가 받아와서 그래미

    order_money = self.item_nowvalue
    max_order_money = 1000000
    mom_ea = abs(int(max_order_money / order_money)) # 총매매금액 나누기 현재가 = 총매매 수량

    # 매도시 매매가능수량 파악을 위해 아래의 부분을 넣어야 함.
    #if self.item_value < mom_ea:
    # mom_ea = self.item_value # 매매가능수량이 총매매수량보다 작으면 매매가능수량을 총매매수량에 넣는다.

    rate = 0.01
    sb_sum = 0
    sellbuy_ea = []

    print("총매매금액 : %s, 현재가 : %s, 총수량 %s" % (max_order_money, order_money, mom_ea))
    for i in range(0, 10):
    sellbuy_ea.append(int(mom_ea * rate))
    rate = rate + 0.02
    sb_sum = int(int(mom_ea * rate) + sb_sum)

    sellbuy_ea = sellbuy_ea

    print("실제매수수량 %s, 매매가능수량 %s" % (order_money * sb_sum, sellbuy_ea))
    # 0.5% ~ 10%까지의 매수호가/매도호가 생성
    sell_m = []
    buy_m = []
    rate_v = 0.005
    for i in range(0, 40): ## 20 = 10%에 대한 매도호가 생성 / 40 = 20%에 대한 매도호가 생성
    sell_m.append(order_money + (order_money * rate_v))
    buy_m.append(order_money - (order_money * rate_v))
    rate_v = rate_v + 0.005
    # print("매도호가",sell_m)
    # 0.5% ~ 10%까지의 폭

    ## 호가를 자리수에 따라 반올림하면서 정수화 함.
    buyQ = []
    sellQ = []
    for i in range(0, len(buy_m)):
    if buy_m[i] < 1000:
    buyQ.append(abs(int(round(buy_m[i], 0))))
    elif buy_m[i] < 5000:
    buyQ.append(abs(int(round(buy_m[i], -1))))
    elif buy_m[i] < 10000:
    buyQ.append(abs(int(round(buy_m[i], -1))))
    elif buy_m[i] < 50000:
    buyQ.append(abs(int(round(buy_m[i], -2))))
    elif buy_m[i] < 100000:
    buyQ.append(abs(int(round(buy_m[i], -2))))
    elif buy_m[i] < 500000:
    buyQ.append(abs(int(round(buy_m[i], -3))))
    elif buy_m[i] < 1000000:
    buyQ.append(abs(int(round(buy_m[i], -3))))
    # print("매수호가 %s " % buyQ)

    print("계좌번호:%s, 종목번호:%s\n총매수수량:%s\n매수호가:%s" % (
    self.account_number, self.item_num, sellbuy_ea, buyQ)) # buyQ는 40호가 까지 / sellbuy_ea는 10개까지)
    # (1:신규매수, 2:신규매도, 3:매수취소, 4:매도취소, 5:매수정정, 6:매도정정)
    delay_time = 0.5
    if sellbuy_ea[0] != 0:
    self.send_order("buy04", "0101", self.account_number, 1, self.item_num, sellbuy_ea[0], buyQ[0], "00","")
    time.sleep(delay_time)
    print("1번성공-%s, %s, %s, %s" % (self.account_number, self.item_num, sellbuy_ea[0], buyQ[0]))

    if sellbuy_ea[1] != 0:
    self.send_order("buy04", "0101", self.account_number, 1, self.item_num, sellbuy_ea[1], buyQ[3], "00","")
    time.sleep(delay_time)
    print("2번성공-%s, %s, %s, %s" % (self.account_number, self.item_num, sellbuy_ea[1], buyQ[3]))

    if sellbuy_ea[2] != 0:
    self.send_order("buy04", "0101", self.account_number, 1, self.item_num, sellbuy_ea[2], buyQ[6], "00","")
    time.sleep(delay_time)
    print("3번성공-%s, %s, %s, %s" % (self.account_number, self.item_num, sellbuy_ea[2], buyQ[6]))

    if sellbuy_ea[3] != 0:
    self.send_order("buy04", "0101", self.account_number, 1, self.item_num, sellbuy_ea[3], buyQ[9], "00","")
    time.sleep(delay_time)
    print("4번성공-%s, %s, %s, %s" % (self.account_number, self.item_num, sellbuy_ea[3], buyQ[9]))

    if sellbuy_ea[4] != 0:
    self.send_order("buy04", "0101", self.account_number, 1, self.item_num, sellbuy_ea[4], buyQ[12], "00","")
    print("5번성공-%s, %s, %s, %s" % (self.account_number, self.item_num, sellbuy_ea[4], buyQ[12]))
    time.sleep(delay_time)

    if sellbuy_ea[5] != 0:
    self.send_order("buy04", "0101", self.account_number, 1, self.item_num, sellbuy_ea[5], buyQ[15], "00","")
    print("6번성공-%s, %s, %s, %s" % (self.account_number, self.item_num, sellbuy_ea[5], buyQ[15]))
    time.sleep(delay_time)

    if sellbuy_ea[6] != 0:
    self.send_order("buy04", "0101", self.account_number, 1, self.item_num, sellbuy_ea[6], buyQ[18], "00","")
    print("7번성공-%s, %s, %s, %s" % (self.account_number, self.item_num, sellbuy_ea[6], buyQ[18]))
    time.sleep(delay_time)

    if sellbuy_ea[7] != 0:
    self.send_order("buy04", "0101", self.account_number, 1, self.item_num, sellbuy_ea[7], buyQ[21], "00","")
    print("8번성공-%s, %s, %s, %s" % (self.account_number, self.item_num, sellbuy_ea[7], buyQ[21]))
    time.sleep(delay_time)

    print("buyQ 지정가 매수완료")
    ##################################################
    # COM 오브젝트 생성.
    def create_kiwoom_instance(self):
    # 레지스트리에 저장된 키움 openAPI 모듈 불러오기
    self.setControl("KHOPENAPI.KHOpenAPICtrl.1")



    def event_collection(self):
    self.OnEventConnect.connect(self.login_slot) # 로그인 관련 이벤트
    self.OnReceiveTrData.connect(self.tr_slot) # 트랜잭션 요청 관련 이벤트

    def login(self):
    self.dynamicCall("CommConnect()") # 시그널 함수 호출.
    self.login_event_loop.exec_()

    def login_slot(self, err_code):
    if err_code == 0:
    print("로그인에 성공하였습니다.")
    else:
    os.system('cls')
    print("에러 내용 :", errors(err_code)[1])
    sys.exit(0)
    self.login_event_loop.exit()

    def get_account_info(self):
    account_list = self.dynamicCall("GetLoginInfo(QString)", "ACCNO")
    account_number = account_list.split(';')[0]
    self.account_number = account_number

    def menu(self):
    sel = ""
    while True:
    os.system('cls')
    print("1. 현재 로그인 상태 확인")
    print("2. 사용자 정보 조회")
    print("3. 예수금 조회")
    print("4. 계좌 잔고 조회")
    print("5. 미체결 내역 조회")
    print("Q. 프로그램 종료")
    sel = input("=> ")

    if sel == "Q" or sel == "q":
    sys.exit(0)

    if sel == "1":
    self.print_login_connect_state()
    elif sel == "2":
    self.print_my_info()
    elif sel == "3":
    self.print_get_deposit_info()
    elif sel == "4":
    self.print_get_account_evaulation_balance_info()
    elif sel == "5":
    self.print_not_signed_account()

    def print_login_connect_state(self):
    os.system('cls')
    isLogin = self.dynamicCall("GetConnectState()")
    if isLogin == 1:
    print("\n현재 계정은 로그인 상태입니다.")
    else:
    print("\n현재 계정은 로그아웃 상태입니다.")
    input()

    def print_my_info(self):
    os.system('cls')
    user_name = self.dynamicCall("GetLoginInfo(QString)", "USER_NAME")
    user_id = self.dynamicCall("GetLoginInfo(QString)", "USER_ID")
    account_count = self.dynamicCall(
    "GetLoginInfo(QString)", "ACCOUNT_CNT")

    print(f"\n이름 : {user_name}")
    print(f"ID : {user_id}")
    print(f"보유 계좌 수 : {account_count}")
    print(f"계좌번호 : {self.account_number}")
    input()

    def print_get_deposit_info(self):
    os.system('cls')
    print(f"\n예수금 : {self.deposit}원")
    print(f"출금 가능 금액 : {self.withdraw_deposit}원")
    print(f"주문 가능 금액 : {self.order_deposit}원")
    input()

    def print_get_account_evaulation_balance_info(self):
    os.system('cls')
    print("\n<싱글 데이터>")
    print(f"총 매입 금액 : {self.total_buy_money}원")
    print(f"총 평가 금액 : {self.total_evaluation_money}원")
    print(f"총 평가 손익 금액 : {self.total_evaluation_profit_and_loss_money}원")
    print(f"총 수익률 : {self.total_yield}%\n")

    table = self.make_table("계좌평가잔고내역요청")
    print("<멀티 데이터>")
    if len(self.account_stock_dict) == 0:
    print("보유한 종목이 없습니다!")
    else:
    print(f"보유 종목 수 : {len(self.account_stock_dict)}개")
    print(table)
    input()

    def make_table(self, sRQName):
    table = BeautifulTable()
    table = BeautifulTable(maxwidth=150)

    if sRQName == "계좌평가잔고내역요청":
    for stock_code in self.account_stock_dict:
    stock = self.account_stock_dict[stock_code]
    stockList = []
    for key in stock:
    output = None

    if key == "종목명":
    output = stock[key]
    elif key == "수익률(%)":
    output = str(stock[key]) + "%"
    elif key == "보유수량" or key == "매매가능수량":
    output = str(stock[key]) + "개"
    else:
    output = str(stock[key]) + "원"
    stockList.append(output)
    table.rows.append(stockList)
    table.columns.header = ["종목명", "평가손익",
    "수익률", "매입가", "보유수량", "매매가능수량", "현재가"]
    table.rows.sort('종목명')

    elif sRQName == "실시간미체결요청":
    for stock_order_number in self.not_signed_account_dict:
    stock = self.not_signed_account_dict[stock_order_number]
    stockList = [stock_order_number]
    for key in stock:
    output = None
    if key == "주문가격" or key == "현재가":
    output = str(stock[key]) + "원"
    elif '량' in key:
    output = str(stock[key]) + "개"
    elif key == "종목코드":
    continue
    else:
    output = stock[key]
    stockList.append(output)
    table.rows.append(stockList)
    table.columns.header = ["주문번호", "종목명", "주문구분", "주문가격", "주문수량",
    "미체결수량", "체결량", "현재가", "주문상태"]
    table.rows.sort('주문번호')
    return table

    def print_not_signed_account(self):
    os.system('cls')
    print()
    table = self.make_table("실시간미체결요청")
    if len(self.not_signed_account_dict) == 0:
    print("미체결 내역이 없습니다!")
    else:
    print(table)
    input()

    def get_deposit_info(self, nPrevNext=0):
    self.dynamicCall("SetInputValue(QString, QString)",
    "계좌번호", self.account_number)
    self.dynamicCall("SetInputValue(QString, QString)", "비밀번호", " ")
    self.dynamicCall("SetInputValue(QString, QString)", "비밀번호입력매체구분", "00")
    self.dynamicCall("SetInputValue(QString, QString)", "조회구분", "2")
    self.dynamicCall("CommRqData(QString, QString, int, QString)",
    "예수금상세현황요청", "opw00001", nPrevNext, self.screen_my_account)

    self.account_event_loop.exec_()

    def get_account_evaluation_balance(self, nPrevNext=0):
    self.dynamicCall("SetInputValue(QString, QString)",
    "계좌번호", self.account_number)
    self.dynamicCall("SetInputValue(QString, QString)", "비밀번호", " ")
    self.dynamicCall("SetInputValue(QString, QString)", "비밀번호입력매체구분", "00")
    self.dynamicCall("SetInputValue(QString, QString)", "조회구분", "1")
    self.dynamicCall("CommRqData(QString, QString, int, QString)",
    "계좌평가잔고내역요청", "opw00018", nPrevNext, self.screen_my_account)

    if not self.account_event_loop.isRunning():
    self.account_event_loop.exec_()

    def not_signed_account(self, nPrevNext=0):
    self.dynamicCall("SetInputValue(QString, QString)",
    "계좌번호", self.account_number)
    self.dynamicCall("SetInputValue(QString, QString)", "전체종목구분", "0")
    self.dynamicCall("SetInputValue(QString, QString)", "매매구분", "0")
    self.dynamicCall("SetInputValue(QString, QString)", "체결구분", "1")
    self.dynamicCall("CommRqData(QString, QString, int, QString)",
    "실시간미체결요청", "opt10075", nPrevNext, self.screen_my_account)

    if not self.account_event_loop.isRunning():
    self.account_event_loop.exec_()





    def send_order(self, rqname, screen_no, acc_no, order_type, code, quantity, price, hoga, order_no):
    self.dynamicCall("SendOrder(QString, QString, QString, int, QString, int, int, QString, QString)",
    [rqname, screen_no, acc_no, order_type, code, quantity, price, hoga, order_no])

    def send_order1(self, rqname, screen_no, acc_no, order_type, code, quantity, price, hoga, order_no):
    self.dynamicCall("SendOrder(QString, QString, QString, int, QString, int, int, QString, QString)",
    [rqname, screen_no, acc_no, order_type, code, quantity, price, hoga, order_no])

    def trcode_buy04(self,sPrevNext="0"): ##현재가로 피라미드 0~4까지 매수
    self.dynamicCall("SetInputValue(QString, QString)", "종목코드", self.item_num)
    self.dynamicCall("CommRqData(QString, QString, int, QString)", "buy04", "opt10001", sPrevNext, "2000")
    print("현재가요청 서버 전송 완료")

    def trcode_buy59(self,sPrevNext="0"): ##현재가로 피라미드 5~9까지 매수
    self.dynamicCall("SetInputValue(QString, QString)", "종목코드", self.item_num)
    self.dynamicCall("CommRqData(QString, QString, int, QString)", "buy59", "opt10001", sPrevNext, "2000")
    print("현재가요청 서버 전송 완료")

    def trcode_sell04(self,sPrevNext="0"): ##현재가로 피라미드 0~4까지 매도
    self.dynamicCall("SetInputValue(QString, QString)", "종목코드", self.item_num)
    self.dynamicCall("CommRqData(QString, QString, int, QString)", "sell04", "opt10001", sPrevNext, "2000")
    print("현재가요청 서버 전송 완료")

    def trcode_sell59(self,sPrevNext="0"): ##현재가로 피라미드 5~9까지 매도
    self.dynamicCall("SetInputValue(QString, QString)", "종목코드", self.item_num)
    self.dynamicCall("CommRqData(QString, QString, int, QString)", "sell59", "opt10001", sPrevNext, "2000")
    print("현재가요청 서버 전송 완료")

    def trcode_closem(self,sPrevNext="0"): ##
    self.dynamicCall("SetInputValue(QString, QString)", "종목코드", self.item_num)
    self.dynamicCall("CommRqData(QString, QString, int, QString)", "종목현재가", "opt10001", sPrevNext, "2000")
    print("현재가요청 서버 전송 완료")




    def tr_slot(self, sScrNo, sRQName, sTrCode, sRecordName, sPrevNext):

    print("tr_slot 수신코드로 진입했습니다.")
    if sRQName == "buy04":
    print("잘 전달했겠죠?")

    ####################[현재가 확인후 피라미드 매수 0~4번]
    if sRQName == "buy59":
    print("현재가피라미드매수-buy59 %s", self.item_num)
    self.dynamicCall("SetInputValue(QString, QString)", "종목코드", self.item_num)
    print("종목코드입력")
    self.dynamicCall("CommRqData(QString, QString, int, QS tring)", "OPT10001", "opt10001", 0, "0101")
    print("종목코드전달")
    trvalue = self.dynamicCall("GetCommData(QString, QString, int, QString)", sTrCode, "OPT10001", 0, "현재가")
    print("현재가 : %s" % abs(int(trvalue.strip())))
    order_money = abs(int(trvalue.strip().replace(",", ""))) # 현재가를 변수에 담기

    max_order_money = 500000
    mom_ea = abs(int(max_order_money / order_money)) # 총매매금액 나누기 현재가 = 총매매 수량
    if self.item_value < mom_ea :
    mom_ea = self.item_value #매매가능수량이 총매매수량보다 작으면 매매가능수량을 총매매수량에 넣는다.
    rate = 0.01
    sb_sum = 0
    sellbuy_ea = []

    print("총매매금액 : %s, 현재가 : %s, 총수량 %s" % (max_order_money, order_money, mom_ea))
    for i in range(0, 5):
    sellbuy_ea.append(int(mom_ea * rate))
    rate = rate + 0.02
    sb_sum = int(int(mom_ea * rate) + sb_sum)

    sellbuy_ea = sellbuy_ea
    print("총매매 주식수 : ", mom_ea)
    print("총매매금액 : ", max_order_money)

    print(order_money * sb_sum, sellbuy_ea)

    # 0.5% ~ 10%까지의 매수호가/매도호가 생성
    sell_m = []
    buy_m = []
    rate_v = 0.005
    for i in range(0, 40): ## 20 = 10%에 대한 매도호가 생성 / 40 = 20%에 대한 매도호가 생성
    sell_m.append(order_money + (order_money * rate_v))
    buy_m.append(order_money - (order_money * rate_v))
    rate_v = rate_v + 0.005
    # print("매도호가",sell_m)
    # 0.5% ~ 10%까지의 폭

    ## 호가를 자리수에따라 반올림하면서 정수화 함.
    buyQ = []
    sellQ = []
    for i in range(0, len(buy_m)):
    if buy_m[i] < 1000:
    buyQ.append(abs(int(round(buy_m[i], 0))))
    elif buy_m[i] < 5000:
    buyQ.append(abs(int(round(buy_m[i], -1))))
    elif buy_m[i] < 10000:
    buyQ.append(abs(int(round(buy_m[i], -1))))
    elif buy_m[i] < 50000:
    buyQ.append(abs(int(round(buy_m[i], -2))))
    elif buy_m[i] < 100000:
    buyQ.append(abs(int(round(buy_m[i], -2))))
    elif buy_m[i] < 500000:
    buyQ.append(abs(int(round(buy_m[i], -3))))
    elif buy_m[i] < 1000000:
    buyQ.append(abs(int(round(buy_m[i], -3))))
    # print("매수호가 %s " % buyQ)

    print("계좌번호:%s, 종목번호:%s\n총매수수량:%s\n매수호가:%s" % (
    self.account_number, self.item_num, sellbuy_ea, buyQ)) # buyQ는 40호가 까지 / sellbuy_ea는 10개까지)
    # (1:신규매수, 2:신규매도, 3:매수취소, 4:매도취소, 5:매수정정, 6:매도정정)

    if sellbuy_ea[5] != 0:
    self.send_order("buy59", "0101", self.account_number, 1, self.item_num, sellbuy_ea[5], buyQ[5], "00", "")
    time.sleep(0.3)
    print("1번성공")

    if sellbuy_ea[6] != 0:
    self.send_order("buy59", "0101", self.account_number, 1, self.item_num, sellbuy_ea[6], buyQ[8], "00", "")
    time.sleep(0.3)
    print("2번성공")

    if sellbuy_ea[7] != 0:
    self.send_order("buy59", "0101", self.account_number, 1, self.item_num, sellbuy_ea[7], buyQ[12], "00", "")
    time.sleep(0.3)
    print("3번성공")

    if sellbuy_ea[8] != 0:
    self.send_order("buy59", "0101", self.account_number, 1, self.item_num, sellbuy_ea[8], buyQ[17], "00", "")
    time.sleep(0.3)
    print("4번성공")

    if sellbuy_ea[9] != 0:
    self.send_order("buy59", "0101", self.account_number, 1, self.item_num, sellbuy_ea[9], buyQ[20], "00", "")
    time.sleep(0.3)
    print("5번성공")

    print("지정가 매수완료")

    ####################[현재가 확인후 피라미드 매도 0~4번]
    if sRQName == "sell04":
    print("현재가피라미드매도-sell04 %s",self.item_num)
    self.dynamicCall("SetInputValue(QString, QString)", "종목코드", self.item_num)
    print("종목코드입력")
    self.dynamicCall("CommRqData(QString, QString, int, QS tring)", "OPT10001", "opt10001", 0, "0101")
    print("종목코드전달")
    trvalue = self.dynamicCall("GetCommData(QString, QString, int, QString)", sTrCode, "OPT10001", 0, "현재가")
    print("현재가 : %s" % abs(int(trvalue.strip())))
    order_money = abs(int(trvalue.strip().replace(",", ""))) # 현재가를 변수에 담기

    max_order_money = 500000
    mom_ea = abs(int(max_order_money / order_money)) # 총매매금액 나누기 현재가 = 총매매 수량
    if self.item_value < mom_ea :
    mom_ea = self.item_value #매매가능수량이 총매매수량보다 작으면 매매가능수량을 총매매수량에 넣는다.
    rate = 0.01
    sb_sum = 0
    sellbuy_ea = []

    print("총매매금액 : %s, 현재가 : %s, 총수량 %s" % (max_order_money, order_money, mom_ea))
    for i in range(0, 5):
    sellbuy_ea.append(int(mom_ea * rate))
    rate = rate + 0.02
    sb_sum = int(int(mom_ea * rate) + sb_sum)

    sellbuy_ea = sellbuy_ea
    print("총매매 주식수 : ", mom_ea)
    print("총매매금액 : ", max_order_money)

    print(order_money * sb_sum, sellbuy_ea)

    # 0.5% ~ 10%까지의 매수호가/매도호가 생성
    sell_m = []
    buy_m = []
    rate_v = 0.005
    for i in range(0, 40): ## 20 = 10%에 대한 매도호가 생성 / 40 = 20%에 대한 매도호가 생성
    sell_m.append(order_money + (order_money * rate_v))
    buy_m.append(order_money - (order_money * rate_v))
    rate_v = rate_v + 0.005
    # print("매도호가",sell_m)
    # 0.5% ~ 10%까지의 폭

    ## 호가를 자리수에따라 반올림하면서 정수화 함.
    buyQ = []
    sellQ = []

    for i in range(0, len(sell_m)):
    if sell_m[i] < 1000:
    sellQ.append(abs(int(round(sell_m[i], 0))))
    elif sell_m[i] < 5000:
    sellQ.append(abs(int(round(sell_m[i], -1))))
    elif sell_m[i] < 10000:
    sellQ.append(abs(int(round(sell_m[i], -1))))
    elif sell_m[i] < 50000:
    sellQ.append(abs(int(round(sell_m[i], -2))))
    elif sell_m[i] < 100000:
    sellQ.append(abs(int(round(sell_m[i], -2))))
    elif sell_m[i] < 500000:
    sellQ.append(abs(int(round(sell_m[i], -3))))
    elif sell_m[i] < 1000000:
    sellQ.append(abs(int(round(sell_m[i], -3))))

    # print("매도호가:%s \n매수호가:%s", (sellQ,buyQ))

    print("계좌번호:%s, 종목번호:%s\n총매수수량:%s\n매수금액:%s" % (
    self.account_number, self.item_num, sellbuy_ea, buyQ)) # buyQ는 40호가 까지 / sellbuy_ea는 10개까지)
    # (1:신규매수, 2:신규매도, 3:매수취소, 4:매도취소, 5:매수정정, 6:매도정정)
    if sellbuy_ea[0] != 0:
    self.send_order("sell04", "0101", self.account_number, 2, self.item_num, sellbuy_ea[0], sellQ[5], "00", "")
    time.sleep(0.3)
    print("1번성공")

    if sellbuy_ea[1] != 0:
    self.send_order("sell04", "0101", self.account_number, 2, self.item_num, sellbuy_ea[1], sellQ[10], "00", "")
    time.sleep(0.3)
    print("2번성공")

    if sellbuy_ea[2] != 0:
    self.send_order("sell04", "0101", self.account_number, 2, self.item_num, sellbuy_ea[2], sellQ[15], "00", "")
    time.sleep(0.3)
    print("3번성공")

    if sellbuy_ea[3] != 0:
    self.send_order("sell04", "0101", self.account_number, 2, self.item_num, sellbuy_ea[3], sellQ[20], "00", "")
    time.sleep(0.3)
    print("4번성공")

    if sellbuy_ea[4] != 0:
    self.send_order("sell04", "0101", self.account_number, 2, self.item_num, sellbuy_ea[4], sellQ[25], "00", "")
    time.sleep(0.3)
    print("5번성공")
    print("5,10,15,20,25호가 지정가 매도완료")

    ####################[현재가 확인후 피라미드 매도 5~9번]
    if sRQName == "sell59":
    print("현재가피라미드매도-sell59 시작! %s" % self.item_num)
    self.dynamicCall("SetInputValue(QString, QString)", "종목코드", self.item_num)
    print("종목코드입력")
    self.dynamicCall("CommRqData(QString, QString, int, QS tring)", "OPT10001", "opt10001", 0, "0101")
    print("종목코드전달")
    trvalue = self.dynamicCall("GetCommData(QString, QString, int, QString)", sTrCode, "OPT10001", 0, "현재가")
    print("현재가 : %s" % abs(int(trvalue.strip())))
    order_money = abs(int(trvalue.strip().replace(",", ""))) # 현재가를 변수에 담기

    max_order_money = 1000000
    mom_ea = abs(int(max_order_money / order_money)) # 총매매금액 나누기 현재가 = 총매매 수량
    if self.item_value < mom_ea :
    mom_ea = self.item_value #매매가능수량이 총매매수량보다 작으면 매매가능수량을 총매매수량에 넣는다.
    rate = 0.01
    sb_sum = 0
    sellbuy_ea = []

    print("총매매금액 : %s, 현재가 : %s, 총수량 %s" % (max_order_money, order_money, mom_ea))
    for i in range(0, 5):
    sellbuy_ea.append(int(mom_ea * rate))
    rate = rate + 0.02
    sb_sum = int(int(mom_ea * rate) + sb_sum)

    sellbuy_ea = sellbuy_ea
    print("총매매 주식수 : ", mom_ea)
    print("총매매금액 : ", max_order_money)

    print(order_money * sb_sum, sellbuy_ea)

    # 0.5% ~ 10%까지의 매수호가/매도호가 생성
    sell_m = []
    buy_m = []
    rate_v = 0.005
    for i in range(0, 40): ## 20 = 10%에 대한 매도호가 생성 / 40 = 20%에 대한 매도호가 생성
    sell_m.append(order_money + (order_money * rate_v))
    buy_m.append(order_money - (order_money * rate_v))
    rate_v = rate_v + 0.005
    # print("매도호가",sell_m)
    # 0.5% ~ 10%까지의 폭

    ## 호가를 자리수에따라 반올림하면서 정수화 함.
    buyQ = []
    sellQ = []
    for i in range(0, len(sell_m)):
    if sell_m[i] < 1000:
    sellQ.append(abs(int(round(sell_m[i], 0))))
    elif sell_m[i] < 5000:
    sellQ.append(abs(int(round(sell_m[i], -1))))
    elif sell_m[i] < 10000:
    sellQ.append(abs(int(round(sell_m[i], -1))))
    elif sell_m[i] < 50000:
    sellQ.append(abs(int(round(sell_m[i], -2))))
    elif sell_m[i] < 100000:
    sellQ.append(abs(int(round(sell_m[i], -2))))
    elif sell_m[i] < 500000:
    sellQ.append(abs(int(round(sell_m[i], -3))))
    elif sell_m[i] < 1000000:
    sellQ.append(abs(int(round(sell_m[i], -3))))

    # print("매도호가:%s \n매수호가:%s", (sellQ,buyQ))

    print("계좌번호:%s, 종목번호:%s\n총매수수량:%s\n매수금액:%s" % (
    self.account_number, self.item_num, sellbuy_ea, buyQ)) # buyQ는 40호가 까지 / sellbuy_ea는 10개까지)
    # (1:신규매수, 2:신규매도, 3:매수취소, 4:매도취소, 5:매수정정, 6:매도정정)

    if sellbuy_ea[5] != 0:
    self.send_order("sell59", "0101", self.account_number, 2, self.item_num, sellbuy_ea[5], sellQ[28], "00", "")
    time.sleep(0.3)
    print("1번성공")

    if sellbuy_ea[6] != 0:
    self.send_order("sell59", "0101", self.account_number, 2, self.item_num, sellbuy_ea[6], sellQ[33], "00", "")
    time.sleep(0.3)
    print("2번성공")

    if sellbuy_ea[7] != 0:
    self.send_order("sell59", "0101", self.account_number, 2, self.item_num, sellbuy_ea[7], sellQ[35], "00", "")
    time.sleep(0.3)
    print("3번성공")

    if sellbuy_ea[8] != 0:
    self.send_order("sell59", "0101", self.account_number, 2, self.item_num, sellbuy_ea[8], sellQ[38], "00", "")
    time.sleep(0.3)
    print("4번성공")

    if sellbuy_ea[9] != 0:
    self.send_order("sell59", "0101", self.account_number, 2, self.item_num, sellbuy_ea[9], sellQ[40], "00", "")
    time.sleep(0.3)
    print("5번성공")
    print("28,33,35,38,40호가 지정가 매도완료")


    if sRQName == "예수금상세현황요청":
    deposit = self.dynamicCall(
    "GetCommData(QString, QString, int, QString)", sTrCode, sRQName, 0, "예수금")
    self.deposit = int(deposit)

    withdraw_deposit = self.dynamicCall(
    "GetCommData(QString, QString, int, QString)", sTrCode, sRQName, 0, "출금가능금액")
    self.withdraw_deposit = int(withdraw_deposit)

    order_deposit = self.dynamicCall(
    "GetCommData(QString, QString, int, QString)", sTrCode, sRQName, 0, "주문가능금액")
    self.order_deposit = int(order_deposit)
    self.cancel_screen_number(self.screen_my_account)
    self.account_event_loop.exit()

    elif sRQName == "계좌평가잔고내역요청":
    if (self.total_buy_money == None or self.total_evaluation_money == None
    or self.total_evaluation_profit_and_loss_money == None or self.total_yield == None):
    total_buy_money = self.dynamicCall(
    "GetCommData(QString, QString, int, QString)", sTrCode, sRQName, 0, "총매입금액")
    self.total_buy_money = int(total_buy_money)

    total_evaluation_money = self.dynamicCall(
    "GetCommData(QString, QString, int, QString)", sTrCode, sRQName, 0, "총평가금액")
    self.total_evaluation_money = int(total_evaluation_money)

    total_evaluation_profit_and_loss_money = self.dynamicCall(
    "GetCommData(QString, QString, int, QString)", sTrCode, sRQName, 0, "총평가손익금액")
    self.total_evaluation_profit_and_loss_money = int(
    total_evaluation_profit_and_loss_money)

    total_yield = self.dynamicCall(
    "GetCommData(QString, QString, int, QString)", sTrCode, sRQName, 0, "총수익률(%)")
    self.total_yield = float(total_yield)

    cnt = self.dynamicCall(
    "GetRepeatCnt(QString, QString)", sTrCode, sRQName)

    for i in range(cnt):
    stock_code = self.dynamicCall(
    "GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "종목번호")
    stock_code = stock_code.strip()[1:]

    stock_name = self.dynamicCall(
    "GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "종목명")
    stock_name = stock_name.strip() # 필요 없는 공백 제거.

    stock_evaluation_profit_and_loss = self.dynamicCall(
    "GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "평가손익")
    stock_evaluation_profit_and_loss = int(
    stock_evaluation_profit_and_loss)

    stock_yield = self.dynamicCall(
    "GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "수익률(%)")
    stock_yield = float(stock_yield)

    stock_buy_money = self.dynamicCall(
    "GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "매입가")
    stock_buy_money = int(stock_buy_money)

    stock_quantity = self.dynamicCall(
    "GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "보유수량")
    stock_quantity = int(stock_quantity)

    stock_trade_quantity = self.dynamicCall(
    "GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "매매가능수량")
    stock_trade_quantity = int(stock_trade_quantity)

    stock_present_price = self.dynamicCall(
    "GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "현재가")
    stock_present_price = int(stock_present_price)

    if not stock_code in self.account_stock_dict:
    self.account_stock_dict[stock_code] = {}

    self.account_stock_dict[stock_code].update({'종목명': stock_name})
    self.account_stock_dict[stock_code].update(
    {'평가손익': stock_evaluation_profit_and_loss})
    self.account_stock_dict[stock_code].update(
    {'수익률(%)': stock_yield})
    self.account_stock_dict[stock_code].update(
    {'매입가': stock_buy_money})
    self.account_stock_dict[stock_code].update(
    {'보유수량': stock_quantity})
    self.account_stock_dict[stock_code].update(
    {'매매가능수량': stock_trade_quantity})
    self.account_stock_dict[stock_code].update(
    {'현재가': stock_present_price})

    if sPrevNext == "2":
    self.get_account_evaluation_balance(2)
    else:
    self.cancel_screen_number(self.screen_my_account)
    self.account_event_loop.exit()

    elif sRQName == "실시간미체결요청":
    cnt = self.dynamicCall(
    "GetRepeatCnt(QString, QString)", sTrCode, sRQName)

    for i in range(cnt):
    stock_code = self.dynamicCall(
    "GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "종목코드")
    stock_code = stock_code.strip()

    stock_order_number = self.dynamicCall(
    "GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "주문번호")
    stock_order_number = int(stock_order_number)

    stock_name = self.dynamicCall(
    "GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "종목명")
    stock_name = stock_name.strip()

    stock_order_type = self.dynamicCall(
    "GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "주문구분")
    stock_order_type = stock_order_type.strip().lstrip('+').lstrip('-')

    stock_order_price = self.dynamicCall(
    "GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "주문가격")
    stock_order_price = int(stock_order_price)

    stock_order_quantity = self.dynamicCall(
    "GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "주문수량")
    stock_order_quantity = int(stock_order_quantity)

    stock_not_signed_quantity = self.dynamicCall(
    "GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "미체결수량")
    stock_not_signed_quantity = int(stock_not_signed_quantity)

    stock_signed_quantity = self.dynamicCall(
    "GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "체결량")
    stock_signed_quantity = int(stock_signed_quantity)

    stock_present_price = self.dynamicCall(
    "GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "현재가")
    stock_present_price = int(
    stock_present_price.strip().lstrip('+').lstrip('-'))

    stock_order_status = self.dynamicCall(
    "GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "주문상태")
    stock_order_status = stock_order_status.strip()

    if not stock_order_number in self.not_signed_account_dict:
    self.not_signed_account_dict[stock_order_number] = {}

    self.not_signed_account_dict[stock_order_number].update(
    {'종목코드': stock_code})
    self.not_signed_account_dict[stock_order_number].update(
    {'종목명': stock_name})
    self.not_signed_account_dict[stock_order_number].update(
    {'주문구분': stock_order_type})
    self.not_signed_account_dict[stock_order_number].update(
    {'주문가격': stock_order_price})
    self.not_signed_account_dict[stock_order_number].update(
    {'주문수량': stock_order_quantity})
    self.not_signed_account_dict[stock_order_number].update(
    {'미체결수량': stock_not_signed_quantity})
    self.not_signed_account_dict[stock_order_number].update(
    {'체결량': stock_signed_quantity})
    self.not_signed_account_dict[stock_order_number].update(
    {'현재가': stock_present_price})
    self.not_signed_account_dict[stock_order_number].update(
    {'주문상태': stock_order_status})

    if sPrevNext == "2":
    self.not_signed_account(2)
    else:
    self.cancel_screen_number(sScrNo)
    self.account_event_loop.exit()

    elif sRQName == "주식일봉차트조회요청":
    stock_code = self.dynamicCall(
    "GetCommData(QString, QString, int, QString)", sTrCode, sRQName, 0, "종목코드")
    #six_hundred_data = self.dynamicCall("GetCommDataEx(QString, QString)", sTrCode, sRQName)

    stock_code = stock_code.strip()
    cnt = self.dynamicCall(
    "GetRepeatCnt(QString, QString)", sTrCode, sRQName) # 최대 600일

    for i in range(cnt):
    calculator_list = []

    current_price = self.dynamicCall(
    "GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "현재가")
    volume = self.dynamicCall(
    "GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "거래량")
    trade_price = self.dynamicCall(
    "GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "거래대금")
    date = self.dynamicCall(
    "GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "일자")
    start_price = self.dynamicCall(
    "GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "시가")
    high_price = self.dynamicCall(
    "GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "고가")
    low_price = self.dynamicCall(
    "GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "저가")

    calculator_list.append("")
    calculator_list.append(int(current_price))
    calculator_list.append(int(volume))
    calculator_list.append(int(trade_price))
    calculator_list.append(int(date))
    calculator_list.append(int(start_price))
    calculator_list.append(int(high_price))
    calculator_list.append(int(low_price))
    calculator_list.append("")

    self.calculator_list.append(calculator_list.copy())

    if sPrevNext == "2":
    self.day_kiwoom_db(stock_code, None, 2)
    else:
    self.calculator_event_loop.exit()

    def cancel_screen_number(self, sScrNo):
    self.dynamicCall("DisconnectRealData(QString)", sScrNo)

    def get_code_list_by_market(self, market_code):
    code_list = self.dynamicCall(
    "GetCodeListByMarket(QString)", market_code)
    code_list = code_list.split(";")[:-1]
    return code_list

    def calculator(self):
    kosdaq_list = self.get_code_list_by_market("10")

    for idx, stock_code in enumerate(kosdaq_list):
    self.dynamicCall("DisconnectRealData(QString)",
    self.screen_calculation_stock)

    print(
    f"{idx + 1} / {len(kosdaq_list)} : KOSDAQ Stock Code : {stock_code} is updating...")
    self.day_kiwoom_db(stock_code)

    def day_kiwoom_db(self, stock_code=None, date=None, nPrevNext=0):
    QTest.qWait(3600) # 3.6초마다 딜레이

    self.dynamicCall("SetInputValue(QString, QString)", "종목코드", stock_code)
    self.dynamicCall("SetInputValue(QString, QString)", "수정주가구분", 1)

    if date != None: # date가 None일 경우 date는 오늘 날짜 기준
    self.dynamicCall("SetInputValue(QString, QString)", "기준일자", date)

    self.dynamicCall("CommRqData(QString, QString, int, QString)",
    "주식일봉차트조회요청", "opt10081", nPrevNext, self.screen_calculation_stock)

    if not self.calculator_event_loop.isRunning():
    self.calculator_event_loop.exec_()

    def errors(err_code):

    err_dic = {0: ('OP_ERR_NONE', '정상처리'),
    -10: ('OP_ERR_FAIL', '실패'),
    -100: ('OP_ERR_LOGIN', '사용자정보교환실패'),
    -101: ('OP_ERR_CONNECT', '서버접속실패'),
    -102: ('OP_ERR_VERSION', '버전처리실패'),
    -103: ('OP_ERR_FIREWALL', '개인방화벽실패'),
    -104: ('OP_ERR_MEMORY', '메모리보호실패'),
    -105: ('OP_ERR_INPUT', '함수입력값오류'),
    -106: ('OP_ERR_SOCKET_CLOSED', '통신연결종료'),
    -200: ('OP_ERR_SISE_OVERFLOW', '시세조회과부하'),
    -201: ('OP_ERR_RQ_STRUCT_FAIL', '전문작성초기화실패'),
    -202: ('OP_ERR_RQ_STRING_FAIL', '전문작성입력값오류'),
    -203: ('OP_ERR_NO_DATA', '데이터없음'),
    -204: ('OP_ERR_OVER_MAX_DATA', '조회가능한종목수초과'),
    -205: ('OP_ERR_DATA_RCV_FAIL', '데이터수신실패'),
    -206: ('OP_ERR_OVER_MAX_FID', '조회가능한FID수초과'),
    -207: ('OP_ERR_REAL_CANCEL', '실시간해제오류'),
    -300: ('OP_ERR_ORD_WRONG_INPUT', '입력값오류'),
    -301: ('OP_ERR_ORD_WRONG_ACCTNO', '계좌비밀번호없음'),
    -302: ('OP_ERR_OTHER_ACC_USE', '타인계좌사용오류'),
    -303: ('OP_ERR_MIS_2BILL_EXC', '주문가격이20억원을초과'),
    -304: ('OP_ERR_MIS_5BILL_EXC', '주문가격이50억원을초과'),
    -305: ('OP_ERR_MIS_1PER_EXC', '주문수량이총발행주수의1 % 초과오류'),
    -306: ('OP_ERR_MIS_3PER_EXC', '주문수량은총발행주수의3 % 초과오류'),
    -307: ('OP_ERR_SEND_FAIL', '주문전송실패'),
    -308: ('OP_ERR_ORD_OVERFLOW', '주문전송과부하'),
    -309: ('OP_ERR_MIS_300CNT_EXC', '주문수량300계약초과'),
    -310: ('OP_ERR_MIS_500CNT_EXC', '주문수량500계약초과'),
    -340: ('OP_ERR_ORD_WRONG_ACCTINFO', '계좌정보없음'),
    -500: ('OP_ERR_ORD_SYMCODE_EMPTY', '종목코드없음')
    }

    result = err_dic[err_code]

    return result


    class KiwoomProcessingError(Exception):
    """ 키움에서 처리실패에 관련된 리턴코드를 받았을 경우 발생하는 예외 """

    def __init__(self, msg="처리 실패"):
    # self.msg = msg
    print(msg)

    def __str__(self):
    return self.msg

    def __repr__(self):
    return self.msg


    ######################## 시작
    if __name__=="__main__":

    kiwoom = Kiwoom()

List of Articles
번호 분류 제목 날짜 조회 수
56 파이썬 파이썬에서 인식이 잘되는 OCR 종류 2023.09.15 60399
55 파이썬 한우경매낙찰 유튜브 영상의 이미지에서 특정 문자 가져와서 저장하기 2023.09.14 58758
54 파이썬 파이썬 랜덤으로 문제풀기 #2 2023.10.04 57777
53 파이썬 파이썬 랜덤으로 시험문제 풀기 file 2023.10.04 56287
52 파이썬 파이썬 requestsbeautifulsoup 으로 웹 input에 입력값 대입한 뒤 결과값 파일로 저장하기 2023.11.13 47443
51 파이썬 python AttributeError: 'WebDriver' object has no attribute 'find_element_by_css_selector' 해결방법 2023.05.07 47282
50 파이썬 DiffusionWrapper has 859.52 M params. 2023.04.21 37109
49 파이썬 자바스크립트 종말각?! HTML에서 파이썬 실행하는 PyScript 등장! 2022.06.08 31066
48 파이썬 파이썬 파이인스톨러 설치하기 2022.05.08 21417
47 파이썬 파이썬 구글스프레드시트 값 불러오기 html로 변환작업 중! 2022.05.08 20151
46 파이썬 파이썬 화면 캡쳐하기 2022.11.26 19295
45 파이썬 Windows용 Tesseract 설치 및 사용법 2022.11.26 19210
44 파이썬 파이썬으로 captCha 분석하여 웹사이트 소스 가져오기 2023.03.25 18757
43 파이썬 파이썬 글자 인식, 파이썬 OCR, 파이썬 Tesseract 사용 2022.11.21 14638
42 파이썬 파이썬에서 captCha 분석 프로그램을 만들 수 있을까? 2023.03.25 11660
41 파이썬 파이썬 easyocr 이미지 문자 인식 2023.01.16 10233
40 파이썬 파이썬 googleapiclient 모듈이 설치가 안될때 해결방법 1 2022.03.27 9702
39 파이썬 Visual Studio Code 파이썬 인터프리터 경로 변경하기 2022.03.09 9189
38 파이썬 파이썬을 이용하여 매크로 만들기 2023.01.13 9149
37 파이썬 웹 페이지에서 동적으로 생성되는 데이터 가져오는 방법 2023.03.15 6865
Board Pagination Prev 1 2 3 Next
/ 3

http://urin79.com

우린친구블로그

sketchbook5, 스케치북5

sketchbook5, 스케치북5

나눔글꼴 설치 안내


이 PC에는 나눔글꼴이 설치되어 있지 않습니다.

이 사이트를 나눔글꼴로 보기 위해서는
나눔글꼴을 설치해야 합니다.

설치 취소