PYTHON/Kiwoom Open API

키움증권 Open API 거래일자 데이터 얻기 (1)

  • -

오늘도 역시 결론부터 설명하자면, 키움증권 Open API 내에서는 거래일자를 조회할 수 있는 함수가 제공되지 않고 있다. 그니까, 특정 일자를 변수로 입력해주면 해당 일자가 거래일인지 아닌지를 반환하는 함수가 제공되지 않는다는 것이다. 우리는 간혹 거래를 진행하다 보면 특정 일자가 거래가 진행되는 날인지 아닌지를 파악해야 하는 경우가 분명 존재하는데, 키움증권의 Open API는 그런 기능을 제공하지 않고 있다는 것이다.

물론 그 이유에 대해서는 알 수 없다. 다만 우리가 특정 일자가 거래일자였는지를 확인하고자 하는 이유는 바로 거래일이라는 개념이 거래를 진행하는 데에 있어 생각보다 큰 영향력을 갖기 때문이다.

예를 들어 미수를 통해 특정 종목에 비중을 실어 매수를 하는 알고리즘이 있다고 했을 때 매수한 날로부터 3일이 되는 날에는 장이 시작됨과 동시에 9시가 되자마자 자동적으로 시장가에 반대 매매가 진행되기 때문에 그 전에 매도가 이루어져야 한다. 뿐만 아니라 본인의 경우에도  ①너무 짧은 기간에 수익이 발생한다면 짧은 수익률만 확정적으로 챙기고 매도하거나  ②너무 긴 기간 동안 수익이 없을 경우 손실만 아니라면 매도하는 경우들이 존재한다. 이 때 사용하는 개념이 바로 "거래일"이다. 

하지만 앞서 이야기했듯이, 키움증권 Open API 내에는 거래일을 계산해주는 함수가 제공되지 않고 있다. 그렇다면 우리는 어떤 방법으로 거래일을 계산한다는 것일까?

 

 

뭐겠어, 꼼수지

당연히 꼼수다보니 데이터 조회의 한계점은 있기 마련이다.

  • 특정 일자를 입력했을 때 해당 일자가 거래일이었는지 아닌지를 반환해주는 것은 아니다.
  • 프로그램을 키지 않으면 거래일 데이터가 쌓이지 않는다. 즉, 거래일이 비어있을 수 있다.

키움증권 Open API 내에서는 실시간 데이터 함수 내에서   realtype == "장시작시간"  이라는 데이터를 제공해주고 있는데, 이는 실시간 등록을 해야 하는 여타 유형의 데이터와는 달리 별도의 실시간 등록 절차가 없더라도 자동적으로 8시 30분부터 9시까지 주기적으로 데이터를 발생시킨다고 한다. 

우리는 이 데이터가 발생했을 때에만 오늘의 날짜를 텍스트 파일에 입력할 것이고, 추후 그 텍스트 파일을 불러와서 우리가 조회하고자 하는 일자의 데이터가 해당 텍스트 파일 안에 입력되어 있는가를 판단함으로써 거래일을 계산해낼 수 있다.

그래도 우리가 텍스트 파일 내에 직접 데이터를 입력해줄 수 있기 때문에 만약 프로그램을 실행시키지 못해 거래일 데이터가 입력되어 있지 않다고 하더라도 직접 입력해주면 될 일이기 때문에 거래일자 데이터를 관리하기에는 편리할 것이다.

 

 

뭐해? 이제 만들어야지

일단 텍스트 파일을 만드는 방법과 텍스트 파일에 데이터를 입력하는 방법, 그리고 그 텍스트 파일을 불러오는 방법은 다양한 곳에서 다양한 방식으로 설명하고 있으니 본인이 알고 있는 방법이 있다면 그 방법대로 해도 된다.

텍스트 파일의 생성과 삭제, 그리고 파일 경로의 조회 등과 같은 부분은 아래의 게시글을 참고하였다.

아래는 폴더나 텍스트 파일을 생성하거나 수정하기 위해 제작한 코드 전문이며, 파일명은   manage_folder.py  로 작성했다.

## 파일명 : manage_folder.py
import os
import shutil

dir = os.getcwd()

def create_folder(name):
	object_dir = dir + "/" + name
	if not os.path.exists(object_dir):
		os.makedirs(object_dir)

def reset_folder(name):
	object_dir = dir + "/" + name
	if os.path.exists(object_dir):
		shutil.rmtree(object_dir)
		os.makedirs(object_dir)

def delete_folder(name):
	object_dir = dir + "/" + name
	if os.path.exists(object_dir):
		shutil.rmtree(object_dir)

def load_file_list(name):
	object_dir = dir + "/" + name
	if os.path.exists(object_dir):
		file_list = os.listdir(object_dir)
		return file_list

def append_text(name, file_name, text):
	object_dir = dir + "/" + name
	if os.path.exists(object_dir):
		file_name_txt = object_dir + "/" + file_name + ".txt"
		with open(file_name_txt, "a") as f:
			f.write(str(text))

def read_text(name, file_name):
	object_dir = dir + "/" + name
	if os.path.exists(object_dir):
		file_name_txt = object_dir + "/" + file_name + ".txt"
		text = open(file_name_txt, 'rt')
		data = text.readlines()
		print(data)

 

 


728x90

 

 

그럼 이제 실시간 데이터 내에서 데이터를 한 번 입력해보자.

실시간 데이터를 처리하는 방법은 단순하게 OnReceiveRealData 이벤트가 발생했을 때 특정 함수로 연결한 후 해당 함수 내에서 데이터를 처리하면 된다.

self.kiwoom.OnReceiveRealData.connect(self.receive_realdata)  ## 실시간 데이터 처리 함수

