AUTO TRADE/[대신증권] CYBOS PLUS

대신증권 CYBOS PLUS 시작하기 (8) - 모듈별로 클래스 생성하기

코드 구현 목표

  • 모듈 별로 각기 다른 py 파일 내에 각기 다른 이름으로 클래스 생성하기
  • 생성한 클래스 사용해보기

지난 게시글에서는 CpSysDib.py 파일을 생성한 후 해당 파일 내에서 CpSysDib 내에 있는 `StockChart` 모듈을 대상으로 하는 인스턴스(`self.stockchart`)를 생성해주었고, 그 인스턴스를 활용하여 대신증권 서버에 데이터를 입력하거나 입력한 데이터를 서버로 전송하고, 그 결과 데이터를 수신했다. 이번 게시글에서는 CpSysDib.StockChart 모듈 뿐만 아니라, 이외에도 대신증권에서 제공하는 여러 모듈을 모듈 별로 하나의 파일을 생성하고 그 안에 클래스를 생성해볼 예정이다.

 

(1) 모듈 별로 각기 다른 py 파일 내에 각기 다른 이름의 클래스 생성하기

현재 Boss.py 파일 내에 있는 `def __init__(self):` 함수 내에 있는 모듈의 종류는 다음과 같다. 아래에 있는 모듈의 종류 중 .을 기준으로 하여 앞에 있는 건 파일 명으로, 뒤에 있는 건 클래스 명으로 하여 각각의 파일과 클래스를 생성해주도록 하자. 앞으로도 살펴보게 될 여러 가지 클래스들에 대해서도, 아래의 규칙에 따라 각각의 파일 내에서 코드를 구현할 예정이다.

  • CpUtil.CpCybos
  • CpUtil.CpStockCode
  • CpTrade.CpTdUtil
  • CpUtil.CpCodeMgr
  • DsCbo1.StockMst
## CpUtil.py ##
import win32com.client

class CpStockCode:
    def __init__(self):
        self.stockcode = win32com.client.Dispatch("CpUtil.CpStockCode")     ## COM 연결

class CpCodeMgr:
    def __init__(self):
        self.codemgr = win32com.client.Dispatch("CpUtil.CpCodeMgr")         ## COM 연결

class CpCybos:
    def __init__(self):
        self.cybos = win32com.client.Dispatch("CpUtil.CpCybos")           ## COM 연결
## CpTrade.py ##
import win32com.client

class CpTdUtil:
    def __init__(self):
        self.trade = win32com.client.Dispatch("CpTrade.CpTdUtil")           ## COM 연결
## DsCbo1.py ##
import win32com.client

class StockMst:
    def __init__(self):
        self.stockmst = win32com.client.Dispatch("DsCbo1.StockMst")         ## COM 연결

 

그 후에는 기존에 Boss.py 파일 내에서 각각의 인스턴스를 활용하여 제작했던 함수들을 각각의 함수가 속한 모듈을 이름으로 하는 파일의 적절한 클래스 내부로 이동시켜주도록 하자.

## CpUtil.py ##
import win32com.client

class CpStockCode:
    def __init__(self):
        self.stockcode = win32com.client.Dispatch("CpUtil.CpStockCode")     ## COM 연결

    def _CodeToName(self, code):
        value = self.stockcode.CodeToName(code)
        print(f"[인자값:{code}] 결과값:{value}")

    def _CodeToFullCode(self, code):
        value = self.stockcode.CodeToFullCode(code)
        print(f"[인자값:{code}] 결과값:{value}")

    def _FullCodeToCode(self, fullcode):
        value = self.stockcode.FullCodeToCode(fullcode)
        print(f"[인자값:{fullcode}] 결과값:{value}")

    def _FullCodeToName(self, fullcode):
        value = self.stockcode.FullCodeToName(fullcode)
        print(f"[인자값:{fullcode}] 결과값:{value}")

    def _CodeToIndex(self, code):
        value = self.stockcode.CodeToIndex(code)
        print(f"[인자값:{code}] 결과값:{value}")

    def _GetCount(self):
        value = self.stockcode.GetCount()
        print(f"전체 종목코드 개수:{value}")

    def _GetData(self, type, index):
        """
        종목코드의 Index와 함께 Type을 전달해주면 Type에 해당하는 데이터를 반환함
        :param type: 0은 종목코드, 1은 종목명, 2은 표준코드 체계 하에서의 코드
        :param index:종목코드 인덱스
        :return: 해당 데이터
        """
        value = self.stockcode.GetData(type, index)
        print(f"[Type:{type}, Index:{index}] 결과값:{value}")


