대신증권 CYBOS PLUS 시작하기 (6) - 분봉차트 데이터 조회하기
학습 목표
- 차트를 조회하는 여러 가지 방법
- 하나의 함수로 분봉부터 일봉 주봉 월봉까지 모두 다 해결할 수 있을까 ?
- 분봉 차트 데이터 조회하기
지난 게시글에서 일봉 차트 데이터를 조회하는 방법에 대하여 살펴봤었는데, 사실 분봉 차트 데이터를 조회하는 방법도 숙지하고 있어야 한다. 간단하게 결론부터 설명하자면 분봉 차트 데이터는 `SetInputValue(6, ord("D"))` 부분에 있는 "D"를 "m"으로 변경해주기만 하면 되고, 주봉은 "W"로, 월봉은 "M"으로 변경해주면 된다. 각각 Day, min, Week, Month의 약자이므로 이 부분은 크게 어렵지 않다. 다만 요청하고자 하는 데이터의 형태에 따라 각기 다른 형태의 데이터를 전달받아야 한다는 점이 문제이다. 즉, 분봉 차트 데이터를 요청할 경우 기본적으로 우리가 사전에 요청했던 '날짜' 데이터만으로는 판단이 불가하고, 날짜 데이터와 더불어 시간 데이터가 필요할 것이다. 예를 들면, 2024.01.01. 09:00.00이나 2024.01.01. 09:03:00과 같은 데이터가 없다면 우리는 그 데이터가 어느 시점의 데이터인지 확인할 수 없기 때문이다. 물론, 주봉이나 월봉의 경우에는 일봉 차트 데이터의 조회 방식과 비교하면 주의해야 할 점은 없고, 요청 구분을 기간으로 하지 않고 개수로 변경한 후 ord("D")에서 "D" 부분을 "W", "M"으로만 변경해주면 올바르게 조회할 수 있다.
(1) 차트를 조회하는 여러 가지 방법
앞서 살펴봤듯이, 차트 데이터를 조회할 때에는 `SetInputValue(6, ord("D"))` 부분의 ord("D") 부분을 ord("W") 또는 ord("M")과 같은 형태로 변경함으로써 주봉이나 월봉 차트 데이터를 요청할 수 있다. 하지만 앞서 작성했던 일봉 차트 조회 요청 코드와 같이 기간으로 조회하는 것은 기본적으로 `SetInputValue(1, ord("1"))`과 같은 형태의 코드가 반드시 포함되어야 하는데, 이전 게시글에서 인자값에 대해 살펴보았듯이 요청 구분을 기간으로 설정할 경우에는 일봉 차트 데이터만 조회할 수 있다. 즉, 주봉, 월봉, 분봉, 틱봉은 기간으로 하여 조회할 수 없고 개수로만 조회할 수 있다는 것이다. 그렇다면 주봉 데이터를 조회하기 위해서는 어떠한 방식으로 사용해야 할까 ? 아래의 코드를 확인해보자.
※ Line: 25, 26, 27, 28, 30, 31
import win32com.client
class cybos:
def __init__(self):
self.cybos = win32com.client.Dispatch("CpUtil.CpCybos") ## COM 연결
self.stockcode = win32com.client.Dispatch("CpUtil.CpStockCode") ## COM 연결
self.trade = win32com.client.Dispatch("CpTrade.CpTdUtil") ## COM 연결
self.codemgr = win32com.client.Dispatch("CpUtil.CpCodeMgr") ## COM 연결
self.stockmst = win32com.client.Dispatch("DsCbo1.StockMst") ## COM 연결
self.stockchart = win32com.client.Dispatch("CpSysDib.StockChart") ## COM 연결
self._StockChart("A005930", "20240101", "20240401")
def _StockChart(self, item_code, start_date, end_date):
"""
Type:5 (반환 데이터의 배열)
0: 날짜, 1: 시간(HHMM), 2: 시가, 3: 고가, 4: 저가, 5: 종가, 6: 전일 대비(37과 함께 사용)
8: 거래량, 9: 거래대금, 10: 누적체결매도수량(분 및 틱), 11: 누적체결매수수량(분 및 틱), 12: 상장주식수
13: 시가총액, 14: 외국인 주문 한도 수량, 15: 외국인 주문 가능 수량, 16: 외국인 현재 보유 수량, 17: 외국인 현재 보유 비율
18: 수정주가일자(YYYYMMDD), 19: 수정주가 비율, 20: 기관 순매수, 21: 기관누적순매수, 22: 등락주선, 23: 등락비율,
24: 예탁금, 25: 주식 회전율, 26: 거래성립률, 37: 대비 부호,
62: 누적체결 매도수량(분 및 틱만 제공, 체결가 비교 방식의 누적체결매도수량)
63: 누적체결 매수수량(분 및 틱만 제공, 체결가 비교 방식의 누적체결매수수량)
"""
self.stockchart.SetInputValue(0, item_code) ## 종목코드
self.stockchart.SetInputValue(1, ord("2")) ## 요청 구분
# self.stockchart.SetInputValue(2, end_date) ## 요청 종료일
# self.stockchart.SetInputValue(3, start_date) ## 요청 시작일
self.stockchart.SetInputValue(4, 10) ## 요청 개수
self.stockchart.SetInputValue(5, [0, 2, 3, 4, 5, 8, 9, 6, 37]) ## 데이터 배열
self.stockchart.SetInputValue(6, ord("W")) ## 차트 구분('D': 일봉, 'W': 주봉, 'M': 월봉, 'm': 분봉, 'T': 틱)
# self.stockchart.SetInputValue(7, ord("7")) ## 주기
self.stockchart.SetInputValue(8, ord("0")) ## 갭 보정 여부(0: 보정 X, 1: 보정 O)
self.stockchart.SetInputValue(9, ord("0")) ## 수정주가 여부(0: 수정 X, 1: 수정 O)
self.stockchart.SetInputValue(10, ord("1")) ## 거래량 구분
self.stockchart.SetInputValue(11, ord("N")) ## 조기 적용 여부
self.stockchart.BlockRequest() ## 데이터 요청
len_fild = self.stockchart.GetHeaderValue(1) ## 요청한 필드 개수
array_fild = self.stockchart.GetHeaderValue(2) ## 팔드 배열
len = self.stockchart.GetHeaderValue(3) ## 데이터 개수 확인
for index in range(len):
date = self.stockchart.GetDataValue(0, index) ## 날짜(0)
open = self.stockchart.GetDataValue(1, index) ## 시가(2)
high = self.stockchart.GetDataValue(2, index) ## 고가(3)
low = self.stockchart.GetDataValue(3, index) ## 저가(4)
close = self.stockchart.GetDataValue(4, index) ## 종가(5)
dif = self.stockchart.GetDataValue(5, index) ## 전일대비(6)
vol = self.stockchart.GetDataValue(6, index) ## 거래량(8)
tvol = self.stockchart.GetDataValue(7, index) ## 거래대금(9)
pm = self.stockchart.GetDataValue(8, index) ## 대비 부호(37)
print(f"[{date}] 시:{open}, 고:{high}, 저:{low}, 종:{close}, 거래량:{vol}, 거래대금:{tvol}, 전일대비:{dif}({pm})")
▶ 실행 결과 확인하기
[20240740] 시:81600, 고:86100, 저:79500, 종:79600, 거래량:119211983, 거래대금:9717243000000, 전일대비:0(48)
[20240730] 시:84400, 고:84900, 저:80100, 종:80900, 거래량:86525177, 거래대금:7110609000000, 전일대비:0(48)
[20240720] 시:84700, 고:88000, 저:83800, 종:84400, 거래량:102837170, 거래대금:8828189000000, 전일대비:0(48)
[20240710] 시:87900, 고:88800, 저:84100, 종:84400, 거래량:114207851, 거래대금:9934942000000, 전일대비:0(48)
[20240650] 시:81500, 고:87100, 저:81000, 종:87100, 거래량:126877856, 거래대금:10675569000000, 전일대비:0(48)
[20240640] 시:79700, 고:81900, 저:79500, 종:81500, 거래량:73521576, 거래대금:5943735000000, 전일대비:0(48)
[20240630] 시:79200, 고:82500, 저:78000, 종:80000, 거래량:96695948, 거래대금:7780815000000, 전일대비:0(48)
[20240620] 시:76100, 고:80500, 저:75100, 종:79600, 거래량:107507071, 거래대금:8329654000000, 전일대비:0(48)
[20240610] 시:74400, 고:78600, 저:74200, 종:77300, 거래량:74171638, 거래대금:5691943000000, 전일대비:0(48)
[20240540] 시:75300, 고:78200, 저:73500, 종:73500, 거래량:147359198, 거래대금:11109104000000, 전일대비:0(48)
위와 같이 주봉 차트에 대해서 개수를 설정하여 차트 데이터를 조회하도록 하였는데, 기본적으로 `SetInputValue()` 함수의 인자 중 Type값이 1인 요청 구분에 대해 일정 기간 범위가 아닌 개수(ord("2"))를 전달해주었기 때문에 위의 코드에서는 ord("W")로 기재되어 있는 부분을 ord("M")으로 바꾸어주면 월봉을 기준으로 10개의 데이터를 조회하게 된다.
※ Line: 30
import win32com.client
class cybos:
def __init__(self):
self.cybos = win32com.client.Dispatch("CpUtil.CpCybos") ## COM 연결
self.stockcode = win32com.client.Dispatch("CpUtil.CpStockCode") ## COM 연결
self.trade = win32com.client.Dispatch("CpTrade.CpTdUtil") ## COM 연결
self.codemgr = win32com.client.Dispatch("CpUtil.CpCodeMgr") ## COM 연결
self.stockmst = win32com.client.Dispatch("DsCbo1.StockMst") ## COM 연결
self.stockchart = win32com.client.Dispatch("CpSysDib.StockChart") ## COM 연결
self._StockChart("A005930", "20240101", "20240401")
def _StockChart(self, item_code, start_date, end_date):
"""
Type:5 (반환 데이터의 배열)
0: 날짜, 1: 시간(HHMM), 2: 시가, 3: 고가, 4: 저가, 5: 종가, 6: 전일 대비(37과 함께 사용)
8: 거래량, 9: 거래대금, 10: 누적체결매도수량(분 및 틱), 11: 누적체결매수수량(분 및 틱), 12: 상장주식수
13: 시가총액, 14: 외국인 주문 한도 수량, 15: 외국인 주문 가능 수량, 16: 외국인 현재 보유 수량, 17: 외국인 현재 보유 비율
18: 수정주가일자(YYYYMMDD), 19: 수정주가 비율, 20: 기관 순매수, 21: 기관누적순매수, 22: 등락주선, 23: 등락비율,
24: 예탁금, 25: 주식 회전율, 26: 거래성립률, 37: 대비 부호,
62: 누적체결 매도수량(분 및 틱만 제공, 체결가 비교 방식의 누적체결매도수량)
63: 누적체결 매수수량(분 및 틱만 제공, 체결가 비교 방식의 누적체결매수수량)
"""
self.stockchart.SetInputValue(0, item_code) ## 종목코드
self.stockchart.SetInputValue(1, ord("2")) ## 요청 구분
# self.stockchart.SetInputValue(2, end_date) ## 요청 종료일
# self.stockchart.SetInputValue(3, start_date) ## 요청 시작일
self.stockchart.SetInputValue(4, 10) ## 요청 개수
self.stockchart.SetInputValue(5, [0, 2, 3, 4, 5, 8, 9, 6, 37]) ## 데이터 배열
self.stockchart.SetInputValue(6, ord("M")) ## 차트 구분('D': 일봉, 'W': 주봉, 'M': 월봉, 'm': 분봉, 'T': 틱)
# self.stockchart.SetInputValue(7, ord("7")) ## 주기
self.stockchart.SetInputValue(8, ord("0")) ## 갭 보정 여부(0: 보정 X, 1: 보정 O)
self.stockchart.SetInputValue(9, ord("0")) ## 수정주가 여부(0: 수정 X, 1: 수정 O)
self.stockchart.SetInputValue(10, ord("1")) ## 거래량 구분
self.stockchart.SetInputValue(11, ord("N")) ## 조기 적용 여부
self.stockchart.BlockRequest() ## 데이터 요청
len_fild = self.stockchart.GetHeaderValue(1) ## 요청한 필드 개수
array_fild = self.stockchart.GetHeaderValue(2) ## 팔드 배열
len = self.stockchart.GetHeaderValue(3) ## 데이터 개수 확인
for index in range(len):
date = self.stockchart.GetDataValue(0, index) ## 날짜(0)
open = self.stockchart.GetDataValue(1, index) ## 시가(2)
high = self.stockchart.GetDataValue(2, index) ## 고가(3)
low = self.stockchart.GetDataValue(3, index) ## 저가(4)
close = self.stockchart.GetDataValue(4, index) ## 종가(5)
dif = self.stockchart.GetDataValue(5, index) ## 전일대비(6)
vol = self.stockchart.GetDataValue(6, index) ## 거래량(8)
tvol = self.stockchart.GetDataValue(7, index) ## 거래대금(9)
pm = self.stockchart.GetDataValue(8, index) ## 대비 부호(37)
print(f"[{date}] 시:{open}, 고:{high}, 저:{low}, 종:{close}, 거래량:{vol}, 거래대금:{tvol}, 전일대비:{dif}({pm})")
▶ 실행 결과 확인하기
[20240800] 시:86000, 고:86100, 저:79500, 종:79600, 거래량:72500888, 거래대금:5906232000000, 전일대비:0(48)
[20240700] 시:81500, 고:88800, 저:80000, 종:83900, 거래량:477159149, 거래대금:40360321000000, 전일대비:0(48)
[20240600] 시:74400, 고:82500, 저:74200, 종:81500, 거래량:351896233, 거래대금:27746149000000, 전일대비:0(48)
[20240500] 시:77600, 고:81500, 저:73500, 종:73500, 거래량:421088782, 거래대금:32637189000000, 전일대비:0(48)
[20240400] 시:83200, 고:86000, 저:75100, 종:77500, 거래량:484342028, 거래대금:39201159000000, 전일대비:0(48)
[20240300] 시:74300, 고:82500, 저:71700, 종:82400, 거래량:448361736, 거래대금:34211193000000, 전일대비:0(48)
[20240200] 시:73000, 고:75500, 저:72000, 종:73400, 거래량:298955484, 거래대금:22030118000000, 전일대비:0(48)
[20240100] 시:78200, 고:79800, 저:70700, 종:72700, 거래량:397638759, 거래대금:29593792000000, 전일대비:0(48)
[20231200] 시:72400, 고:78500, 저:71100, 종:78500, 거래량:254875780, 거래대금:18885776000000, 전일대비:0(48)
[20231100] 시:67500, 고:73400, 저:67300, 종:72800, 거래량:273455511, 거래대금:19473918000000, 전일대비:0(48)
결과 데이터를 보면 날짜 부분이 일 데이터는 없고 년도와 월까지만 표기된 것을 확인할 수 있다. 그렇다면 우리는 매번 이렇게 값을 변경해주면서 데이터를 확인해야 할까? 아니다. 하나의 함수 내에서 모두 해결할 수 있는 방법을 찾아보도록 하자.
(2) 하나의 함수로 분봉부터 일봉 주봉 월봉까지 모두 다 해결할 수 있을까 ?
일단 이 질문에 대한 정답을 말하자면 '가능하다.'이다. 하지만 함수를 여러 개를 작성하느냐 아니면 한 개만 작성하느냐에 따라 코드의 줄 수는 크게 다르지 않다. 다만 하나의 함수 내에서 모든 기능을 구현하게 된다면 그만큼 추후에 문제가 발생했을 때 어느 부분에서 문제가 발생했는지 알 수 없기 때문에 내용을 수정하기 어렵다는 단점과 매번 다양한 인자를 전달해주어야 한다는 단점이 있지만 함수를 호출할 때에는 한 가지 함수만 사용하면 되기 때문에 함수 호출 측면에서는 훨씬 유리하다. 다만 함수를 각기 다른 기능을 넣어서 구현하게 될 경우에는 기본적으로 중복되는 코드가 많아지기 때문에 절대적인 코드의 줄 수가 길어진다는 단점도 있고, 호출할 때마다 각각의 기능을 품고 있는 함수를 호출하고 각각의 함수에 적절한 인자를 전달해주어야 한다는 단점이 있다.
어떠한 구조의 함수를 구현하던지 간에 기본적으로 ① 기간을 대상으로 하는 일봉 차트 조회 기능, ② 개수를 대상으로 하는 일봉·주봉·월봉 차트 조회 기능, ③ 개수를 대상으로 하는 분봉 차트 조회 기능이라는 세 가지 기능을 기준으로 함수를 포괄적으로 작성하는 것을 권장한다. 이 세 가지 기능을 기준으로 하나의 함수 안에 모두 구현할 것인지 아니면 각각의 기능을 가진 세 개의 함수를 구현할 것인지는 개인의 선택이다. 필자는 각각의 기능에 따라 데이터 요청을 할 때 달리 요청해야 하는 부분이 있다는 점과 수신 데이터 역시도 각기 다르다는 점을 고려하여 기능에 따라 세 가지 함수를 구현하기로 결정했다. 이 중 첫 번째 기능(기간을 대상으로 하는 일봉 차트 조회)을 가진 함수는 이전에 구현하였으니 함수 이름만 다른 이름으로 바꿔준 후, 두 번째 기능(개수를 대상으로 하는 일봉·주봉·월봉 차트 조회)을 가진 함수를 구현해보도록 하자.
※ 기존에 제작했던 함수인 `def _StockChart(self):`는 `def _StockChart_day_range(self):`로 변경했다.
해당 함수의 인자로 전달받을 인자 목록은 가장 먼저 종목코드(`item_code`)가 있고, 그 다음으로는 요청 구분(`request`), 마지막으로는 조회할 데이터의 개수(`num`)의 세 가지이다. 이제 이 함수를 사용할 때에는 종목코드와 더불어 요청 구분을 일봉이라면 "D"를, 주봉이라면 "W"를, 월봉이라면 "M"를 전달하여 주면 된다. 이 함수의 경우에는 앞전에 제작한 함수와는 달리 사전에 전달받은 인자가 올바른 형태로 전달되었는지를 확인하기 위해 조건문을 추가(Line: 2)하여 "D", "W", "M" 셋 중 한 가지 형태만 인자로 전달받았을 때 그 하단의 코드가 실행되도록 하였다.
def _StockChart_num(self, item_code, request, num):
if request in ["D", "W", "M"]:
self.stockchart.SetInputValue(0, item_code) ## 종목코드
self.stockchart.SetInputValue(1, ord("2")) ## 요청 구분
self.stockchart.SetInputValue(4, num) ## 요청 개수
self.stockchart.SetInputValue(5, [0, 2, 3, 4, 5, 8, 9]) ## 요청 데이터 배열
self.stockchart.SetInputValue(6, ord(f"{request}")) ## 차트 구분("D", "W", "M:)
self.stockchart.SetInputValue(8, ord("0")) ## 갭 보정 여부(0: 보정 X, 1: 보정 O)
self.stockchart.SetInputValue(9, ord("0")) ## 수정주가 여부(0: 수정 X, 1: 수정 O)
self.stockchart.SetInputValue(10, ord("1")) ## 거래량 구분
self.stockchart.SetInputValue(11, ord("N")) ## 조기 적용 여부
self.stockchart.BlockRequest() ## 데이터 요청
len_fild = self.stockchart.GetHeaderValue(1) ## 요청한 필드 개수
array_fild = self.stockchart.GetHeaderValue(2) ## 팔드 배열
len = self.stockchart.GetHeaderValue(3) ## 데이터 개수 확인
print(f"필드 개수:{len_fild}({array_fild}), 데이터 개수:{len}")
for index in range(len):
date = self.stockchart.GetDataValue(0, index) ## 날짜(0)
open = self.stockchart.GetDataValue(1, index) ## 시가(2)
high = self.stockchart.GetDataValue(2, index) ## 고가(3)
low = self.stockchart.GetDataValue(3, index) ## 저가(4)
close = self.stockchart.GetDataValue(4, index) ## 종가(5)
vol = self.stockchart.GetDataValue(5, index) ## 거래량(8)
tvol = self.stockchart.GetDataValue(6, index) ## 거래량(9)
print(f"[{date}] 시:{open}, 고:{high}, 저:{low}, 종:{close}, 거래량:{vol}, 거래대금:{tvol}")
else:
return False
이제 함수의 제작이 완료되었다면 함수를 실행해보자.
※ Line: 14~42
import win32com.client
class cybos:
def __init__(self):
self.cybos = win32com.client.Dispatch("CpUtil.CpCybos") ## COM 연결
self.stockcode = win32com.client.Dispatch("CpUtil.CpStockCode") ## COM 연결
self.trade = win32com.client.Dispatch("CpTrade.CpTdUtil") ## COM 연결
self.codemgr = win32com.client.Dispatch("CpUtil.CpCodeMgr") ## COM 연결
self.stockmst = win32com.client.Dispatch("DsCbo1.StockMst") ## COM 연결
self.stockchart = win32com.client.Dispatch("CpSysDib.StockChart") ## COM 연결
# self._StockChart_day("A005930", "20240101", "20240401")
self._StockChart_num("A005930", "D", 10)
def _StockChart_num(self, item_code, request, num):
if request in ["D", "W", "M"]:
self.stockchart.SetInputValue(0, item_code) ## 종목코드
self.stockchart.SetInputValue(1, ord("2")) ## 요청 구분
self.stockchart.SetInputValue(4, num) ## 요청 개수
self.stockchart.SetInputValue(5, [0, 2, 3, 4, 5, 8, 9]) ## 요청 데이터 배열
self.stockchart.SetInputValue(6, ord(f"{request}")) ## 차트 구분("D", "W", "M:)
self.stockchart.SetInputValue(8, ord("0")) ## 갭 보정 여부(0: 보정 X, 1: 보정 O)
self.stockchart.SetInputValue(9, ord("0")) ## 수정주가 여부(0: 수정 X, 1: 수정 O)
self.stockchart.SetInputValue(10, ord("1")) ## 거래량 구분
self.stockchart.SetInputValue(11, ord("N")) ## 조기 적용 여부
self.stockchart.BlockRequest() ## 데이터 요청
len_fild = self.stockchart.GetHeaderValue(1) ## 요청한 필드 개수
array_fild = self.stockchart.GetHeaderValue(2) ## 팔드 배열
len = self.stockchart.GetHeaderValue(3) ## 데이터 개수 확인
print(f"필드 개수:{len_fild}({array_fild}), 데이터 개수:{len}")
for index in range(len):
date = self.stockchart.GetDataValue(0, index) ## 날짜(0)
open = self.stockchart.GetDataValue(1, index) ## 시가(2)
high = self.stockchart.GetDataValue(2, index) ## 고가(3)
low = self.stockchart.GetDataValue(3, index) ## 저가(4)
close = self.stockchart.GetDataValue(4, index) ## 종가(5)
vol = self.stockchart.GetDataValue(5, index) ## 거래량(8)
tvol = self.stockchart.GetDataValue(6, index) ## 거래량(9)
print(f"[{date}] 시:{open}, 고:{high}, 저:{low}, 종:{close}, 거래량:{vol}, 거래대금:{tvol}")
else:
return False
▶ 실행 결과 확인하기
필드 개수:7(('날짜', '시가', '고가', '저가', '종가', '거래량', '거래대금')), 데이터 개수:10
[20240802] 시:81000, 고:81400, 저:79500, 종:79600, 거래량:25800275, 거래대금:2072583000000
[20240801] 시:86000, 고:86100, 저:83100, 종:83100, 거래량:20900338, 거래대금:1761066000000
[20240731] 시:81200, 고:83900, 저:80900, 종:83900, 거래량:20744323, 거래대금:1709905000000
[20240730] 시:80400, 고:81000, 저:80000, 종:81000, 거래량:13169636, 거래대금:1058509000000
[20240729] 시:81600, 고:82000, 저:81100, 종:81200, 거래량:12797136, 거래대금:1042595000000
[20240726] 시:80700, 고:81300, 저:80400, 종:80900, 거래량:14508334, 거래대금:1171301000000
[20240725] 시:80400, 고:81000, 저:80100, 종:80400, 거래량:20323811, 거래대금:1634938000000
[20240724] 시:82900, 고:83300, 저:81900, 종:82000, 거래량:16939083, 거래대금:1397137000000
[20240723] 시:84200, 고:84700, 저:83400, 종:83900, 거래량:15766389, 거래대금:1325673000000
[20240722] 시:84400, 고:84900, 저:82600, 종:83000, 거래량:18987560, 거래대금:1581559000000
(3) 분봉 차트 데이터 조회하기
분봉 차트 데이터의 경우에도 주봉 및 월봉 차트와 마찬가지로 기간을 대상으로 하여 조회할 순 없고 개수를 기준으로 하여 데이터를 조회할 수 있는데, 분봉 차트 데이터는 이외에도 '주기'라는 값을 입력해주어야 한다. 여기서의 주기란 흔히들 알고 있는 O분봉 차트를 이야기할 때 들어가는 O에 해당하는 값이다. 즉, 3분봉 차트라면 주기 값으로 3을 전달해주어야 한다는 것이다.
※ Line: 1, 2, 8
def _StockChart_min(self, item_code, request, tick, num):
if request in ["m", "T"]:
self.stockchart.SetInputValue(0, item_code) ## 종목코드
self.stockchart.SetInputValue(1, ord("2")) ## 요청 구분
self.stockchart.SetInputValue(4, num) ## 요청 개수
self.stockchart.SetInputValue(5, [0, 2, 3, 4, 5, 8, 9]) ## 요청 데이터 배열
self.stockchart.SetInputValue(6, ord(f"{request}")) ## 요청구분("m": 분봉, "T": 틱)
self.stockchart.SetInputValue(7, tick) ## 차트 주기
self.stockchart.SetInputValue(8, ord("0")) ## 갭 보정 여부(0: 보정 X, 1: 보정 O)
self.stockchart.SetInputValue(9, ord("0")) ## 수정주가 여부(0: 수정 X, 1: 수정 O)
self.stockchart.SetInputValue(10, ord("1")) ## 거래량 구분
self.stockchart.SetInputValue(11, ord("N")) ## 조기 적용 여부
self.stockchart.BlockRequest() ## 데이터 요청
len_fild = self.stockchart.GetHeaderValue(1) ## 요청한 필드 개수
array_fild = self.stockchart.GetHeaderValue(2) ## 팔드 배열
len = self.stockchart.GetHeaderValue(3) ## 데이터 개수 확인
print(f"필드 개수:{len_fild}({array_fild}), 데이터 개수:{len}")
for index in range(len):
date = self.stockchart.GetDataValue(0, index) ## 날짜(0)
open = self.stockchart.GetDataValue(1, index) ## 시가(2)
high = self.stockchart.GetDataValue(2, index) ## 고가(3)
low = self.stockchart.GetDataValue(3, index) ## 저가(4)
close = self.stockchart.GetDataValue(4, index) ## 종가(5)
vol = self.stockchart.GetDataValue(5, index) ## 거래량(8)
tvol = self.stockchart.GetDataValue(6, index) ## 거래량(9)
print(f"[{date}] 시:{open}, 고:{high}, 저:{low}, 종:{close}, 거래량:{vol}, 거래대금:{tvol}")
else:
return False
▶ 실행 결과 확인하기
필드 개수:7(('날짜', '시가', '고가', '저가', '종가', '거래량', '거래대금')), 데이터 개수:10
[20240802] 시:79600, 고:79600, 저:79600, 종:79600, 거래량:1309354, 거래대금:104224580000
[20240802] 시:79700, 고:79900, 저:79600, 종:79700, 거래량:579650, 거래대금:46220520000
[20240802] 시:79600, 고:79700, 저:79500, 종:79700, 거래량:452357, 거래대금:35998700000
[20240802] 시:79700, 고:79800, 저:79500, 종:79600, 거래량:451815, 거래대금:35992130000
[20240802] 시:79800, 고:79900, 저:79700, 종:79800, 거래량:448638, 거래대금:35798600000
[20240802] 시:79800, 고:79900, 저:79800, 종:79800, 거래량:144961, 거래대금:11576350000
[20240802] 시:79900, 고:79900, 저:79800, 종:79900, 거래량:175492, 거래대금:14018590000
[20240802] 시:79600, 고:79900, 저:79500, 종:79900, 거래량:437063, 거래대금:34825750000
[20240802] 시:79500, 고:79600, 저:79500, 종:79600, 거래량:223640, 거래대금:17789600000
[20240802] 시:79600, 고:79600, 저:79500, 종:79500, 거래량:184878, 거래대금:14704470000
결과 데이터를 봤는데 뭔가 이상하다는 걸 확인할 수 있다. 바로 날짜 데이터만 출력되고 있다는 것이다. 우리가 이전에 살펴봤던 `SetInputValue()` 함수 내에서 Type값 5의 인자로 전달할 수 있었던 데이터 중에 0은 종목코드, 2는 시가, 3은 고가를 의미했었는데 일봉과 주봉, 월봉에서는 빠져있었던 1이 바로 시간(HHMM) 데이터였다. 따라서 요청 데이터 배열에 1을 추가한 데이터를 수신해보도록 하자.
※ Line: 20, 35~43
import win32com.client
class cybos:
def __init__(self):
self.cybos = win32com.client.Dispatch("CpUtil.CpCybos") ## COM 연결
self.stockcode = win32com.client.Dispatch("CpUtil.CpStockCode") ## COM 연결
self.trade = win32com.client.Dispatch("CpTrade.CpTdUtil") ## COM 연결
self.codemgr = win32com.client.Dispatch("CpUtil.CpCodeMgr") ## COM 연결
self.stockmst = win32com.client.Dispatch("DsCbo1.StockMst") ## COM 연결
self.stockchart = win32com.client.Dispatch("CpSysDib.StockChart") ## COM 연결
# self._StockChart_day("A005930", "20240101", "20240401")
# self._StockChart_num("A005930", "D", 10)
self._StockChart_min("A005930", "m", 5, 10)
def _StockChart_min(self, item_code, request, tick, num):
if request in ["m", "T"]:
self.stockchart.SetInputValue(0, item_code) ## 종목코드
self.stockchart.SetInputValue(1, ord("2")) ## 요청 구분
self.stockchart.SetInputValue(4, num) ## 요청 개수
self.stockchart.SetInputValue(5, [0, 1, 2, 3, 4, 5, 8, 9]) ## 요청 데이터 배열
self.stockchart.SetInputValue(6, ord(f"{request}")) ## 요청구분("m": 분봉, "T": 틱)
self.stockchart.SetInputValue(7, tick) ## 차트 주기
self.stockchart.SetInputValue(8, ord("0")) ## 갭 보정 여부(0: 보정 X, 1: 보정 O)
self.stockchart.SetInputValue(9, ord("0")) ## 수정주가 여부(0: 수정 X, 1: 수정 O)
self.stockchart.SetInputValue(10, ord("1")) ## 거래량 구분
self.stockchart.SetInputValue(11, ord("N")) ## 조기 적용 여부
self.stockchart.BlockRequest() ## 데이터 요청
len_fild = self.stockchart.GetHeaderValue(1) ## 요청한 필드 개수
array_fild = self.stockchart.GetHeaderValue(2) ## 팔드 배열
len = self.stockchart.GetHeaderValue(3) ## 데이터 개수 확인
print(f"필드 개수:{len_fild}({array_fild}), 데이터 개수:{len}")
for index in range(len):
date = self.stockchart.GetDataValue(0, index) ## 날짜(0)
time = self.stockchart.GetDataValue(1, index) ## 시간(1)
open = self.stockchart.GetDataValue(2, index) ## 시가(2)
high = self.stockchart.GetDataValue(3, index) ## 고가(3)
low = self.stockchart.GetDataValue(4, index) ## 저가(4)
close = self.stockchart.GetDataValue(5, index) ## 종가(5)
vol = self.stockchart.GetDataValue(6, index) ## 거래량(8)
tvol = self.stockchart.GetDataValue(7, index) ## 거래량(9)
print(f"[{date} {time}] 시:{open}, 고:{high}, 저:{low}, 종:{close}, 거래량:{vol}, 거래대금:{tvol}")
else:
return False
▶ 실행 결과 확인하기
필드 개수:8(('날짜', '시간', '시가', '고가', '저가', '종가', '거래량', '거래대금')), 데이터 개수:10
[20240802 1530] 시:79600, 고:79600, 저:79600, 종:79600, 거래량:1309354, 거래대금:104224580000
[20240802 1520] 시:79700, 고:79900, 저:79600, 종:79700, 거래량:579650, 거래대금:46220520000
[20240802 1515] 시:79600, 고:79700, 저:79500, 종:79700, 거래량:452357, 거래대금:35998700000
[20240802 1510] 시:79700, 고:79800, 저:79500, 종:79600, 거래량:451815, 거래대금:35992130000
[20240802 1505] 시:79800, 고:79900, 저:79700, 종:79800, 거래량:448638, 거래대금:35798600000
[20240802 1500] 시:79800, 고:79900, 저:79800, 종:79800, 거래량:144961, 거래대금:11576350000
[20240802 1455] 시:79900, 고:79900, 저:79800, 종:79900, 거래량:175492, 거래대금:14018590000
[20240802 1450] 시:79600, 고:79900, 저:79500, 종:79900, 거래량:437063, 거래대금:34825750000
[20240802 1445] 시:79500, 고:79600, 저:79500, 종:79600, 거래량:223640, 거래대금:17789600000
[20240802 1440] 시:79600, 고:79600, 저:79500, 종:79500, 거래량:184878, 거래대금:14704470000
이제 모든 데이터가 정상적으로 출력되고 있음을 확인할 수 있다. 그렇다면 해당 기능이 올바르게 동작하는지 확인하기 위해 수신받을 데이터의 개수를 늘려보도록 하자. 현재 데이터를 요청하는 주기 기준인 5은 5분봉을 조회하겠다는 것인데, 하루 동안의 차트 데이터는 9시부터 시작하여 15시 30분까지 이루어지므로 390분에 해당하는 시간 동안의 차트 데이터가 발생하게 되고, 이를 5분으로 나누게 되면 78개의 봉이 발생한다. 그렇다면 우리는 조금 여유롭게 80개의 5분봉 차트 데이터를 수신해보도록 하자. 수신일 기준 전일의 차트 데이터까지 조회가 된다면 분봉 차트 데이터함수가 성공적으로 구현된 것이라 볼 수 있다.
import win32com.client
class cybos:
def __init__(self):
self.cybos = win32com.client.Dispatch("CpUtil.CpCybos") ## COM 연결
self.stockcode = win32com.client.Dispatch("CpUtil.CpStockCode") ## COM 연결
self.trade = win32com.client.Dispatch("CpTrade.CpTdUtil") ## COM 연결
self.codemgr = win32com.client.Dispatch("CpUtil.CpCodeMgr") ## COM 연결
self.stockmst = win32com.client.Dispatch("DsCbo1.StockMst") ## COM 연결
self.stockchart = win32com.client.Dispatch("CpSysDib.StockChart") ## COM 연결
# self._StockChart_day("A005930", "20240101", "20240401")
# self._StockChart_num("A005930", "D", 10)
self._StockChart_min("A005930", "m", 5, 80)
def _StockChart_min(self, item_code, request, tick, num):
if request in ["m", "T"]:
self.stockchart.SetInputValue(0, item_code) ## 종목코드
self.stockchart.SetInputValue(1, ord("2")) ## 요청 구분
self.stockchart.SetInputValue(4, num) ## 요청 개수
self.stockchart.SetInputValue(5, [0, 1, 2, 3, 4, 5, 8, 9]) ## 요청 데이터 배열
self.stockchart.SetInputValue(6, ord(f"{request}")) ## 요청구분("m": 분봉, "T": 틱)
self.stockchart.SetInputValue(7, tick) ## 차트 주기
self.stockchart.SetInputValue(8, ord("0")) ## 갭 보정 여부(0: 보정 X, 1: 보정 O)
self.stockchart.SetInputValue(9, ord("0")) ## 수정주가 여부(0: 수정 X, 1: 수정 O)
self.stockchart.SetInputValue(10, ord("1")) ## 거래량 구분
self.stockchart.SetInputValue(11, ord("N")) ## 조기 적용 여부
self.stockchart.BlockRequest() ## 데이터 요청
len_fild = self.stockchart.GetHeaderValue(1) ## 요청한 필드 개수
array_fild = self.stockchart.GetHeaderValue(2) ## 팔드 배열
len = self.stockchart.GetHeaderValue(3) ## 데이터 개수 확인
print(f"필드 개수:{len_fild}({array_fild}), 데이터 개수:{len}")
for index in range(len):
date = self.stockchart.GetDataValue(0, index) ## 날짜(0)
time = self.stockchart.GetDataValue(1, index) ## 시간(1)
open = self.stockchart.GetDataValue(2, index) ## 시가(2)
high = self.stockchart.GetDataValue(3, index) ## 고가(3)
low = self.stockchart.GetDataValue(4, index) ## 저가(4)
close = self.stockchart.GetDataValue(5, index) ## 종가(5)
vol = self.stockchart.GetDataValue(6, index) ## 거래량(8)
tvol = self.stockchart.GetDataValue(7, index) ## 거래량(9)
print(f"[{date} {time}] 시:{open}, 고:{high}, 저:{low}, 종:{close}, 거래량:{vol}, 거래대금:{tvol}")
else:
return False
▶ 실행 결과 확인하기
필드 개수:8(('날짜', '시간', '시가', '고가', '저가', '종가', '거래량', '거래대금')), 데이터 개수:80
[20240802 1530] 시:79600, 고:79600, 저:79600, 종:79600, 거래량:1309354, 거래대금:104224580000
[20240802 1520] 시:79700, 고:79900, 저:79600, 종:79700, 거래량:579650, 거래대금:46220520000
[20240802 1515] 시:79600, 고:79700, 저:79500, 종:79700, 거래량:452357, 거래대금:35998700000
[20240802 1510] 시:79700, 고:79800, 저:79500, 종:79600, 거래량:451815, 거래대금:35992130000
[20240802 1505] 시:79800, 고:79900, 저:79700, 종:79800, 거래량:448638, 거래대금:35798600000
[20240802 1500] 시:79800, 고:79900, 저:79800, 종:79800, 거래량:144961, 거래대금:11576350000
[20240802 1455] 시:79900, 고:79900, 저:79800, 종:79900, 거래량:175492, 거래대금:14018590000
[20240802 1450] 시:79600, 고:79900, 저:79500, 종:79900, 거래량:437063, 거래대금:34825750000
· · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · (중략) · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · ·
[20240802 930] 시:81000, 고:81100, 저:80900, 종:81000, 거래량:322207, 거래대금:26090330000
[20240802 925] 시:81200, 고:81300, 저:80900, 종:81000, 거래량:473035, 거래대금:38364010000
[20240802 920] 시:81000, 고:81300, 저:80900, 종:81100, 거래량:370689, 거래대금:30078310000
[20240802 915] 시:80900, 고:81200, 저:80800, 종:81000, 거래량:694043, 거래대금:56185550000
[20240802 910] 시:81400, 고:81400, 저:80800, 종:80900, 거래량:756984, 거래대금:61424800000
[20240802 905] 시:81000, 고:81400, 저:80700, 종:81300, 거래량:2476001, 거래대금:200571550000
[20240801 1530] 시:83100, 고:83100, 저:83100, 종:83100, 거래량:1237645, 거래대금:102848290000
[20240801 1520] 시:83500, 고:83500, 저:83400, 종:83500, 거래량:196586, 거래대금:16407280000
[20240801 1515] 시:83500, 고:83700, 저:83400, 종:83500, 거래량:366184, 거래대금:30581510000
'AUTO TRADE > [대신증권] CYBOS PLUS' 카테고리의 다른 글
대신증권 CYBOS PLUS 시작하기 (8) - 모듈별로 클래스 생성하기 (0) | 2024.08.08 |
---|---|
대신증권 CYBOS PLUS 시작하기 (7) - 차트조회 클래스 생성하기 (0) | 2024.08.04 |
대신증권 CYBOS PLUS 시작하기 (5) - 일봉차트 데이터 조회하기 (0) | 2024.08.04 |
대신증권 CYBOS PLUS 시작하기 (4) - 특정종목 현재가 조회하기 (0) | 2024.08.03 |
대신증권 CYBOS PLUS 시작하기 (3) - 대신증권 모듈 이해하기 (0) | 2024.07.29 |
소중한 공감 감사합니다