This commit is contained in:
dosangyoon
2022-07-31 17:07:29 +09:00
parent cddcdf4f35
commit 5b5e2196c1
8 changed files with 502 additions and 62 deletions

View File

@@ -1,25 +1,22 @@
from math import nan
from datetime import datetime, timedelta
import copy
import pandas as pd
import plotly.graph_objects as go
from plotly import subplots
import sqlite3
import os
from hts.HTS import HTS
from stock.util.Stock2Vector import Stock2Vector
from hts.BuySellChecker import BuySellChecker
class Simulation (HTS):
stock2Vector = None
buySellChecker = None
stock_code = None
def __init__(self, RESOURCE_PATH, stock_code):
def __init__(self, RESOURCE_PATH):
super().__init__(RESOURCE_PATH)
self.stock2Vector = Stock2Vector(RESOURCE_PATH)
self.buySellChecker = BuySellChecker()
self.stock_code = stock_code
self.RESOURCE_PATH = RESOURCE_PATH
#self.connect()
return
@@ -129,30 +126,19 @@ class Simulation (HTS):
return
def getRealTime(self, stock_code, today, LAST_DATA=None):
if LAST_DATA is not None:
result = copy.deepcopy(LAST_DATA)
else:
result = {"check": set(), "time": [], "open": [], "close": [], "high": [], "low": [], "vol": []}
def simulate(self, stock_code, today):
LAST_DATA = self.stock2Vector.getLastData(stock_code, today)
self.getDBData(stock_code, today, result)
return result
def simulate(self, today):
LAST_DATA = self.getLastData(self.stock_code, today)
result = self.getRealTime(self.stock_code, today, LAST_DATA)
result = self.stock2Vector.getRealTime(stock_code, today, LAST_DATA)
# 규칙 기반의 분석을 통해서 볼린저밴드 상/하단을 계산한다.
data = self.buySellChecker.analyzeByRule(result)
# 사야 할 시점과 팔아야 할 시점을 체크한다.
bsLine, data = self.buySellChecker.checkTransaction(data, self.stock_code, False)
bsLine, data = self.buySellChecker.checkTransaction(data, stock_code, False)
# 그래프를 그린다.
self.draw(self.stock_code, today, data, bsLine)
self.draw(stock_code, today, data, bsLine)
return
@@ -165,13 +151,13 @@ if __name__ == "__main__":
stock_codes = {
# 252670
# 122630
"122630": ['20220725'],
"122630": ['20220729'],
}
for stock_code in stock_codes:
simulation = Simulation(RESOURCE_PATH, stock_code)
simulation = Simulation(RESOURCE_PATH)
for given_day in stock_codes[stock_code]:
simulation.simulate(given_day)
simulation.simulate(stock_code, given_day)
print ("done...")

83
StockTrainer.py Normal file
View File

@@ -0,0 +1,83 @@
import os
import keras
import numpy as np
from stock.util.Stock2Vector import Stock2Vector
from classification_models.keras import Classifiers
class StockTrainer:
RESOURCE_PATH = None
stock2Vector = None
def __init__(self, RESOURCE_PATH):
self.RESOURCE_PATH = RESOURCE_PATH
self.stock2Vector = Stock2Vector(RESOURCE_PATH)
return
def getDataset(self, stock_code):
df, minmax_df = self.stock2Vector.makeTrainData(stock_code)
TOTAL_X, TOTAL_Y = [], []
for key in df:
if key == "date":
continue
elif key == "label":
TOTAL_Y.append(df[key].tolist())
else:
TOTAL_X.append(df[key].tolist())
X, Y = [], []
for i in range(299, len(TOTAL_X[0])):
temp_X, temp_Y = np.zeros((299, 299)), np.zeros(0)
idx = 0
for j in range(i-299, i):
for k in range(len(TOTAL_X)):
temp_X[k][idx] = TOTAL_X[k][j]
idx += 1
X.append(temp_X)
Y.append(TOTAL_Y[i])
return X, Y
def train(self, stock_code):
ResNet18, preprocess_input = Classifiers.get('inceptionresnetv2')
X, Y = self.getDataset(stock_code)
X = preprocess_input(X)
n_classes = 3
# build model
base_model = ResNet18(input_shape=(299, 299, 3), weights='imagenet', include_top=False)
x = keras.layers.GlobalAveragePooling2D()(base_model.output)
output = keras.layers.Dense(n_classes, activation='softmax')(x)
model = keras.models.Model(inputs=[base_model.input], outputs=[output])
# train
model.compile(optimizer='SGD', loss='categorical_crossentropy', metrics=['accuracy'])
model.fit(X, Y)
return
if __name__ == "__main__":
PROJECT_HOME = os.path.join(os.path.dirname(__file__))
RESOURCE_PATH = os.path.join(PROJECT_HOME, "resources")
# to check bying
stock_codes = {
# 252670
# 122630
"252670": ['20220729'],
}
for stock_code in stock_codes:
stockTrainer = StockTrainer(RESOURCE_PATH)
stockTrainer.train(stock_code)
print ("done...")

