From 0b49e88adf18a4e34630f784eee7711c7656dc1b Mon Sep 17 00:00:00 2001 From: dsyoon Date: Fri, 3 Jun 2022 13:35:25 +0900 Subject: [PATCH] init --- hts/HTS.py | 371 +++++++++++++++++++++++++++++++++++++ hts/HTS_122630.py | 366 +----------------------------------- hts/HTS_252670.py | 369 +----------------------------------- hts/util/DataDownloader.py | 299 ++++++++++++++++++++++++++++++ 4 files changed, 676 insertions(+), 729 deletions(-) create mode 100644 hts/HTS.py create mode 100644 hts/util/DataDownloader.py diff --git a/hts/HTS.py b/hts/HTS.py new file mode 100644 index 0000000..3d87287 --- /dev/null +++ b/hts/HTS.py @@ -0,0 +1,371 @@ +import win32com.client +import time +from hts.OrderItem import OrderItem + +class HTS: + + objCpCybos = None + objCpCodeMgr = None + + def __init__(self): + #self.connect() + return + + def connect(self): + # 연결 여부 체크 + self.objCpCybos = win32com.client.Dispatch("CpUtil.CpCybos") + bConnect = self.objCpCybos.IsConnect + if (bConnect == 0): + print("PLUS가 정상적으로 연결되지 않음. ") + exit() + return + + def all_stocks(self): + # 종목코드 리스트 구하기 + self.objCpCodeMgr = win32com.client.Dispatch("CpUtil.CpCodeMgr") + codeList = self.objCpCodeMgr.GetStockListByMarket(1) # 거래소 + codeList2 = self.objCpCodeMgr.GetStockListByMarket(2) # 코스닥 + + print("거래소 종목코드", len(codeList)) + for i, code in enumerate(codeList): + secondCode = self.objCpCodeMgr.GetStockSectionKind(code) + name = self.objCpCodeMgr.CodeToName(code) + stdPrice = self.objCpCodeMgr.GetStockStdPrice(code) + print(i, code, secondCode, stdPrice, name) + + print("코스닥 종목코드", len(codeList2)) + for i, code in enumerate(codeList2): + secondCode = self.objCpCodeMgr.GetStockSectionKind(code) + name = self.objCpCodeMgr.CodeToName(code) + stdPrice = self.objCpCodeMgr.GetStockStdPrice(code) + print(i, code, secondCode, stdPrice, name) + + print("거래소 + 코스닥 종목코드 ", len(codeList) + len(codeList2)) + return + + # 차트 데이터 구하기 + def getChartData(self, stock_code): + # 차트 객체 구하기 + objStockChart = win32com.client.Dispatch("CpSysDib.StockChart") + + objStockChart.SetInputValue(0, 'A'+stock_code) # 종목 코드 - 삼성전자 + objStockChart.SetInputValue(1, ord('2')) # 개수로 조회 + objStockChart.SetInputValue(4, 100) # 최근 100일 치 + objStockChart.SetInputValue(5, [0, 2, 3, 4, 5, 8]) # 날짜,시가,고가,저가,종가,거래량 + objStockChart.SetInputValue(6, ord('D')) # '차트 주가 - 일간 차트 요청 + objStockChart.SetInputValue(9, ord('1')) # 수정주가 사용 + objStockChart.BlockRequest() + + len = objStockChart.GetHeaderValue(3) + + print("날짜", "시가", "고가", "저가", "종가", "거래량") + print("==============================================-") + + for i in range(len): + day = objStockChart.GetDataValue(0, i) + open = objStockChart.GetDataValue(1, i) + high = objStockChart.GetDataValue(2, i) + low = objStockChart.GetDataValue(3, i) + close = objStockChart.GetDataValue(4, i) + vol = objStockChart.GetDataValue(5, i) + print(day, open, high, low, close, vol) + + return + + # 주식 현재가 조회 + def currentStock(self, stock_code): + # 현재가 객체 구하기 + self.objStockMst = win32com.client.Dispatch("DsCbo1.StockMst") + self.objStockMst.SetInputValue(0, 'A'+stock_code) # 종목 코드 - 삼성전자 + self.objStockMst.BlockRequest() + + # 현재가 통신 및 통신 에러 처리 + rqStatus = self.objStockMst.GetDibStatus() + rqRet = self.objStockMst.GetDibMsg1() + print("통신상태", rqStatus, rqRet) + if rqStatus != 0: + exit() + + # 현재가 정보 조회 + code = self.objStockMst.GetHeaderValue(0) # 종목코드 + name = self.objStockMst.GetHeaderValue(1) # 종목명 + time = self.objStockMst.GetHeaderValue(4) # 시간 + cprice = self.objStockMst.GetHeaderValue(11) # 종가 + diff = self.objStockMst.GetHeaderValue(12) # 대비 + open = self.objStockMst.GetHeaderValue(13) # 시가 + high = self.objStockMst.GetHeaderValue(14) # 고가 + low = self.objStockMst.GetHeaderValue(15) # 저가 + offer = self.objStockMst.GetHeaderValue(16) # 매도호가 + bid = self.objStockMst.GetHeaderValue(17) # 매수호가 + vol = self.objStockMst.GetHeaderValue(18) # 거래량 + vol_value = self.objStockMst.GetHeaderValue(19) # 거래대금 + + # 예상 체결관련 정보 + exFlag = self.objStockMst.GetHeaderValue(58) # 예상체결가 구분 플래그 + exPrice = self.objStockMst.GetHeaderValue(55) # 예상체결가 + exDiff = self.objStockMst.GetHeaderValue(56) # 예상체결가 전일대비 + exVol = self.objStockMst.GetHeaderValue(57) # 예상체결수량 + + print("코드", code) + print("이름", name) + print("시간", time) + print("종가", cprice) + print("대비", diff) + print("시가", open) + print("고가", high) + print("저가", low) + print("매도호가", offer) + print("매수호가", bid) + print("거래량", vol) + print("거래대금", vol_value) + + if (exFlag == ord('0')): + print("장 구분값: 동시호가와 장중 이외의 시간") + elif (exFlag == ord('1')): + print("장 구분값: 동시호가 시간") + elif (exFlag == ord('2')): + print("장 구분값: 장중 또는 장종료") + + print("예상체결가 대비 수량") + print("예상체결가", exPrice) + print("예상체결가 대비", exDiff) + print("예상체결수량", exVol) + + return + + # 주식 현금 매수주문 + def requestOrder(self, type, stock_code, count, price): + # type = 2: buy, type=1: sell + # 주문 초기화 + objTrade = win32com.client.Dispatch("CpTrade.CpTdUtil") + initCheck = objTrade.TradeInit(0) + if (initCheck != 0): + print("주문 초기화 실패") + exit() + + # 주식 매수 주문 + acc = objTrade.AccountNumber[0] # 계좌번호 + accFlag = objTrade.GoodsList(acc, 1) # 주식상품 구분 + # acc = "782446178" + # accFlag[0] = "01" + objStockOrder = win32com.client.Dispatch("CpTrade.CpTd0311") + objStockOrder.SetInputValue(0, type.value) # 1: 매도, 2: 매수 + objStockOrder.SetInputValue(1, acc) # 계좌번호 + objStockOrder.SetInputValue(2, accFlag[0]) # 상품구분 - 주식 상품 중 첫번째 + objStockOrder.SetInputValue(3, "A"+stock_code) # 종목코드 + objStockOrder.SetInputValue(4, count) # 매수수량 count주 + objStockOrder.SetInputValue(5, price) # 주문단가 - price 원 + objStockOrder.SetInputValue(7, "0") # 주문 조건 구분 코드, 0: 기본 1: IOC 2:FOK + objStockOrder.SetInputValue(8, "01") # 주문호가 구분코드 - 01: 보통 + + # 매수 주문 요청 + nRet = objStockOrder.BlockRequest() + if (nRet != 0): + print("order error", nRet) + return None + + rqStatus = objStockOrder.GetDibStatus() + rqRet = objStockOrder.GetDibMsg1() + print("통신상태", rqStatus, rqRet) + if rqStatus != 0: + return None + + orderNum = objStockOrder.GetHeaderValue(0) + + if (type == "1"): + print ("(SELL", count, price, ")") + else: + print ("(BUY", count, price, ")") + return orderNum + + # 계좌 잔고 확인 + def requstJango(self): + jangoDic = {} + + objTrade = win32com.client.Dispatch("CpTrade.CpTdUtil") + initCheck = objTrade.TradeInit(0) + if (initCheck != 0): + print("주문 초기화 실패") + exit() + + # 주식 매수 주문 + acc = objTrade.AccountNumber[0] # 계좌번호 + accFlag = objTrade.GoodsList(acc, 1) # 주식상품 구분 + + objRq = win32com.client.Dispatch("CpTrade.CpTd6033") + + objRq.SetInputValue(0, acc) # 계좌번호 + objRq.SetInputValue(1, accFlag[0]) # 상품구분 - 주식 상품 중 첫번째 + objRq.SetInputValue(2, 50) # 요청 건수(최대 50) + dicflag1 = {ord(' '): '현금', + ord('Y'): '융자', + ord('D'): '대주', + ord('B'): '담보', + ord('M'): '매입담보', + ord('P'): '플러스론', + ord('I'): '자기융자', + } + while True: + objRq.BlockRequest() + # 통신 및 통신 에러 처리 + rqStatus = objRq.GetDibStatus() + rqRet = objRq.GetDibMsg1() + #print("통신상태", rqStatus, rqRet) + if rqStatus != 0: + return False + + cnt = objRq.GetHeaderValue(7) + if cnt > 3: + return jangoDic + + for i in range(cnt): + item = {} + code = objRq.GetDataValue(12, i) # 종목코드 + item['종목코드'] = code + item['종목명'] = objRq.GetDataValue(0, i) # 종목명 + item['대출일'] = objRq.GetDataValue(2, i) # 대출일 + item['잔고수량'] = objRq.GetDataValue(7, i) # 체결잔고수량 + item['매도가능'] = objRq.GetDataValue(15, i) + item['장부가'] = objRq.GetDataValue(17, i) # 체결장부단가 + # item['평가금액'] = self.objRq.GetDataValue(9, i) # 평가금액(천원미만은 절사 됨) + # item['평가손익'] = self.objRq.GetDataValue(11, i) # 평가손익(천원미만은 절사 됨) + # 매입금액 = 장부가 * 잔고수량 + item['매입금액'] = item['장부가'] * item['잔고수량'] + item['현재가'] = 0 + item['대비'] = 0 + item['거래량'] = 0 + + # 잔고 추가 + # key = (code, item['현금신용'],item['대출일'] ) + key = code + jangoDic[key] = item + + if len(jangoDic) >= 3: # 최대 3 종목만, + break + + if len(jangoDic) >= 3: + break + + if (objRq.Continue == False): + break + + check = False + for item in jangoDic: + if item: + check = True + break + if not check: + return None + return jangoDic + + # 예약 주문 내역 조회 및 미체결 리스트 구하기 + def requestOrderList(self): + # type = 2: buy, type=1: sell + orderList = [] + # 주문 초기화 + objTrade = win32com.client.Dispatch("CpTrade.CpTdUtil") + initCheck = objTrade.TradeInit(0) + if (initCheck != 0): + print("주문 초기화 실패") + exit() + + # 주식 매수 주문 + acc = objTrade.AccountNumber[0] # 계좌번호 + accFlag = objTrade.GoodsList(acc, 1) # 주식상품 구분 + + objResult = win32com.client.Dispatch("CpTrade.CpTd5339") + objResult.SetInputValue(0, acc) # 계좌번호 + objResult.SetInputValue(1, accFlag[0]) # 상품구분 - 주식 상품 중 첫번째 + objResult.SetInputValue(4, "0") # 전체 + objResult.SetInputValue(5, "1") # 정렬 기준 - 역순 + objResult.SetInputValue(6, "0") # 전체 + objResult.SetInputValue(7, 20) # 요청개수 - 최대 20개 + + while True: + ret = objResult.BlockRequest() + if objResult.GetDibStatus() != 0: + print("통신상태", objResult.GetDibStatus(), objResult.GetDibMsg1()) + return False + + if (ret == 2 or ret == 3): + print("통신 오류", ret) + return False; + + # 통신 초과 요청 방지에 의한 요류 인 경우 + while (ret == 4): # 연속 주문 오류 임. 이 경우는 남은 시간동안 반드시 대기해야 함. + time.sleep(1) + ret = objResult.BlockRequest() + + # 수신 개수 + cnt = objResult.GetHeaderValue(5) + print("[Cp5339] 수신 개수 ", cnt) + if cnt == 0: + break + + for i in range(cnt): + item = OrderItem() + item.orderNum = objResult.GetDataValue(1, i) + item.orderPrev = objResult.GetDataValue(2, i) + item.code = objResult.GetDataValue(3, i) # 종목코드 + item.name = objResult.GetDataValue(4, i) # 종목명 + item.orderDesc = objResult.GetDataValue(5, i) # 주문구분내용 + item.amount = objResult.GetDataValue(6, i) # 주문수량 + item.price = objResult.GetDataValue(7, i) # 주문단가 + item.ContAmount = objResult.GetDataValue(8, i) # 체결수량 + item.credit = objResult.GetDataValue(9, i) # 신용구분 + item.modAvali = objResult.GetDataValue(11, i) # 정정취소 가능수량 + item.buysell = objResult.GetDataValue(13, i) # 매매구분코드 + item.creditdate = objResult.GetDataValue(17, i) # 대출일 + item.orderFlagDesc = objResult.GetDataValue(19, i) # 주문호가구분코드내용 + item.orderFlag = objResult.GetDataValue(21, i) # 주문호가구분코드 + + orderList.append(item) + + # 연속 처리 체크 - 다음 데이터가 없으면 중지 + if objResult.Continue == False: + print("[Cp5339] 연속 조회 여부: 다음 데이터가 없음") + break + + return orderList + + # 미체결 취소하기 + def cancelOrderList(self, orderList): + + if len(orderList) < 1: + return + + objTrade = win32com.client.Dispatch("CpTrade.CpTdUtil") + initCheck = objTrade.TradeInit(0) + if (initCheck != 0): + print("주문 초기화 실패") + exit() + acc = objTrade.AccountNumber[0] # 계좌번호 + accFlag = objTrade.GoodsList(acc, 1) # 주식상품 구분 + + objCancelOrder = win32com.client.Dispatch("CpTrade.CpTd0314") # 취소 + + onums = [] + codes = [] + amounts = [] + for item in orderList: + onums.append(item.orderNum) + codes.append(item.code) + amounts.append(item.amount) + + for i in range(len(onums)): + ordernum = onums[i] + code = codes[i] + amount = amounts[i] + objCancelOrder.SetInputValue(1, ordernum) # 원주문 번호 - 정정을 하려는 주문 번호 + objCancelOrder.SetInputValue(2, acc) # 상품구분 - 주식 상품 중 첫번째 + objCancelOrder.SetInputValue(3, accFlag[0]) # 상품구분 - 주식 상품 중 첫번째 + objCancelOrder.SetInputValue(4, code) # 종목코드 + objCancelOrder.SetInputValue(5, amount) # 정정 수량, 0 이면 잔량 취소임 + + # 취소주문 요청 + ret = objCancelOrder.BlockRequest() + print("[CpRPOrder/BlockRequestCancel] 주문결과", objCancelOrder.GetDibStatus(), objCancelOrder.GetDibMsg1()) + if objCancelOrder.GetDibStatus() != 0: + break + + return diff --git a/hts/HTS_122630.py b/hts/HTS_122630.py index 2806144..52dcee2 100644 --- a/hts/HTS_122630.py +++ b/hts/HTS_122630.py @@ -13,376 +13,14 @@ from hts.OrderChecker import OrderChecker class HTS_122630: - objCpCybos = None - objCpCodeMgr = None - buySellChecker = None stock_code = None def __init__(self, stock_code): + super().__init__() + self.buySellChecker = BuySellChecker() self.stock_code = stock_code - - #self.connect() - return - - def connect(self): - # 연결 여부 체크 - self.objCpCybos = win32com.client.Dispatch("CpUtil.CpCybos") - bConnect = self.objCpCybos.IsConnect - if (bConnect == 0): - print("PLUS가 정상적으로 연결되지 않음. ") - exit() - return - - def all_stocks(self): - # 종목코드 리스트 구하기 - self.objCpCodeMgr = win32com.client.Dispatch("CpUtil.CpCodeMgr") - codeList = self.objCpCodeMgr.GetStockListByMarket(1) # 거래소 - codeList2 = self.objCpCodeMgr.GetStockListByMarket(2) # 코스닥 - - print("거래소 종목코드", len(codeList)) - for i, code in enumerate(codeList): - secondCode = self.objCpCodeMgr.GetStockSectionKind(code) - name = self.objCpCodeMgr.CodeToName(code) - stdPrice = self.objCpCodeMgr.GetStockStdPrice(code) - print(i, code, secondCode, stdPrice, name) - - print("코스닥 종목코드", len(codeList2)) - for i, code in enumerate(codeList2): - secondCode = self.objCpCodeMgr.GetStockSectionKind(code) - name = self.objCpCodeMgr.CodeToName(code) - stdPrice = self.objCpCodeMgr.GetStockStdPrice(code) - print(i, code, secondCode, stdPrice, name) - - print("거래소 + 코스닥 종목코드 ", len(codeList) + len(codeList2)) - return - - # 차트 데이터 구하기 - def getChartData(self, stock_code): - # 차트 객체 구하기 - objStockChart = win32com.client.Dispatch("CpSysDib.StockChart") - - objStockChart.SetInputValue(0, 'A'+stock_code) # 종목 코드 - 삼성전자 - objStockChart.SetInputValue(1, ord('2')) # 개수로 조회 - objStockChart.SetInputValue(4, 100) # 최근 100일 치 - objStockChart.SetInputValue(5, [0, 2, 3, 4, 5, 8]) # 날짜,시가,고가,저가,종가,거래량 - objStockChart.SetInputValue(6, ord('D')) # '차트 주가 - 일간 차트 요청 - objStockChart.SetInputValue(9, ord('1')) # 수정주가 사용 - objStockChart.BlockRequest() - - len = objStockChart.GetHeaderValue(3) - - print("날짜", "시가", "고가", "저가", "종가", "거래량") - print("==============================================-") - - for i in range(len): - day = objStockChart.GetDataValue(0, i) - open = objStockChart.GetDataValue(1, i) - high = objStockChart.GetDataValue(2, i) - low = objStockChart.GetDataValue(3, i) - close = objStockChart.GetDataValue(4, i) - vol = objStockChart.GetDataValue(5, i) - print(day, open, high, low, close, vol) - - return - - # 주식 현재가 조회 - def currentStock(self, stock_code): - # 현재가 객체 구하기 - self.objStockMst = win32com.client.Dispatch("DsCbo1.StockMst") - self.objStockMst.SetInputValue(0, 'A'+stock_code) # 종목 코드 - 삼성전자 - self.objStockMst.BlockRequest() - - # 현재가 통신 및 통신 에러 처리 - rqStatus = self.objStockMst.GetDibStatus() - rqRet = self.objStockMst.GetDibMsg1() - print("통신상태", rqStatus, rqRet) - if rqStatus != 0: - exit() - - # 현재가 정보 조회 - code = self.objStockMst.GetHeaderValue(0) # 종목코드 - name = self.objStockMst.GetHeaderValue(1) # 종목명 - time = self.objStockMst.GetHeaderValue(4) # 시간 - cprice = self.objStockMst.GetHeaderValue(11) # 종가 - diff = self.objStockMst.GetHeaderValue(12) # 대비 - open = self.objStockMst.GetHeaderValue(13) # 시가 - high = self.objStockMst.GetHeaderValue(14) # 고가 - low = self.objStockMst.GetHeaderValue(15) # 저가 - offer = self.objStockMst.GetHeaderValue(16) # 매도호가 - bid = self.objStockMst.GetHeaderValue(17) # 매수호가 - vol = self.objStockMst.GetHeaderValue(18) # 거래량 - vol_value = self.objStockMst.GetHeaderValue(19) # 거래대금 - - # 예상 체결관련 정보 - exFlag = self.objStockMst.GetHeaderValue(58) # 예상체결가 구분 플래그 - exPrice = self.objStockMst.GetHeaderValue(55) # 예상체결가 - exDiff = self.objStockMst.GetHeaderValue(56) # 예상체결가 전일대비 - exVol = self.objStockMst.GetHeaderValue(57) # 예상체결수량 - - print("코드", code) - print("이름", name) - print("시간", time) - print("종가", cprice) - print("대비", diff) - print("시가", open) - print("고가", high) - print("저가", low) - print("매도호가", offer) - print("매수호가", bid) - print("거래량", vol) - print("거래대금", vol_value) - - if (exFlag == ord('0')): - print("장 구분값: 동시호가와 장중 이외의 시간") - elif (exFlag == ord('1')): - print("장 구분값: 동시호가 시간") - elif (exFlag == ord('2')): - print("장 구분값: 장중 또는 장종료") - - print("예상체결가 대비 수량") - print("예상체결가", exPrice) - print("예상체결가 대비", exDiff) - print("예상체결수량", exVol) - - return - - # 주식 현금 매수주문 - def requestOrder(self, type, stock_code, count, price): - # type = 2: buy, type=1: sell - # 주문 초기화 - objTrade = win32com.client.Dispatch("CpTrade.CpTdUtil") - initCheck = objTrade.TradeInit(0) - if (initCheck != 0): - print("주문 초기화 실패") - exit() - - # 주식 매수 주문 - acc = objTrade.AccountNumber[0] # 계좌번호 - accFlag = objTrade.GoodsList(acc, 1) # 주식상품 구분 - # acc = "782446178" - # accFlag[0] = "01" - objStockOrder = win32com.client.Dispatch("CpTrade.CpTd0311") - objStockOrder.SetInputValue(0, type.value) # 1: 매도, 2: 매수 - objStockOrder.SetInputValue(1, acc) # 계좌번호 - objStockOrder.SetInputValue(2, accFlag[0]) # 상품구분 - 주식 상품 중 첫번째 - objStockOrder.SetInputValue(3, "A"+stock_code) # 종목코드 - objStockOrder.SetInputValue(4, count) # 매수수량 count주 - objStockOrder.SetInputValue(5, price) # 주문단가 - price 원 - objStockOrder.SetInputValue(7, "0") # 주문 조건 구분 코드, 0: 기본 1: IOC 2:FOK - objStockOrder.SetInputValue(8, "01") # 주문호가 구분코드 - 01: 보통 - - # 매수 주문 요청 - nRet = objStockOrder.BlockRequest() - if (nRet != 0): - print("order error", nRet) - return None - - rqStatus = objStockOrder.GetDibStatus() - rqRet = objStockOrder.GetDibMsg1() - print("통신상태", rqStatus, rqRet) - if rqStatus != 0: - return None - - orderNum = objStockOrder.GetHeaderValue(0) - - if (type == "1"): - print ("(SELL", count, price, ")") - else: - print ("(BUY", count, price, ")") - return orderNum - - # 계좌 잔고 확인 - def requstJango(self): - jangoDic = {} - - objTrade = win32com.client.Dispatch("CpTrade.CpTdUtil") - initCheck = objTrade.TradeInit(0) - if (initCheck != 0): - print("주문 초기화 실패") - exit() - - # 주식 매수 주문 - acc = objTrade.AccountNumber[0] # 계좌번호 - accFlag = objTrade.GoodsList(acc, 1) # 주식상품 구분 - - objRq = win32com.client.Dispatch("CpTrade.CpTd6033") - - objRq.SetInputValue(0, acc) # 계좌번호 - objRq.SetInputValue(1, accFlag[0]) # 상품구분 - 주식 상품 중 첫번째 - objRq.SetInputValue(2, 50) # 요청 건수(최대 50) - dicflag1 = {ord(' '): '현금', - ord('Y'): '융자', - ord('D'): '대주', - ord('B'): '담보', - ord('M'): '매입담보', - ord('P'): '플러스론', - ord('I'): '자기융자', - } - while True: - objRq.BlockRequest() - # 통신 및 통신 에러 처리 - rqStatus = objRq.GetDibStatus() - rqRet = objRq.GetDibMsg1() - #print("통신상태", rqStatus, rqRet) - if rqStatus != 0: - return False - - cnt = objRq.GetHeaderValue(7) - if cnt > 3: - return jangoDic - - for i in range(cnt): - item = {} - code = objRq.GetDataValue(12, i) # 종목코드 - item['종목코드'] = code - item['종목명'] = objRq.GetDataValue(0, i) # 종목명 - item['대출일'] = objRq.GetDataValue(2, i) # 대출일 - item['잔고수량'] = objRq.GetDataValue(7, i) # 체결잔고수량 - item['매도가능'] = objRq.GetDataValue(15, i) - item['장부가'] = objRq.GetDataValue(17, i) # 체결장부단가 - # item['평가금액'] = self.objRq.GetDataValue(9, i) # 평가금액(천원미만은 절사 됨) - # item['평가손익'] = self.objRq.GetDataValue(11, i) # 평가손익(천원미만은 절사 됨) - # 매입금액 = 장부가 * 잔고수량 - item['매입금액'] = item['장부가'] * item['잔고수량'] - item['현재가'] = 0 - item['대비'] = 0 - item['거래량'] = 0 - - # 잔고 추가 - # key = (code, item['현금신용'],item['대출일'] ) - key = code - jangoDic[key] = item - - if len(jangoDic) >= 3: # 최대 3 종목만, - break - - if len(jangoDic) >= 3: - break - - if (objRq.Continue == False): - break - - check = False - for item in jangoDic: - if item: - check = True - break - if not check: - return None - return jangoDic - - # 예약 주문 내역 조회 및 미체결 리스트 구하기 - def requestOrderList(self): - # type = 2: buy, type=1: sell - orderList = [] - # 주문 초기화 - objTrade = win32com.client.Dispatch("CpTrade.CpTdUtil") - initCheck = objTrade.TradeInit(0) - if (initCheck != 0): - print("주문 초기화 실패") - exit() - - # 주식 매수 주문 - acc = objTrade.AccountNumber[0] # 계좌번호 - accFlag = objTrade.GoodsList(acc, 1) # 주식상품 구분 - - objResult = win32com.client.Dispatch("CpTrade.CpTd5339") - objResult.SetInputValue(0, acc) # 계좌번호 - objResult.SetInputValue(1, accFlag[0]) # 상품구분 - 주식 상품 중 첫번째 - objResult.SetInputValue(4, "0") # 전체 - objResult.SetInputValue(5, "1") # 정렬 기준 - 역순 - objResult.SetInputValue(6, "0") # 전체 - objResult.SetInputValue(7, 20) # 요청개수 - 최대 20개 - - while True: - ret = objResult.BlockRequest() - if objResult.GetDibStatus() != 0: - print("통신상태", objResult.GetDibStatus(), objResult.GetDibMsg1()) - return False - - if (ret == 2 or ret == 3): - print("통신 오류", ret) - return False; - - # 통신 초과 요청 방지에 의한 요류 인 경우 - while (ret == 4): # 연속 주문 오류 임. 이 경우는 남은 시간동안 반드시 대기해야 함. - time.sleep(1) - ret = objResult.BlockRequest() - - # 수신 개수 - cnt = objResult.GetHeaderValue(5) - print("[Cp5339] 수신 개수 ", cnt) - if cnt == 0: - break - - for i in range(cnt): - item = OrderItem() - item.orderNum = objResult.GetDataValue(1, i) - item.orderPrev = objResult.GetDataValue(2, i) - item.code = objResult.GetDataValue(3, i) # 종목코드 - item.name = objResult.GetDataValue(4, i) # 종목명 - item.orderDesc = objResult.GetDataValue(5, i) # 주문구분내용 - item.amount = objResult.GetDataValue(6, i) # 주문수량 - item.price = objResult.GetDataValue(7, i) # 주문단가 - item.ContAmount = objResult.GetDataValue(8, i) # 체결수량 - item.credit = objResult.GetDataValue(9, i) # 신용구분 - item.modAvali = objResult.GetDataValue(11, i) # 정정취소 가능수량 - item.buysell = objResult.GetDataValue(13, i) # 매매구분코드 - item.creditdate = objResult.GetDataValue(17, i) # 대출일 - item.orderFlagDesc = objResult.GetDataValue(19, i) # 주문호가구분코드내용 - item.orderFlag = objResult.GetDataValue(21, i) # 주문호가구분코드 - - orderList.append(item) - - # 연속 처리 체크 - 다음 데이터가 없으면 중지 - if objResult.Continue == False: - print("[Cp5339] 연속 조회 여부: 다음 데이터가 없음") - break - - return orderList - - # 미체결 취소하기 - def cancelOrderList(self, orderList): - - if len(orderList) < 1: - return - - objTrade = win32com.client.Dispatch("CpTrade.CpTdUtil") - initCheck = objTrade.TradeInit(0) - if (initCheck != 0): - print("주문 초기화 실패") - exit() - acc = objTrade.AccountNumber[0] # 계좌번호 - accFlag = objTrade.GoodsList(acc, 1) # 주식상품 구분 - - objCancelOrder = win32com.client.Dispatch("CpTrade.CpTd0314") # 취소 - - onums = [] - codes = [] - amounts = [] - for item in orderList: - onums.append(item.orderNum) - codes.append(item.code) - amounts.append(item.amount) - - for i in range(len(onums)): - ordernum = onums[i] - code = codes[i] - amount = amounts[i] - objCancelOrder.SetInputValue(1, ordernum) # 원주문 번호 - 정정을 하려는 주문 번호 - objCancelOrder.SetInputValue(2, acc) # 상품구분 - 주식 상품 중 첫번째 - objCancelOrder.SetInputValue(3, accFlag[0]) # 상품구분 - 주식 상품 중 첫번째 - objCancelOrder.SetInputValue(4, code) # 종목코드 - objCancelOrder.SetInputValue(5, amount) # 정정 수량, 0 이면 잔량 취소임 - - # 취소주문 요청 - ret = objCancelOrder.BlockRequest() - print("[CpRPOrder/BlockRequestCancel] 주문결과", objCancelOrder.GetDibStatus(), objCancelOrder.GetDibMsg1()) - if objCancelOrder.GetDibStatus() != 0: - break - return # 주식 현재가 조회 diff --git a/hts/HTS_252670.py b/hts/HTS_252670.py index 65e8f94..024a996 100644 --- a/hts/HTS_252670.py +++ b/hts/HTS_252670.py @@ -4,6 +4,7 @@ import os from datetime import datetime import pandas as pd +from hts.HTS import HTS from hts.OrderType import OrderType from hts.OrderItem import OrderItem @@ -11,378 +12,16 @@ from hts.BuySellChecker import BuySellChecker from hts.OrderChecker import OrderChecker -class HTS_252670: - - objCpCybos = None - objCpCodeMgr = None +class HTS_252670 (HTS): buySellChecker = None stock_code = None def __init__(self, stock_code): + super().__init__() + self.buySellChecker = BuySellChecker() self.stock_code = stock_code - - #self.connect() - return - - def connect(self): - # 연결 여부 체크 - self.objCpCybos = win32com.client.Dispatch("CpUtil.CpCybos") - bConnect = self.objCpCybos.IsConnect - if (bConnect == 0): - print("PLUS가 정상적으로 연결되지 않음. ") - exit() - return - - def all_stocks(self): - # 종목코드 리스트 구하기 - self.objCpCodeMgr = win32com.client.Dispatch("CpUtil.CpCodeMgr") - codeList = self.objCpCodeMgr.GetStockListByMarket(1) # 거래소 - codeList2 = self.objCpCodeMgr.GetStockListByMarket(2) # 코스닥 - - print("거래소 종목코드", len(codeList)) - for i, code in enumerate(codeList): - secondCode = self.objCpCodeMgr.GetStockSectionKind(code) - name = self.objCpCodeMgr.CodeToName(code) - stdPrice = self.objCpCodeMgr.GetStockStdPrice(code) - print(i, code, secondCode, stdPrice, name) - - print("코스닥 종목코드", len(codeList2)) - for i, code in enumerate(codeList2): - secondCode = self.objCpCodeMgr.GetStockSectionKind(code) - name = self.objCpCodeMgr.CodeToName(code) - stdPrice = self.objCpCodeMgr.GetStockStdPrice(code) - print(i, code, secondCode, stdPrice, name) - - print("거래소 + 코스닥 종목코드 ", len(codeList) + len(codeList2)) - return - - # 차트 데이터 구하기 - def getChartData(self, stock_code): - # 차트 객체 구하기 - objStockChart = win32com.client.Dispatch("CpSysDib.StockChart") - - objStockChart.SetInputValue(0, 'A'+stock_code) # 종목 코드 - 삼성전자 - objStockChart.SetInputValue(1, ord('2')) # 개수로 조회 - objStockChart.SetInputValue(4, 100) # 최근 100일 치 - objStockChart.SetInputValue(5, [0, 2, 3, 4, 5, 8]) # 날짜,시가,고가,저가,종가,거래량 - objStockChart.SetInputValue(6, ord('D')) # '차트 주가 - 일간 차트 요청 - objStockChart.SetInputValue(9, ord('1')) # 수정주가 사용 - objStockChart.BlockRequest() - - len = objStockChart.GetHeaderValue(3) - - print("날짜", "시가", "고가", "저가", "종가", "거래량") - print("==============================================-") - - for i in range(len): - day = objStockChart.GetDataValue(0, i) - open = objStockChart.GetDataValue(1, i) - high = objStockChart.GetDataValue(2, i) - low = objStockChart.GetDataValue(3, i) - close = objStockChart.GetDataValue(4, i) - vol = objStockChart.GetDataValue(5, i) - print(day, open, high, low, close, vol) - - return - - # 주식 현재가 조회 - def currentStock(self, stock_code): - # 현재가 객체 구하기 - self.objStockMst = win32com.client.Dispatch("DsCbo1.StockMst") - self.objStockMst.SetInputValue(0, 'A'+stock_code) # 종목 코드 - 삼성전자 - self.objStockMst.BlockRequest() - - # 현재가 통신 및 통신 에러 처리 - rqStatus = self.objStockMst.GetDibStatus() - rqRet = self.objStockMst.GetDibMsg1() - print("통신상태", rqStatus, rqRet) - if rqStatus != 0: - exit() - - # 현재가 정보 조회 - code = self.objStockMst.GetHeaderValue(0) # 종목코드 - name = self.objStockMst.GetHeaderValue(1) # 종목명 - time = self.objStockMst.GetHeaderValue(4) # 시간 - cprice = self.objStockMst.GetHeaderValue(11) # 종가 - diff = self.objStockMst.GetHeaderValue(12) # 대비 - open = self.objStockMst.GetHeaderValue(13) # 시가 - high = self.objStockMst.GetHeaderValue(14) # 고가 - low = self.objStockMst.GetHeaderValue(15) # 저가 - offer = self.objStockMst.GetHeaderValue(16) # 매도호가 - bid = self.objStockMst.GetHeaderValue(17) # 매수호가 - vol = self.objStockMst.GetHeaderValue(18) # 거래량 - vol_value = self.objStockMst.GetHeaderValue(19) # 거래대금 - - # 예상 체결관련 정보 - exFlag = self.objStockMst.GetHeaderValue(58) # 예상체결가 구분 플래그 - exPrice = self.objStockMst.GetHeaderValue(55) # 예상체결가 - exDiff = self.objStockMst.GetHeaderValue(56) # 예상체결가 전일대비 - exVol = self.objStockMst.GetHeaderValue(57) # 예상체결수량 - - print("코드", code) - print("이름", name) - print("시간", time) - print("종가", cprice) - print("대비", diff) - print("시가", open) - print("고가", high) - print("저가", low) - print("매도호가", offer) - print("매수호가", bid) - print("거래량", vol) - print("거래대금", vol_value) - - if (exFlag == ord('0')): - print("장 구분값: 동시호가와 장중 이외의 시간") - elif (exFlag == ord('1')): - print("장 구분값: 동시호가 시간") - elif (exFlag == ord('2')): - print("장 구분값: 장중 또는 장종료") - - print("예상체결가 대비 수량") - print("예상체결가", exPrice) - print("예상체결가 대비", exDiff) - print("예상체결수량", exVol) - - return - - # 주식 현금 매수주문 - def requestOrder(self, type, stock_code, count, price): - # type = 2: buy, type=1: sell - # 주문 초기화 - objTrade = win32com.client.Dispatch("CpTrade.CpTdUtil") - initCheck = objTrade.TradeInit(0) - if (initCheck != 0): - print("주문 초기화 실패") - exit() - - # 주식 매수 주문 - acc = objTrade.AccountNumber[0] # 계좌번호 - accFlag = objTrade.GoodsList(acc, 1) # 주식상품 구분 - # acc = "782446178" - # accFlag[0] = "01" - objStockOrder = win32com.client.Dispatch("CpTrade.CpTd0311") - objStockOrder.SetInputValue(0, type.value) # 1: 매도, 2: 매수 - objStockOrder.SetInputValue(1, acc) # 계좌번호 - objStockOrder.SetInputValue(2, accFlag[0]) # 상품구분 - 주식 상품 중 첫번째 - objStockOrder.SetInputValue(3, "A"+stock_code) # 종목코드 - objStockOrder.SetInputValue(4, count) # 매수수량 count주 - objStockOrder.SetInputValue(5, price) # 주문단가 - price 원 - objStockOrder.SetInputValue(7, "0") # 주문 조건 구분 코드, 0: 기본 1: IOC 2:FOK - objStockOrder.SetInputValue(8, "01") # 주문호가 구분코드 - 01: 보통 - - # 매수 주문 요청 - nRet = objStockOrder.BlockRequest() - if (nRet != 0): - print("order error", nRet) - return None - - rqStatus = objStockOrder.GetDibStatus() - rqRet = objStockOrder.GetDibMsg1() - print("통신상태", rqStatus, rqRet) - if rqStatus != 0: - return None - - orderNum = objStockOrder.GetHeaderValue(0) - - if (type == "1"): - print ("(SELL", count, price, ")") - else: - print ("(BUY", count, price, ")") - return orderNum - - # 계좌 잔고 확인 - def requstJango(self): - jangoDic = {} - - objTrade = win32com.client.Dispatch("CpTrade.CpTdUtil") - initCheck = objTrade.TradeInit(0) - if (initCheck != 0): - print("주문 초기화 실패") - exit() - - # 주식 매수 주문 - acc = objTrade.AccountNumber[0] # 계좌번호 - accFlag = objTrade.GoodsList(acc, 1) # 주식상품 구분 - - objRq = win32com.client.Dispatch("CpTrade.CpTd6033") - - objRq.SetInputValue(0, acc) # 계좌번호 - objRq.SetInputValue(1, accFlag[0]) # 상품구분 - 주식 상품 중 첫번째 - objRq.SetInputValue(2, 50) # 요청 건수(최대 50) - dicflag1 = {ord(' '): '현금', - ord('Y'): '융자', - ord('D'): '대주', - ord('B'): '담보', - ord('M'): '매입담보', - ord('P'): '플러스론', - ord('I'): '자기융자', - } - while True: - objRq.BlockRequest() - # 통신 및 통신 에러 처리 - rqStatus = objRq.GetDibStatus() - rqRet = objRq.GetDibMsg1() - #print("통신상태", rqStatus, rqRet) - if rqStatus != 0: - return False - - cnt = objRq.GetHeaderValue(7) - if cnt > 3: - return jangoDic - - for i in range(cnt): - item = {} - code = objRq.GetDataValue(12, i) # 종목코드 - item['종목코드'] = code - item['종목명'] = objRq.GetDataValue(0, i) # 종목명 - item['대출일'] = objRq.GetDataValue(2, i) # 대출일 - item['잔고수량'] = objRq.GetDataValue(7, i) # 체결잔고수량 - item['매도가능'] = objRq.GetDataValue(15, i) - item['장부가'] = objRq.GetDataValue(17, i) # 체결장부단가 - # item['평가금액'] = self.objRq.GetDataValue(9, i) # 평가금액(천원미만은 절사 됨) - # item['평가손익'] = self.objRq.GetDataValue(11, i) # 평가손익(천원미만은 절사 됨) - # 매입금액 = 장부가 * 잔고수량 - item['매입금액'] = item['장부가'] * item['잔고수량'] - item['현재가'] = 0 - item['대비'] = 0 - item['거래량'] = 0 - - # 잔고 추가 - # key = (code, item['현금신용'],item['대출일'] ) - key = code - jangoDic[key] = item - - if len(jangoDic) >= 3: # 최대 3 종목만, - break - - if len(jangoDic) >= 3: - break - - if (objRq.Continue == False): - break - - check = False - for item in jangoDic: - if item: - check = True - break - if not check: - return None - return jangoDic - - # 예약 주문 내역 조회 및 미체결 리스트 구하기 - def requestOrderList(self): - # type = 2: buy, type=1: sell - orderList = [] - # 주문 초기화 - objTrade = win32com.client.Dispatch("CpTrade.CpTdUtil") - initCheck = objTrade.TradeInit(0) - if (initCheck != 0): - print("주문 초기화 실패") - exit() - - # 주식 매수 주문 - acc = objTrade.AccountNumber[0] # 계좌번호 - accFlag = objTrade.GoodsList(acc, 1) # 주식상품 구분 - - objResult = win32com.client.Dispatch("CpTrade.CpTd5339") - objResult.SetInputValue(0, acc) # 계좌번호 - objResult.SetInputValue(1, accFlag[0]) # 상품구분 - 주식 상품 중 첫번째 - objResult.SetInputValue(4, "0") # 전체 - objResult.SetInputValue(5, "1") # 정렬 기준 - 역순 - objResult.SetInputValue(6, "0") # 전체 - objResult.SetInputValue(7, 20) # 요청개수 - 최대 20개 - - while True: - ret = objResult.BlockRequest() - if objResult.GetDibStatus() != 0: - print("통신상태", objResult.GetDibStatus(), objResult.GetDibMsg1()) - return False - - if (ret == 2 or ret == 3): - print("통신 오류", ret) - return False; - - # 통신 초과 요청 방지에 의한 요류 인 경우 - while (ret == 4): # 연속 주문 오류 임. 이 경우는 남은 시간동안 반드시 대기해야 함. - time.sleep(1) - ret = objResult.BlockRequest() - - # 수신 개수 - cnt = objResult.GetHeaderValue(5) - print("[Cp5339] 수신 개수 ", cnt) - if cnt == 0: - break - - for i in range(cnt): - item = OrderItem() - item.orderNum = objResult.GetDataValue(1, i) - item.orderPrev = objResult.GetDataValue(2, i) - item.code = objResult.GetDataValue(3, i) # 종목코드 - item.name = objResult.GetDataValue(4, i) # 종목명 - item.orderDesc = objResult.GetDataValue(5, i) # 주문구분내용 - item.amount = objResult.GetDataValue(6, i) # 주문수량 - item.price = objResult.GetDataValue(7, i) # 주문단가 - item.ContAmount = objResult.GetDataValue(8, i) # 체결수량 - item.credit = objResult.GetDataValue(9, i) # 신용구분 - item.modAvali = objResult.GetDataValue(11, i) # 정정취소 가능수량 - item.buysell = objResult.GetDataValue(13, i) # 매매구분코드 - item.creditdate = objResult.GetDataValue(17, i) # 대출일 - item.orderFlagDesc = objResult.GetDataValue(19, i) # 주문호가구분코드내용 - item.orderFlag = objResult.GetDataValue(21, i) # 주문호가구분코드 - - orderList.append(item) - - # 연속 처리 체크 - 다음 데이터가 없으면 중지 - if objResult.Continue == False: - print("[Cp5339] 연속 조회 여부: 다음 데이터가 없음") - break - - return orderList - - # 미체결 취소하기 - def cancelOrderList(self, orderList): - - if len(orderList) < 1: - return - - objTrade = win32com.client.Dispatch("CpTrade.CpTdUtil") - initCheck = objTrade.TradeInit(0) - if (initCheck != 0): - print("주문 초기화 실패") - exit() - acc = objTrade.AccountNumber[0] # 계좌번호 - accFlag = objTrade.GoodsList(acc, 1) # 주식상품 구분 - - objCancelOrder = win32com.client.Dispatch("CpTrade.CpTd0314") # 취소 - - onums = [] - codes = [] - amounts = [] - for item in orderList: - onums.append(item.orderNum) - codes.append(item.code) - amounts.append(item.amount) - - for i in range(len(onums)): - ordernum = onums[i] - code = codes[i] - amount = amounts[i] - objCancelOrder.SetInputValue(1, ordernum) # 원주문 번호 - 정정을 하려는 주문 번호 - objCancelOrder.SetInputValue(2, acc) # 상품구분 - 주식 상품 중 첫번째 - objCancelOrder.SetInputValue(3, accFlag[0]) # 상품구분 - 주식 상품 중 첫번째 - objCancelOrder.SetInputValue(4, code) # 종목코드 - objCancelOrder.SetInputValue(5, amount) # 정정 수량, 0 이면 잔량 취소임 - - # 취소주문 요청 - ret = objCancelOrder.BlockRequest() - print("[CpRPOrder/BlockRequestCancel] 주문결과", objCancelOrder.GetDibStatus(), objCancelOrder.GetDibMsg1()) - if objCancelOrder.GetDibStatus() != 0: - break - return # 주식 현재가 조회 diff --git a/hts/util/DataDownloader.py b/hts/util/DataDownloader.py new file mode 100644 index 0000000..bfc0a20 --- /dev/null +++ b/hts/util/DataDownloader.py @@ -0,0 +1,299 @@ +import win32com.client +import time +import os +from datetime import datetime +import pandas as pd + +from hts.HTS import HTS + +from hts.BuySellChecker import BuySellChecker + + +class DataDownloader (HTS): + + buySellChecker = None + stock_code = None + + def __init__(self): + super().__init__() + + return + + # 주식 현재가 조회 + def writeStockData(self, stock_code, given_day): + objCpCybos = win32com.client.Dispatch("CpUtil.CpCybos") + bConnect = objCpCybos.IsConnect + if (bConnect == 0): + print("PLUS가 정상적으로 연결되지 않음. ") + exit() + + # 차트 객체 구하기 + objStockChart = win32com.client.Dispatch("CpSysDib.StockChart") + + outfp = open("./data/"+stock_code+"_"+given_day+".csv", mode="w", encoding="utf-8") + objStockChart.SetInputValue(0, 'A' + stock_code) # 종목 코드 + objStockChart.SetInputValue(1, ord('1')) # 1: 기간으로 조회, 2: 개수로 조회 + objStockChart.SetInputValue(2, given_day) # 기간 조회 시, 시작일 + objStockChart.SetInputValue(3, given_day) # 기간 조회 시, 종료일 + objStockChart.SetInputValue(4, 400) # 조회 시 가져오는 Line 개수 + objStockChart.SetInputValue(5, [0, 1, 2, 3, 4, 5, 8]) # 날짜,시간,시가,고가,저가,종가,거래량 + objStockChart.SetInputValue(6, ord('m')) # '차트 주가 - 월(M), 주(W), 일(D), 시(H), 분(m), 초(S) 차트 요청 + objStockChart.SetInputValue(7, 1) + objStockChart.SetInputValue(9, ord('1')) # 수정주가 사용 + objStockChart.BlockRequest() + + size = objStockChart.GetHeaderValue(3) + + outfp.write("%s,%s,%s,%s,%s,%s,%s\n" % ("날짜", "시간", "시가", "고가", "저가", "종가", "거래량")) + for i in range(size - 1, -1, -1): + day = objStockChart.GetDataValue(0, i) + time = objStockChart.GetDataValue(1, i) + start = objStockChart.GetDataValue(2, i) + high = objStockChart.GetDataValue(3, i) + low = objStockChart.GetDataValue(4, i) + close = objStockChart.GetDataValue(5, i) + vol = objStockChart.GetDataValue(6, i) + outfp.write("%d,%s,%d,%d,%d,%d,%d\n" % (day, str(time).zfill(4), start, high, low, close, vol)) + outfp.close() + + return + + + def write(self, day, result): + #날짜,시간,시가,고가,저가,종가,거래량 + #20210909,900,2070,2070,2070,2070,0 + + outFp = open(day+".csv", mode="w", encoding="UTF-8") + outFp.write("날짜,시간,시가,고가,저가,종가,거래량\n") + for i in range(len(result["time"])): + outFp.write("%s,%s,%s,%s,%s,%s,%s\n"%( + result["time"][i].strftime('%Y%m%d'), + result["time"][i].strftime('%H%M'), + result["open"][i], + result["high"][i], + result["low"][i], + result["close"][i], + result["vol"][i])) + outFp.close() + return + + # 주식 현재가 조회 + def getRealTime(self, stock_code, given_day, result): + int_given_day = int(given_day) + objCpCybos = win32com.client.Dispatch("CpUtil.CpCybos") + bConnect = objCpCybos.IsConnect + if (bConnect == 0): + print("PLUS가 정상적으로 연결되지 않음. ") + exit() + + # 차트 객체 구하기 + objStockChart = win32com.client.Dispatch("CpSysDib.StockChart") + + objStockChart.SetInputValue(0, 'A'+stock_code) # 종목 코드 + objStockChart.SetInputValue(1, ord('1')) # 1: 기간으로 조회, 2: 개수로 조회 + objStockChart.SetInputValue(2, given_day) # 기간 조회 시, 시작일 + objStockChart.SetInputValue(3, given_day) # 기간 조회 시, 종료일 + objStockChart.SetInputValue(4, 400) # 조회 시 가져오는 Line 개수 + objStockChart.SetInputValue(5, [0, 1, 2, 3, 4, 5, 8]) # 날짜,시간,시가,고가,저가,종가,거래량 + objStockChart.SetInputValue(6, ord('m')) # '차트 주가 - 월(M), 주(W), 일(D), 시(H), 분(m), 초(S) 차트 요청 + objStockChart.SetInputValue(7, 1) + objStockChart.SetInputValue(9, ord('1')) # 수정주가 사용 + objStockChart.BlockRequest() + + size = objStockChart.GetHeaderValue(3) + + #print("날짜", "시간", "시가", "고가", "저가", "종가", "거래량") + start_time = datetime.strptime(given_day + " 090000", '%Y%m%d %H%M%S') + for i in range(size-1, -1, -1): + int_day = objStockChart.GetDataValue(0, i) + int_time = objStockChart.GetDataValue(1, i) + + if int_day < int_given_day: + continue + time = datetime.strptime(str(int_day)+" "+str(int_time).zfill(4)+"00", '%Y%m%d %H%M%S') + if time < start_time: + continue + + open = objStockChart.GetDataValue(2, i) + close = objStockChart.GetDataValue(5, i) + high = objStockChart.GetDataValue(3, i) + low = objStockChart.GetDataValue(4, i) + vol = objStockChart.GetDataValue(6, i) + + if len(result["check"]) == 0: + result["check"].add(start_time) + result["time"].append(start_time) + result["open"].append(open) + result["close"].append(open) + result["high"].append(open) + result["low"].append(open) + result["vol"].append(0) + + if time not in result["check"]: + result["check"].add(time) + result["time"].append(time) + + result["open"].append(open) + result["close"].append(close) + result["high"].append(high) + result["low"].append(low) + result["vol"].append(vol) + + return + + def checkTransaction(self, data): + size = len(data["close"]) + + bsLine = {} + bsLine['buy'] = [-1 for i in range(size)] + bsLine['weight'] = [-1 for i in range(size)] + bsLine['sell'] = [-1 for i in range(size)] + + i = size - 1 + if i < 5: + return -1, -1, -1 + + buy, weight, sell = self.buySellChecker.getPriceAndWeight1(data, i) + return buy, weight, sell + + def getSellingPrice(self, final_price): + # 만약 잔고가 있으면 장부가보다 5원 높게 매도한다. + jangoDic = self.requstJango() + if jangoDic and len(jangoDic.keys()) > 0: + for code in jangoDic: + if jangoDic[code]['매도가능'] > 0: + if final_price >= jangoDic[code]['장부가'] + 5: + return jangoDic[code]['매도가능'], final_price + else: + # 장부가 가격의 마지막 자리를 0으로 만든다. (2090 -> 2090, 2092 -> 2090, 2098 -> 2090) + sell_price = int(jangoDic[code]['장부가'] / 10) * 10 + # 장부가의 마지막 자리수를 가져온다. + last_number = int(jangoDic[code]['장부가']) % 10 + if last_number in [0, 1, 2, 3]: + # 장부가의 마지막 자리수가 0,1,2,3 이라면 (2090, 2091, 2092 -> 2095 에 매도) + return jangoDic[code]['매도가능'], sell_price + 5 + elif last_number in [4, 5, 6, 7]: + # 장부가의 마지막 자리수가 4,5,6,7 이라면 (2093, 2094, 2095, 2096 -> 2100 에 매도) + return jangoDic[code]['매도가능'], sell_price + 10 + else: + # 장부가의 마지막 자리수가 8,9 라면 (2098, 2099 -> 2105 에 매도) + return jangoDic[code]['매도가능'], sell_price + 15 + + return 0, 0 + + def buyRealTime(self, GIVEN_DAY): + orderChecker = OrderChecker(self.stock_code) + BASE_COUNT = 500 + + timecheckList = pd.read_csv("timecheck.csv").values.tolist() + timecheck = {GIVEN_DAY + " " + str(second).zfill(6):False for second, check in timecheckList} + + result = {"check": set(), + "time": [], + "open": [], + "close": [], + "high": [], + "low": [], + "vol": []} + + print ("START...") + THIS_TIME = datetime.now() + while datetime.strptime(GIVEN_DAY + " 070000", '%Y%m%d %H%M%S') < THIS_TIME < datetime.strptime(GIVEN_DAY + " 15200", '%Y%m%d %H%M%S'): + + if datetime.strptime(GIVEN_DAY + " 090100", '%Y%m%d %H%M%S') < THIS_TIME < datetime.strptime(GIVEN_DAY + " 151500", '%Y%m%d %H%M%S'): + if THIS_TIME.strftime('%Y%m%d %H%M%S') in timecheck and not timecheck[THIS_TIME.strftime('%Y%m%d %H%M%S')]: + + # 데이터를 가지고 온다. + self.getRealTime(self.stock_code, GIVEN_DAY, result) + + # 분석을 통해서 볼린저밴드 상/하단을 계산한다. + data = self.buySellChecker.analyze(result) + # 사야 할 시점/가격과 팔아야 할 시점/가격을 체크한다. + bs_buy_price, bs_weight, bs_sell_price = self.checkTransaction(data) + data_size = len(data["close"]) + final_price = data["close"][data_size-1] + + if bs_buy_price > 0: + # 기본 100 주에 가중치를 추가해서 매수한다. + #BUY_COUNT = int(BASE_COUNT * bs_weight) + BUY_COUNT = int(BASE_COUNT * 1) + + + # 매수를 주문한다. + orderNum = self.requestOrder(OrderType.buy, self.stock_code, BUY_COUNT , bs_buy_price) + + # 미체결 기록을 가져온다. + ORDER_LIST = self.requestOrderList() + # 매수 주문을 기록한다. + orderListToCancel = orderChecker.add(self.stock_code, OrderType.buy, orderNum, BUY_COUNT, bs_buy_price, ORDER_LIST) + # 두 시간 이전 미체결을 모두 취소한다. + self.cancelOrderList(orderListToCancel) + # 로그 출력 + print("BUY", THIS_TIME.strftime('%Y%m%d %H%M%S'), BUY_COUNT, bs_buy_price, len(orderListToCancel), len(ORDER_LIST)) + + """ + if bs_sell_price > 0: + # 미체결 기록을 가져온다. + ORDER_LIST = self.requestOrderList() + # 매도 주문을 기록을 가져온다. + orderListToCancel = orderChecker.remove(self.stock_code, OrderType.sell, ORDER_LIST) + # 매도 미체결을 모두 취소한다. + self.cancelOrderList(orderListToCancel) + + # 매도 가격을 가져온다. + selling_count, selling_price = self.getSellingPrice(final_price) + # 분석되 가격으로 매도 요청한다. + if selling_count != 0 and selling_price != 0: + # 매도를 요청한다. + orderNum = self.requestOrder(OrderType.sell, self.stock_code, selling_count, selling_price) + + # 로그 출력 + print("SELL", THIS_TIME.strftime('%Y%m%d %H%M%S'), selling_count, selling_price, len(orderListToCancel), len(ORDER_LIST)) + """ + # 로그 출력 + print("TIMECHECK: %s, price: %d, low: %d, lower: %.2f, avg5: %.2f, slow_k_1: %.2f, slow_d_1: %.2f, slow_k: %.2f, slow_d: %.2f, rsi: %.2f, rsis: %.2f" % + (str(THIS_TIME), final_price, data["low"][data_size-1], data["lower"][data_size-1], data["avg5"][data_size-1], + data["slow_k"][data_size-2], data["slow_d"][data_size-2], data["slow_k"][data_size-1], data["slow_d"][data_size-1], + data["rsi"][data_size-1], data["rsis"][data_size-1])) + timecheck[THIS_TIME] = True + """ + if datetime.strptime(GIVEN_DAY + " 151530", '%Y%m%d %H%M%S') < THIS_TIME: + #### + # 손해 보지 않는 가격에 매도한다. + #### + + # 주문 리스트를 가져온다. + orderList = self.requestOrderList() + # 15:10:00 이후라면 모든 미체결 취소한다. + self.cancelOrderList(orderList) + + # 매도 가격을 가져온다. + selling_count, selling_price = self.getSellingPrice(final_price) + # 분석되 가격으로 매도 요청한다. + if selling_count != 0 and selling_price != 0: + orderNum = self.requestOrder(OrderType.sell, self.stock_code, selling_count, selling_price) + # 로그 출력 + print("SELL", THIS_TIME, selling_count, selling_price) + + break + """ + time.sleep(0.9) + THIS_TIME = datetime.now() + + return + +if __name__ == "__main__": + + today = datetime.today() + + PROJECT_HOME = os.path.join(os.path.dirname(os.path.join(os.path.dirname(__file__)))) + RESOURCE_DIR = PROJECT_HOME + "/resources/analysis/"+today.strftime("%Y%m%d") + + # KODEX 인버스 * 2 + stock_code = "252670" + dataDownloader = DataDownloader() + given_day = datetime.today().strftime('%Y%m%d') + + dataDownloader.writeStockData(stock_code, "20220520") + + print ("done...")