class CpCodeMgr:
    def __init__(self):
        self.codemgr = win32com.client.Dispatch("CpUtil.CpCodeMgr")         ## COM 연결


    def _GetStockMarginRate(self, code):
        """
        :param code: 종목코드
        :return:     주식 매수 증거금율
        """
        value = self.codemgr.GetStockMarginRate(code)
        print(f"[인자값:{code}] 매수 증거금율:{value}%({type(value)})")

    def _GetStockMarketKind(self, code):
        """
        :param code: 종목코드
        :return:     해당 종목코드의 소속 시장 반환
            0: 구분없음
            1: 거래소
            2: 코스닥
            3: K-OTC
            4: KRX
            5: KONEX
        """
        value = self.codemgr.GetStockMarketKind(code)
        name = ""   ## 지역변수 설정
        if value == 0:
            name = "구분없음"
        elif value == 1:
            name = "거래소"
        elif value == 2:
            name = "코스닥"
        elif value == 3:
            name = "K-OTC"
        elif value == 4:
            name = "KRX"
        elif value == 5:
            name = "KONEX"
        print(f"[인자값:{code}] 소속시장:{value}({name})")

    def _GetStockListByMarket(self, market_kind_code):
        """
        :param market_kind_code: GetStockMarketKind 함수의 인자값 참조
            1: 거래소, 2: 코스닥, 3: K-OTC, 4: KRX, 5: KONEX
        :return                : 시장 구분에 따른 주식 종목 배열
        """
        value = self.codemgr.GetStockListByMarket(market_kind_code)
        print(f"[인자값:{market_kind_code}] 종목코드 목록:{value}")

    def _GetIndustryList(self):
        """
        :return: 증권 전산 업종코드 리스트를 모두 반환
        """
        value = self.codemgr.GetIndustryList()
        print(f"[증권 전산 업종코드 목록] {value}")

    def _GetIndustryName(self, code):
        """
        :param code: 증권 전산 업종코드
        :return    : 증권 전산 업종명
        """
        value = self.codemgr.GetIndustryName(code)
        print(f"[증권 전산 업종코드:{code}] 업종명:{value}")

    def _GetIndustryGroupCodeList(self, code):
        value = self.codemgr.GetIndustryGroupCodeList(code)
        print(f"[증권 전산 업종코드:{code}] 종목목록:{value}")


class CpCybos:
    def __init__(self):
        self.cybos = win32com.client.Dispatch("CpUtil.CpCybos")           ## COM 연결

    def _IsConnect(self):
        value = self.cybos.IsConnect
        if value == 1:
            print(f"[통신결과:{value}] 서버와의 연결에 성공했습니다.")
        elif value == 0:
            print(f"[통신결과:{value}] 서버와의 연결에 실패했습니다.")

    def _ServerType(self):
        """
        0: 연결 끊김
        1: CybosPlus 서버
        2:HTS 보통 서버(1번 제외)
        """
        value = self.cybos.ServerType
        if value == 0:
            print(f"[서버종류:{value}] 서버와의 연결이 끊겼습니다.")
        elif value == 1:
            print(f"[서버종류:{value}] CybosPlus 서버와의 연결에 성공했습니다.")
        elif value == 2:
            print(f"[서버종류:{value}] HTS 보통 서버와의 연결에 성공했습니다.")
## CpTrade.py ##
import win32com.client

class CpTdUtil:
    def __init__(self):
        self.trade = win32com.client.Dispatch("CpTrade.CpTdUtil")           ## COM 연결

    def _TradeInit(self):
        """
        :return: 주문과 관련된 결과값 반환
            -1: 오류 (계좌 비밀번호 오류도 포함함)
             0: 정상
             1: OTP/보안카드 키 입력 잘못됨
             3: 취소
        """
        value = self.trade.TradeInit(0)
        result = ""   ## 지역변수 설정
        if value == -1:
            result = "오류(계좌 비밀번호 오류도 포함함)"
        elif value == 0:
            result = "정상"
        elif value == 1:
            result = "OTP/보안카드 키 입력 잘못됨"
        elif value == 3:
            result = "취소"
        print(f"[주문 오브젝트 초기화 결과] {value}({result})")

    def _AccountNumber(self):
        """
        [Only Read, 읽기 전용 함수]
        :return: 계좌 목록 표기
        """
        value = self.trade.AccountNumber
        print(f"[마스터 계좌 표기] {value}")