View File

@@ -836,6 +836,331 @@ class BuySellChecker:
return data
def getSign(self, data1, data2):
diff_sign = []
for i in range(0, len(data1)):
if data1[i] > data2[i]: diff_sign.append(2)
elif data1[i] == data2[i]: diff_sign.append(1)
else: diff_sign.append(0)
return diff_sign
def getVectorFeature(self, result):
# 기본 캔들 정보
open = result["open"]
close = result["close"]
high = result["high"]
low = result["low"]
vol = result["vol"]
label = result["label"]
# 캔들 정보 연산
height = [close[i] - open[i] for i in range(0, len(close))]
top_tail_height = [high[i] - max(open[i], close[i]) for i in range(0, len(close))]
bottom_tail_height = [min(open[i], close[i]) - low[i] for i in range(0, len(close))]
diff_price = [close[i] - close[i - 1] for i in range(1, len(close))]
diff_price.insert(0, 0)
diff_price_sign = []
for i in range(1, len(close)):
if close[i] > close[i - 1]: diff_price_sign.append(2)
elif close[i] == close[i - 1]: diff_price_sign.append(1)
else: diff_price_sign.append(0)
diff_price_sign.insert(0, 0)
# 이동 평균
close_df = pd.DataFrame(close)
avg3_list = close_df.rolling(window=3).mean().fillna(close[0]).values.tolist()
avg3 = [item[0] for item in avg3_list]
avg5_list = close_df.rolling(window=5).mean().fillna(close[0]).values.tolist()
avg5 = [item[0] for item in avg5_list]
avg10_list = close_df.rolling(window=10).mean().fillna(close[0]).values.tolist()
avg10 = [item[0] for item in avg10_list]
avg20_list = close_df.rolling(window=20).mean().fillna(close[0]).values.tolist()
avg20 = [item[0] for item in avg20_list]
avg30_list = close_df.rolling(window=30).mean().fillna(close[0]).values.tolist()
avg30 = [item[0] for item in avg30_list]
avg60_list = close_df.rolling(window=60).mean().fillna(close[0]).values.tolist()
avg60 = [item[0] for item in avg60_list]
abs_avg_1 = [max(avg3[i], avg5[i], avg10[i], avg20[i], avg30[i], avg60[i]) - min(avg3[i], avg5[i], avg10[i], avg20[i], avg30[i], avg60[i]) for i in range(0, len(close))]
abs_avg_2 = [max(avg3[i], avg5[i], avg10[i], avg20[i], avg30[i]) - min(avg3[i], avg5[i], avg10[i], avg20[i], avg30[i]) for i in range(0, len(close))]
abs_avg_3 = [max(avg3[i], avg5[i], avg10[i], avg20[i]) - min(avg3[i], avg5[i], avg10[i], avg20[i]) for i in range(0, len(close))]
abs_avg_4 = [max(avg3[i], avg5[i], avg10[i]) - min(avg3[i], avg5[i], avg10[i]) for i in range(0, len(close))]
abs_avg_5 = [max(avg3[i], avg5[i]) - min(avg3[i], avg5[i]) for i in range(0, len(close))]
diff_avg3_avg5 = [avg3[i]-avg5[i] for i in range(0, len(close))]
diff_avg3_avg10 = [avg3[i] - avg10[i] for i in range(0, len(close))]
diff_avg3_avg20 = [avg3[i] - avg20[i] for i in range(0, len(close))]
diff_avg3_avg30 = [avg3[i] - avg30[i] for i in range(0, len(close))]
diff_avg3_avg60 = [avg3[i] - avg60[i] for i in range(0, len(close))]
diff_avg5_avg10 = [avg5[i] - avg10[i] for i in range(0, len(close))]
diff_avg5_avg20 = [avg5[i] - avg20[i] for i in range(0, len(close))]
diff_avg5_avg30 = [avg5[i] - avg30[i] for i in range(0, len(close))]
diff_avg5_avg60 = [avg5[i] - avg60[i] for i in range(0, len(close))]
diff_avg10_avg20 = [avg10[i] - avg20[i] for i in range(0, len(close))]
diff_avg10_avg30 = [avg10[i] - avg30[i] for i in range(0, len(close))]
diff_avg10_avg60 = [avg10[i] - avg60[i] for i in range(0, len(close))]
diff_avg20_avg30 = [avg20[i] - avg30[i] for i in range(0, len(close))]
diff_avg20_avg60 = [avg20[i] - avg60[i] for i in range(0, len(close))]
diff_avg30_avg60 = [avg30[i] - avg60[i] for i in range(0, len(close))]
diff_avg3_avg5_sign = self.getSign(avg3, avg5)
diff_avg3_avg10_sign = self.getSign(avg3, avg10)
diff_avg3_avg20_sign = self.getSign(avg3, avg20)
diff_avg3_avg30_sign = self.getSign(avg3, avg30)
diff_avg3_avg60_sign = self.getSign(avg3, avg60)
diff_avg5_avg10_sign = self.getSign(avg5, avg10)
diff_avg5_avg20_sign = self.getSign(avg5, avg20)
diff_avg5_avg30_sign = self.getSign(avg5, avg30)
diff_avg5_avg60_sign = self.getSign(avg5, avg60)
diff_avg10_avg20_sign = self.getSign(avg10, avg20)
diff_avg10_avg30_sign = self.getSign(avg10, avg30)
diff_avg10_avg60_sign = self.getSign(avg10, avg60)
diff_avg20_avg30_sign = self.getSign(avg20, avg30)
diff_avg20_avg60_sign = self.getSign(avg20, avg60)
diff_avg30_avg60_sign = self.getSign(avg30, avg60)
# 볼린져 밴드
df = pd.DataFrame(close)
max20 = df.rolling(window=20).mean()
stddev20 = df.rolling(window=20).std()
upper_df = max20 + (stddev20 * 2) # 상단 볼린저 밴드
lower_df = max20 - (stddev20 * 2) # 하단 볼린저 밴드
upper, lower = [], []
for i in range(len(upper_df)):
if i < 10:
upper.append(upper_df.values[0][0])
lower.append(lower_df.values[0][0])
else:
upper.append(upper_df.values[i][0])
lower.append(lower_df.values[i][0])
point_temp = result["time"]
STOCK = []
for i in range(len(open)):
STOCK.append({'volume': vol[i], 'close': close[i], 'open': open[i], 'high': high[i], 'low': low[i],
'avg3': avg3[i], 'avg5': avg5[i],'avg10': avg10[i],'avg20': avg20[i],'avg30': avg30[i],'avg60': avg60[i]})
# stochastic
stochastic_df = self.stochastic.apply(STOCK, n=30, m=5, t=5)
fast_k = stochastic_df['fast_k'].values.tolist()
slow_k = stochastic_df['slow_k'].values.tolist()
slow_d = stochastic_df['slow_d'].values.tolist()
# macd
macd_df = self.macd.apply(STOCK, short=12, long=26, t=9)
macd = macd_df['macd'].values.tolist()
macds = macd_df['macds'].values.tolist()
macdo = macd_df['macdo'].values.tolist()
# rsi
rsi_df = self.rsi.apply(STOCK, period=30, window=5)
rsi = rsi_df['rsi'].values.tolist()
rsis = rsi_df['rsis'].values.tolist()
# ichimokuCloud
ichimokuCloud_df = self.ichimokuCloud.apply(STOCK, c=9, b=26, l=52)
ichimokuCloud_df = ichimokuCloud_df[:len(ichimokuCloud_df) - 51]
changeLine = ichimokuCloud_df['changeLine'].values.tolist()
baseLine = ichimokuCloud_df['baseLine'].values.tolist()
leadingSpan1 = ichimokuCloud_df['leadingSpan1'].values.tolist()
leadingSpan2 = ichimokuCloud_df['leadingSpan2'].values.tolist()
# 간격
##### 볼린져 밴드
diff_upper_lower = [upper[i] - lower[i] for i in range(0, len(upper))]
diff_open_lower = [open[i] - lower[i] for i in range(0, len(open))]
diff_open_upper = [open[i] - upper[i] for i in range(0, len(open))]
diff_close_lower = [close[i] - lower[i] for i in range(0, len(close))]
diff_close_upper = [close[i] - upper[i] for i in range(0, len(close))]
diff_high_lower = [high[i] - lower[i] for i in range(0, len(high))]
diff_high_upper = [high[i] - upper[i] for i in range(0, len(high))]
diff_low_lower = [low[i] - lower[i] for i in range(0, len(low))]
diff_low_upper = [low[i] - upper[i] for i in range(0, len(low))]
diff_upper_lower_sign = self.getSign(upper, lower)
diff_open_lower_sign = self.getSign(open, lower)
diff_open_upper_sign = self.getSign(open, upper)
diff_close_lower_sign = self.getSign(close, lower)
diff_close_upper_sign = self.getSign(close, upper)
diff_high_lower_sign = self.getSign(high, lower)
diff_high_upper_sign = self.getSign(high, upper)
diff_low_lower_sign = self.getSign(low, lower)
diff_low_upper_sign = self.getSign(low, upper)
##### 일목균형표
diff_lead1_lead2 = [leadingSpan1[i] - leadingSpan2[i] for i in range(0, len(leadingSpan1))]
diff_change_base = [changeLine[i] - baseLine[i] for i in range(0, len(baseLine))]
diff_base_lead1 = [baseLine[i] - leadingSpan1[i] for i in range(0, len(baseLine))]
diff_base_lead2 = [baseLine[i] - leadingSpan2[i] for i in range(0, len(baseLine))]
diff_change_lead1 = [changeLine[i] - leadingSpan1[i] for i in range(0, len(changeLine))]
diff_change_lead2 = [changeLine[i] - leadingSpan2[i] for i in range(0, len(changeLine))]
diff_open_lead2 = [open[i] - leadingSpan2[i] for i in range(0, len(open))]
diff_open_lead1 = [open[i] - leadingSpan1[i] for i in range(0, len(open))]
diff_open_change = [open[i] - changeLine[i] for i in range(0, len(open))]
diff_open_base = [open[i] - baseLine[i] for i in range(0, len(open))]
diff_close_lead2 = [close[i] - leadingSpan2[i] for i in range(0, len(close))]
diff_close_lead1 = [close[i] - leadingSpan1[i] for i in range(0, len(close))]
diff_close_change = [close[i] - changeLine[i] for i in range(0, len(close))]
diff_close_base = [close[i] - baseLine[i] for i in range(0, len(close))]
diff_high_lead2 = [high[i] - leadingSpan2[i] for i in range(0, len(high))]
diff_high_lead1 = [high[i] - leadingSpan1[i] for i in range(0, len(high))]
diff_high_change = [high[i] - changeLine[i] for i in range(0, len(high))]
diff_high_base = [high[i] - baseLine[i] for i in range(0, len(high))]
diff_low_lead2 = [low[i] - leadingSpan2[i] for i in range(0, len(low))]
diff_low_lead1 = [low[i] - leadingSpan1[i] for i in range(0, len(low))]
diff_low_change = [low[i] - changeLine[i] for i in range(0, len(low))]
diff_low_base = [low[i] - baseLine[i] for i in range(0, len(low))]
diff_macd_macds = [macd[i] - macds[i] for i in range(0, len(macd))]
diff_slowk_slowd = [slow_k[i] - slow_d[i] for i in range(0, len(slow_k))]
diff_rsi_rsis = [rsi[i] - rsis[i] for i in range(0, len(rsi))]
diff_lead1_lead2_sign = self.getSign(leadingSpan1, leadingSpan2)
diff_change_base_sign = self.getSign(changeLine, baseLine)
diff_base_lead1_sign = self.getSign(baseLine, leadingSpan1)
diff_base_lead2_sign = self.getSign(baseLine, leadingSpan2)
diff_change_lead1_sign = self.getSign(changeLine, leadingSpan1)
diff_change_lead2_sign = self.getSign(changeLine, leadingSpan2)
diff_open_lead2_sign = self.getSign(open, leadingSpan2)
diff_open_lead1_sign = self.getSign(open, leadingSpan1)
diff_open_change_sign = self.getSign(open, changeLine)
diff_open_base_sign = self.getSign(open, baseLine)
diff_close_lead2_sign = self.getSign(close, leadingSpan2)
diff_close_lead1_sign = self.getSign(close, leadingSpan1)
diff_close_change_sign = self.getSign(close, changeLine)
diff_close_base_sign = self.getSign(close, baseLine)
diff_high_lead2_sign = self.getSign(high, leadingSpan2)
diff_high_lead1_sign = self.getSign(high, leadingSpan1)
diff_high_change_sign = self.getSign(high, changeLine)
diff_high_base_sign = self.getSign(high, baseLine)
diff_low_lead2_sign = self.getSign(low, leadingSpan2)
diff_low_lead1_sign = self.getSign(low, leadingSpan1)
diff_low_change_sign = self.getSign(low, changeLine)
diff_low_base_sign = self.getSign(low, baseLine)
diff_macd_macds_sign = self.getSign(macd, macds)
diff_slowk_slowd_sign = self.getSign(slow_k, slow_d)
diff_rsi_rsis_sign = self.getSign(rsi, rsis)
# 결과
temp = {
"date": point_temp,
"open": open, "high": high, "low": low, "close": close, "volume": vol,
"avg3": avg3, "avg5": avg5, "avg10": avg10, "avg20": avg20, "avg30": avg30, "avg60": avg60,
"upper": upper, "lower": lower,
"macd": macd, "macds": macds, "macdo": macdo,
"fast_k": fast_k, "slow_k": slow_k, "slow_d": slow_d,
"rsi": rsi, "rsis": rsis,
"changeLine": changeLine, "baseLine": baseLine, "leadingSpan1": leadingSpan1, "leadingSpan2": leadingSpan2,
"diff_price": diff_price, "height": height, "top_tail_height": top_tail_height, "bottom_tail_height": bottom_tail_height,
"abs_avg_1": abs_avg_1, "abs_avg_2": abs_avg_2, "abs_avg_3": abs_avg_3, "abs_avg_4": abs_avg_4, "abs_avg_5": abs_avg_5,
"diff_avg3_avg5": diff_avg3_avg5,
"diff_avg3_avg10": diff_avg3_avg10,
"diff_avg3_avg20": diff_avg3_avg20,
"diff_avg3_avg30": diff_avg3_avg30,
"diff_avg3_avg60": diff_avg3_avg60,
"diff_avg5_avg10": diff_avg5_avg10,
"diff_avg5_avg20": diff_avg5_avg20,
"diff_avg5_avg30": diff_avg5_avg30,
"diff_avg5_avg60": diff_avg5_avg60,
"diff_avg10_avg20": diff_avg10_avg20,
"diff_avg10_avg30": diff_avg10_avg30,
"diff_avg10_avg60": diff_avg10_avg60,
"diff_avg20_avg30": diff_avg20_avg30,
"diff_avg20_avg60": diff_avg20_avg60,
"diff_avg30_avg60": diff_avg30_avg60,
"diff_upper_lower": diff_upper_lower,
"diff_open_lower": diff_open_lower,
"diff_open_upper": diff_open_upper,
"diff_close_lower": diff_close_lower,
"diff_close_upper": diff_close_upper,
"diff_high_lower": diff_high_lower,
"diff_high_upper": diff_high_upper,
"diff_low_lower": diff_low_lower,
"diff_low_upper": diff_low_upper,
"diff_lead1_lead2": diff_lead1_lead2,
"diff_change_base": diff_change_base,
"diff_base_lead1": diff_base_lead1,
"diff_base_lead2": diff_base_lead2,
"diff_change_lead1": diff_change_lead1,
"diff_change_lead2": diff_change_lead2,
"diff_open_lead2": diff_open_lead2,
"diff_open_lead1": diff_open_lead1,
"diff_open_change": diff_open_change,
"diff_open_base": diff_open_base,
"diff_close_lead2": diff_close_lead2,
"diff_close_lead1": diff_close_lead1,
"diff_close_change": diff_close_change,
"diff_close_base": diff_close_base,
"diff_high_lead2": diff_high_lead2,
"diff_high_lead1": diff_high_lead1,
"diff_high_change": diff_high_change,
"diff_high_base": diff_high_base,
"diff_low_lead2": diff_low_lead2,
"diff_low_lead1": diff_low_lead1,
"diff_low_change": diff_low_change,
"diff_low_base": diff_low_base,
"diff_macd_macds": diff_macd_macds,
"diff_slowk_slowd": diff_slowk_slowd,
"diff_rsi_rsis": diff_rsi_rsis,
"diff_price_sign": diff_price_sign,
"diff_avg3_avg5_sign": diff_avg3_avg5_sign,
"diff_avg3_avg10_sign": diff_avg3_avg10_sign,
"diff_avg3_avg20_sign": diff_avg3_avg20_sign,
"diff_avg3_avg30_sign": diff_avg3_avg30_sign,
"diff_avg3_avg60_sign": diff_avg3_avg60_sign,
"diff_avg5_avg10_sign": diff_avg5_avg10_sign,
"diff_avg5_avg20_sign": diff_avg5_avg20_sign,
"diff_avg5_avg30_sign": diff_avg5_avg30_sign,
"diff_avg5_avg60_sign": diff_avg5_avg60_sign,
"diff_avg10_avg20_sign": diff_avg10_avg20_sign,
"diff_avg10_avg30_sign": diff_avg10_avg30_sign,
"diff_avg10_avg60_sign": diff_avg10_avg60_sign,
"diff_avg20_avg30_sign": diff_avg20_avg30_sign,
"diff_avg20_avg60_sign": diff_avg20_avg60_sign,
"diff_avg30_avg60_sign": diff_avg30_avg60_sign,
"diff_upper_lower_sign": diff_upper_lower_sign,
"diff_open_lower_sign": diff_open_lower_sign,
"diff_open_upper_sign": diff_open_upper_sign,
"diff_close_lower_sign": diff_close_lower_sign,
"diff_close_upper_sign": diff_close_upper_sign,
"diff_high_lower_sign": diff_high_lower_sign,
"diff_high_upper_sign": diff_high_upper_sign,
"diff_low_lower_sign": diff_low_lower_sign,
"diff_low_upper_sign": diff_low_upper_sign,
"diff_lead1_lead2_sign": diff_lead1_lead2_sign,
"diff_change_base_sign": diff_change_base_sign,
"diff_base_lead1_sign": diff_base_lead1_sign,
"diff_base_lead2_sign": diff_base_lead2_sign,
"diff_change_lead1_sign": diff_change_lead1_sign,
"diff_change_lead2_sign": diff_change_lead2_sign,
"diff_open_lead2_sign": diff_open_lead2_sign,
"diff_open_lead1_sign": diff_open_lead1_sign,
"diff_open_change_sign": diff_open_change_sign,
"diff_open_base_sign": diff_open_base_sign,
"diff_close_lead2_sign": diff_close_lead2_sign,
"diff_close_lead1_sign": diff_close_lead1_sign,
"diff_close_change_sign": diff_close_change_sign,
"diff_close_base_sign": diff_close_base_sign,
"diff_high_lead2_sign": diff_high_lead2_sign,
"diff_high_lead1_sign": diff_high_lead1_sign,
"diff_high_change_sign": diff_high_change_sign,
"diff_high_base_sign": diff_high_base_sign,
"diff_low_lead2_sign": diff_low_lead2_sign,
"diff_low_lead1_sign": diff_low_lead1_sign,
"diff_low_change_sign": diff_low_change_sign,
"diff_low_base_sign": diff_low_base_sign,
"diff_macd_macds_sign": diff_macd_macds_sign,
"diff_slowk_slowd_sign": diff_slowk_slowd_sign,
"diff_rsi_rsis_sign": diff_rsi_rsis_sign,
"label": label
}
data = pd.DataFrame(temp)
df_final_time = pd.DatetimeIndex(point_temp)
data.index = df_final_time
data = data.fillna(close[0])
return data
def checkTransaction(self, data, stock_code, type=True):
# 4일치 중에서 앞에 2일은 제거한다.
date = data['date'].dt.date.unique().tolist()

