대신증권 CYBOS PLUS 프로그램 구현 (12) - 분봉 차트 조회하기
프로그램 구현 목표
- 최대로 회신 가능한 데이터 확인하기
- 분봉 차트 조회 함수 제작하기
- 연속 조회 기능 구현하기
- 15분봉 말고 다른 분봉도 조회해보죠 ① GUI로 기능 구현하기
- 15분봉 말고 다른 분봉도 조회해보죠 ② 함수의 인자로 전달받기
최대로 회신 가능한 데이터 확인하기
여기서 살펴볼 회신 가능한 데이터라는 개념은 일봉 차트를 구현할 때 확인했던 2,856개(분봉은 2,499개임)라는 개념과는 달리, 분봉 차트 데이터의 경우에만 적용되는 조회 가능한 범위의 한계가 있다. 대신증권 운영진 측의 답변에 따르면 아래와 같이 정리된다.
- 1분봉: 2년
- 5분봉: 5년
- 틱봉: 20일
분봉 차트 조회 함수 제작하기
분봉 차트는 기존에 살펴봤던 내용과 같이 데이터의 개수로만 조회가 가능하다. 그 전에 앞서 이전에 제작해두었던 일봉·주봉·월봉 차트 조회 함수인 `def _cont_len_chart():`의 이름을 `def chart_DWM():`으로 바꾸어준 후, 이번에 새롭게 만들 함수인 분봉·틱봉 차트 조회 함수의 이름을 `def chart_MT():`로 하여 새롭게 만들어주도록 하자.
※ Line: 10, 81, 82
## CpSysDib.py ##
import win32com.client
import pandas as pd
class StockChart:
def __init__(self):
self.stockchart = win32com.client.Dispatch("CpSysDib.StockChart") ## COM 인스턴스 생성
self.handlers = win32com.client.WithEvents(self.stockchart, event_handler_CpSysDib)
def chart_DWM(self, item_code, request, quantity):
_df = {'date':[], 'open':[], 'high':[], 'low':[], 'close':[], 'vol':[], 'tvol':[]}
self.stockchart.SetInputValue(0, item_code)
self.stockchart.SetInputValue(1, ord("2"))
self.stockchart.SetInputValue(4, quantity)
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.handlers.set_instance(self.stockchart, "_cont_len_chart")
self.stockchart.BlockRequest() ## 데이터 요청
len_fild = self.stockchart.GetHeaderValue(1) ## 요청한 필드 개수
array_fild = self.stockchart.GetHeaderValue(2) ## 팔드 배열
len_data = self.stockchart.GetHeaderValue(3) ## 데이터 개수 확인
# print(f"필드 개수:{len_fild}({array_fild}), 데이터 개수:{len_data}")
for index in range(len_data):
date = self.stockchart.GetDataValue(0, index) ## 0: 날짜, index: 인덱스 번호
open = self.stockchart.GetDataValue(1, index) ## 2: 시가, index: 인덱스 번호
high = self.stockchart.GetDataValue(2, index) ## 3: 고가, index: 인덱스 번호
low = self.stockchart.GetDataValue(3, index) ## 4: 저가, index: 인덱스 번호
close = self.stockchart.GetDataValue(4, index) ## 5: 종가, index: 인덱스 번호
vol = self.stockchart.GetDataValue(5, index) ## 8: 거래량, index: 인덱스 번호
tvol = self.stockchart.GetDataValue(6, index) ## 9: 거래대금, index: 인덱스 번호
_df['date'].append(str(date))
_df['open'].append(open)
_df['high'].append(high)
_df['low'].append(low)
_df['close'].append(close)
_df['vol'].append(vol)
_df['tvol'].append(tvol)
# print(self.stockchart.Continue)
# print(f"회신받은 개수:{len(_df['date'])}, 요청한 개수:{quantity}")
while True:
if len(_df['date']) <= quantity: ## 아직 다 회신받지 못한 경우
if self.stockchart.Continue == 1: ## 추가 작업 수행
self.handlers.set_instance(self.stockchart, "_cont_len_chart")
self.stockchart.BlockRequest() ## 데이터 요청
len_fild = self.stockchart.GetHeaderValue(1) ## 요청한 필드 개수
array_fild = self.stockchart.GetHeaderValue(2) ## 팔드 배열
len_data = self.stockchart.GetHeaderValue(3) ## 데이터 개수 확인
# print(f"필드 개수:{len_fild}({array_fild}), 데이터 개수:{len_data}")
for index in range(len_data):
date = self.stockchart.GetDataValue(0, index) ## 0: 날짜, index: 인덱스 번호
open = self.stockchart.GetDataValue(1, index) ## 2: 시가, index: 인덱스 번호
high = self.stockchart.GetDataValue(2, index) ## 3: 고가, index: 인덱스 번호
low = self.stockchart.GetDataValue(3, index) ## 4: 저가, index: 인덱스 번호
close = self.stockchart.GetDataValue(4, index) ## 5: 종가, index: 인덱스 번호
vol = self.stockchart.GetDataValue(5, index) ## 8: 거래량, index: 인덱스 번호
tvol = self.stockchart.GetDataValue(6, index) ## 9: 거래대금, index: 인덱스 번호
_df['date'].append(str(date))
_df['open'].append(open)
_df['high'].append(high)
_df['low'].append(low)
_df['close'].append(close)
_df['vol'].append(vol)
_df['tvol'].append(tvol)
else: ## 데이터 조회 종료
break
else: ## 데이터 조회 종료(모두 회신받음)
break
chart_data = pd.DataFrame(_df, columns=['date', 'open', 'high', 'low', 'close', 'vol', 'tvol']).iloc[:quantity]
print(chart_data)
def chart_MT(self, item_code, request, quantity):
pass
이제 분봉 차트를 조회하는 시점에서 `SetInputValue()` 함수를 통해 서버에 전달해주어야 하는 데이터는 일봉 차트를 조회할 때 사용했던 것과 크게 다르지 않고 특별히 다른 점이 있다면 필드 배열의 차이와 입력 데이터가 한 개 추가된다는 정도로 볼 수 있다. 필드 배열의 차이는 천천히 살펴보도록 하고, 입력 데이터가 한 개 늘어난다는 것은 차트 주기를 의미한다. 다시 말해, 일봉이나 주봉이나 월봉같은 경우에는 서버에서 자동적으로 입력받아 처리하기 때문에 상관은 없지만 분봉이나 틱봉같은 경우에는 정확히 몇분봉을 의미하는지를 함께 전달해주어야 한다는 것이다. 이 때 사용하는 입력 데이터의 번호는 7번이다. 일단 현재는 간단하게 15분봉을 조회한다고 가정하고 코드를 만들어보자.
※ Line: 7
def chart_MT(self, item_code, request, quantity):
self.stockchart.SetInputValue(0, item_code)
self.stockchart.SetInputValue(1, ord("2"))
self.stockchart.SetInputValue(4, quantity)
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, 15) ## 분틱 주기(1, 3, 5, 10, 15 등등)
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.handlers.set_instance(self.stockchart, "_cont_len_chart")
self.stockchart.BlockRequest() ## 데이터 요청
그 후에 데이터를 요청했으니 데이터를 회신받아야 하는데, 이 때 사용하는 함수도 일봉 차트 데이터를 조회할 때 사용했던 것과 거의 동일하다. 차이점이 있다면 필드 배열이 변경됨에 따라 날짜 데이터를 별도로 수신받아야 한다는 차이점만 있다. 코드를 아래와 같이 수정한 후에, 프로그램에서 차트구분을 분봉으로 놓고 6,000개의 분봉 차트 데이터를 조회해보도록 하자.
※ Line: 15 ~ 29
def chart_MT(self, item_code, request, quantity):
self.stockchart.SetInputValue(0, item_code)
self.stockchart.SetInputValue(1, ord("2"))
self.stockchart.SetInputValue(4, quantity)
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, 15) ## 분틱 주기(1, 3, 5, 10, 15 등등)
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.handlers.set_instance(self.stockchart, "_cont_len_chart")
self.stockchart.BlockRequest() ## 데이터 요청
len_fild = self.stockchart.GetHeaderValue(1) ## 요청한 필드 개수
array_fild = self.stockchart.GetHeaderValue(2) ## 팔드 배열
len_data = self.stockchart.GetHeaderValue(3) ## 데이터 개수 확인
print(f"필드 개수:{len_fild}({array_fild}), 데이터 개수:{len_data}")
for index in range(len_data):
date = self.stockchart.GetDataValue(0, index) ## 0: 날짜, index: 인덱스 번호
hour = self.stockchart.GetDataValue(1, index) ## 1: 시간, index: 인덱스 번호
open = self.stockchart.GetDataValue(2, index) ## 2: 시가, index: 인덱스 번호
high = self.stockchart.GetDataValue(3, index) ## 3: 고가, index: 인덱스 번호
low = self.stockchart.GetDataValue(4, index) ## 4: 저가, index: 인덱스 번호
close = self.stockchart.GetDataValue(5, index) ## 5: 종가, index: 인덱스 번호
vol = self.stockchart.GetDataValue(6, index) ## 8: 거래량, index: 인덱스 번호
tvol = self.stockchart.GetDataValue(7, index) ## 9: 거래대금, index: 인덱스 번호
print(f"[{date} {hour}] 시:{open}, 고:{high}, 저:{low}, 종:{close}, 거래:{vol}, 대금:{tvol}")
프로그램 실행 전에 앞서, 일봉 차트를 조회하는 함수는 `def chart_DWM`으로 바꾸었고 분봉 차트를 조회하는 함수의 이름은 `def chart_MT`로 새롭게 생성한 만큼 Boss.py 파일에 있는 코드를 조금 수정해주어야 한다. 이전에 `comboBox_2`의 `currentIndex()`를 활용하여 콤보박스의 활성화되어 있는 데이터가 틱봉이면 "T", 분봉이면 "m", 일봉이면 "D"와 같은 데이터를 `request` 변수에 입력하도록 해주었다. 따라서 우리는 콤보박스의 `currentIndex()`값이 틱봉·분봉을 뜻하는 0과 1인 경우에는 `chart_MT`를 실행시키도록 하고 일봉·주봉·월봉을 뜻하는 2, 3, 4인 경우에는 `chart_DWM`을 실행시키도록 해주어야 한다.
※ Line: 34 ~ 48
## Boss.py ##
import win32com.client
from pywinauto import application
from COM import CpSysDib
from COM import CpUtil
from COM import CpTrade
from COM import DsCbo1
import time
## GUI ##
import sys
from PyQt5 import uic
from PyQt5.QtWidgets import *
main_ui = uic.loadUiType("main.ui")[0]
class cybos(QMainWindow, main_ui):
def __init__(self):
super().__init__()
self.setupUi(self)
self.stockcode = CpUtil.CpStockCode()
self.trade = CpTrade.CpTdUtil()
self.stockmst = DsCbo1.StockMst()
self._open_cybosplus()
self.pushButton.clicked.connect(self._GetStockListByMarket)
self.pushButton_2.clicked.connect(self._day_range)
self.pushButton_3.clicked.connect(self._len_chart)
def _len_chart(self):
item_code = self.lineEdit_4.text()
data_len = int(self.lineEdit_5.text())
cur_idx = self.comboBox_2.currentIndex()
if cur_idx == 0:
request = "T"
CpSysDib.StockChart().chart_MT(item_code, request, data_len)
elif cur_idx == 1:
request = "m"
CpSysDib.StockChart().chart_MT(item_code, request, data_len)
elif cur_idx == 2:
request = "D"
CpSysDib.StockChart().chart_DWM(item_code, request, data_len)
elif cur_idx == 3:
request = "W"
CpSysDib.StockChart().chart_DWM(item_code, request, data_len)
elif cur_idx == 4:
request = "M"
CpSysDib.StockChart().chart_DWM(item_code, request, data_len)
▶ 실행 결과 확인하기
self.object:CpCybos
[통신결과:1] 서버와의 연결에 성공했습니다.
로그인되어 있습니다.
self.object:_cont_len_chart
필드 개수:8(('날짜', '시간', '시가', '고가', '저가', '종가', '거래량', '거래대금')), 데이터 개수:2499
[20240906 1530] 시:68800, 고:69000, 저:68800, 종:68900, 거래:1343919, 대금:92591640000
[20240906 1515] 시:69000, 고:69200, 저:68800, 종:68900, 거래:812495, 대금:56032100000
( 중략 )
[20240418 1500] 시:79700, 고:79800, 저:79600, 종:79700, 거래:498107, 대금:39696840000
[20240418 1445] 시:79800, 고:79900, 저:79500, 종:79600, 거래:705055, 대금:56208310000
연속 조회 기능 구현하기
위의 실행 결과에서 확인할 수 있듯이, 분봉 차트 데이터의 경우에는 일봉과는 달리 최대 2,499개의 데이터만 회신해준다는 것을 확인할 수 있다. 하지만 요청 회당 최대 몇 개의 데이터를 회신해주는지와는 무관하게 우리는 연속 조회 기능을 구현해주어야만 한다. 연속 조회 기능은 일전에 일봉 차트 데이터에서 구현했던 것과 거의 동일한 로직으로 구현해주면 된다.
※ Line: 2, 31 ~ 76
def chart_MT(self, item_code, request, quantity):
_df = {'date':[], 'hour':[], 'dhour':[], 'open':[], 'high':[], 'low':[], 'close':[], 'vol':[], 'tvol':[]}
self.stockchart.SetInputValue(0, item_code)
self.stockchart.SetInputValue(1, ord("2"))
self.stockchart.SetInputValue(4, quantity)
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, 15) ## 분틱 주기(1, 3, 5, 10, 15 등등)
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.handlers.set_instance(self.stockchart, "_cont_len_chart")
self.stockchart.BlockRequest() ## 데이터 요청
len_fild = self.stockchart.GetHeaderValue(1) ## 요청한 필드 개수
array_fild = self.stockchart.GetHeaderValue(2) ## 팔드 배열
len_data = self.stockchart.GetHeaderValue(3) ## 데이터 개수 확인
# print(f"필드 개수:{len_fild}({array_fild}), 데이터 개수:{len_data}")
for index in range(len_data):
date = self.stockchart.GetDataValue(0, index) ## 0: 날짜, index: 인덱스 번호
hour = self.stockchart.GetDataValue(1, index) ## 1: 시간, index: 인덱스 번호
open = self.stockchart.GetDataValue(2, index) ## 2: 시가, index: 인덱스 번호
high = self.stockchart.GetDataValue(3, index) ## 3: 고가, index: 인덱스 번호
low = self.stockchart.GetDataValue(4, index) ## 4: 저가, index: 인덱스 번호
close = self.stockchart.GetDataValue(5, index) ## 5: 종가, index: 인덱스 번호
vol = self.stockchart.GetDataValue(6, index) ## 8: 거래량, index: 인덱스 번호
tvol = self.stockchart.GetDataValue(7, index) ## 9: 거래대금, index: 인덱스 번호
# print(f"[{date} {hour}] 시:{open}, 고:{high}, 저:{low}, 종:{close}, 거래:{vol}, 대금:{tvol}")
_df['date'].append(str(date))
_df['hour'].append(str(hour))
_df['dhour'].append(f"{str(date)}{str(hour)}")
_df['open'].append(open)
_df['high'].append(high)
_df['low'].append(low)
_df['close'].append(close)
_df['vol'].append(vol)
_df['tvol'].append(tvol)
while True:
if len(_df['date']) <= quantity: ## 아직 다 회신받지 못한 경우
if self.stockchart.Continue == 1: ## 추가 작업 수행
self.handlers.set_instance(self.stockchart, "_cont_len_chart")
self.stockchart.BlockRequest() ## 데이터 요청
len_fild = self.stockchart.GetHeaderValue(1) ## 요청한 필드 개수
array_fild = self.stockchart.GetHeaderValue(2) ## 팔드 배열
len_data = self.stockchart.GetHeaderValue(3) ## 데이터 개수 확인
# print(f"필드 개수:{len_fild}({array_fild}), 데이터 개수:{len_data}")
for index in range(len_data):
date = self.stockchart.GetDataValue(0, index) ## 0: 날짜, index: 인덱스 번호
hour = self.stockchart.GetDataValue(1, index) ## 1: 시간, index: 인덱스 번호
open = self.stockchart.GetDataValue(2, index) ## 2: 시가, index: 인덱스 번호
high = self.stockchart.GetDataValue(3, index) ## 3: 고가, index: 인덱스 번호
low = self.stockchart.GetDataValue(4, index) ## 4: 저가, index: 인덱스 번호
close = self.stockchart.GetDataValue(5, index) ## 5: 종가, index: 인덱스 번호
vol = self.stockchart.GetDataValue(6, index) ## 8: 거래량, index: 인덱스 번호
tvol = self.stockchart.GetDataValue(7, index) ## 9: 거래대금, index: 인덱스 번호
# print(f"[{date} {hour}] 시:{open}, 고:{high}, 저:{low}, 종:{close}, 거래:{vol}, 대금:{tvol}")
_df['date'].append(str(date))
_df['hour'].append(str(hour))
_df['dhour'].append(f"{str(date)}{str(hour)}")
_df['open'].append(open)
_df['high'].append(high)
_df['low'].append(low)
_df['close'].append(close)
_df['vol'].append(vol)
_df['tvol'].append(tvol)
else: ## 데이터 조회 종료
break
else: ## 데이터 조회 종료(모두 회신받음)
break
chart_data = pd.DataFrame(_df, columns=['date', 'hour', 'dhour', 'open', 'high', 'low', 'close', 'vol', 'tvol']).iloc[:quantity]
print(chart_data)
▶ 실행 결과 확인하기
self.object:CpCybos
[통신결과:1] 서버와의 연결에 성공했습니다.
로그인되어 있습니다.
self.object:chart_MT
self.object:chart_MT
self.object:chart_MT
date hour dhour open ... low close vol tvol
0 20240906 1530 202409061530 68800 ... 68800 68900 1343919 92591640000
1 20240906 1515 202409061515 69000 ... 68800 68900 812495 56032100000
2 20240906 1500 202409061500 68700 ... 68600 69100 681327 46945020000
3 20240906 1445 202409061445 68700 ... 68600 68700 565439 38874400000
4 20240906 1430 202409061430 69000 ... 68700 68800 615722 42367610000
... ... ... ... ... ... ... ... ... ...
5995 20230927 1030 202309271030 68700 ... 68600 68700 485409 33349120000
5996 20230927 1015 202309271015 68600 ... 68500 68800 569140 39104320000
5997 20230927 1000 202309271000 68800 ... 68500 68500 498518 34254920000
5998 20230927 945 20230927945 68900 ... 68800 68900 492186 33892640000
5999 20230927 930 20230927930 69000 ... 68800 68800 502016 34598440000
[6000 rows x 9 columns]
15분봉 말고 다른 분봉도 조회해보죠 ① GUI로 기능 구현하기
글의 제목에서 알 수 있듯이, 이번 목차에서는 GUI 상에서 분봉을 입력할 수 있는 기능을 넣어서 그 데이터에 해당하는 분봉을 조회해 볼 예정이다. 먼저, GUI와 관련된 이벤트들을 처리하는 qt_gui.py 파일을 생성해주고, `class etc:`라는 이름의 클래스를 먼저 생성해주자. 그 후에 초기화 함수에서는 Boss.py 파일의 클래스를 상속받은 후, 콤보박스 2에서 발생하는 데이터들을 처리하기 위해 `def comboBox_2_CIC()`라는 이름의 함수를 생성해주도록 하자.
## qt_gui.py ##
class etc:
def __init__(self, boss):
self.boss = boss
def comboBox_2_CIC(self):
pass
물론 Boss.py 파일의 초기화 함수에서 추가적인 코드가 구현되어야 하지만, 그 부분은 아래에서 구현해보도록 하고 일단 당장은 `def comboBox_2_CIC(self):` 함수 내부에서는 `self.boss`라는 내용을 통해 GUI에 접근할 수 있다고 가정하고 코드를 구현해보자. 일단 이 함수의 이름에 있는 CIC는 currentIndexChanged의 약자인데, 이는 `QComboBox` 객체가 지원하는 메서드인 `currentIndexChanged`를 따온 것이다. 이 메서드는 `comboBox_2`의 데이터가 변경될 때 발생하는 이벤트이다. 다시 말해, GUI의 comboBox_2가 틱봉으로 설정되어 있는 상태에서 분봉으로 변경되면 이 이벤트가 발생하고, 분봉에서 또 다른 것으로 변경될 때에도 이벤트가 발생한다. 아래와 같이 `def comboBox_2CIC(self):` 함수를 수정해주자.
※ Line: 7, 8, 9
## qt_gui.py ##
class etc:
def __init__(self, boss):
self.boss = boss
def comboBox_2_CIC(self):
"""CIC: current Index Changed"""
cur_index = self.boss.comboBox_2.currentIndex()
print(f" 콤보박스 인덱스 변경됨:{cur_index}")
그 후에 다시 Boss.ui(GUI) 파일을 열어서 아래와 같이 lineEdit을 활용하여 주기 구분을 추가해주도록 하자. (해당 객체의 이름은 `lineEdit_6`이다.)
그 후 다시 Boss.py 파일로 돌아와 GUI와 관련된 내용을 호출하는 구간에서 `from gui import qt_gui`라는 구문을 통해 해당 파일을 임포트한 후, `class cybos`의 초기화 함수 부분에서 `lambda` 함수를 활용하여 `class etc`의 인자로 `self`를 전달해주도록 하자. 이제 qt_gui.py 파일 내부의 `class etc`에서는 `self.boss.comboBox_2`나 `self.boss.lineEdit_6`와 같은 구문을 통해 GUI에 접근할 수 있다.
※ Line: 30
## Boss.py ##
import win32com.client
from pywinauto import application
from COM import CpSysDib
from COM import CpUtil
from COM import CpTrade
from COM import DsCbo1
import time
## GUI ##
import sys
from PyQt5 import uic
from PyQt5.QtWidgets import *
from gui import qt_gui
main_ui = uic.loadUiType("main.ui")[0]
class cybos(QMainWindow, main_ui):
def __init__(self):
super().__init__()
self.setupUi(self)
self.stockcode = CpUtil.CpStockCode()
self.trade = CpTrade.CpTdUtil()
self.stockmst = DsCbo1.StockMst()
self._open_cybosplus()
self.pushButton.clicked.connect(self._GetStockListByMarket)
self.pushButton_2.clicked.connect(self._day_range)
self.pushButton_3.clicked.connect(self._len_chart)
self.comboBox_2.currentIndexChanged.connect(lambda: qt_gui.etc(self).comboBox_2_CIC())
이제 다시 qt_gui.py 파일로 돌아와서 `def comboBox_2_CIC(self):` 함수 내부에서 `QLineEdit` 객체의 `setEnabled` 메서드를 활용하여 `lineEdit_6`를 활성화시키거나 비활성화시킬 수 있다. 즉, comboBox_2의 데이터를 바탕으로 그 아래에 있는 주기구분에 데이터를 입력할 수 있는지 없는지를 결정지을 수 있다는 것이다.
※ Line: 10 ~ 13
## qt_gui.py ##
class etc:
def __init__(self, boss):
self.boss = boss
def comboBox_2_CIC(self):
"""CIC: current Index Changed"""
cur_index = self.boss.comboBox_2.currentIndex()
print(f" 콤보박스 인덱스 변경됨:{cur_index}")
if cur_index == 0 or cur_index == 1:
self.boss.lineEdit_6.setEnabled(True)
else:
self.boss.lineEdit_6.setEnabled(False)
□ 프로그램을 실행시켜서 차트구분 데이터를 변경해보자.
self.object:CpCybos
[통신결과:1] 서버와의 연결에 성공했습니다.
로그인되어 있습니다.
콤보박스 인덱스 변경됨:2
콤보박스 인덱스 변경됨:0
콤보박스 인덱스 변경됨:1
콤보박스 인덱스 변경됨:0
15분봉 말고 다른 분봉도 조회해보죠 ② 함수의 인자로 전달받기
일단 함수의 인자로 전달받기 위해서는 CpSysDib.py 파일 내부의 `def chart_MT()` 함수의 인자를 변경해주면 된다. 기존에는 종목코드(`item_code`)와 요청구분(`request`), 요청개수(`quantity`)까지만 구현되어 있었지만 마지막 자리에 `cycle`이라는 주기구분을 추가해주면 된다.
※ Line: 1, 8
def chart_MT(self, item_code, request, quantity, cycle):
_df = {'date':[], 'hour':[], 'dhour':[], 'open':[], 'high':[], 'low':[], 'close':[], 'vol':[], 'tvol':[]}
self.stockchart.SetInputValue(0, item_code)
self.stockchart.SetInputValue(1, ord("2"))
self.stockchart.SetInputValue(4, quantity)
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, cycle) ## 분틱 주기(1, 3, 5, 10, 15 등등)
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.handlers.set_instance(self.stockchart, "chart_MT")
self.stockchart.BlockRequest() ## 데이터 요청
len_fild = self.stockchart.GetHeaderValue(1) ## 요청한 필드 개수
array_fild = self.stockchart.GetHeaderValue(2) ## 팔드 배열
len_data = self.stockchart.GetHeaderValue(3) ## 데이터 개수 확인
# print(f"필드 개수:{len_fild}({array_fild}), 데이터 개수:{len_data}")
for index in range(len_data):
date = self.stockchart.GetDataValue(0, index) ## 0: 날짜, index: 인덱스 번호
hour = self.stockchart.GetDataValue(1, index) ## 1: 시간, index: 인덱스 번호
open = self.stockchart.GetDataValue(2, index) ## 2: 시가, index: 인덱스 번호
high = self.stockchart.GetDataValue(3, index) ## 3: 고가, index: 인덱스 번호
low = self.stockchart.GetDataValue(4, index) ## 4: 저가, index: 인덱스 번호
close = self.stockchart.GetDataValue(5, index) ## 5: 종가, index: 인덱스 번호
vol = self.stockchart.GetDataValue(6, index) ## 8: 거래량, index: 인덱스 번호
tvol = self.stockchart.GetDataValue(7, index) ## 9: 거래대금, index: 인덱스 번호
# print(f"[{date} {hour}] 시:{open}, 고:{high}, 저:{low}, 종:{close}, 거래:{vol}, 대금:{tvol}")
_df['date'].append(str(date))
_df['hour'].append(str(hour))
_df['dhour'].append(f"{str(date)}{str(hour)}")
_df['open'].append(open)
_df['high'].append(high)
_df['low'].append(low)
_df['close'].append(close)
_df['vol'].append(vol)
_df['tvol'].append(tvol)
while True:
if len(_df['date']) <= quantity: ## 아직 다 회신받지 못한 경우
if self.stockchart.Continue == 1: ## 추가 작업 수행
self.handlers.set_instance(self.stockchart, "chart_MT")
self.stockchart.BlockRequest() ## 데이터 요청
len_fild = self.stockchart.GetHeaderValue(1) ## 요청한 필드 개수
array_fild = self.stockchart.GetHeaderValue(2) ## 팔드 배열
len_data = self.stockchart.GetHeaderValue(3) ## 데이터 개수 확인
# print(f"필드 개수:{len_fild}({array_fild}), 데이터 개수:{len_data}")
for index in range(len_data):
date = self.stockchart.GetDataValue(0, index) ## 0: 날짜, index: 인덱스 번호
hour = self.stockchart.GetDataValue(1, index) ## 1: 시간, index: 인덱스 번호
open = self.stockchart.GetDataValue(2, index) ## 2: 시가, index: 인덱스 번호
high = self.stockchart.GetDataValue(3, index) ## 3: 고가, index: 인덱스 번호
low = self.stockchart.GetDataValue(4, index) ## 4: 저가, index: 인덱스 번호
close = self.stockchart.GetDataValue(5, index) ## 5: 종가, index: 인덱스 번호
vol = self.stockchart.GetDataValue(6, index) ## 8: 거래량, index: 인덱스 번호
tvol = self.stockchart.GetDataValue(7, index) ## 9: 거래대금, index: 인덱스 번호
# print(f"[{date} {hour}] 시:{open}, 고:{high}, 저:{low}, 종:{close}, 거래:{vol}, 대금:{tvol}")
_df['date'].append(str(date))
_df['hour'].append(str(hour))
_df['dhour'].append(f"{str(date)}{str(hour)}")
_df['open'].append(open)
_df['high'].append(high)
_df['low'].append(low)
_df['close'].append(close)
_df['vol'].append(vol)
_df['tvol'].append(tvol)
else: ## 데이터 조회 종료
break
else: ## 데이터 조회 종료(모두 회신받음)
break
chart_data = pd.DataFrame(_df, columns=['date', 'hour', 'dhour', 'open', 'high', 'low', 'close', 'vol', 'tvol']).iloc[:quantity]
print(chart_data)
그 후에 다시 Boss.py 파일로 돌아와서 차트 데이터를 요청하는 지점의 조건문 하단을 아래와 같이 수정해주면 된다.
※ Line: 7, 8, 11, 12
def _len_chart(self):
item_code = self.lineEdit_4.text()
data_len = int(self.lineEdit_5.text())
cur_idx = self.comboBox_2.currentIndex()
if cur_idx == 0:
request = "T"
cycle = int(self.lineEdit_6.text())
CpSysDib.StockChart().chart_MT(item_code, request, data_len, cycle)
elif cur_idx == 1:
request = "m"
cycle = int(self.lineEdit_6.text())
CpSysDib.StockChart().chart_MT(item_code, request, data_len, cycle)
elif cur_idx == 2:
request = "D"
CpSysDib.StockChart().chart_DWM(item_code, request, data_len)
elif cur_idx == 3:
request = "W"
CpSysDib.StockChart().chart_DWM(item_code, request, data_len)
elif cur_idx == 4:
request = "M"
CpSysDib.StockChart().chart_DWM(item_code, request, data_len)
□ 삼성전자(A005930) 5분봉 차트 5,000개를 조회했을 때의 결과 데이터 확인
date hour dhour open ... low close vol tvol
0 20240906 1530 202409061530 68900 ... 68900 68900 1028428 70858680000
1 20240906 1520 202409061520 68800 ... 68800 69000 315491 21732960000
2 20240906 1515 202409061515 68900 ... 68800 68900 372529 25666710000
3 20240906 1510 202409061510 69000 ... 68900 68900 324893 22415900000
4 20240906 1505 202409061505 69000 ... 69000 69000 115073 7949490000
... ... ... ... ... ... ... ... ... ...
4995 20240607 925 20240607925 78000 ... 77800 77800 482247 37601560000
4996 20240607 920 20240607920 78000 ... 77800 78100 713218 55588130000
4997 20240607 915 20240607915 78400 ... 78000 78100 928028 72729810000
4998 20240607 910 20240607910 78100 ... 78100 78300 488149 38189320000
4999 20240607 905 20240607905 78400 ... 78000 78100 2502156 195973050000
[5000 rows x 9 columns]
□ 삼성전자(A005930) 10분봉 차트 데이터 5,000개를 조회했을 때의 결과 데이터 확인
date hour dhour open ... low close vol tvol
0 20240906 1530 202409061530 68900 ... 68900 68900 1028428 70858680000
1 20240906 1520 202409061520 68900 ... 68800 69000 688020 47399670000
2 20240906 1510 202409061510 69000 ... 68900 68900 439966 30365390000
3 20240906 1500 202409061500 68900 ... 68800 69100 429750 29658980000
4 20240906 1450 202409061450 68800 ... 68600 68900 480089 32983000000
... ... ... ... ... ... ... ... ... ...
4995 20240304 1440 202403041440 74900 ... 74700 74700 653767 48906200000
4996 20240304 1430 202403041430 74900 ... 74800 74800 202991 15194780000
4997 20240304 1420 202403041420 74800 ... 74700 74800 221277 16561570000
4998 20240304 1410 202403041410 74800 ... 74700 74700 587372 43932510000
4999 20240304 1400 202403041400 74700 ... 74600 74800 430371 32154100000
[5000 rows x 9 columns]
□ 삼성전자(A005930) 30분봉 차트 데이터 5,000개를 조회했을 때의 결과 데이터 확인
date hour dhour open ... low close vol tvol
0 20240906 1530 202409061530 69000 ... 68800 68900 2156414 148623740000
1 20240906 1500 202409061500 68700 ... 68600 69100 1246766 85819420000
2 20240906 1430 202409061430 69100 ... 68700 68800 875163 60264220000
3 20240906 1400 202409061400 68900 ... 68900 69000 1023127 70690760000
4 20240906 1330 202409061330 69100 ... 68800 69000 654774 45133180000
... ... ... ... ... ... ... ... ... ...
4995 20230215 1300 202302151300 62300 ... 62100 62300 325506 20249150000
4996 20230215 1230 202302151230 62200 ... 62100 62300 683753 42533210000
4997 20230215 1200 202302151200 62300 ... 62000 62200 827141 51410100000
4998 20230215 1130 202302151130 62400 ... 62100 62300 802252 49940830000
4999 20230215 1100 202302151100 62600 ... 62200 62300 1116184 69657400000
[5000 rows x 9 columns]
'AUTO TRADE > [대신증권] CYBOS PLUS' 카테고리의 다른 글
대신증권 CYBOS PLUS 프로그램 구현 (14) - 차트 데이터 저장하기 ① (1) | 2024.09.16 |
---|---|
대신증권 CYBOS PLUS 프로그램 구현 (13) - 로그인 시 계좌 조회하기 (0) | 2024.09.07 |
대신증권 CYBOS PLUS 프로그램 구현 (11) - 일봉 차트 조회 : 연속 조회 사용하기 ② (1) | 2024.09.06 |
대신증권 CYBOS PLUS 프로그램 구현 (10) - 일봉 차트 조회 : 연속 조회 사용하기 ① (0) | 2024.09.02 |
대신증권 CYBOS PLUS 프로그램 구현 (9) - 일봉 차트 조회 : 오류 개선 (1) | 2024.09.01 |
소중한 공감 감사합니다