이전에 첫 번째 게시글에서는 대신증권 CYBOS PLUS의 통신 방식을 간략하게 알아보았고, 두 번째 게시글에서는 통신 방식에 대해 하나의 예시를 들어 조금 더 자세하게 살펴보았다. 이번 게시글에서는 대신증권 CYBOS PLUS와 연결해보도록 하자. 그 전에, 대신증권의 CYBOS PLUS는 파이썬 언어를 통해 구현할 예정이며, 해당 시스템을 구현하기 위한 IDE인 파이참의 설치와 파이참 설정 방법은 해당 텍스트에 걸려 있는 링크를 통해 설치하고 설정을 변경하고 오도록 하자.
(1) trade_cybos 프로젝트 생성
프로젝트명은 `trade_cybos`로 하고, 해당 프로젝트의 전체적인 내용을 담을 파일 명을 `Boss.py`로 하여 프로젝트를 생성했다. 프로젝트 생성은 파일(F) - 새 프로젝트를 클릭하여 생성할 수 있다.
(2) 프로젝트 실행 함수 구현
기본적으로 대신증권 CYBOS PLUS는 거의 모든 작업이 `Boss.py` 파일 내에서 이루어질 예정인데, 그렇다면 `Boss.py` 파일을 실행시켰을 때 그 안에 있는 함수 코드들을 바로 실행토록 하는 작업을 한 다음에 세부적인 코드를 구현해보자.
일단 가장 기본적인 `cybos` 클래스와 초기화 함수인 `__init__` 함수를 사용하여 클래스를 정의하고, 맨 아래에 조건문을 통해 현재 실행된 파일이 `__main__`인 경우에 `cybos()`를 실행하도록 하자. 아래와 같은 코드 구조가 가장 기본적인 형태의 프로젝트 실행 코드이다.
class cybos:
def __init__(self):
pass
if __name__ == "__main__":
cybos()
예제를 하나 따라해보자. `cybos()` 클래스가 실행됐을 때 '실행되었습니다.'라는 문구를 출력하도록 `print()`문을 사용하여 코드를 제작하고 그 코드를 실행해보면 아래의 더보기와 같은 결과물을 얻을 수 있다.
class cybos:
def __init__(self):
print("실행되었습니다.")
if __name__ == "__main__":
cybos()
대신증권의 Open API는 기본적으로 COM 방식을 사용하고 있는데, COM 방식이 어떤 방식인지에 대해서는 감사하게도 간략하게 잘 정리되어 있는 게시글이 있으므로 그 게시글을 참고하여 이해하도록 하자. 우리는 프로그램을 구현하기만 하면 되니까, 디테일한 지식까지는 필요 없고 코드만 필요하다.
다시 본론으로 돌아와, 파이썬 언어에서 COM 방식을 사용하는 방법은 아래와 같다. win32com 파일의 client 클래스 내 Dispath 함수를 사용하여 해당 COM 파일을 사용하는 방식이다.
win32com.client.Dispatch("COM 파일")
여기서 win32com을 활용하여 client와 Dispatch를 사용하려면 기본적으로 win32com 모듈을 `import` 해야 되는데, 그 과정에서 win32com이 아예 설치되어 있지 않다면 아래와 같이 빨간색 줄로 표기될 것이다. (오른쪽의 알림을 누르면 관련 오류 메시지도 확인할 수 있다.)
만약 위와 같이 win32com을 `import`했을 때 오류가 발생한다면 따로 win32com을 설치해줘야 하는데, 파이참이 설치되어 있다면 파이참 내 왼쪽 상단에 있는 [파일] - [설정]에 들어가서 아래의 이미지를 참고하여 `pywin32`를 설치해주면 된다. ※ 파이참이 없는 경우에도 Python IDLE에서 `pip install pywin32`을 입력해서 설치할 수 있긴 하지만, 그 전에 일단 나부터가 일반적인 파이썬만으로는 프로젝트 관리가 어렵기 때문에 앞으로도 파이참을 사용할 예정이다.
이제 설치가 완료된 후에는 아래 왼쪽과 같이 win32com 밑에 있던 빨간 줄은 사라졌지만, 아래의 `def __init__(self)` 초기화 함수 내에 있는 `win32com.client.Dispatch` 부분에서 `client`에 노란색 배경이 생긴 것을 확인할 수 있다. 이건 설치가 잘못된 것이 아니고, 애초에 우리가 `import` 해야 하는 것은 `win32com`이 끝이 아니라 `win32com.client`였기 때문에 맨 위에 있는 `import` 구문을 오른쪽 사진과 같이 수정해주면 된다.
import win32com.client
class cybos:
def __init__(self):
win32com.client.Dispatch("")
if __name__ == "__main__":
cybos()
이제 대신증권의 CYBOS PLUS에서 제공하는 Open API를 파이썬 `win32com.client.Dispatch("")` 안에 입력해주면 되는데, 이 안에는 아래 게시글의 제목인 `CpUtil.CpCybos`를 입력해주면 된다. 이제 아래의 코드까지만 작성하면 파이썬 언어를 통해 사용자와 대신증권 CYBOS PLUS를 연결하는 작업은 모두 끝난다. ※대신증권 공식 도움말 링크
import win32com.client
class cybos:
def __init__(self):
win32com.client.Dispatch("CpUtil.CpCybos") ## COM 연결
if __name__ == "__main__":
cybos()
프로그램을 실행해도 아무런 동작도 이루어지지 않는데, 사실 당연한 결과다. 왜냐하면 앞서 작성한 코드는 어디까지나 대신증권 Open API에 접근하여 사용할 준비를 끝마쳤을 뿐, 그 어떠한 작업도 수행하지 않았기 때문이다. 그렇다면 이제 대신증권에 '나, 지금 CYBOS PLUS에 연결되어있어 ?'라고 묻는 코드를 입력해서 실행해보도록 하자.
그 전에, 바로 앞에서 COM과 연결한 코드(`win32com.client.Dispatch("CpUtil.CpCybos")`)를 하나의 인스턴스로 생성해주어야 한다. 설명이 어렵게 느껴질 수 있지만 한 단계 간단히 설명하자면 위의 코드를 하나의 전역 변수로 생성하여 우리가 작업을 진행하는 Boss.py 파일의 `class cybos` 내부에서라면 어디서든지 대신증권과의 통신을 가능하게 해주는 것이다. 우리는 이 작업을 앞서 COM과 연결한 코드를 `self.cybos`라는 변수에 입력할 것이다. 이 작업이 이루어진다면 이제 앞으로는 `self.cybos`만 가지고도 CYBOS PLUS와 통신할 수 있다.
import win32com.client
class cybos:
def __init__(self):
self.cybos = win32com.client.Dispatch("CpUtil.CpCybos") ## COM 연결
if __name__ == "__main__":
cybos()
이제 대신증권과 통신할 준비는 모두 끝났으니, 하나의 예제로 `IsConnect()`를 서버로 데이터를 요청해보도록 하자. 대신증권 홈페이지를 살펴보면 각 함수들에 대한 설명이 담긴 게시글들을 확인할 수 있다. 일종의 도움말이니, 궁금한 게 있다면 직접 검색하면서 코드를 어떠한 방식으로 구현해야 하는지 참고하면서 구현하면 된다.
이제 내용을 봤다면, 게시글 내에서 value = object.IsConnect라고 표기되어 있는 부분을 한 번 구현해볼 건데, 게시글 내에 object라고 표기되어 있는 부분이 곧 우리가 앞서 정의했던 `self.cybos`에 해당하는 부분이니 아래와 같이 구현하면 된다. 코드를 구현한 후에는 `value`를 출력하여 그 값을 확인해보도록 하자.
결과값이 0이 나오면 연결 실패고 1이 나와야 연결 성공이다.
import win32com.client
class cybos:
def __init__(self):
self.cybos = win32com.client.Dispatch("CpUtil.CpCybos") ## COM 연결
value = self.cybos.IsConnect
print(value)
if __name__ == "__main__":
cybos()
파이썬이나 파이참 자체를 관리자 권한으로 실행하지 않으면 코드가 정상적으로 작성되었음에도 불구하고 로그인에 실패할 수 있습니다. 만약 파이썬이나 파이참의 실행 권한이 관리자 권한으로 설정되어 있지 않다면 파이참이나 파이썬 아이콘을 우클릭한 후에 '속성' 메뉴의 '호환성' 탭에 들어가서 기본 실행 권한을 관리자 권한으로 설정하시기 바랍니다. (아래의 이미지를 따라서 설정하면 됩니다.)
import win32com.client
class cybos:
def __init__(self):
self.cybos = win32com.client.Dispatch("CpUtil.CpCybos") ## COM 연결
value = self.cybos.IsConnect
print(value)
if __name__ == "__main__":
cybos()