## DsCbo1.py ##
import win32com.client

class StockMst:
    def __init__(self):
        self.stockmst = win32com.client.Dispatch("DsCbo1.StockMst")         ## COM 연결

    def _StockMst(self, item_code):
        """주식종목현재가 반환"""
        self.stockmst.SetInputValue(0, item_code)
        self.stockmst.BlockRequest()
        item_code = self.stockmst.GetHeaderValue(0)
        item_name = self.stockmst.GetHeaderValue(1)
        y_close = self.stockmst.GetHeaderValue(10)
        now = self.stockmst.GetHeaderValue(11)
        open = self.stockmst.GetHeaderValue(13)
        high = self.stockmst.GetHeaderValue(14)
        low = self.stockmst.GetHeaderValue(15)
        print(f"[{item_code}] {item_name}")
        print(f"  전일종가:{y_close}, 현재가:{now} ")
        print(f"  시가:{open}, 고가:{high}, 저가:{low}")

 

이제 마지막으로, 지난 게시글에서 수행했던 작업과 동일한 방식으로 Boss.py 파일 내에서 각각의 클래스를 호출한 후 클래스별로 별도의 인스턴스를 생성해주도록 하자. 그러면 아래와 같이 깔끔한 Boss.py 파일이 생길 것이다.

## Boss.py ##
import win32com.client
from COM import CpSysDib
from COM import CpUtil
from COM import CpTrade
from COM import DsCbo1

class cybos:
    def __init__(self):
        self.cybos = CpUtil.CpCybos()
        self.stockchart = CpUtil.CpStockCode()
        self.trade = CpTrade.CpTdUtil()
        self.codemgr = CpUtil.CpCodeMgr()
        self.stockmst = DsCbo1.StockMst()
        self.stockchart = CpSysDib.StockChart()

if __name__ == "__main__":
    cybos()

 

 

(2) 생성한 클래스 사용해보기

그렇다면 이제 Boss.py 파일이 실행되면 자동으로 로그인을 수행하도록 하는 코드를 구현해볼 예정인데, 이 코드를 구현하는 방식은 크게 두 가지 방법이 있다. ① 로그인과 관련된 모듈인 CpUtil.CpCybos의 인스턴스인 self.cybos를 갖고 Boss.py 파일의 초기화 함수 내에서 `IsConnect()`를 사용하여 그 출력 결과를 확인하거나, ② CpUtil.py 파일 내부의 `class CpCybos` 클래스의 초기화 함수 내에서 해당 클래스가 호출되는 즉시 `IsConnect()`를 실행하도록 하여 그 출력 결과를 확인하는 방법이다. 
※ Line: 16, 18, 19

## Boss.py ##
import win32com.client
from COM import CpSysDib
from COM import CpUtil
from COM import CpTrade
from COM import DsCbo1

class cybos:
    def __init__(self):
        self.cybos = CpUtil.CpCybos()
        self.stockchart = CpUtil.CpStockCode()
        self.trade = CpTrade.CpTdUtil()
        self.codemgr = CpUtil.CpCodeMgr()
        self.stockmst = DsCbo1.StockMst()
        self.stockchart = CpSysDib.StockChart()
        self.auto_login()

    def auto_login(self):
        self.cybos._IsConnect()

if __name__ == "__main__":
    cybos()

▶ 실행 결과 확인하기

더보기
더보기
더보기

[통신결과:1] 서버와의 연결에 성공했습니다.

위와 같이 `def auto_login(self):` 함수를 지정하지 않고도, 아래와 같이 로그인 함수(`self.cybos._IsConnect()`)를 초기화 함수 내부에서 작성해도 프로그램 실행과 동시에 바로 로그인 여부를 확인할 수 있다.
※ Line: 16

## Boss.py ##
import win32com.client
from COM import CpSysDib
from COM import CpUtil
from COM import CpTrade
from COM import DsCbo1

class cybos:
    def __init__(self):
        self.cybos = CpUtil.CpCybos()
        self.stockchart = CpUtil.CpStockCode()
        self.trade = CpTrade.CpTdUtil()
        self.codemgr = CpUtil.CpCodeMgr()
        self.stockmst = DsCbo1.StockMst()
        self.stockchart = CpSysDib.StockChart()
        self.cybos._IsConnect()

if __name__ == "__main__":
    cybos()

▶ 실행 결과 확인하기

더보기
더보기

[통신결과:1] 서버와의 연결에 성공했습니다.

 

 


728x90
반응형
Contents

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

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