This commit is contained in:
dosang.yoon
2022-06-26 23:58:57 +09:00
parent 5c1be31d03
commit c48bde70c8
6 changed files with 231 additions and 1472 deletions

View File

@@ -2,6 +2,7 @@ import pandas as pd
from stockpredictor.analysis.Common import Common from stockpredictor.analysis.Common import Common
from stockpredictor.analysis.Stochastic import Stochastic from stockpredictor.analysis.Stochastic import Stochastic
from stockpredictor.analysis.RSI import RSI from stockpredictor.analysis.RSI import RSI
from stockpredictor.analysis.MACD import MACD
class BuySellChecker: class BuySellChecker:
@@ -13,6 +14,7 @@ class BuySellChecker:
self.common = Common() self.common = Common()
self.stochastic = Stochastic() self.stochastic = Stochastic()
self.rsi = RSI() self.rsi = RSI()
self.macd = MACD()
return return
@@ -20,7 +22,7 @@ class BuySellChecker:
status = set() status = set()
# 정배열 체크 # 정배열 체크
temp_status = self.common.check_RightArrange(STOCK, last_index) temp_status = self.common.check_RightArrange(STOCK)
if temp_status != "": if temp_status != "":
status.add(temp_status) status.add(temp_status)
@@ -183,60 +185,52 @@ class BuySellChecker:
def getPriceAndWeight1(self, data, i): def getPriceAndWeight1(self, data, i):
buy, weight, sell = -1, -1, -1 buy, weight, sell = -1, -1, -1
################ if i >= 3:
### sell 분석 ### ################
################ ### sell 분석 ###
# 1. 볼린져밴드 상단이 최고와 종가 사이 아래에 있는 경우 매도한다. ################
if (data["high"][i] - data["close"][i]) / 2 + data["close"][i] > data["upper"][i]: # 1. 볼린져밴드 상단이 최고와 종가 사이 아래에 있는 경우 매도한다.
sell = data["high"][i] #if (data["high"][i] - data["close"][i]) / 2 + data["close"][i] > data["upper"][i]:
""" # sell = data["high"][i]
# 2. slow_k가 90이 넘으면 매도한다.
if data["slow_k"][i] >= 90: # 2. slow_k가 90이 넘으면 매도한다.
sell = data["high"][i] if data["slow_k"][i] > 90:
"""
if data["slow_k"][i] >= 85:
if data["slow_d"][i-1] < data["slow_k"][i-1] and data["slow_k"][i] < data["slow_d"][i]:
sell = data["high"][i] sell = data["high"][i]
# 3. 2시 이후에는 최고가가 볼린져밴드 상단 위에 있으면 매도한다. #if data["slow_k"][i] >= 85:
if i > 300 and data["high"][i] > data["upper"][i]: # if data["slow_d"][i-1] < data["slow_k"][i-1] and data["slow_k"][i] < data["slow_d"][i]:
sell = data["high"][i] # sell = data["high"][i]
########################## # 3. 2시 이후에는 최고가가 볼린져밴드 상단 위에 있으면 매도한다.
### STOCHASTIC buy 분석 ### if i > 300 and data["high"][i] > data["upper"][i]:
########################## sell = data["high"][i]
if i < 40:
if data["low"][i] < data["lower"][i]+5: ##########################
if data["slow_k"][i-1] < 50 and data["slow_k"][i] < 55: ### buy 분석 ###
if data["slow_k"][i-1] < data["slow_d"][i-1] and data["slow_d"][i] < data["slow_k"][i] and data["slow_k"][i-1] < data["slow_k"][i]: ##########################
buy = data["low"][i] if data["low"][i] < data["lower"][i] + 5 and data["open"][i] <= data["close"][i]:
else:
if data["low"][i] < data["lower"][i] + 5:
if data["slow_k"][i-1] < 30 and data["slow_k"][i] < 30: if data["slow_k"][i-1] < 30 and data["slow_k"][i] < 30:
if data["slow_k"][i-1] < data["slow_k"][i]: if data["slow_k"][i-1] < data["slow_k"][i]:
buy = data["low"][i] buy = data["low"][i]
############################# if data["rsi"][i] < 25:
### STOCHASTIC weight 분석 ### if data["rsi"][i - 2] < data["rsis"][i - 2] and data["rsi"][i - 1] < data["rsis"][i - 1] and data["rsis"][i] < data["rsi"][i]:
############################# if data["close"][i] < data["avg5"][i]:
if data["slow_k"][i] in (0, 1, 2, 3): buy = data["close"][i]
weight = 1 else:
if data["slow_k"][i] in (4, 5, 6, 7, 8): buy = data["low"][i]
weight = 1 weight = 1
elif data["slow_k"][i] in (9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20):
weight = 1
elif data["slow_k"][i] in (21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35):
weight = 1
################### #############################
### RSI buy 분석 ### ### STOCHASTIC weight 분석 ###
################### #############################
if data["rsi"][i] < 25: if data["slow_k"][i] in (0, 1, 2, 3):
if data["rsi"][i - 2] < data["rsis"][i - 2] and data["rsi"][i - 1] < data["rsis"][i - 1] and data["rsis"][i] < data["rsi"][i]: weight = 1
if data["close"][i] < data["avg5"][i]: if data["slow_k"][i] in (4, 5, 6, 7, 8):
buy = data["close"][i] weight = 1
else: elif data["slow_k"][i] in (9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20):
buy = data["low"][i] weight = 1
elif data["slow_k"][i] in (21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35):
weight = 1 weight = 1
return buy, weight, sell return buy, weight, sell
@@ -301,63 +295,14 @@ class BuySellChecker:
return buy, weight, sell return buy, weight, sell
def getPriceAndWeight_1minute(self, data, i): def getPriceAndWeight3(self, data, i):
buy, weight, sell = -1, -1, -1 buy, weight, sell = -1, -1, -1
################ # 381: 어제 날짜 데이터 개수
### sell 분석 ### if i >= 381 + 5:
################ if data["macdo"][i] < 0 and data["macd"][i] < -5:
# 1. 볼린져밴드 상단이 최고와 종가 사이 아래에 있는 경우 매도한다. if data["macd"][i-3] > data["macd"][i-2] and data["macd"][i-2] > data["macd"][i-1] and data["macd"][i-1] < data["macd"][i]:
if (data["high"][i] - data["close"][i]) / 2 + data["close"][i] > data["upper"][i]: buy = data["close"][i]
sell = data["high"][i]
if data["slow_k"][i] >= 85:
if data["slow_d"][i - 1] < data["slow_k"][i - 1] and data["slow_k"][i] < data["slow_d"][i]:
sell = data["high"][i]
# 3. 2시 이후에는 최고가가 볼린져밴드 상단 위에 있으면 매도한다.
if i > 300 and data["high"][i] > data["upper"][i]:
sell = data["high"][i]
##########################
### STOCHASTIC buy 분석 ###
##########################
if i < 40:
pre_slow = data["slow_k"][i - 1] / data["slow_d"][i - 1] - 1
now_slow = data["slow_k"][i] / data["slow_d"][i] - 1
if pre_slow < 0 and 0 < now_slow:
if data["slow_k"][i] <= 35:
if (data["close"][i] - data["lower"][i]) / (data["upper"][i] - data["lower"][i]) < 0.35:
if data["slow_k"][i - 1] < data["slow_d"][i - 1] and data["slow_d"][i] < data["slow_k"][i]:
if data['avg3'][i] <= data['avg2'][i]:
if data["open"][i] < data["close"][i]:
buy = data["close"][i]
else:
buy = data["low"][i]
else:
pre_slow = data["slow_k"][i - 1] / data["slow_d"][i - 1] - 1
now_slow = data["slow_k"][i] / data["slow_d"][i] - 1
if pre_slow < 0 and pre_slow < now_slow and -0.15 < now_slow:
if data["slow_k"][i] <= 10:
if (data["close"][i] - data["lower"][i]) / (data["upper"][i] - data["lower"][i]) < 0.35:
if data["slow_k"][i - 1] < data["slow_d"][i - 1] and data["slow_d"][i] < data["slow_k"][i]:
if data['avg3'][i] <= data['avg2'][i]:
if data["close"][i] < data["avg5"][i]:
buy = data["close"][i]
else:
buy = data["low"][i]
#############################
### STOCHASTIC weight 분석 ###
#############################
if data["slow_k"][i] in (0, 1, 2, 3):
weight = 1
if data["slow_k"][i] in (4, 5, 6, 7, 8):
weight = 1
elif data["slow_k"][i] in (9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20):
weight = 1
elif data["slow_k"][i] in (21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35):
weight = 1
return buy, weight, sell return buy, weight, sell
@@ -370,8 +315,8 @@ class BuySellChecker:
vol = result["vol"] vol = result["vol"]
close_df = pd.DataFrame(close) close_df = pd.DataFrame(close)
avg2_list = close_df.rolling(window=2).mean().fillna(close[0]).values.tolist() avg3_list = close_df.rolling(window=3).mean().fillna(close[0]).values.tolist()
avg2 = [item[0] for item in avg2_list] avg3 = [item[0] for item in avg3_list]
avg5_list = close_df.rolling(window=5).mean().fillna(close[0]).values.tolist() avg5_list = close_df.rolling(window=5).mean().fillna(close[0]).values.tolist()
avg5 = [item[0] for item in avg5_list] avg5 = [item[0] for item in avg5_list]
avg10_list = close_df.rolling(window=10).mean().fillna(close[0]).values.tolist() avg10_list = close_df.rolling(window=10).mean().fillna(close[0]).values.tolist()
@@ -382,8 +327,8 @@ class BuySellChecker:
avg60 = [item[0] for item in avg60_list] avg60 = [item[0] for item in avg60_list]
df = pd.DataFrame(close) df = pd.DataFrame(close)
max20 = df.rolling(window=10).mean() max20 = df.rolling(window=20).mean()
stddev20 = df.rolling(window=10).std() stddev20 = df.rolling(window=20).std()
upper_df = max20 + (stddev20 * 2) # 상단 볼린저 밴드 upper_df = max20 + (stddev20 * 2) # 상단 볼린저 밴드
lower_df = max20 - (stddev20 * 2) # 하단 볼린저 밴드 lower_df = max20 - (stddev20 * 2) # 하단 볼린저 밴드
@@ -401,7 +346,7 @@ class BuySellChecker:
STOCK = [] STOCK = []
for i in range(len(open)): for i in range(len(open)):
STOCK.append({'volume': vol[i], 'close': close[i], 'open': open[i], 'high': high[i], 'low': low[i], STOCK.append({'volume': vol[i], 'close': close[i], 'open': open[i], 'high': high[i], 'low': low[i],
'avg2': avg2[i], 'avg5': avg5[i],'avg10': avg10[i],'avg30': avg30[i],'avg60': avg60[i]}) 'avg3': avg3[i], 'avg5': avg5[i],'avg10': avg10[i],'avg30': avg30[i],'avg60': avg60[i]})
# stochastic 계산 # stochastic 계산
stochastic_df = self.stochastic.apply(STOCK, n=30, m=5, t=5) stochastic_df = self.stochastic.apply(STOCK, n=30, m=5, t=5)
@@ -410,6 +355,13 @@ class BuySellChecker:
slow_k = stochastic_df['slow_k'].values.tolist() slow_k = stochastic_df['slow_k'].values.tolist()
slow_d = stochastic_df['slow_d'].values.tolist() slow_d = stochastic_df['slow_d'].values.tolist()
# macd 계산
macd_df = self.macd.apply(STOCK, short=12, long=26, t=9)
macd_df = macd_df.fillna(100)
macd = macd_df['macd'].values.tolist()
macds = macd_df['macds'].values.tolist()
macdo = macd_df['macdo'].values.tolist()
# rsi 계산 # rsi 계산
rsi_df = self.rsi.apply(STOCK, period=30, window=5) rsi_df = self.rsi.apply(STOCK, period=30, window=5)
rsi_df = rsi_df.fillna(100) rsi_df = rsi_df.fillna(100)
@@ -418,10 +370,32 @@ class BuySellChecker:
temp = {"date": point_temp, temp = {"date": point_temp,
"open": open, "high": high, "low": low, "close": close, "volume": vol, "upper": upper, "lower": lower, "open": open, "high": high, "low": low, "close": close, "volume": vol, "upper": upper, "lower": lower,
"avg2": avg2, "avg5": avg5, "avg10": avg10, "avg30": avg30, "avg60": avg60, "avg3": avg3, "avg5": avg5, "avg10": avg10, "avg30": avg30, "avg60": avg60,
"fast_k": fast_k, "slow_k": slow_k, "slow_d": slow_d, "rsi": rsi, "rsis": rsis} "macd": macd, "macds": macds, "macdo": macdo,
"fast_k": fast_k, "slow_k": slow_k, "slow_d": slow_d,
"rsi": rsi, "rsis": rsis}
data = pd.DataFrame(temp) data = pd.DataFrame(temp)
df_final_time = pd.DatetimeIndex(point_temp) df_final_time = pd.DatetimeIndex(point_temp)
data.index = df_final_time data.index = df_final_time
return data return data
def checkTransaction(self, data, stock_code):
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)]
for i in range(size):
if stock_code == "252670":
buy, weight, sell = self.getPriceAndWeight3(data, i)
else:
buy, weight, sell = self.getPriceAndWeight3(data, i)
bsLine['buy'][i] = buy
bsLine['weight'][i] = weight
bsLine['sell'][i] = sell
return bsLine

