지난번에는 주식종목코드와 종목명을 DB에 저장하는 로직을 구현했습니다. 이번에는 사용자 별 관심주식종목을 관리하는 DB를 구성하고 그 DB를 기준으로 일봉차트를 조회하여 DB에 저장하는 부분을 구현해 보도록 하겠습니다. 이 부분도 기존에 구현해 놓은 부분이기 때문에, DB에만 잘 저장하면 될 것으로 생각이 됩니다.
1. 주식종목 관리 DB구성
사용자 별로 관심있는 주식종목을 저장하고 관리를 해야하기 때문에, 사용자ID와 주식종목코드가 있어야 하겠고... 사용자ID는 중복이 가능해야 하겠죠?? 그리고 이력 관리를 위해서 생성한 날짜와, 삭제한 날짜의 정보도 함께 저장하도록 하겠습니다.
CREATE TABLE stocks_select_user(
seq INT(20) PRIMARY KEY AUTO_INCREMENT,
user_id INT(20),
stocks_id VARCHAR(10),
create_date DATETIME,
delete_yn VARCHAR(1),
delete_date DATETIME
);
그리고 해당 관리 view page는 나중에 구현을 할 것이기 때문에... 우선은 강제로 test를 위한 데이터를 insert해보도록 하겠습니다.
INSERT INTO stocks_select_user (user_id, stocks_id, create_date, delete_yn)
VALUES ("1", "000020", NOW(), 'N');
INSERT INTO stocks_select_user (user_id, stocks_id, create_date, delete_yn)
VALUES ("1", "000040", NOW(), 'N');
INSERT INTO stocks_select_user (user_id, stocks_id, create_date, delete_yn)
VALUES ("1", "000050", NOW(), 'N');
INSERT INTO stocks_select_user (user_id, stocks_id, create_date, delete_yn)
VALUES ("2", "000040", NOW(), 'N');
INSERT INTO stocks_select_user (user_id, stocks_id, create_date, delete_yn)
VALUES ("2", "000050", NOW(), 'N');
INSERT INTO stocks_select_user (user_id, stocks_id, create_date, delete_yn)
VALUES ("2", "000060", NOW(), 'N');
INSERT INTO stocks_select_user (user_id, stocks_id, create_date, delete_yn)
VALUES ("2", "000070", NOW(), 'Y');
중복된 데이터도 넣어주고, delete_yn이 Y인 데이터도 넣어줍니다.
2. 대상 주식종목 가져오기
사용자별 관심 주식종목 관리 DB를 만들었다면, 그 DB에서 대상 주식종목을 가져오는 로직이 필요합니다. 이 주식종목 리스트를 기반으로 키움증권 Open API+를 통해서 일봉차트를 가져오고 그 데이터를 자체 DB에 저장하여 서비스에 활용할 것이기 때문입니다.
그럼 우선 대상 주식종목을 가져오는 쿼리를 만들어 볼까요?? stocks_id는 중복이 가능하고, delete_yn에 'Y'인 데이터는 가져오면 안되기 때문에...
SELECT DISTINCT(stocks_id) FROM stocks_select_user WHERE delete_yn = 'N';
이 쿼리를 사용하겠습니다. 사용결과 중복을 제거하고 N인 데이터 4개를 정확히 가져왔습니다.
이제 쿼리는 되었으니, python코드내에 구현하고 list로 받아오는 로직이 필요합니다. 별로 길지 않으니 바로 결과를 확인해 보겠습니다.
# 사용자 관심 주식종목 전체 가져오기
sql_dml = 'SELECT DISTINCT(stocks_id) FROM stocks_select_user WHERE delete_yn = "N"'
mariadb_cur.execute(sql_dml)
sList = mariadb_cur.fetchall()
print(sList)
네 잘 가져왔습니다. 이제 이것을 가지고 기존에 특정종목에 대해서 가져왔던 일봉차트를 개선하고, DB에 저장해 보도록 하겠습니다.
3. 일봉차트 DB에 저장하기
우선 일봉차트를 DB에 저장하기 위해서는 대상 종목에 대해서 opt_10081로 조회를 해야하고 조회한 결과를 하나의 컬렉션에 잘 쌓아놓아야 합니다. 결국 DB에는 pandas에서 제공하는 to_sql로 할 것이기 때문에, DataFrame으로 만들면 가장좋겠죠?? 그렇게 가능하게 하는건 2 x 2 matrix에서는 dict형이 정답입니다.
def AT_opt10081(self, sTrCode, sRQName):
dataCnt = self.GetRepeatCnt(sTrCode, sRQName);
for i in range(dataCnt):
date = self.GetCommData(sTrCode, sRQName, i, "일자").strip()
finish = self.GetCommData(sTrCode, sRQName, i, "현재가").strip()
mount = self.GetCommData(sTrCode, sRQName, i, "거래량").strip()
start = self.GetCommData(sTrCode, sRQName, i, "시가").strip()
high = self.GetCommData(sTrCode, sRQName, i, "고가").strip()
low = self.GetCommData(sTrCode, sRQName, i, "저가").strip()
self.opt10081_res['date'].append(date)
self.opt10081_res['finish'].append(finish)
self.opt10081_res['mount'].append(mount)
self.opt10081_res['start'].append(start)
self.opt10081_res['high'].append(high)
self.opt10081_res['low'].append(low)
# opt10081 TR요청
kd.opt10081_res = {'date': [], 'start': [], 'high': [], 'low': [], 'finish': [], 'mount': []}
TR을 요청할때, 해당 인스턴스에 dict형의 변수를 하나 생성하고, 실제로 opt_10081이 동작해서 실행이 될 때는 그 변수에 값을 계속추가를 해 주는 방식입니다. 데이터를 다 호출해오면 결국 해당 변수에 모든 데이터가 적재가 되어있기 때문에 해당 변수만 DB로 저장을 해주면 됩니다.
opt10081_res_pd = pd.DataFrame(kd.opt10081_res)
opt10081_res_pd.to_sql(i[0], engine, if_exists='replace', index=False, index_label=None, chunksize=500)
그렇게 가져왔으면... pandas의 DataFrame으로 전환해주고, to_sql을 통해서 DB로 넣어주면 됩니다. 종목은 여러가 가져오기 때문에, loop를 사용하고 위의 코드만 중복해서 실행해 주면 되겠네요. 전체코드는 아래와 같습니다.
@주의사항!! table명을 종목코드로 하고 싶지만, 이럴경우 mysql(mariadb)에서는 저장은 가능하나 해당 테이블의 사용이 어려워집니다. 따라서 앞에 구분자 영문소문자를 추가하여 저장해야 합니다.
# 사용자 관심 주식종목 전체 일봉차트 DB저장
engine = create_engine('mysql://root:' + '[password]' + '@localhost/at_project', encoding='utf-8')
now = time.strftime('%Y-%m-%d')
for i in sList:
# opt10081 TR요청
kd.opt10081_res = {'date': [], 'start': [], 'high': [], 'low': [], 'finish': [], 'mount': []}
kd.SetInputValue("종목코드", i[0])
kd.SetInputValue("기준일자", now)
kd.SetInputValue("수정주가구분", "1")
kd.CommRqData("AT_opt10081", "opt10081", "0", "0101")
while kd.haveNext:
time.sleep(kd.sleepDuration)
kd.SetInputValue("종목코드", i[0])
kd.SetInputValue("기준일자", now)
kd.SetInputValue("수정주가구분", "1")
kd.CommRqData("AT_opt10081", "opt10081", "2", "0101")
opt10081_res_pd = pd.DataFrame(kd.opt10081_res)
opt10081_res_pd.to_sql('stock_'+i[0], engine, if_exists='replace', index=False, index_label=None, chunksize=500)
이렇게 되면, DB에는 총 4가지 종목에 대한 상장후 지금까지의 종목에 대한 일봉차트가 저장되어 있을 것입니다. 한번 DB를 확인해 볼까요??
다음과 같습니다. 이제 기본적인 데이터를 가져오는 부분에 대해서는 어느정도 구현이 된 것 같습니다. 이제 이 데이터를 가지고 기본적으로 분석을 위해 사용되는 항목을 뽑아내고, 활용하는 방법을 알아보고 구현을 해야겠습니다.
-Ayotera Lab-
댓글