대신증권 CYBOS PLUS 시작하기 (7) - 차트조회 클래스 생성하기
코드 구축 목표
- 기작업한 차트 조회 함수들을 별도의 클래스로 생성
- 메인으로 작업할 클래스에서 해당 클래스 호출하여 차트 조회해보기
지난 두 번의 게시글에서 일봉, 주봉, 월봉, 분봉 차트 데이터를 조회하는 방법에 대해 살펴보았다. 이제 슬슬 하나의 파일 안에서 모든 코드를 제작하다 보니 코드가 관리하기 어려워지는 게 와닿을 것이다. 그래서 이번에는 새로운 폴더를 만들어서 그 안에 새롭게 파일을 생성하고, 파일 별로 하나의 클래스를 만들어서 아예 분리된 캡슐화 작업을 할 예정이다.
일단 우리가 작업하고 있는 trade_cybos 프로젝트(폴더) 안에 COM이라는 이름을 가진 폴더를 생성한 후, CpSysDib.py 파일을 생성해주도록 하자. 앞으로 COM과 관련된 내용들은 모두 COM이라는 폴더 안에 기능을 구현할 예정이다.
(1) 차트 조회 함수들을 묶어서 클래스로 생성하기
이전에 Boss.py 파일 내에서도 `class cybos` 바로 아래에 `def __init__(self):` 함수를 생성하면서 이 초기화 함수에 대해서 간략하게 설명했었는데, 초기화 함수는 간단하게 '해당 클래스가 호출되면 따로 호출되지 않아도 실행되는 함수'라고 생각하면 된다. 그렇기 때문에 이번에도 CpSysDib.py 파일 내에서도 별도의 클래스를 생성한 후, 초기화 함수 내부에서 COM과 연결하는 작업을 진행해주면 된다. COM과 연결하는 작업을 처리한 후 인스턴스를 생성해주어야 하는데, 인스턴스의 이름은 이전 게시글에서 사용했던 것과 동일하게 `self.stockchart`로 하였다.
## CpSysDib.py ##
import win32com.client
class StockChart:
def __init__(self):
self.stockchart = win32com.client.Dispatch("CpSysDib.StockChart") ## COM 연결
그 후에는 기존에 Boss.py 파일 내에서 제작했던 차트 데이터 조회 함수들을 그대로 복사해서 CpSysDib.py 파일에 그대로 붙여넣어주도록 하자. 붙여넣은 후에는 기존에 있던 Boss.py 파일 내에서는 해당 코드들을 삭제해주도록 하자.
## CpSysDib.py ##
import win32com.client
class StockChart:
def __init__(self):
self.stockchart = win32com.client.Dispatch("CpSysDib.StockChart") ## COM 연결
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
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
def _StockChart_day_range(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("1")) ## 요청 구분
self.stockchart.SetInputValue(2, end_date) ## 요청 종료일
self.stockchart.SetInputValue(3, start_date) ## 요청 시작일
self.stockchart.SetInputValue(5, [0, 2, 3, 4, 5, 8, 9, 6, 37]) ## 데이터 배열
self.stockchart.SetInputValue(6, ord("D")) ## 차트 구분('D': 일봉, 'W': 주봉, 'M': 월봉, 'm': 분봉, 'T': 틱)
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)
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})")
(2) 새롭게 생성한 클래스를 호출하여 차트 조회해보기
이제 차트 데이터를 조회할 수 있는 함수들을 별도의 폴더에 모두 넣어놨으므로 Boss.py 폴더 내에서 그 함수들을 사용하려면, 우리가 COM을 `import win32com.client` 구문을 추가하여 import한 후에 별도의 인스턴스를 생성하여 그 인스턴스를 통해 사용했듯이 CpSysDib.py 파일 내에 있는 클래스에 대해서도 import 과정을 거친 후에 별도의 인스턴스를 생성해주어야만 사용이 가능하다. 아래 코드를 참고해보도록 하자.
※ Line: 3, 12
## Boss.py ##
import win32com.client
from COM import CpSysDib
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 = CpSysDib.StockChart()
그 후에는 `self.stockchart`라는 인스턴스를 통해서 각각의 함수에 인자를 전달하여 직접 함수를 실행시킬 수 있다. 가장 먼저 분봉 차트 조회 함수인 `_StockChart_min()` 함수를 조회해볼 예정인데, 그 인자로 전달해줘야 하는 것들은 아래의 코드를 참고하여 전달하고, 그 결과 데이터를 확인해보도록 하자.
※ Line: 13
## Boss.py ##
import win32com.client
from COM import CpSysDib
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 = CpSysDib.StockChart()
self.stockchart._StockChart_min("A005930", "m", 5, 80)
▶ 실행 결과 확인하기
필드 개수: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 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
이제 이쯤 되니 기존에 작성해두었던 함수(지금은 CpSysDib.py 파일 내에 있는)들의 이름이 너무 쓸데없이 긴 것 같다는 생각이 들 수도 있다. 각각의 함수들을 조금 간략하게 수정한 후에, 아직 사용하지 않은 ① 기간 대상 일봉 조회 함수와 ② 개수 기준 차트 조회 함수를 사용해보도록 하자.
※ `_StockChart_day_range → _day_range`, `_StockChart_num → _num`, `_StockChart_min → _min`
## Boss.py ##
import win32com.client
from COM import CpSysDib
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 = CpSysDib.StockChart()
self.stockchart._min("A005930", "m", 5, 80)
self.stockchart._num("A005930", "D", 20)
self.stockchart._day_range("A005930", "20240101", "20240401")
▶ 실행 결과 확인하기
필드 개수: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 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
필드 개수:7(('날짜', '시가', '고가', '저가', '종가', '거래량', '거래대금')), 데이터 개수:20
[20240802] 시:81000, 고:81400, 저:79500, 종:79600, 거래량:25800275, 거래대금:2072583000000
[20240801] 시:86000, 고:86100, 저:83100, 종:83100, 거래량:20900338, 거래대금:1761066000000
· · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · (중략) · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · ·
[20240709] 시:87800, 고:88200, 저:86900, 종:87800, 거래량:21336201, 거래대금:1869414000000
[20240708] 시:87900, 고:88600, 저:86900, 종:87400, 거래량:24035809, 거래대금:2105162000000
필드 개수:9(('날짜', '시가', '고가', '저가', '종가', '전일대비', '거래량', '거래대금', '대비부호')), 데이터 개수:62
[20240401] 시:83200, 고:83300, 저:82000, 종:82000, 거래량:20116513, 거래대금:1661276000000, 전일대비:-400(53)
[20240329] 시:81200, 고:82500, 저:80900, 종:82400, 거래량:27126366, 거래대금:2224901000000, 전일대비:1600(50)
· · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · (중략) · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · ·
[20240103] 시:78500, 고:78800, 저:77000, 종:77000, 거래량:21753644, 거래대금:1691690000000, 전일대비:-2600(53)
[20240102] 시:78200, 고:79800, 저:78200, 종:79600, 거래량:17142847, 거래대금:1356958000000, 전일대비:1100(50)
함수를 호출할 때 어떠한 인자를 전달해야 할지 알 수 없을 때, 파이참의 경우에는 그 함수의 이름에 마우스 커서를 올려두면 어떠한 인자를 요구하는지 확인할 수 있다. 이 때 그 순서에 상관없이 사용하고 싶을 때에는, 전달하고자 하는 인자를 직접 지정하여 전달해주는 방법으로도 함수를 사용할 수 있다. 즉, 마우스 커서를 올려서 해당 함수의 인자들을 확인한 후에 각각의 인자에 대해 특정 값을 지정해주는 방식이다. 이 방식은 인자의 순서에 구애받지 않는 방식이다. 아래의 코드를 확인해보자.
※ Line: 13~15
## Boss.py ##
import win32com.client
from COM import CpSysDib
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 = CpSysDib.StockChart()
self.stockchart._min(item_code="A005930", request="m", tick=5, num=80)
self.stockchart._num(item_code="A005930", request="D", num=20)
self.stockchart._day_range(item_code="A005930", start_date="20240101", end_date="20240401")
'AUTO TRADE > [대신증권] CYBOS PLUS' 카테고리의 다른 글
대신증권 CYBOS PLUS 시작하기 (9) - WithEvents 알아보기 (1) | 2024.08.18 |
---|---|
대신증권 CYBOS PLUS 시작하기 (8) - 모듈별로 클래스 생성하기 (0) | 2024.08.08 |
대신증권 CYBOS PLUS 시작하기 (6) - 분봉차트 데이터 조회하기 (0) | 2024.08.04 |
대신증권 CYBOS PLUS 시작하기 (5) - 일봉차트 데이터 조회하기 (0) | 2024.08.04 |
대신증권 CYBOS PLUS 시작하기 (4) - 특정종목 현재가 조회하기 (0) | 2024.08.03 |
소중한 공감 감사합니다