지난 글에서 증권사 API 중 대신증권의 CYBOS Plus, 이베스트투자증권의 XingAPI, 키움증권의 OpenAPI+가 가장 많이 사용된다고 말씁드렸습니다.
그런데 이 중에서 이베스트투자증권의 XingAPI의 경우는 로그인을 API로 수행할 수 있지만 대신증권의 CYBOS Plus의 경우는 HTS 프로그램을 통해서 로그인하고 그 세션을 공유해서 처리하도록 되어 있습니다.
키움증권의 OpenAPI+의 경우는 OCX 방식을 사용하고 있어서 GUI를 이용하지 않으면 사용이 까다롭다는 단점이 있죠.
3가지 OpenAPI에 대한 비교를 아래의 링크에서 다루고 있으니 참고하시면 좋을듯 합니다.
퀀티랩 블로그 - 증권사 API 장단점 비교 (quantylab.com)
이런 이유로 우리가 프로그램을 만들고 사용할 때 따로 신경을 쓰지 않고 자동화하기가 제일 편한 것은 이베스트투자증권의 XingAPI 인것 같습니다.
물론 기본적인 코드와 샘플들을 살펴본 후에는 GUI를 적용할 것이기때문에 키움증권의 OpenAPI+도 문제 없습니다만 일단은 XingAPI를 우선적으로 살펴보겠습니다.
XingAPI의 개발 가이드는 웹 브라우저에서 아래의 링크를 통해 바로 살펴볼 수 있습니다.
www.ebestsec.co.kr/apiguide/guide.jsp?cno=200
XingAPI는 가볍고 빠르게 동작하는 DLL 버전과 쉽게 사용할 수 있는 COM 버전이 있는데, DLL 버전은 C++과 같은 언어로 개발하는 것이 그 성능을 끌어내기에 좋습니다(개발하기는 더 어렵긴 합니다).
그렇지만 우리는 파이썬을 주 언어로 사용할 것이기때문에 COM 버전을 사용할 것입니다.
그리고 XingAPI의 COM 버전에 대한 공식 개발 가이드는 Visual Basic 코드를 이용해서 제공되기때문에 가이드의 코드를 그대로 사용할 수 없습니다.
가이드의 코드를 분석, 이해한 수 파이썬으로 재작성을 해야 되겠죠.
시중에 판매되고 있는 도서에서 파이썬으로 재작성된 예제들을 쉽게 찾아볼 수 있습니다.
이 글에서는 시중에 판매되는 도서의 코드를 그대로 사용하기보다는 좀 비효율적이더라도 여러가지로 변경해보면서 사용할 계획입니다.
그 쪽이 공부하기에는 더 좋을 것 같네요.
먼저 가장 중요한 XingAPI COM 버전의 구성을 살펴보면...
객체명 | 설명 | 파일명 |
XASession | 서버연결, 로그인 등 | XA_Session.dll |
XAQuery | 조회 TR | XA_DataSet.dll |
XAReal | 실시간 TR | XA_DataSet.dll |
와 같이 되어 있습니다.
COM 버전의 사용 방식은 아래의 그림처럼 구성되어 있습니다.
DLL 버전은 직접 증권사 데이터에 접근하기때문에 더 빠르고 가볍죠.
COM 버전은 DLL 버전의 기능을 가져와서 사용하기때문에 래핑된 수준에 따라 더 사용이 쉽고 간편하지만 그만큼 처리 단계가 늘어나기때문에 속도나 효율성은 떨어집니다.
그런데 어차피 제공되는 API의 기능은 서버에 부하를 많이 주지 않기 위하여 사용빈도, 시간 및 용량에 제한이 주어져 있기때문에 COM을 통함으로써 발생하는 효율성 감소는 우리가 크게 느낄 수 있는 부분은 아닙니다.
우리는 위에서 주어진 3개의 객체를 이용하여 각 기능을 호출하게 되는데, XASession 객체는 서버를 연결하고 로그인을 하는 목적이 대부분입니다.
실제적인 기능의 구현은 XAQuery 객체와 XAReal 객체의 메소드를 호출함으로써 이루어집니다.
꾸준히 데이터를 쌓아나가서 분석과 예측에 사용하기 위해서는 주고 XAQuery 객체를 이용하는 것이 좋을 것이고, 변화하는 주가에 따라 실시간으로 자동 거래를 수행하려면 XAReal 객체를 이용해야 되겠죠.
지난 시간에 다루었던 대로 먼저 서버를 연결합니다.
그리고는 증권사에 등록한 계정으로 로그인을 해야 되겠죠.
로그인을 위한 코드는 아래와 같습니다.
# 이 코드는 실행해보지 말고 그냥 살펴봐주세요
import win32com.client
import pythoncom
class CallbackEventHandler:
state = 0
def OnEventLogin(self, nResult):
print("CallbackEventHandler.EventLogin: nResult=%s" % nResult)
def OnEventConnect(self, nResult):
print("CallbackEventHandler.EventConnect: nResult=%s" % nResult)
xa_session = win32com.client.DispatchWithEvents("XA_Session.XASession", CallbackEventHandler)
xa_session.ConnectServer('demo.ebestsec.co.kr', 20001)
xa_session.Login('******', '******', '', 0, 0)
while xa_session.state == 0:
pythoncom.PumpWaitingMessages()
먼저 필요한 COM을 사용하기 위하여 win32com.client 라이브러리를 import합니다.
다음에 import한 pythoncom 라이브러리는 마지막의 PumpWaitingMessages() 메소드를 호출하기 위한 것입니다.
다음으로 CallbackEventHandler라는 클래스를 생성하였습니다.
XingAPI가 구현된 COM을 사용하기 위하여 우리는 XA_Session.XASession와 접속해야 하는데 이때 사용되는 것이 win32com.client 라이브러리에 포함된 DispatchWithEvents 메소드입니다.
DispatchWithEvents 메소드의 첫 번째 파라미터는 어떤 COM 모듈에 접속할 것인지를 지정하고, 두 번째 파라미터에서는 결과를 받아와서 사용하기 위한 Callback을 지정합니다.
앞에서 생성한 CallbackEventHandler 클래스가 우리가 지정하려는 Callback 객체입니다.
Callback 클래스에서는 OnEventLogin 메소드와 OnEventConnect메소드를 구현하게 됩니다.
여기서는 다른 기능은 필요없으니 그냥 필요한 메시지 출력만 하게 해 두었습니다.
그럼 Callback도 지정하였으니 COM 모듈에 접속한 세션을 xa_session 변수에 할당하고, 지금부터는 xa_session 변수를 이용해서 접근하면 됩니다.
xa_session.ConnectServer에서 접속하려는 서버를 지정해 줍니다.
이베스트투자증권의 시스템에서 테스트를 위한 모의서버의 호스트는 "demo.ebestsec.co.kr"이며 사용하는 포트는 20001번입니다.
다음으로 xa_session.Login 메소드를 이용해서 로그인을 해 줍니다.
로그인 메소드에서 "******" 부분은 ID와 비밀번호가 순서대로 들어가면 됩니다.
세번째 파라미터에는 공인인증서 비밀번호가 들어가지만 모의투자 서버인 "demo.ebestsec.co.kr"을 사용할 때에는 비워두어도 괜찮습니다.
여기까지가 로그인을 위한 코드입니다.
이제 로그인 결과를 이용해서 원하는 기능들을 구현하면 됩니다.
while 구문 이전까지 수행하면 그 결과가 True가 나오는데 여기서 말하는 True가 로그인 성공을 뜻하는 것은 아닙니다.
로그인 결과는 Error 메시지의 형태로 날아오며 그때 포함된 코드가 '0000'이라면 로그인이 성공한 것입니다.
xa_session.state의 값이 0, 즉 아직 로그인되었다고 상태값이 변경되지않았다면 변경될때까지 계속 신호를 받으면서 대기해야 하는데 그것을 위해서 마지막의 while 구문이 사용됩니다.
while 구문 안에서 pythoncom.PumpWaitingMessage()를 계속해서 호출해 주는데 이렇게 대기하는 기능때문에 실제로 사용할때는 쓰레드를 사용해서구현하게 됩니다.
개별로 쓰레드를 사용하는 이유는 언제라도 Callback이 올 수도 있기때문이죠.
위의 코드를 실제로 실행해보면 결과는 "0000"으로 성공메시지가 오지만... 끝없이 반복됩니다.
그래서 각 내용을 제대로 정리를 하여 코드를 작성하면 아래와 같습니다.
import win32com.client
import pythoncom
class XASessionHandler:
login_state = 0
def OnLogin(code, msg):
if code == "0000":
print(code, msg)
XASessionHandler.login_state = 1
else:
print(code, msg)
def OnDisconnect():
print("Session disconnected...")
XASessionHandler.login_state = 0
class EBest:
def __init__(self):
# def __init__(self, mode): 이제는 mode가 필요없게 되었습니다.
self.user = '******'
self.password = '******'
self.cert_password = ''
self.host = 'demo.ebestsec.co.kr'
self.port = 20001
self.xa_session_handler = win32com.client.DispatchWithEvents("XA_Session.XASession", XASessionHandler)
def login(self):
self.xa_session_handler.ConnectServer(self.host, self.port)
self.xa_session_handler.Login(self.user, self.password, self.cert_password, 0, 0)
# self.xa_session_handler.Login(self.user, self.password, self.cert_password, mode, 0)
while XASessionHandler.login_state == 0:
pythoncom.PumpWaitingMessages()
def logout(self):
XASessionHandler.login_state = 0
self.xa_session_handler.DisconnectServer()
ebest = EBest()
ebest.login()
# ebest.login(1) : 이제는 mode가 필요없게 되었습니다. (mode=0:실서버, mode=1:모의서버)
이제 파이썬으로 자동 주식 트레이딩하기.. 종류의 책들에서 흔히 볼 수 있는 코드가 나왔습니다.
앞에서 다룬 코드를 보셨으니 이번 코드는 쉽게 이해하실 수 있을것입니다.
이 코드를 실행해보면...
이렇게 모의투자 참가신청을 하라고 합니다.
그냥 계정만 만든 것으로는 로그인되지 않네요.
이베스트 사이트에 방문해서 참가신청을 하고 나면...
위와 같이 에러메시지 형태로 로그인 성공 메시지가 날아오게 됩니다.
여기까지 해서 XingAPI의 경우 COM을 이용하여 로그인하는 과정을 살펴보았습니다.
다음 글에서는 주가데이터를 읽어보도록 하겠습니다.
'기타 > 주가분석' 카테고리의 다른 글
증권사 API로 시스템에 접근하기 (0) | 2021.02.24 |
---|---|
증권사별 Open API (0) | 2021.02.19 |
주가 데이터를 읽어오기 위해서는 32bit 파이썬이 필요하다. (1) | 2021.02.18 |
AI를 활용해서 주가 예측 시스템을 개발해보자 (2) (0) | 2020.12.29 |
AI를 활용해서 주가 예측 시스템을 개발해보자 (1) (1) | 2020.12.15 |