View File

@@ -553,7 +553,7 @@ class HTS:
conn = sqlite3.connect(os.path.join(self.RESOURCE_PATH, "hts.db"))
cursor = conn.cursor()
cursor.execute('SELECT ymd, hms, open, high, low, close, volume FROM ' + tableName + ' WHERE CODE=? and ymd=? order by ymd, hms', (stock_code, day,))
cursor.execute('SELECT ymd, hms, open, high, low, close, volume, label FROM ' + tableName + ' WHERE CODE=? and ymd=? order by ymd, hms', (stock_code, day,))
db_result = cursor.fetchall()
for rows in db_result:
ymd = rows[0] # hts.날짜
@@ -563,6 +563,7 @@ class HTS:
low = rows[4] # hts.저가
close = rows[5] # hts.종가
vol = rows[6] # hts.거래량
label = 0 if rows[7] is None else rows[7] # hts.매매구분
temp = datetime.strptime(str(ymd) + " " + str(hms).zfill(4) + "00", '%Y%m%d %H%M%S')
@@ -572,6 +573,7 @@ class HTS:
result["high"].append(int(high))
result["low"].append(int(low))
result["vol"].append(int(vol))
result["label"].append(int(label))
return
@@ -593,7 +595,8 @@ class HTS:
"close": [],
"high": [],
"low": [],
"vol": []}
"vol": [],
"label": []}
days = []
for i in range(1, 10):
@@ -601,10 +604,10 @@ class HTS:
isValid = self.isValidYMD(stock_code, last_day)
if isValid:
days.append(last_day)
if len(days) >= 3:
if len(days) >= n:
break
days.sort()
days = sorted(days)
for day in days:
self.getDBData(stock_code, day, result)
@@ -615,10 +618,11 @@ class HTS:
if LAST_DATA is not None:
result = copy.deepcopy(LAST_DATA)
else:
result = {"check": set(), "time": [], "open": [], "close": [], "high": [], "low": [], "vol": []}
result = {"check": set(), "time": [], "open": [], "close": [], "high": [], "low": [], "vol": [], "label": []}
self.getDBData(stock_code, today, result)
int_given_day = int(today)
objCpCybos = win32com.client.Dispatch("CpUtil.CpCybos")
bConnect = objCpCybos.IsConnect

