diff --git a/hts/HTS.py b/hts/HTS.py index 5a48991..64dcc63 100644 --- a/hts/HTS.py +++ b/hts/HTS.py @@ -3,7 +3,6 @@ import time import os from datetime import datetime, timedelta import pandas as pd -import schedule import matplotlib.pyplot as plt import plotly.graph_objects as go @@ -141,7 +140,7 @@ class HTS: return # 주식 현금 매수주문 - def orderToBuy(self, stock_code): + def orderToBuy(self, stock_code, count, price): # 주문 초기화 objTrade = win32com.client.Dispatch("CpTrade.CpTdUtil") initCheck = objTrade.TradeInit(0) @@ -158,8 +157,8 @@ class HTS: objStockOrder.SetInputValue(1, acc) # 계좌번호 objStockOrder.SetInputValue(2, accFlag[0]) # 상품구분 - 주식 상품 중 첫번째 objStockOrder.SetInputValue(3, "A"+stock_code) # 종목코드 - objStockOrder.SetInputValue(4, 10) # 매수수량 10주 - objStockOrder.SetInputValue(5, 14100) # 주문단가 - 14,100원 + objStockOrder.SetInputValue(4, count) # 매수수량 count주 + objStockOrder.SetInputValue(5, price) # 주문단가 - price 원 objStockOrder.SetInputValue(7, "0") # 주문 조건 구분 코드, 0: 기본 1: IOC 2:FOK objStockOrder.SetInputValue(8, "01") # 주문호가 구분코드 - 01: 보통 @@ -175,7 +174,7 @@ class HTS: return # 주식 현금 매도주문 - def orderToSell(self, stock_code): + def orderToSell(self, stock_code, count, price): # 주문 초기화 objTrade = win32com.client.Dispatch("CpTrade.CpTdUtil") initCheck = objTrade.TradeInit(0) @@ -192,8 +191,8 @@ class HTS: objStockOrder.SetInputValue(1, acc) # 계좌번호 objStockOrder.SetInputValue(2, accFlag[0]) # 상품구분 - 주식 상품 중 첫번째 objStockOrder.SetInputValue(3, "A"+stock_code) # 종목코드 - A003540 - 대신증권 종목 - objStockOrder.SetInputValue(4, 10) # 매도수량 10주 - objStockOrder.SetInputValue(5, 14100) # 주문단가 - 14,100원 + objStockOrder.SetInputValue(4, count) # 매도수량 count 주 + objStockOrder.SetInputValue(5, price) # 주문단가 - price 원 objStockOrder.SetInputValue(7, "0") # 주문 조건 구분 코드, 0: 기본 1: IOC 2:FOK objStockOrder.SetInputValue(8, "01") # 주문호가 구분코드 - 01: 보통 @@ -391,33 +390,7 @@ class HTS: df_final_time = pd.DatetimeIndex(point_temp) data.index = df_final_time - # 살 시점인지 체크 - # 볼린저밴드 하단에 연속으로 같은 가격이 왔을 때, - # 해당 하단 가격 + 5원에 매수를 시도함 - check = False - buy_line = [-1 for i in range(len(lower_temp))] - for i in range(3, len(lower_temp)): - for j in range(i-3, i): - if (low[j] < lower_temp[j]) and (low[i] < lower_temp[i] and low[j] == low[i]): - #buy_line[i] = low[i] - check = True - break - if check and i < len(lower_temp) - 1: - buy_line[i+1] = low[i] + 5 - check = False - - # 팔 시점 체크 - # 산 가격에 5원 위로 매도를 건다. - sell_line = [-1 for i in range(len(lower_temp))] - for i in range(len(buy_line)): - if buy_line[i] > 0: - for j in range(i+1, len(buy_line)): - # 5원 이득을 보고 판다. - if close[j] >= buy_line[i] + 5: - sell_line[j] = buy_line[i] + 5 - break - - return data, upper_temp, lower_temp, buy_line, sell_line + return data, upper_temp, lower_temp def draw(self, given_day, data, upper, lower, buy_line, sell_line): # 그래프 설정을 위한 변수를 생성한다. @@ -455,7 +428,42 @@ class HTS: fig.show() return + def checkTransaction(self, data, lower): + low = data["Low"] + close = data["Close"] + + # 살 시점인지 체크 + # 볼린저밴드 하단에 연속으로 같은 가격이 왔을 때, + # 해당 하단 가격 + 5원에 매수를 시도함 + check = False + buy_line = [-1 for i in range(len(lower))] + for i in range(3, len(lower)): + for j in range(i-3, i): + if (low[j] < lower[j]) and (low[i] < lower[i] and low[j] == low[i]): + #buy_line[i] = low[i] + check = True + break + if check and i < len(lower) - 1: + buy_line[i+1] = low[i] + 5 + check = False + + # 팔 시점 체크 + # 산 가격에 5원 위로 매도를 건다. + sell_line = [-1 for i in range(len(lower))] + for i in range(len(buy_line)): + if buy_line[i] > 0: + for j in range(i+1, len(buy_line)): + # 5원 이득을 보고 판다. + if close[j] >= buy_line[i] + 5: + sell_line[j] = buy_line[i] + 5 + break + + return buy_line, sell_line + def simulate(self, stock_code, given_day): + timecheckList = pd.read_csv("timecheck.csv").values.tolist() + timecheck = {datetime.strptime(given_day + " " + str(second).zfill(6), '%Y%m%d %H%M%S'): False for second, check in timecheckList} + result = {"check": set(), "time": [], "open": [], @@ -471,29 +479,20 @@ class HTS: self.write(given_day, result) # 분석을 통해서 볼린저밴드 상/하단을 계산한다. - data, upper, lower, buy_line, sell_line = self.analyze(result) + data, upper, lower = self.analyze(result) + + # 사야 할 시점과 팔아야 할 시점을 체크한다. + buy_line, sell_line = self.checkTransaction(data, lower) # 그래프를 그린다. self.draw(given_day, data, upper, lower, buy_line, sell_line) return - def checkRealTime(self, stock_code, given_day, result): - # 데이터를 가지고 온다. - self.getRealTime(stock_code, given_day, result) - - # 가져온 만큼 데이터를 누적해서 파일로 작성한다. - self.write(given_day, result) - - # 분석을 통해서 볼린저밴드 상/하단을 계산한다. - data, upper, lower, buy_line, sell_line = self.analyze(result) - - # 주문 및 매도 처리 - # self.draw(given_day, data, upper, lower, buy_line, sell_line) - - return - def buyRealTime(self, stock_code, given_day): + timecheckList = pd.read_csv("timecheck.csv").values.tolist() + timecheck = {datetime.strptime(given_day + " " + str(second).zfill(6), '%Y%m%d %H%M%S'):False for second, check in timecheckList} + result = {"check": set(), "time": [], "open": [], @@ -502,22 +501,38 @@ class HTS: "low": [], "vol": []} - schedule.every().hour.at(":0:5").do(self.checkRealTime(stock_code, given_day, result)) # 매시간 0분 5초에 작업 실행 - schedule.every().hour.at(":5:5").do(self.checkRealTime(stock_code, given_day, result)) # 매시간 5분 5초에 작업 실행 - schedule.every().hour.at(":10:5").do(self.checkRealTime(stock_code, given_day, result)) # 매시간 10분 5초에 작업 실행 - schedule.every().hour.at(":15:5").do(self.checkRealTime(stock_code, given_day, result)) # 매시간 15분 5초에 작업 실행 - schedule.every().hour.at(":20:5").do(self.checkRealTime(stock_code, given_day, result)) # 매시간 20분 5초에 작업 실행 - schedule.every().hour.at(":25:5").do(self.checkRealTime(stock_code, given_day, result)) # 매시간 25분 5초에 작업 실행 - schedule.every().hour.at(":30:5").do(self.checkRealTime(stock_code, given_day, result)) # 매시간 30분 5초에 작업 실행 - schedule.every().hour.at(":35:5").do(self.checkRealTime(stock_code, given_day, result)) # 매시간 35분 5초에 작업 실행 - schedule.every().hour.at(":40:5").do(self.checkRealTime(stock_code, given_day, result)) # 매시간 40분 5초에 작업 실행 - schedule.every().hour.at(":45:5").do(self.checkRealTime(stock_code, given_day, result)) # 매시간 45분 5초에 작업 실행 - schedule.every().hour.at(":50:5").do(self.checkRealTime(stock_code, given_day, result)) # 매시간 50분 5초에 작업 실행 - schedule.every().hour.at(":55:5").do(self.checkRealTime(stock_code, given_day, result)) # 매시간 55분 5초에 작업 실행 + while datetime.strptime(given_day + " 085900", '%Y%m%d %H%M%S') < datetime.now() < datetime.strptime(given_day + " 151500", '%Y%m%d %H%M%S'): + second = datetime.now().strftime('%Y%m%d %H%M%S') + if second in timecheck and timecheck[second] == False: - while datetime.now() < datetime.strptime(given_day + " 151500", '%Y%m%d %H%M%S'): - schedule.run_pending() - time.sleep(1) + # 데이터를 가지고 온다. + self.getRealTime(stock_code, given_day, result) + + # 가져온 만큼 데이터를 누적해서 파일로 작성한다. + self.write(given_day, result) + + # 분석을 통해서 볼린저밴드 상/하단을 계산한다. + data, upper, lower = self.analyze(result) + + # 사야 할 시점과 팔아야 할 시점을 체크한다. + buy_line, sell_line = self.checkTransaction(data, lower) + + # 주문 및 매도 처리 + price = buy_line[len(buy_line)-1] + + # 매수신청과 5원 높여서 매도신청 + if price > 0: + print(second, price) + + count = 1 + self.orderToBuy(stock_code, count, price) + self.orderToSell(stock_code, count, price + 5) + + timecheck[second] = True + + # self.draw(given_day, data, upper, lower, buy_line, sell_line) + + time.sleep(0.5) return diff --git a/hts/timecheck.csv b/hts/timecheck.csv new file mode 100644 index 0000000..8e99367 --- /dev/null +++ b/hts/timecheck.csv @@ -0,0 +1,77 @@ +time, check +090403,False +090903,False +091403,False +091903,False +092403,False +092903,False +093403,False +093903,False +094403,False +094903,False +095403,False +095903,False +100403,False +100903,False +101403,False +101903,False +102403,False +102903,False +103403,False +103903,False +104403,False +104903,False +105403,False +105903,False +110403,False +110903,False +111403,False +111903,False +112403,False +112903,False +113403,False +113903,False +114403,False +114903,False +115403,False +115903,False +120403,False +120903,False +121403,False +121903,False +122403,False +122903,False +123403,False +123903,False +124403,False +124903,False +125403,False +125903,False +130403,False +130903,False +131403,False +131903,False +132403,False +132903,False +133403,False +133903,False +134403,False +134903,False +135403,False +135903,False +140403,False +140903,False +141403,False +141903,False +142403,False +142903,False +143403,False +143903,False +144403,False +144903,False +145403,False +145903,False +150403,False +150903,False +151403,False +151903,False \ No newline at end of file