Files
DeepStock/hts/HTS.py
dsyoon 5dbfb3e68e init
2021-09-30 17:39:23 +09:00

823 lines
34 KiB
Python

import win32com.client
import time
import os
from datetime import datetime, timedelta
import pandas as pd
from enum import Enum
#import plotly.graph_objects as go
# enum 주문 상태 세팅용
class EorderBS(Enum):
buy = 1 # 매수
sell= 2 # 매도
none =3
class orderData:
def __init__(self):
self.dicEx = {EorderBS.buy: "매수", EorderBS.sell: "매도", EorderBS.none: "없음"}
self.orderNum = 0
self.bs = EorderBS.none # 0 : buy 1: sell
self.code = ""
self.amount = 0
self.price = 0
def debugPrint(self):
print(self.dicEx.get(self.bs), self.code, self.orderNum, self.amount, self.price)
class HTS:
objCpCybos = None
objCpCodeMgr = None
stock = []
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) # 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
rqStatus = objStockOrder.GetDibStatus()
rqRet = objStockOrder.GetDibMsg1()
print("통신상태", rqStatus, rqRet)
if rqStatus != 0:
return
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.CpTd9065")
objResult.SetInputValue(0, acc) # 계좌번호
objResult.SetInputValue(1, accFlag[0]) # 상품구분 - 주식 상품 중 첫번째
objResult.SetInputValue(2, 20)
while True:
objResult.BlockRequest()
if objResult.GetDibStatus() != 0:
print("통신상태", objResult.GetDibStatus(), objResult.GetDibMsg1())
return False
cnt = objResult.GetHeaderValue(4)
if cnt == 0:
break
for i in range(cnt):
i1 = objResult.GetDataValue(1, i) # 주문구분(매수 또는 매도)
i2 = objResult.GetDataValue(2, i) # 코드
i3 = objResult.GetDataValue(3, i) # 주문 수량
i4 = objResult.GetDataValue(4, i) # 주문호가구분
i5 = objResult.GetDataValue(6, i) # 예약번호
i6 = objResult.GetDataValue(12, i) # 처리구분내용 - 주문취소 또는 주문예정
i7 = objResult.GetDataValue(9, i) # 주문단가
i8 = objResult.GetDataValue(11, i) # 주문번호
i9 = objResult.GetDataValue(12, i) # 처리구분코드
i10 = objResult.GetDataValue(13, i) # 거부코드
i11 = objResult.GetDataValue(14, i) # 거부내용
print(i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11)
# 미체결
if (i6 == "주문예정"):
item = orderData()
item.orderNum = i5
if (i1 == "매수"):
item.bs = EorderBS.buy
else:
item.bs = EorderBS.sell
item.code = i2
item.amount = i3
item.price = i7
orderList.append(item)
# 연속 처리 체크 - 다음 데이터가 없으면 중지
if objResult.Continue == False:
break
return orderList
# 주식 현재가 조회
def printStockData(self, stock_code, 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, day) # 기간 조회 시, 시작일
objStockChart.SetInputValue(3, 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("%s,%s,%s,%s,%s,%s,%s" % ("날짜", "시간", "시가", "고가", "저가", "종가", "거래량"))
for i in range(size - 1, -1, -1):
day = objStockChart.GetDataValue(0, i)
time = objStockChart.GetDataValue(1, i)
open = objStockChart.GetDataValue(2, i)
high = objStockChart.GetDataValue(3, i)
low = objStockChart.GetDataValue(4, i)
close = objStockChart.GetDataValue(5, i)
vol = objStockChart.GetDataValue(6, i)
print("%d,%s,%d,%d,%d,%d,%d" % (day, str(time).zfill(4), open, high, low, close, vol))
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 getCSV(self, fileName, given_day, result):
data = pd.read_csv(fileName)
days = data.날짜
time = data.시간
open = data.시가
close = data.종가
high = data.고가
low = data.저가
vol = data.거래량
start_time = datetime.strptime(given_day + " 090000", '%Y%m%d %H%M%S')
for i in range(len(data)):
temp = datetime.strptime(str(days[i]) + " " + str(time[i]).zfill(4)+"00", '%Y%m%d %H%M%S')
if temp < start_time:
continue
if temp not in result["check"]:
result["check"].add(temp)
result["time"].append(temp)
result["open"].append(open[i])
result["close"].append(close[i])
result["high"].append(high[i])
result["low"].append(low[i])
result["vol"].append(vol[i])
return
def analyze(self, result):
df = pd.DataFrame(result["close"])
max20 = df.rolling(window=10).mean()
stddev20 = df.rolling(window=10).std()
upper_df = max20 + (stddev20 * 2) # 상단 볼린저 밴드
lower_df = max20 - (stddev20 * 2) # 하단 볼린저 밴드
size = len(result["open"])
window = 5
open = [result["open"][i] for i in range(0, size, window)]
close = [result["close"][i-1] for i in range(window-1, size, window)]
for i in range(len(open)-len(close)):
close.append(result["close"][len(result["close"])-1])
high = [max(result["high"][i:i+window]) for i in range(0, size, window)]
low = [min(result["low"][i:i+window]) for i in range(0, size, window)]
vol = [sum(result["vol"][i:i+window]) for i in range(0, size, window)]
close_df = pd.DataFrame(close)
ma2_list = close_df.rolling(window=2).mean().fillna(close[0]).values.tolist()
ma2 = [item[0] for item in ma2_list]
ma5_list = close_df.rolling(window=5).mean().fillna(close[0]).values.tolist()
ma5 = [item[0] for item in ma5_list]
ma10_list = close_df.rolling(window=10).mean().fillna(close[0]).values.tolist()
ma10 = [item[0] for item in ma10_list]
ma15_list = close_df.rolling(window=15).mean().fillna(close[0]).values.tolist()
ma15 = [item[0] for item in ma15_list]
ma20_list = close_df.rolling(window=20).mean().fillna(close[0]).values.tolist()
ma20 = [item[0] for item in ma20_list]
upper, lower = [], []
for i in range(len(upper_df)):
if i < window:
upper.append(upper_df.values[window - 1][0])
lower.append(lower_df.values[window - 1][0])
else:
upper.append(upper_df.values[i][0])
lower.append(lower_df.values[i][0])
point_temp = [result["time"][i] for i in range(size) if i % window == 0]
upper_temp = [upper[i] for i in range(size) if i % window == 0]
lower_temp = [lower[i] for i in range(size) if i % window == 0]
temp = {"Date": point_temp, "Open": open, "High": high, "Low": low, "Close": close, "Volume": vol, "ma2": ma2, "ma5": ma5, "ma10": ma10, "ma15": ma15, "ma20": ma20}
data = pd.DataFrame(temp)
df_final_time = pd.DatetimeIndex(point_temp)
data.index = df_final_time
return data, upper_temp, lower_temp
def draw(self, given_day, data, upper, lower, buy_line, sell_line):
# 그래프 설정을 위한 변수를 생성한다.
data['Open'] = pd.to_numeric(data['Open'])
data['High'] = pd.to_numeric(data['High'])
data['Low'] = pd.to_numeric(data['Low'])
data['Close'] = pd.to_numeric(data['Close'])
data['Volume'] = pd.to_numeric(data['Volume'])
data['ma2'] = pd.to_numeric(data['ma2'])
data['ma5'] = pd.to_numeric(data['ma5'])
data['ma10'] = pd.to_numeric(data['ma10'])
data['ma15'] = pd.to_numeric(data['ma15'])
data['ma20'] = pd.to_numeric(data['ma20'])
buy_colors = []
for i in range(len(buy_line)):
if buy_line[i] < 0:
buy_colors.append("#ffffff")
buy_line[i] = lower[0]
else:
buy_colors.append("#ff00ff")
sell_colors = []
for i in range(len(sell_line)):
if sell_line[i] < 0:
sell_colors.append("#ffffff")
sell_line[i] = lower[0]
else:
sell_colors.append("#00ced1")
# 그래프를 설정한다.
buy_check = go.Scatter(x=data['Date'], y=buy_line, mode='markers', name="buy", marker=dict(size=14, color=buy_colors, line_width=0))
sell_check = go.Scatter(x=data['Date'], y=sell_line, mode='markers', name="sell", marker=dict(size=14, color=sell_colors, line_width=0))
bolinger_upper = go.Scatter(x=data['Date'], y=upper, name="upper", line_color='#8B4513')
bolinger_lower = go.Scatter(x=data['Date'], y=lower, name="lower", line_color='#8B4513')
ma2 = go.Scatter(x=data['Date'], y=data['ma2'], name="ma2", line_color='#FF0000')
ma5 = go.Scatter(x=data['Date'], y=data['ma5'], name="ma5", line_color='#F43B86')
ma10 = go.Scatter(x=data['Date'], y=data['ma10'], name="ma10", line_color='#F0A500')
ma15 = go.Scatter(x=data['Date'], y=data['ma15'], name="ma15", line_color='#14279B')
ma20 = go.Scatter(x=data['Date'], y=data['ma20'], name="ma20", line_color='#000000')
candle_stick = go.Candlestick(x=data['Date'], open=data['Open'], high=data['High'], low=data['Low'], close=data['Close'], increasing_line_color='red', decreasing_line_color='blue')
# 그래프를 그린다.
fig = go.Figure(data=[candle_stick, bolinger_upper, bolinger_lower, buy_check, sell_check, ma2, ma5, ma10, ma15, ma20])
fig.update_layout(title=given_day + "_2x")
fig.show()
return
def checkTransaction(self, data, upper, lower):
low = data["Low"]
high = data["High"]
close = data["Close"]
open = data["Open"]
ma2 = data["ma2"]
ma5 = data["ma5"]
ma10 = data["ma10"]
ma15 = data["ma15"]
ma20 = data["ma20"]
# 살 시점인지 체크
# 볼린저밴드 하단에 연속으로 같은 가격이 왔을 때,
# 해당 하단 가격 + 5원에 매수를 시도함
check = False
buy_line = [-1 for i in range(len(lower))]
for i in range(3, len(lower)):
# 하락 추세에서는 매수하지 않는다.
if ma2[i] < ma5[i] < ma10[i]:
continue
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
if low[i-2] < lower[i-2] and low[i-1] < lower[i-1] and low[i] < open[i] == close[i] < high[i] and open[i] - low[i] == high [i] - open[i]:
if not (open[i-2] < close[i-2] and open[i-1] < close[i-1]) and not (open[i-2] == close[i-2] or open[i-1] == close[i-1]):
buy_line[i+1] = high[i]
# 2일과 5일선이 10일 선 위로 올라오면 매수한다.
if (ma2[i-1] < ma10[i-1] and ma5[i-1] < ma10[i-1]) and (ma10[i] < ma5[i] < ma2[i]):
buy_line[i+1] = low[i] + 5
# 팔 시점 체크
# 산 가격에 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": [],
"close": [],
"high": [],
"low": [],
"vol": []}
# 데이터를 가지고 온다.
self.getCSV(given_day+".csv", given_day, result)
# 분석을 통해서 볼린저밴드 상/하단을 계산한다.
data, upper, lower = self.analyze(result)
# 사야 할 시점과 팔아야 할 시점을 체크한다.
buy_line, sell_line = self.checkTransaction(data, upper, lower)
# 그래프를 그린다.
self.draw(given_day, data, upper, lower, buy_line, sell_line)
# 가져온 만큼 데이터를 누적해서 파일로 작성한다.
self.write(given_day, result)
return
def buyRealTime(self, stock_code, given_day):
data, upper, lower = None, None, None
previous_price = 0
buy_count = 700
total_byu_amt = 0
logFp = open(given_day+".log", "w")
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": []}
while datetime.strptime(given_day + " 083000", '%Y%m%d %H%M%S') < datetime.now() < datetime.strptime(given_day + " 151000", '%Y%m%d %H%M%S'):
second = datetime.now().strftime('%Y%m%d %H%M%S')
if second in timecheck and not timecheck[second]:
print("TIMECHECK", second)
logFp.write("%s,%s,\n" %("TIMECHECK", second))
logFp.flush()
# 데이터를 가지고 온다.
self.getRealTime(stock_code, given_day, result)
# 분석을 통해서 볼린저밴드 상/하단을 계산한다.
data, upper, lower = self.analyze(result)
# 사야 할 시점과 팔아야 할 시점을 체크한다.
buy_line, sell_line = self.checkTransaction(data, upper, lower)
# 주문 및 매도 처리
price = buy_line[len(buy_line)-1]
# 매수신청과 5원 높여서 매도신청
if price > 0:
if previous_price > 0:
if previous_price > price:
if buy_count < 600:
buy_count = 600
buy_count += 100
if buy_count > 1000:
buy_count = 1000
elif previous_price < price:
if buy_count > 800:
buy_count = 800
buy_count -= 100
if buy_count < 500:
buy_count = 500
previous_price = price
# 매수 주문
# 현재까지 매입금액이 7백만원 이하일 때만 매수를 한다.
if total_byu_amt < 7000000:
self.requestOrder("2", stock_code, buy_count , price)
## 매도 주문 (아래 잔고를 체킇서 매도를 호출하는 것으로 시도한다.)
#time.sleep(60)
#self.requestOrder("1", stock_code, buy_count , price + 5)
print("BUY", second, price)
logFp.write("%s,%s, %d\n" % ("BUY", second, price))
logFp.flush()
# 가져온 만큼 데이터를 누적해서 파일로 작성한다.
self.write(given_day, result)
timecheck[second] = True
else:
#print("NONE", second)
logFp.write("%s,%s,\n" % ("NONE", second))
logFp.flush()
# 만약 잔고가 있으면 장부가보다 5원 높게 매도한다.
jangoDic = self.requstJango()
if jangoDic and len(jangoDic.keys()) > 0:
for code in jangoDic:
total_byu_amt = jangoDic[code]['매입금액']
if jangoDic[code]['매도가능'] > 0:
# 가장 마지막 현재가를 가져온다.
if len(result['close']) > 0:
last_price = result['close'][len(result['close'])-1]
else:
last_price = 0
# 현재가가 장부가보다 크다면 현재가 + 5원 매도한다.
if last_price > int(jangoDic[code]['장부가']):
# 현재가가 장부가보다 크다면,
self.requestOrder("1", stock_code, jangoDic[code]['매도가능'], last_price)
else:
# 장부가가 현재가보다 크다면,
# 장부가의 마지막 자리수를 가져온다.
last_number = int(jangoDic[code]['장부가']) % 10
# 장부가 가격의 마지막 자리를 0으로 만든다. (2092 -> 2090, 2098 -> 2090)
sell_price = int(jangoDic[code]['장부가'] / 10) * 10
# 만약 오후 1시 이전이라면 한 호가 (5원) 더 올려서 매도한다.
if datetime.now() < datetime.strptime(given_day + " 104000", '%Y%m%d %H%M%S'):
if lower != None:
if lower[len(lower)-2] < lower[len(lower)-1]:
sell_price += 5
if last_number in [0, 1, 2]:
# 장부가의 마지막 자리수가 0,1,2 라면 (2090, 2091, 2092 -> 2095 에 매도)
self.requestOrder("1", stock_code, jangoDic[code]['매도가능'], sell_price + 5)
elif last_number in [3, 4, 5, 6]:
# 장부가의 마지막 자리수가 3,4,5,6 라면 (2093, 2094, 2095, 2096 -> 2100 에 매도)
self.requestOrder("1", stock_code, jangoDic[code]['매도가능'], sell_price + 10)
else:
# 장부가의 마지막 자리수가 7,8,9 라면 (2097, 2098, 2099 -> 2105 에 매도)
self.requestOrder("1", stock_code, jangoDic[code]['매도가능'], sell_price + 15)
time.sleep(0.9)
logFp.close()
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")
stock_code = "252670"
given_day = datetime.today().strftime('%Y%m%d')
hts = HTS()
#hts.all_stocks()
#hts.getChartData(stock_code)
#hts.currentStock(stock_code)
hts.printStockData(stock_code, given_day)
#given_days = ['20210909','20210910','20210913','20210914','20210915','20210916','20210917','20210923','20210924','20210927','20210928','20210929']
#given_days = ['20210929']
#for given_day in given_days:
# hts.simulate(stock_code, given_day)
#hts.buyRealTime(stock_code, given_day)
print ("done...")