View File

@@ -1,5 +1,7 @@
import win32com.client import win32com.client
import csv
import time import time
from datetime import datetime
from hts.OrderItem import OrderItem from hts.OrderItem import OrderItem
class HTS: class HTS:
@@ -371,7 +373,7 @@ class HTS:
return return
# 주식 현재가 조회 # 주식 현재가 조회
def writeStockData(self, stock_code, given_day): def writeStockData(self, stock_code, today):
objCpCybos = win32com.client.Dispatch("CpUtil.CpCybos") objCpCybos = win32com.client.Dispatch("CpUtil.CpCybos")
bConnect = objCpCybos.IsConnect bConnect = objCpCybos.IsConnect
if (bConnect == 0): if (bConnect == 0):
@@ -381,11 +383,11 @@ class HTS:
# 차트 객체 구하기 # 차트 객체 구하기
objStockChart = win32com.client.Dispatch("CpSysDib.StockChart") objStockChart = win32com.client.Dispatch("CpSysDib.StockChart")
outfp = open("./data/"+stock_code+"_"+given_day+".csv", mode="w", encoding="utf-8") outfp = open("./data/"+stock_code+"_"+today+".csv", mode="w", encoding="utf-8")
objStockChart.SetInputValue(0, 'A' + stock_code) # 종목 코드 objStockChart.SetInputValue(0, 'A' + stock_code) # 종목 코드
objStockChart.SetInputValue(1, ord('1')) # 1: 기간으로 조회, 2: 개수로 조회 objStockChart.SetInputValue(1, ord('1')) # 1: 기간으로 조회, 2: 개수로 조회
objStockChart.SetInputValue(2, given_day) # 기간 조회 시, 시작일 objStockChart.SetInputValue(2, today) # 기간 조회 시, 시작일
objStockChart.SetInputValue(3, given_day) # 기간 조회 시, 종료일 objStockChart.SetInputValue(3, today) # 기간 조회 시, 종료일
objStockChart.SetInputValue(4, 400) # 조회 시 가져오는 Line 개수 objStockChart.SetInputValue(4, 400) # 조회 시 가져오는 Line 개수
objStockChart.SetInputValue(5, [0, 1, 2, 3, 4, 5, 8]) # 날짜,시간,시가,고가,저가,종가,거래량 objStockChart.SetInputValue(5, [0, 1, 2, 3, 4, 5, 8]) # 날짜,시간,시가,고가,저가,종가,거래량
objStockChart.SetInputValue(6, ord('m')) # '차트 주가 - 월(M), 주(W), 일(D), 시(H), 분(m), 초(S) 차트 요청 objStockChart.SetInputValue(6, ord('m')) # '차트 주가 - 월(M), 주(W), 일(D), 시(H), 분(m), 초(S) 차트 요청
@@ -428,9 +430,47 @@ class HTS:
outFp.close() outFp.close()
return return
def getCSV(self, fileName, given_day, result):
with open(fileName, 'r') as infp:
reader = csv.reader(infp)
next(reader)
for rows in reader:
days = rows[0] # data.날짜
time = rows[1] # data.시간
open_v = rows[2] # data.시가
high = rows[3] # data.고가
low = rows[4] # data.저가
close = rows[5] # data.종가
vol = rows[6] # data.거래량
start_time = datetime.strptime(given_day + " 090000", '%Y%m%d %H%M%S')
temp = datetime.strptime(str(days) + " " + str(time).zfill(4) + "00", '%Y%m%d %H%M%S')
if temp < start_time:
continue
result["time"].append(temp)
result["open"].append(int(open_v))
result["close"].append(int(close))
result["high"].append(int(high))
result["low"].append(int(low))
result["vol"].append(int(vol))
return
# 주식 현재가 조회 # 주식 현재가 조회
def getRealTime(self, stock_code, given_day, result): def getRealTime(self, stock_code, lastday, today):
int_given_day = int(given_day) result = {"check": set(),
"time": [],
"open": [],
"close": [],
"high": [],
"low": [],
"vol": []}
self.getCSV("./data/" + stock_code + "_" + lastday + ".csv", today, result)
int_given_day = int(today)
objCpCybos = win32com.client.Dispatch("CpUtil.CpCybos") objCpCybos = win32com.client.Dispatch("CpUtil.CpCybos")
bConnect = objCpCybos.IsConnect bConnect = objCpCybos.IsConnect
if (bConnect == 0): if (bConnect == 0):
@@ -442,8 +482,8 @@ class HTS:
objStockChart.SetInputValue(0, 'A'+stock_code) # 종목 코드 objStockChart.SetInputValue(0, 'A'+stock_code) # 종목 코드
objStockChart.SetInputValue(1, ord('1')) # 1: 기간으로 조회, 2: 개수로 조회 objStockChart.SetInputValue(1, ord('1')) # 1: 기간으로 조회, 2: 개수로 조회
objStockChart.SetInputValue(2, given_day) # 기간 조회 시, 시작일 objStockChart.SetInputValue(2, today) # 기간 조회 시, 시작일
objStockChart.SetInputValue(3, given_day) # 기간 조회 시, 종료일 objStockChart.SetInputValue(3, today) # 기간 조회 시, 종료일
objStockChart.SetInputValue(4, 400) # 조회 시 가져오는 Line 개수 objStockChart.SetInputValue(4, 400) # 조회 시 가져오는 Line 개수
objStockChart.SetInputValue(5, [0, 1, 2, 3, 4, 5, 8]) # 날짜,시간,시가,고가,저가,종가,거래량 objStockChart.SetInputValue(5, [0, 1, 2, 3, 4, 5, 8]) # 날짜,시간,시가,고가,저가,종가,거래량
objStockChart.SetInputValue(6, ord('m')) # '차트 주가 - 월(M), 주(W), 일(D), 시(H), 분(m), 초(S) 차트 요청 objStockChart.SetInputValue(6, ord('m')) # '차트 주가 - 월(M), 주(W), 일(D), 시(H), 분(m), 초(S) 차트 요청
@@ -454,7 +494,7 @@ class HTS:
size = objStockChart.GetHeaderValue(3) size = objStockChart.GetHeaderValue(3)
#print("날짜", "시간", "시가", "고가", "저가", "종가", "거래량") #print("날짜", "시간", "시가", "고가", "저가", "종가", "거래량")
start_time = datetime.strptime(given_day + " 090000", '%Y%m%d %H%M%S') start_time = datetime.strptime(today + " 090000", '%Y%m%d %H%M%S')
for i in range(size-1, -1, -1): for i in range(size-1, -1, -1):
int_day = objStockChart.GetDataValue(0, i) int_day = objStockChart.GetDataValue(0, i)
int_time = objStockChart.GetDataValue(1, i) int_time = objStockChart.GetDataValue(1, i)