View File

@@ -4,3 +4,4 @@ matplotlib
pandas_datareader
bs4
ipywidgets==7.0.0
image-classifiers

Binary file not shown.

View File

@@ -14,10 +14,10 @@ class DBManager:
cursor = conn.cursor()
# 테이블 생성
cursor.execute("CREATE TABLE IF NOT EXISTS " + tableName + " (CODE text, NAME text, ymd text, hms text, close REAL, open REAL, high REAL, low REAL, volume REAL, type INTEGER)")
cursor.execute("CREATE TABLE IF NOT EXISTS " + tableName + " (CODE text, NAME text, ymd text, hms text, close REAL, open REAL, high REAL, low REAL, volume REAL, label INTEGER)")
# 키 생성
create_key = "CREATE INDEX IF NOT EXISTS " + tableName + "_idx on " + tableName + " (CODE, ymd, hms, type) "
create_key = "CREATE INDEX IF NOT EXISTS " + tableName + "_idx on " + tableName + " (CODE, ymd, hms, label) "
cursor.execute(create_key)
conn.commit()

View File

@@ -1,7 +1,12 @@
import os
import copy
import sqlite3
from datetime import datetime, timedelta
import numpy as np
import pandas as pd
from datetime import datetime, timedelta
from hts.BuySellChecker import BuySellChecker
from hts.HTS import HTS
from stock.analysis.Common import Common
from stock.analysis.Stochastic import Stochastic
@@ -9,7 +14,7 @@ from stock.analysis.RSI import RSI
from stock.analysis.MACD import MACD
from stock.analysis.IchimokuCloud import IchimokuCloud
class Stock2Vector:
class Stock2Vector(HTS):
RESOURCE_PATH = None
@@ -20,8 +25,12 @@ class Stock2Vector:
ichimokuCloud = None
def __init__(self, RESOURCE_PATH):
super().__init__(RESOURCE_PATH)
self.RESOURCE_PATH = RESOURCE_PATH
self.buySellChecker = BuySellChecker()
self.common = Common()
self.stochastic = Stochastic()
self.rsi = RSI()
@@ -110,16 +119,48 @@ class Stock2Vector:
df_final_time = pd.DatetimeIndex(point_temp)
data.index = df_final_time
data.fillna(0)
data = data.fillna(0)
return data
def getDBData(self, stock_code, lastday, result):
def getRealTime(self, stock_code, today, LAST_DATA=None):
if LAST_DATA is not None:
result = copy.deepcopy(LAST_DATA)
else:
result = {"check": set(), "time": [], "open": [], "close": [], "high": [], "low": [], "vol": [], "label": []}
self.getDBData(stock_code, today, result)
return result
def makeData(self, today, stock_code):
LAST_DATA = self.getLastData(stock_code, today)
result = self.getRealTime(stock_code, today, LAST_DATA)
# 분석을 통해서 볼린저밴드 상/하단을 계산한다.
df = self.buySellChecker.getVectorFeature(result)
minmax_df1 = (df - df.min()) / (df.max() - df.min())
minmax_df2 = minmax_df1.drop(["date"], axis="columns")
minmax_df = minmax_df2.join(df['date'])
# 4일치 중에서 앞에 2일은 제거한다.
date = df['date'].dt.date.unique().tolist()
df = df[df['date'].dt.date != date[0]]
df = df[df['date'].dt.date != date[1]]
minmax_df = minmax_df[minmax_df['date'].dt.date != date[0]]
minmax_df = minmax_df[minmax_df['date'].dt.date != date[1]]
return df, minmax_df
def makeTrainData(self, stock_code):
result = {"check": set(), "time": [], "open": [], "close": [], "high": [], "low": [], "vol": [], "label": []}
tableName = 'hts'
conn = sqlite3.connect(os.path.join(self.RESOURCE_PATH, "hts.db"))
cursor = conn.cursor()
cursor.execute('SELECT ymd, hms, open, high, low, close, volume FROM ' + tableName + ' WHERE CODE=? and ymd=? order by ymd, hms', (stock_code, lastday,))
cursor.execute('SELECT ymd, hms, open, high, low, close, volume, label FROM ' + tableName + ' WHERE CODE=? order by ymd, hms', (stock_code,))
db_result = cursor.fetchall()
for rows in db_result:
ymd = rows[0] # hts.날짜
@@ -129,6 +170,7 @@ class Stock2Vector:
low = rows[4] # hts.저가
close = rows[5] # hts.종가
vol = rows[6] # hts.거래량
label = 0 if rows[7] is None else rows[7] # hts.매매구분
temp = datetime.strptime(str(ymd) + " " + str(hms).zfill(4) + "00", '%Y%m%d %H%M%S')
@@ -138,46 +180,45 @@ class Stock2Vector:
result["high"].append(int(high))
result["low"].append(int(low))
result["vol"].append(int(vol))
return
def vectorize(self, stock_code, given_day):
result = {"check": set(),
"time": [],
"open": [],
"close": [],
"high": [],
"low": [],
"vol": []}
for i in range(1, 10):
last_day = (datetime.strptime(given_day, '%Y%m%d') - timedelta(i)).strftime('%Y%m%d')
self.getDBData(stock_code, last_day, result)
if len(result['time']) > 0:
break
self.getDBData(stock_code, given_day, result)
result["label"].append(int(label))
# 분석을 통해서 볼린저밴드 상/하단을 계산한다.
data = self.analyze(result)
df = self.buySellChecker.getVectorFeature(result)
minmax_df1 = (df - df.min()) / (df.max() - df.min())
minmax_df2 = minmax_df1.drop(["date"], axis="columns")
minmax_df = minmax_df2.join(df['date'])
return data
minmax_df = minmax_df.fillna(0)
return df, minmax_df
def vectorize(self, data):
vector = []
for key in data:
if key == "date":
continue
vector.append(data[key].tolist())
return np.asarray(vector)
if __name__ == "__main__":
PROJECT_HOME = os.path.join(os.path.dirname(os.path.join(os.path.dirname(os.path.join(os.path.dirname(__file__))))))
RESOURCE_PATH = os.path.join(PROJECT_HOME, "resources")
stock2Vector = Stock2Vector(RESOURCE_PATH)
# to check bying
stock_codes = {
# 252670
# 122630
"122630": ['20220725'],
"252670": ['20220729'],
}
for stock_code in stock_codes:
stock2Vector = Stock2Vector(RESOURCE_PATH)
for given_day in stock_codes[stock_code]:
stock2Vector.vectorize(stock_code, given_day)
data, minmax_data = stock2Vector.makeData(given_day, stock_code)
vector = stock2Vector.vectorize(data)
minmax_vector = stock2Vector.vectorize(minmax_data)
print (given_day)
print ("done...")