## 실시간데이터 발생 지점
def receive_realdata(self, jongmokcode, realtype, realdata):
	## 기타 데이터들 처리하기
	if realtype == "주식체결":
		pass

	if realtype == "장시작시간":
	## 8시 30분부터 9시까지 주기적으로 데이터가 수신됨
		trade_gubun = self._getcommrealdata(jongmokcode, 215)  ## 0:장시작전, 2:장종료전, 3:장시작, 4,8:장종료, 9:장마감
		# trade_time = self._getcommrealdata(jongmokcode, 20)        ## 체결시간(HHMMSS)(미사용)
		# remain_time = self._getcommrealdata(jongmokcode, 214)      ## 장시작 예상 잔여시간(미사용)

		if trade_gubun == 0:
			self.lineEdit_4.setText("장시작 전")
		if trade_gubun == 2:
			self.lineEdit_4.setText("장종료 전")
		if trade_gubun == 3:
			self.lineEdit_4.setText("장 시작")
		if trade_gubun == 4 or 8:
			self.lineEdit_4.setText("장 종료")
		if trade_gubun == 9:
			self.lineEdit_4.setText("장 마감")

 

위의 코드를 보면, realtype == "장시작시간"이라는 실시간 데이터가 발생했을 때 세부 데이터는 FID 번호가 215일 경우 장시작전, 장종료전 등과 같은 데이터를 반환한다. 본인은 이 데이터를 trade_gubun이라는 변수 내에 입력한 후, 해당 변수의 데이터가 무엇인가에 따라 다른 데이터들이 출력되도록 설정했다. 자세한 내용은 아래와 같다.

  • FID 215가 0인 경우 : "장시작전"
  • FID 215가 2인 경우 : "장종료전"
  • FID 215가 3인 경우 : "장시작"
  • FID 215가 4, 8인 경우 : "장종료"
  • FID 215가 9인 경우 : "장마감"

우리는 여기서 "장시작전"이라는 데이터가 발생하면 거래일자 텍스트 파일 안에 오늘의 날짜를 입력해주면 된다. 만약 장 마감 후에 당일의 거래일자를 입력하고 싶다면   if trade_gubun == 9:  의 하단부에 제작해주면 된다. 

 

 

텍스트 파일에 날짜 데이터를 입력해보자.

날짜 데이터를 계산하는 코드도 다양한 게시글에서 다뤄주고 있으니 여기서는 본인이 참고한 게시글의 링크만 남겨놓도록 할 것이므로 해당 게시글을 통해 날짜 데이터를 제작한 후에 넘어오도록 하자.

그렇다면 날짜 데이터를 계산하는 코드는 이미 구축했다고 가정하고, 이제 특정 텍스트 파일 내에 날짜 데이터를 입력해보도록 하자. 위의   manage_folder.py  파일 내에 있는 함수 중   def append_text()  를 사용하면 텍스트 파일이 없다면 텍스트 파일을 생성한 후에 데이터를 입력하고, 텍스트 파일이 있다면 해당 텍스트 파일에 데이터를 입력하니 간편하게 텍스트 파일을 관리할 수 있다.

다만   def append_text()  함수의 경우에는 텍스트 파일을 생성할 폴더가 없다면 오류가 발생할 수 있으니,   manage_folder  를 import한 후에 프로그램이 실행되기 전에 앞서 "거래일 데이터"라는 폴더를 자동적으로 생성하도록 하는 코드를 구축하자.

from web_crawler import manage_folder as mf
mf.create_folder("거래일데이터")

 

그 후에 다시   realtype == "장시작시간"  부분으로 내려와서,   def append_text()  를 이용해서 데이터를 입력해주면 된다. def append_text() 함수는 세 개의 인자를 전달받도록 제작했는데, 각각의 자리에는 "폴더명", "파일명", "입력할 데이터"가 위치하므로 자리에 맞게 데이터를 입력해주면 된다.

if realtype == "장시작시간":
	## 8시 30분부터 9시까지 주기적으로 데이터가 수신됨
	trade_gubun = self._getcommrealdata(jongmokcode, 215)  ## 0:장시작전, 2:장종료전, 3:장시작, 4,8:장종료, 9:장마감
	# trade_time = self._getcommrealdata(jongmokcode, 20)        ## 체결시간(HHMMSS)
	# remain_time = self._getcommrealdata(jongmokcode, 214)      ## 장시작 예상 잔여시간

	if trade_gubun == 0:
		self.lineEdit_4.setText("장시작 전")
		mf.append_text("거래일데이터", "trade_date", datee)
	if trade_gubun == 2:
		self.lineEdit_4.setText("장종료 전")
	if trade_gubun == 3:
		self.lineEdit_4.setText("장 시작")
	if trade_gubun == 4 or 8:
		self.lineEdit_4.setText("장 종료")
	if trade_gubun == 9:
		self.lineEdit_4.setText("장 마감")
		# mf.append_text("거래일데이터", "trade_date", datee) ## 장마감 후 데이터를 입력하고 싶다면 여기에 제작

 

이제 실시간데이터 중 realtype == "장시작시간"이라는 데이터가 발생했을 때 trade_gubun == 0이라는 조건이 충족된다면 manage_folder.py가 위치한 폴더 내에 "거래일데이터"라는 폴더가 생성된 후, 해당 폴더 안에는 "trade_date.txt"라는 텍스트 파일이 생성될 것이고 그 파일 안에는 datee라는 거래일 데이터가 입력될 것이다.

다음 게시글에서는 해당 텍스트 파일 내에 데이터가 올바르게 입력되어 있는지 그리고 해당 텍스트 파일 내에 임의의 거래일 데이터를 입력한 후 실제 거래일인지 아닌지를 판단하는 코드를 구축할 예정이다.

 


728x90
반응형
Contents

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

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