View File

@@ -1,180 +0,0 @@
import time
import os
from datetime import datetime
import pandas as pd
from hts.HTS import HTS
from hts.OrderType import OrderType
from hts.BuySellChecker import BuySellChecker
from hts.OrderChecker import OrderChecker
class HTS_122630 (HTS):
buySellChecker = None
stock_code = None
buy_count = None
def __init__(self, stock_code, buy_count):
super().__init__()
self.buySellChecker = BuySellChecker()
self.stock_code = stock_code
self.buy_count = buy_count
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.getPriceAndWeight2(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)
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": []}
final_price = 0
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(self.buy_count * bs_weight)
BUY_COUNT = int(self.buy_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", THIS_TIME, final_price, data["low"][data_size-1], data["slow_k"][data_size-1], data["slow_d"][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 = "122630"
buy_count = 120
hts = HTS_122630(stock_code, buy_count)
given_day = datetime.today().strftime('%Y%m%d')
hts.writeStockData(stock_code, "20220620")
#hts.buyRealTime(given_day)
print ("done...")

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
import time import time
import os import os
from datetime import datetime from datetime import datetime, timedelta
import pandas as pd import pandas as pd
from hts.HTS import HTS from hts.HTS import HTS
@@ -32,11 +32,8 @@ class HTS_252670 (HTS):
bsLine['weight'] = [-1 for i in range(size)] bsLine['weight'] = [-1 for i in range(size)]
bsLine['sell'] = [-1 for i in range(size)] bsLine['sell'] = [-1 for i in range(size)]
i = size - 1 last_index = size - 1
if i < 5: buy, weight, sell = self.buySellChecker.getPriceAndWeight1(data, last_index)
return -1, -1, -1
buy, weight, sell = self.buySellChecker.getPriceAndWeight1(data, i)
return buy, weight, sell return buy, weight, sell
def getSellingPrice(self, final_price): def getSellingPrice(self, final_price):
@@ -64,32 +61,25 @@ class HTS_252670 (HTS):
return 0, 0 return 0, 0
def buyRealTime(self, GIVEN_DAY): def buyRealTime(self, lastday, today):
orderChecker = OrderChecker(self.stock_code) orderChecker = OrderChecker(self.stock_code)
timecheckList = pd.read_csv("timecheck.csv").values.tolist() timecheckList = pd.read_csv("timecheck.csv").values.tolist()
timecheck = {GIVEN_DAY + " " + str(second).zfill(6):False for second, check in timecheckList} timecheck = {today + " " + str(second).zfill(6):False for second, check in timecheckList}
result = {"check": set(),
"time": [],
"open": [],
"close": [],
"high": [],
"low": [],
"vol": []}
print ("START...") print ("START...")
THIS_TIME = datetime.now() 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'): while datetime.strptime(today + " 070000", '%Y%m%d %H%M%S') < THIS_TIME < datetime.strptime(today + " 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 datetime.strptime(today + " 090100", '%Y%m%d %H%M%S') < THIS_TIME < datetime.strptime(today + " 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')]: 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) result = self.getRealTime(self.stock_code, lastday, today)
# 분석을 통해서 볼린저밴드 상/하단을 계산한다. # 분석을 통해서 볼린저밴드 상/하단을 계산한다.
data = self.buySellChecker.analyze(result) data = self.buySellChecker.analyze(result)
# 사야 할 시점/가격과 팔아야 할 시점/가격을 체크한다. # 사야 할 시점/가격과 팔아야 할 시점/가격을 체크한다.
bs_buy_price, bs_weight, bs_sell_price = self.checkTransaction(data) bs_buy_price, bs_weight, bs_sell_price = self.checkTransaction(data)
data_size = len(data["close"]) data_size = len(data["close"])
@@ -140,7 +130,7 @@ class HTS_252670 (HTS):
data["rsi"][data_size-1], data["rsis"][data_size-1])) data["rsi"][data_size-1], data["rsis"][data_size-1]))
timecheck[THIS_TIME] = True timecheck[THIS_TIME] = True
if datetime.strptime(GIVEN_DAY + " 151530", '%Y%m%d %H%M%S') < THIS_TIME: if datetime.strptime(today + " 151530", '%Y%m%d %H%M%S') < THIS_TIME:
#### ####
# 손해 보지 않는 가격에 매도한다. # 손해 보지 않는 가격에 매도한다.
#### ####
@@ -177,9 +167,14 @@ if __name__ == "__main__":
buy_count = 120 buy_count = 120
hts = HTS_252670(stock_code, buy_count) hts = HTS_252670(stock_code, buy_count)
given_day = datetime.today().strftime('%Y%m%d') today_str = today.strftime('%Y%m%d')
lastday_str = ""
for i in range(1, 10):
lastday_str = (today - timedelta(i)).strftime('%Y%m%d')
if os.path.isfile("./data/" + stock_code + "_" + lastday_str + ".csv"):
break
hts.buyRealTime(given_day) hts.buyRealTime(lastday_str, today_str)
hts.writeStockData(stock_code, "20220620") hts.writeStockData(stock_code, today_str)
print ("done...") print ("done...")

