init
This commit is contained in:
@@ -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
83
StockTrainer.py
Normal 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...")
|
||||
@@ -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()
|
||||
|
||||
14
hts/HTS.py
14
hts/HTS.py
@@ -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
|
||||
|
||||
@@ -4,3 +4,4 @@ matplotlib
|
||||
pandas_datareader
|
||||
bs4
|
||||
ipywidgets==7.0.0
|
||||
image-classifiers
|
||||
BIN
resources/hts.db
BIN
resources/hts.db
Binary file not shown.
@@ -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()
|
||||
|
||||
@@ -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...")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user