View File

@@ -1,5 +1,6 @@
import os from math import nan
from datetime import datetime, timedelta from datetime import datetime, timedelta
import csv
import pandas as pd import pandas as pd
import plotly.graph_objects as go import plotly.graph_objects as go
from plotly import subplots from plotly import subplots
@@ -19,110 +20,102 @@ class Simulation:
return return
def getCSV(self, fileName, given_day, result): def getCSV(self, fileName, given_day, result):
data = pd.read_csv(fileName) with open(fileName, 'r') as infp:
reader = csv.reader(infp)
next(reader)
days = data.날짜 for rows in reader:
time = data.시간 days = rows[0] # data.날짜
open = data.시가 time = rows[1] # data.시간
close = data. open_v = rows[2] # data.시
high = data.고가 high = rows[3] # data.고가
low = data.저가 low = rows[4] # data.저가
vol = data.거래량 close = rows[5] # data.종가
start_time = datetime.strptime(given_day + " 090000", '%Y%m%d %H%M%S') vol = rows[6] # 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) + " " + str(time).zfill(4)+"00", '%Y%m%d %H%M%S')
temp = datetime.strptime(str(days[i]) + " " + str(time[i]).zfill(4)+"00", '%Y%m%d %H%M%S') if temp < start_time:
if temp < start_time: continue
continue
if temp not in result["check"]:
result["check"].add(temp)
result["time"].append(temp) result["time"].append(temp)
result["open"].append(open[i]) result["open"].append(int(open_v))
result["close"].append(close[i]) result["close"].append(int(close))
result["high"].append(high[i]) result["high"].append(int(high))
result["low"].append(low[i]) result["low"].append(int(low))
result["vol"].append(vol[i]) result["vol"].append(int(vol))
return 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)]
for i in range(6, size-5):
if self.stock_code == "252670":
buy, weight, sell = self.buySellChecker.getPriceAndWeight1(data, i)
else:
buy, weight, sell = self.buySellChecker.getPriceAndWeight2(data, i)
bsLine['buy'][i] = buy
bsLine['weight'][i] = weight
bsLine['sell'][i] = sell
return bsLine
def draw(self, stock_code, given_day, data, bsLine): def draw(self, stock_code, given_day, data, bsLine):
buy_line = bsLine['buy'] # 어제 데이터는 지운다.
sell_line = bsLine['sell'] data = data.loc[pd.DatetimeIndex(data.index).day == int(given_day[6:])]
buy_line = bsLine['buy'][381:]
sell_line = bsLine['sell'][381:]
#buy_line = bsLine['buy']
#sell_line = bsLine['sell']
# 그래프 설정을 위한 변수를 생성한다. # 그래프 설정을 위한 변수를 생성한다.
data['open'] = pd.to_numeric(data['open']) data = data.astype({'open': 'int',
data['high'] = pd.to_numeric(data['high']) 'high': 'int',
data['low'] = pd.to_numeric(data['low']) 'low': 'int',
data['close'] = pd.to_numeric(data['close']) 'close': 'int',
data['volume'] = pd.to_numeric(data['volume']) 'volume': 'int',
data['avg2'] = pd.to_numeric(data['avg2']) 'avg3': 'float',
data['avg5'] = pd.to_numeric(data['avg5']) 'avg5': 'float',
data['avg10'] = pd.to_numeric(data['avg10']) 'avg10': 'float',
data['avg30'] = pd.to_numeric(data['avg30']) 'avg30': 'float',
data['avg60'] = pd.to_numeric(data['avg60']) 'avg60': 'float',
data["fast_k"] = pd.to_numeric(data['fast_k']) 'fast_k': 'float',
data["slow_k"] = pd.to_numeric(data['slow_k']) 'slow_k': 'float',
data["slow_d"] = pd.to_numeric(data['slow_d']) 'slow_d': 'float',
data["rsi"] = pd.to_numeric(data['rsi']) 'rsi': 'float',
data["rsis"] = pd.to_numeric(data['rsis']) 'rsis': 'float'
})
buy_colors = [] buy_colors = []
for i in range(len(buy_line)): for i in range(len(buy_line)):
if buy_line[i] < 0: if buy_line[i] < 0:
buy_colors.append("#ffffff") buy_colors.append("#ffffff")
buy_line[i] = data["lower"][0] buy_line[i] = nan
else: else:
buy_colors.append("#ff00ff") buy_colors.append("#ff00ff")
sell_colors = [] sell_colors = []
for i in range(len(sell_line)): for i in range(len(sell_line)):
if sell_line[i] < 0: if sell_line[i] < 0:
sell_colors.append("#ffffff") sell_colors.append("#ffffff")
sell_line[i] = data["lower"][0] sell_line[i] = nan
else: else:
sell_colors.append("#00ced1") 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)) 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)) 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=data["upper"], name="upper", line_color='#8B4513') upper = go.Scatter(x=data['date'], y=data["upper"], name="upper", line_color='#000000')
bolinger_lower = go.Scatter(x=data['date'], y=data["lower"], name="lower", line_color='#8B4513') lower = go.Scatter(x=data['date'], y=data["lower"], name="lower", line_color='#000000')
avg2 = go.Scatter(x=data['date'], y=data["avg2"], name="avg2", line_color='#800080') avg3 = go.Scatter(x=data['date'], y=data["avg3"], name="avg3", line_color='#000000')
avg5 = go.Scatter(x=data['date'], y=data["avg5"], name="avg5", line_color='#800080') avg5 = go.Scatter(x=data['date'], y=data["avg5"], name="avg5", line_color='#00FF00')
avg10 = go.Scatter(x=data['date'], y=data["avg10"], name="avg10", line_color='#ff00ff') avg10 = go.Scatter(x=data['date'], y=data["avg10"], name="avg10", line_color='#ff00ff')
avg30 = go.Scatter(x=data['date'], y=data["avg30"], name="avg30", line_color='#00ffff') avg30 = go.Scatter(x=data['date'], y=data["avg30"], name="avg30", line_color='#FFA500')
avg60 = go.Scatter(x=data['date'], y=data["avg60"], name="avg60", line_color='#008000') #avg60 = go.Scatter(x=data['date'], y=data["avg60"], name="avg60", line_color='#008000')
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') 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')
volume_line = go.Scatter(x=data['date'], y=data["volume"], mode='lines', name='volume') volume_line = go.Scatter(x=data['date'], y=data["volume"], mode='lines', name='volume')
fast_k_line = go.Scatter(x=data['date'], y=data["fast_k"], mode='lines', name='fast_k') #fast_k_line = go.Scatter(x=data['date'], y=data["fast_k"], mode='lines', name='fast_k')
macd_line = go.Scatter(x=data['date'], y=data["macd"], mode='lines', name='macd')
macd_s_line = go.Scatter(x=data['date'], y=data["macds"], mode='lines', name='macds')
macd_o_line = go.Scatter(x=data['date'], y=data["macdo"], mode='lines', name='macdo')
slow_k_line = go.Scatter(x=data['date'], y=data["slow_k"], mode='lines', name='slow_k') slow_k_line = go.Scatter(x=data['date'], y=data["slow_k"], mode='lines', name='slow_k')
slow_d_line = go.Scatter(x=data['date'], y=data["slow_d"], mode='lines', name='slow_d') slow_d_line = go.Scatter(x=data['date'], y=data["slow_d"], mode='lines', name='slow_d')
rsi_line = go.Scatter(x=data['date'], y=data["rsi"], mode='lines', name='rsi') rsi_line = go.Scatter(x=data['date'], y=data["rsi"], mode='lines', name='rsi')
rsis_line = go.Scatter(x=data['date'], y=data["rsis"], mode='lines', name='rsis') rsis_line = go.Scatter(x=data['date'], y=data["rsis"], mode='lines', name='rsis')
#candle_data = [candle_stick, bolinger_upper, bolinger_lower, buy_check, sell_check, avg1, avg2, avg5, avg10, avg20, avg30, avg40, avg50, avg60] candle_data = [candle_stick, upper, lower, avg3, avg5, avg10, avg30, buy_check, sell_check]
candle_data = [candle_stick, bolinger_upper, bolinger_lower, avg2, avg5, avg10, avg30, avg60, buy_check, sell_check]
volume_data = [volume_line] volume_data = [volume_line]
stochastic_data = [fast_k_line, slow_k_line, slow_d_line] macd_data = [macd_line, macd_s_line, macd_o_line]
stochastic_data = [slow_k_line, slow_d_line]
rsi_data = [rsi_line, rsis_line] rsi_data = [rsi_line, rsis_line]
# 그래프를 그린다. # 그래프를 그린다.
@@ -132,15 +125,17 @@ class Simulation:
fig.show() fig.show()
""" """
fig = subplots.make_subplots(rows=4, cols=1, subplot_titles=('캔들', "거래량", "스토캐스틱", "RSI")) fig = subplots.make_subplots(rows=5, cols=1, subplot_titles=('캔들', "거래량", "MACD", "스토캐스틱", "RSI"))
for trace in candle_data: for trace in candle_data:
fig.append_trace(trace, 1, 1) fig.append_trace(trace, 1, 1)
for trace in volume_data: for trace in volume_data:
fig.append_trace(trace, 2, 1) fig.append_trace(trace, 2, 1)
for trace in stochastic_data: for trace in macd_data:
fig.append_trace(trace, 3, 1) fig.append_trace(trace, 3, 1)
for trace in rsi_data: for trace in stochastic_data:
fig.append_trace(trace, 4, 1) fig.append_trace(trace, 4, 1)
for trace in rsi_data:
fig.append_trace(trace, 5, 1)
#fig.update_xaxes(nticks=5) #fig.update_xaxes(nticks=5)
#fig.update_layout(height=1800, title=stock_code + "_" + given_day, xaxis_rangeslider_visible=False) #fig.update_layout(height=1800, title=stock_code + "_" + given_day, xaxis_rangeslider_visible=False)
@@ -149,12 +144,12 @@ class Simulation:
buy_count = len(df.loc[df["buy"] > 0]) buy_count = len(df.loc[df["buy"] > 0])
sell_count = len(df.loc[df["sell"] > 0]) sell_count = len(df.loc[df["sell"] > 0])
fig.update_layout(height=1800, title=stock_code + "_" + given_day + "_" + str(buy_count)+","+str(sell_count)) fig.update_layout(height=5000, title=stock_code + "_" + given_day + "_" + str(buy_count)+","+str(sell_count))
fig.show() fig.show()
return return
def simulate(self, GIVEN_DAY): def simulate(self, days):
result = {"check": set(), result = {"check": set(),
"time": [], "time": [],
"open": [], "open": [],
@@ -163,30 +158,31 @@ class Simulation:
"low": [], "low": [],
"vol": []} "vol": []}
last_day = days[0]
today = days[1]
# 데이터를 가지고 온다. # 데이터를 가지고 온다.
self.getCSV("./data/"+self.stock_code+"_"+GIVEN_DAY+".csv", GIVEN_DAY, result) self.getCSV("./data/" + self.stock_code + "_" + last_day + ".csv", last_day, result)
self.getCSV("./data/" + self.stock_code + "_" + today + ".csv", today, result)
# 분석을 통해서 볼린저밴드 상/하단을 계산한다. # 분석을 통해서 볼린저밴드 상/하단을 계산한다.
data = self.buySellChecker.analyze(result) data = self.buySellChecker.analyze(result)
# 사야 할 시점과 팔아야 할 시점을 체크한다. # 사야 할 시점과 팔아야 할 시점을 체크한다.
bsLine = self.checkTransaction(data) bsLine = self.buySellChecker.checkTransaction(data, self.stock_code)
# 그래프를 그린다. # 그래프를 그린다.
self.draw(self.stock_code, GIVEN_DAY, data, bsLine) self.draw(self.stock_code, today, data, bsLine)
return return
if __name__ == "__main__": 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_codes = { stock_codes = {
"252670": ['20220520', '20220128', '20220121', '20220120', '20211026'], # "252670": ['20220620', '20220621', '20220622', '20220623', '20220624'],
"122630": ['20211026', '20211025', '20211022', '20211021', '20211020'] # "122630": ['20220620', '20220621', '20220622', '20220623', '20220624']
"252670": [('20220620', '20220621')],
"122630": [('20220620', '20220621')]
} }
for stock_code in stock_codes: for stock_code in stock_codes: