Merge remote-tracking branch 'origin/master'

This commit is contained in:
dsyoon
2022-08-05 00:38:39 +09:00
10 changed files with 265 additions and 125 deletions

View File

@@ -6,6 +6,7 @@ import os
from hts.HTS import HTS
from stock.util.Stock2Vector import Stock2Vector
from stock.util.StockPredictor import StockPredictor
from hts.BuySellChecker import BuySellChecker
class Simulation (HTS):
@@ -16,6 +17,7 @@ class Simulation (HTS):
super().__init__(RESOURCE_PATH)
self.stock2Vector = Stock2Vector(RESOURCE_PATH)
self.stockPredictor = StockPredictor()
self.buySellChecker = BuySellChecker()
self.RESOURCE_PATH = RESOURCE_PATH
#self.connect()
@@ -126,23 +128,23 @@ class Simulation (HTS):
return
def analyzeAutoMode(self, data):
return data, None
def simulate(self, stock_code, today, type="rule"):
LAST_DATA = self.stock2Vector.getLastData(stock_code, today)
def simulate(self, stock_code, today, method="rule"):
result = self.stock2Vector.getRealTime(stock_code, today, LAST_DATA)
if method == "ml":
LAST_DATA = self.stock2Vector.getLastData(stock_code, today, n=10)
result = self.stock2Vector.getRealTime(stock_code, today, LAST_DATA)
df, minmax_df = self.stock2Vector.preprocessData(result)
bsLine, data = self.stockPredictor.predict(df, minmax_df, isRealTime=False)
else:
LAST_DATA = self.stock2Vector.getLastData(stock_code, today)
result = self.stock2Vector.getRealTime(stock_code, today, LAST_DATA)
if type == "rule":
# 이동평균, RSI, MACD, 일목균형, 볼린저밴드 상/하단을 계산한다.
data = self.buySellChecker.analyze(result)
# 사야 할 시점과 팔아야 할 시점을 체크한다.
bsLine, data = self.buySellChecker.checkTransaction(data, stock_code, isRealTime=False)
elif type == "auto":
data, bsLine = self.analyzeAutoMode(result)
else:
data, bsLine = None, None
if data is not None:
# 그래프를 그린다.
@@ -159,13 +161,13 @@ if __name__ == "__main__":
stock_codes = {
# 252670
# 122630
"122630": ['20220729'],
"122630": ['20220803'],
}
for stock_code in stock_codes:
simulation = Simulation(RESOURCE_PATH)
for given_day in stock_codes[stock_code]:
simulation.simulate(stock_code, given_day)
simulation.simulate(stock_code, given_day, method='ml')
print ("done...")

View File

@@ -1,73 +1,74 @@
import os
import shutil
import datetime
import time
from datetime import datetime
from stock.crawler.FnGuideCrawler import FnGuideCrawler
from stock.crawler.MetaCrawler import MetaCrawler
from stock.crawler.StockCrawler import StockCrawler
from stock.analysis.AnalyzerSqlite import AnalyzerSqlite
today = datetime.datetime.now().strftime("%Y-%m-%d")
today = datetime.now().strftime("%Y-%m-%d")
# DB Browser for SQLite: http://hleecaster.com/python-sqlite3/
PROJECT_HOME = os.path.join(os.path.dirname(os.path.join(os.path.dirname(os.path.join(os.path.dirname(os.path.join(os.path.dirname(__file__))))))))
PROJECT_HOME = os.path.join(os.path.dirname(__file__))
START_DATE = "1900.01.01"
start = time.time()
stockFileName = PROJECT_HOME + '/resources/stock.db'
week = datetime.today().weekday()
# 재무제표는 3개월마다 다운로드를 한다.
fnGuideCrawler = FnGuideCrawler(START_DATE)
print("[KOSPI 상장기업 재무제표 다운로드]")
fnGuideCrawler.crawl_fnguide(stockFileName)
if week in (0, 1, 2, 3, 4):
metaCrawler = MetaCrawler(START_DATE)
print("\n[증시자금동향 (신용잔고, 펀드자금 잔고)]")
metaCrawler.crawl_money_trend(stockFileName)
# 재무제표는 3개월마다 다운로드를 한다.
fnGuideCrawler = FnGuideCrawler(START_DATE)
print("[KOSPI 상장기업 재무제표 다운로드]")
fnGuideCrawler.crawl_fnguide(stockFileName)
print("\n[국내 시장금리]")
metaCrawler.crawl_interest_rates(stockFileName)
metaCrawler = MetaCrawler(START_DATE)
print("\n[증시자금동향 (신용잔고, 펀드자금 잔고)]")
metaCrawler.crawl_money_trend(stockFileName)
print("\n[투자자별 매매동향(Trading_Trend)]")
metaCrawler.crawl_trading_trend(stockFileName)
print("\n[국내 시장금리]")
metaCrawler.crawl_interest_rates(stockFileName)
print("\n[환율 (USD, JPY, EUR, CNY)]")
metaCrawler.crawl_exchange(stockFileName)
print("\n[투자자별 매매동향(Trading_Trend)]")
metaCrawler.crawl_trading_trend(stockFileName)
print("\n[원유 (WTI), 국제금, COPPER, NATURALGAS, CORN, SOYBEAN]")
metaCrawler.crawl_meterials(stockFileName)
print("\n[환율 (USD, JPY, EUR, CNY)]")
metaCrawler.crawl_exchange(stockFileName)
print("\n[원유 (WTI), 국제금, COPPER, NATURALGAS, CORN, SOYBEAN]")
metaCrawler.crawl_meterials(stockFileName)
print("\n[종목 다운로드]")
stockCrawler = StockCrawler(START_DATE)
stockCrawler.crawl_etf_stocks(stockFileName)
stockCrawler.crawl_stocks(stockFileName)
#stockCrawler.crawl_special_stocks(stockFileName)
print("\n[종목 다운로드]")
stockCrawler = StockCrawler(START_DATE)
stockCrawler.crawl_etf_stocks(stockFileName)
stockCrawler.crawl_stocks(stockFileName)
#stockCrawler.crawl_special_stocks(stockFileName)
print("\n[종목 분석]")
# S: 분석까지 진행
inFileName = PROJECT_HOME + '/resources/stock.db'
analyzerSqlite = AnalyzerSqlite(PROJECT_HOME, stockFileName)
print("\n[종목 분석]")
# S: 분석까지 진행
inFileName = PROJECT_HOME + '/resources/stock.db'
analyzerSqlite = AnalyzerSqlite(PROJECT_HOME, stockFileName)
analyzerSqlite.analyzeDaily()
analyzerSqlite.analyzeGrouping("weekly")
analyzerSqlite.analyzeGrouping("monthly")
analyzerSqlite = AnalyzerSqlite(PROJECT_HOME, stockFileName)
print("\n[종목 결정]")
day = datetime.datetime.today().strftime("%Y%m%d")
outPath = PROJECT_HOME + "/resources/analysis/" + day
if os.path.isdir(outPath):
shutil.rmtree(outPath)
os.mkdir(outPath)
print("print to Html...")
analyzerSqlite.findCandidate(outPath)
# E: 분석까지 진행
analyzerSqlite.analyzeDaily()
analyzerSqlite.analyzeGrouping("weekly")
analyzerSqlite.analyzeGrouping("monthly")
analyzerSqlite = AnalyzerSqlite(PROJECT_HOME, stockFileName)
print("\n[종목 결정]")
day = datetime.today().strftime("%Y%m%d")
outPath = PROJECT_HOME + "/resources/analysis/" + day
if os.path.isdir(outPath):
shutil.rmtree(outPath)
os.mkdir(outPath)
print("print to Html...")
analyzerSqlite.findCandidate(outPath)
# E: 분석까지 진행
print("time : %6.2f", (time.time() - start))

View File

@@ -1,7 +1,6 @@
import os
import keras
import numpy as np
from numpy import zeros, newaxis
import tensorflow as tf
from stock.util.Stock2Vector import Stock2Vector
from classification_models.keras import Classifiers
@@ -18,16 +17,17 @@ class StockTrainer:
def getDataset(self, stock_code):
VECTOR_SIZE = 299
df, minmax_df = self.stock2Vector.makeTrainData(stock_code)
result = self.stock2Vector.getTrainData(stock_code)
df, minmax_df = self.stock2Vector.preprocessData(result)
TOTAL_X, TOTAL_Y = [], []
for key in df:
for key in minmax_df:
if key == "date":
continue
elif key == "label":
TOTAL_Y.append(df[key].tolist())
TOTAL_Y.append(minmax_df[key].tolist())
else:
TOTAL_X.append(df[key].tolist())
TOTAL_X.append(minmax_df[key].tolist())
SIZE_WIDTH = len(TOTAL_X[0])
SIZE_HEIGHT = len(TOTAL_X)
@@ -44,38 +44,37 @@ class StockTrainer:
Y.append([0, 1, 0])
else:
Y.append([0, 0, 1])
if i >= VECTOR_SIZE+10:
break
X = np.asarray(X)
Y = np.asarray(Y)
return X, Y
def train(self, stock_code):
ResNet18, preprocess_input = Classifiers.get('inceptionresnetv2')
X, Y = self.getDataset(stock_code)
# build model
n_classes = 3
Inceptionresnetv2, preprocess_input = Classifiers.get('inceptionresnetv2')
X = preprocess_input(X)
n_classes = 3
# build model
base_model = ResNet18(input_shape=(299, 299, 3), include_top=False)
# train
checkpoint_filename = os.path.join(self.RESOURCE_PATH, "model", "stock.ckpt")
base_model = Inceptionresnetv2(input_shape=(299, 299, 3), include_top=False)
x = tf.keras.layers.GlobalAveragePooling2D()(base_model.output)
output = tf.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'])
checkpoint_filename = os.path.join(self.RESOURCE_PATH, "model", "stock.ckpt")
chekpoint = tf.keras.callbacks.ModelCheckpoint(filepath=checkpoint_filename, save_weights_only=True, verbose=1)
earlystop = tf.keras.callbacks.EarlyStopping(monitor='loss', patience=3, mode="auto")
earlystop = tf.keras.callbacks.EarlyStopping(monitor='loss', patience=5, mode="auto")
if os.path.isfile(checkpoint_filename):
model.load_weights(checkpoint_filename)
model.fit(x=X,
y=Y,
epochs=10,
batch_size=10000,
epochs=10000,
callbacks=[chekpoint, earlystop])
return
@@ -95,5 +94,4 @@ if __name__ == "__main__":
stockTrainer = StockTrainer(RESOURCE_PATH)
stockTrainer.train(stock_code)
print ("done...")

View File

@@ -634,7 +634,7 @@ class HTS:
"label": []}
days = []
for i in range(1, 10):
for i in range(1, 100):
last_day = (datetime.strptime(today, '%Y%m%d') - timedelta(i)).strftime('%Y%m%d')
isValid = self.isValidYMD(stock_code, last_day)
if isValid:
@@ -655,6 +655,7 @@ class HTS:
else:
result = {"check": set(), "time": [], "open": [], "close": [], "high": [], "low": [], "vol": [], "label": []}
#### real time에서 아직 저장된 것이 없기 때문에 result는 아무것도 채워지지 않는다.
self.getDBData(stock_code, today, result)

View File

@@ -2,9 +2,9 @@ import json
import os
import time
import shutil
from stockpredictor.analysis.Common import Common
from stockpredictor.analysis.Stochastic import Stochastic
from stockpredictor.analysis.BolingerBand import BolingerBand
from stock.analysis.Common import Common
from stock.analysis.Stochastic import Stochastic
from stock.analysis.BolingerBand import BolingerBand
import matplotlib.pyplot as plt
import datetime
import sqlite3

View File

@@ -16,12 +16,12 @@ import plotly.graph_objs as go
from plotly import tools, subplots
import plotly.io as po
from stockpredictor.analysis.Common import Common
from stockpredictor.analysis.Stochastic import Stochastic
from stockpredictor.analysis.BolingerBand import BolingerBand
from stockpredictor.analysis.IchimokuCloud import IchimokuCloud
from stockpredictor.analysis.RSI import RSI
from stockpredictor.crawler.sQLite.MovingAverage import MovingAverage
from stock.analysis.Common import Common
from stock.analysis.Stochastic import Stochastic
from stock.analysis.BolingerBand import BolingerBand
from stock.analysis.IchimokuCloud import IchimokuCloud
from stock.analysis.RSI import RSI
from stock.crawler.MovingAverage import MovingAverage
class AnalyzerSqlite:
PROJECT_HOME = None
@@ -118,6 +118,7 @@ class AnalyzerSqlite:
high = list(reversed(stock['high']))
low = list(reversed(stock['low']))
volume = list(reversed(stock['volume']))
avg3 = list(reversed(stock['avg3']))
avg4 = list(reversed(stock['avg4']))
avg5 = list(reversed(stock['avg5']))
avg6 = list(reversed(stock['avg6']))
@@ -142,6 +143,7 @@ class AnalyzerSqlite:
# general
candle_stick = go.Candlestick(x=ymd, open=open, high=high, low=low, close=close, increasing_line_color='red', decreasing_line_color='blue')
avg3 = go.Scatter(x=ymd, y=avg3, name="avg3", line_color='#085F1B')
avg4 = go.Scatter(x=ymd, y=avg4, name="avg4", line_color='#085F1B')
avg5 = go.Scatter(x=ymd, y=avg5, name="avg5", line_color='#000000')
avg6 = go.Scatter(x=ymd, y=avg6, name="avg6", line_color='#698D09')
@@ -160,7 +162,7 @@ class AnalyzerSqlite:
changeLine = go.Scatter(x=ymd, y=ichimokucloud_changeLine, name="changeLine", line_color='#000000')
baseLine = go.Scatter(x=ymd, y=ichimokucloud_baseLine, name="baseLine", line_color='#FF0000')
candle_data = [candle_stick, avg4, avg5, avg6, avg10, avg12, avg20, avg36, avg40, avg48, avg60, avg120, avg240, avg300, bolinger_upper, bolinger_lower, changeLine, baseLine]
candle_data = [candle_stick, avg3, avg4, avg5, avg6, avg10, avg12, avg20, avg36, avg40, avg48, avg60, avg120, avg240, avg300, bolinger_upper, bolinger_lower, changeLine, baseLine]
#candle_data = [candle_stick, bolinger_upper, bolinger_lower, changeLine, baseLine]
volume = go.Bar(x=ymd, y=volume, name="volume")
@@ -229,6 +231,9 @@ class AnalyzerSqlite:
os.mkdir(outPath)
self.makeDir("final")
self.makeDir("daily_3일선_10일선_상향돌파")
self.makeDir("daily_3일선_10일선_하향돌파")
self.makeDir("weekly_4주선_48주선_상향돌파")
self.makeDir("weekly_종가_12주선_상향돌파")
self.makeDir("weekly_rsi_20이하")
@@ -297,7 +302,7 @@ class AnalyzerSqlite:
cursor = conn.cursor()
sql = 'SELECT ymd, close, open, high, low, volume, '
sql += ' avg4, avg5, avg6, avg10, avg12, avg20, avg36, avg40, avg48, avg60, avg120, avg200, avg240, avg300, '
sql += ' avg3, avg4, avg5, avg6, avg10, avg12, avg20, avg36, avg40, avg48, avg60, avg120, avg200, avg240, avg300, '
sql += ' bolingerband_upper, bolingerband_lower, bolingerband_middle, '
sql += ' ichimokucloud_changeLine, ichimokucloud_baseLine, ichimokucloud_leadingSpan1, ichimokucloud_leadingSpan2, '
sql += ' stochastic_fast_k, stochastic_slow_k, stochastic_slow_d, '
@@ -311,7 +316,7 @@ class AnalyzerSqlite:
ymd = []
close, open, high, low, volume = [], [], [], [], []
avg4, avg5, avg6, avg10, avg12, avg20, avg36, avg40, avg48, avg60, avg120, avg200, avg240, avg300 = [], [], [], [], [], [], [], [], [], [], [], [], [], []
avg3, avg4, avg5, avg6, avg10, avg12, avg20, avg36, avg40, avg48, avg60, avg120, avg200, avg240, avg300 = [], [], [], [], [], [], [], [], [], [], [], [], [], [], []
bolingerband_upper, bolingerband_lower, bolingerband_middle = [], [], []
ichimokucloud_changeLine, ichimokucloud_baseLine, ichimokucloud_leadingSpan1, ichimokucloud_leadingSpan2 = [], [], [], []
stochastic_fast_k, stochastic_slow_k, stochastic_slow_d = [], [], []
@@ -324,37 +329,38 @@ class AnalyzerSqlite:
high.append(price[3])
low.append(price[4])
volume.append(price[5])
avg4.append(price[6])
avg5.append(price[7])
avg6.append(price[8])
avg10.append(price[9])
avg12.append(price[10])
avg20.append(price[11])
avg36.append(price[12])
avg40.append(price[13])
avg48.append(price[14])
avg60.append(price[15])
avg120.append(price[16])
avg200.append(price[17])
avg240.append(price[18])
avg300.append(price[19])
bolingerband_upper.append(price[20])
bolingerband_lower.append(price[21])
bolingerband_middle.append(price[22])
ichimokucloud_changeLine.append(price[23])
ichimokucloud_baseLine.append(price[24])
ichimokucloud_leadingSpan1.append(price[25])
ichimokucloud_leadingSpan2.append(price[26])
stochastic_fast_k.append(price[27])
stochastic_slow_k.append(price[28])
stochastic_slow_d.append(price[29])
rsi.append(price[30])
rsis.append(price[31])
avg3.append(price[6])
avg4.append(price[7])
avg5.append(price[8])
avg6.append(price[9])
avg10.append(price[10])
avg12.append(price[11])
avg20.append(price[12])
avg36.append(price[13])
avg40.append(price[14])
avg48.append(price[15])
avg60.append(price[16])
avg120.append(price[17])
avg200.append(price[18])
avg240.append(price[19])
avg300.append(price[20])
bolingerband_upper.append(price[21])
bolingerband_lower.append(price[22])
bolingerband_middle.append(price[23])
ichimokucloud_changeLine.append(price[24])
ichimokucloud_baseLine.append(price[25])
ichimokucloud_leadingSpan1.append(price[26])
ichimokucloud_leadingSpan2.append(price[27])
stochastic_fast_k.append(price[28])
stochastic_slow_k.append(price[29])
stochastic_slow_d.append(price[30])
rsi.append(price[31])
rsis.append(price[32])
stock = {
"ymd": ymd,
"close": close, "open": open, "high": high, "low": low, "volume": volume,
"avg4": avg4, "avg5": avg5, "avg6": avg6, "avg10": avg10, "avg12": avg12, "avg20": avg20, "avg36": avg36, "avg40": avg40, "avg48": avg48, "avg60": avg60, "avg120": avg120, "avg200": avg200, "avg300": avg300,
"avg3": avg3, "avg4": avg4, "avg5": avg5, "avg6": avg6, "avg10": avg10, "avg12": avg12, "avg20": avg20, "avg36": avg36, "avg40": avg40, "avg48": avg48, "avg60": avg60, "avg120": avg120, "avg200": avg200, "avg300": avg300,
"avg240": avg240,
"bolingerband_upper": bolingerband_upper, "bolingerband_lower": bolingerband_lower,
"bolingerband_middle": bolingerband_middle,
@@ -408,6 +414,26 @@ class AnalyzerSqlite:
# 종목 상태 체크 분석
# [Dailly]
if (stock_daily['avg3'][0] >= stock_daily['avg10'][0] and
stock_daily['avg3'][1] <= stock_daily['avg10'][1] and
stock_daily['avg3'][2] <= stock_daily['avg10'][2] and
stock_daily['avg3'][3] <= stock_daily['avg10'][3]):
type = "daily_3일선_10일선_상향돌파"
final_status += " " + type
final_status_count += 1
self.writeFile(type, CODE, NAME, top, stock_weekly, status)
if (stock_daily['avg3'][0] <= stock_daily['avg10'][0] and
stock_daily['avg3'][1] >= stock_daily['avg10'][1] and
stock_daily['avg3'][2] >= stock_daily['avg10'][2] and
stock_daily['avg3'][3] >= stock_daily['avg10'][3]):
type = "daily_3일선_10일선_하향돌파"
final_status += " " + type
final_status_count += 1
self.writeFile(type, CODE, NAME, top, stock_weekly, status)
# [Weekly]
# 정배열 체크
temp_status = self.common.check_RightArrange(stock_weekly)
@@ -564,6 +590,7 @@ class AnalyzerSqlite:
return
def get_moving_average(self, stock):
q_3 = MovingAverage(3)
q_4 = MovingAverage(4)
q_5 = MovingAverage(5)
q_6 = MovingAverage(6)
@@ -580,6 +607,7 @@ class AnalyzerSqlite:
q_300 = MovingAverage(300)
for i in range(len(stock)):
q_3.enqueue(stock[i]['close'])
q_4.enqueue(stock[i]['close'])
q_5.enqueue(stock[i]['close'])
q_6.enqueue(stock[i]['close'])
@@ -595,6 +623,7 @@ class AnalyzerSqlite:
q_240.enqueue(stock[i]['close'])
q_300.enqueue(stock[i]['close'])
stock[i]['avg3'] = q_3.avg()
stock[i]['avg4'] = q_4.avg()
stock[i]['avg5'] = q_5.avg()
stock[i]['avg6'] = q_6.avg()
@@ -625,6 +654,7 @@ class AnalyzerSqlite:
"high": weekDict['high'][ts],
"low": weekDict['low'][ts],
"volume": weekDict['volume'][ts],
"avg3": -1,
"avg4": -1,
"avg5": -1,
"avg6": -1,
@@ -664,7 +694,7 @@ class AnalyzerSqlite:
stockAnalysisTableName = 'stock_analysis_' + type
# 테이블 생성
cursor.execute("CREATE TABLE IF NOT EXISTS " + stockAnalysisTableName + " (CODE text, NAME text, ymd text, close REAL, diff REAL, open REAL, high REAL, low REAL, volume REAL, avg4 REAL, avg5 REAL, avg6 REAL, avg10 REAL, avg12 REAL, avg20 REAL, avg36 REAL, avg40 REAL, avg48 REAL, avg60 REAL, avg120 REAL, avg200 REAL, avg240 REAL, avg300 REAL, bolingerband_upper REAL, bolingerband_lower REAL, bolingerband_middle REAL, ichimokucloud_changeLine REAL, ichimokucloud_baseLine REAL, ichimokucloud_leadingSpan1 REAL, ichimokucloud_leadingSpan2 REAL, stochastic_fast_k REAL, stochastic_slow_k REAL, stochastic_slow_d REAL, rsi REAL, rsis REAL)")
cursor.execute("CREATE TABLE IF NOT EXISTS " + stockAnalysisTableName + " (CODE text, NAME text, ymd text, close REAL, diff REAL, open REAL, high REAL, low REAL, volume REAL, avg3 REAL, avg4 REAL, avg5 REAL, avg6 REAL, avg10 REAL, avg12 REAL, avg20 REAL, avg36 REAL, avg40 REAL, avg48 REAL, avg60 REAL, avg120 REAL, avg200 REAL, avg240 REAL, avg300 REAL, bolingerband_upper REAL, bolingerband_lower REAL, bolingerband_middle REAL, ichimokucloud_changeLine REAL, ichimokucloud_baseLine REAL, ichimokucloud_leadingSpan1 REAL, ichimokucloud_leadingSpan2 REAL, stochastic_fast_k REAL, stochastic_slow_k REAL, stochastic_slow_d REAL, rsi REAL, rsis REAL)")
# 키 생성
create_key = "CREATE INDEX IF NOT EXISTS " + stockAnalysisTableName + "_idx on " + stockAnalysisTableName + " (CODE, ymd) "
@@ -685,16 +715,16 @@ class AnalyzerSqlite:
result = cursor.fetchone()
if result == None:
sql = "INSERT INTO " + stockAnalysisTableName + "(CODE, NAME, ymd, close, diff, open, high, low, volume, "
sql += " avg4, avg5, avg6, avg10, avg12, avg20, avg36, avg40, avg48, avg60, avg120, avg200, avg240, avg300, "
sql += " avg3, avg4, avg5, avg6, avg10, avg12, avg20, avg36, avg40, avg48, avg60, avg120, avg200, avg240, avg300, "
sql += " bolingerband_upper, bolingerband_lower, bolingerband_middle, "
sql += " ichimokucloud_changeLine, ichimokucloud_baseLine, ichimokucloud_leadingSpan1, ichimokucloud_leadingSpan2, "
sql += " stochastic_fast_k, stochastic_slow_k, stochastic_slow_d, "
sql += " rsi, rsis) "
sql += " VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"
sql += " VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"
cursor.execute(sql, (
stock["CODE"], stock["NAME"], price['ymd'], price['close'], price['diff'], price['open'], price['high'], price['low'], price['volume'],
price['avg4'], price['avg5'], price['avg6'], price['avg10'], price['avg12'], price['avg20'], price['avg36'], price['avg40'], price['avg48'], price['avg60'], price['avg120'], price['avg200'], price['avg240'], price['avg300'],
price['avg3'], price['avg4'], price['avg5'], price['avg6'], price['avg10'], price['avg12'], price['avg20'], price['avg36'], price['avg40'], price['avg48'], price['avg60'], price['avg120'], price['avg200'], price['avg240'], price['avg300'],
price['bolingerband_upper'], price['bolingerband_lower'], price['bolingerband_middle'],
price['ichimokucloud_changeLine'], price['ichimokucloud_baseLine'], price['ichimokucloud_leadingSpan1'],
price['ichimokucloud_leadingSpan2'],
@@ -703,7 +733,7 @@ class AnalyzerSqlite:
else:
sql = "UPDATE " + stockAnalysisTableName + " SET close=?, diff=?, open=?, high=?, low=?, volume=?, "
sql += " avg4=?, avg5=?, avg6=?, avg10=?, avg12=?, avg20=?, avg36=?, avg40=?, avg48=?, avg60=?, avg120=?, avg200=?, avg240=?, avg300=?, "
sql += " avg3=?, avg4=?, avg5=?, avg6=?, avg10=?, avg12=?, avg20=?, avg36=?, avg40=?, avg48=?, avg60=?, avg120=?, avg200=?, avg240=?, avg300=?, "
sql += " bolingerband_upper=?, bolingerband_lower=?, bolingerband_middle=?, "
sql += " ichimokucloud_changeLine=?, ichimokucloud_baseLine=?, ichimokucloud_leadingSpan1=?, ichimokucloud_leadingSpan2=?, "
sql += " stochastic_fast_k=?, stochastic_slow_k=?, stochastic_slow_d=?, "
@@ -712,7 +742,7 @@ class AnalyzerSqlite:
cursor.execute(sql,
(price['close'], price['diff'], price['open'], price['high'], price['low'], price['volume'],
price['avg4'], price['avg5'], price['avg6'], price['avg10'], price['avg12'], price['avg20'], price['avg36'], price['avg40'], price['avg48'], price['avg60'], price['avg120'], price['avg200'], price['avg240'], price['avg300'],
price['avg3'], price['avg4'], price['avg5'], price['avg6'], price['avg10'], price['avg12'], price['avg20'], price['avg36'], price['avg40'], price['avg48'], price['avg60'], price['avg120'], price['avg200'], price['avg240'], price['avg300'],
price['bolingerband_upper'], price['bolingerband_lower'], price['bolingerband_middle'], price['ichimokucloud_changeLine'], price['ichimokucloud_baseLine'],
price['ichimokucloud_leadingSpan1'], price['ichimokucloud_leadingSpan2'],
price['stochastic_fast_k'], price['stochastic_slow_k'], price['stochastic_slow_d'],
@@ -752,6 +782,7 @@ class AnalyzerSqlite:
"high": item[4],
"low": item[5],
"volume": item[6],
"avg3": -1,
"avg4": -1,
"avg5": -1,
"avg6": -1,
@@ -815,6 +846,7 @@ class AnalyzerSqlite:
"high": item[4],
"low": item[5],
"volume": item[6],
"avg3": -1,
"avg4": -1,
"avg5": -1,
"avg6": -1,

View File

@@ -1,5 +1,5 @@
import pandas as pd
from stockpredictor.analysis.Common import Common
from stock.analysis.Common import Common
import plotly.graph_objs as go
from plotly import tools, subplots
import plotly.io as po

View File

@@ -338,7 +338,7 @@ class StockCrawler:
continue
stock_data.append({
'CODE':item_code, 'NAME':us_stocks[item_code], 'ymd': ymd.strftime('%Y.%m.%d'),
'CODE':item_code, 'NAME':special_stocks[item_code], 'ymd': ymd.strftime('%Y.%m.%d'),
'close': round(stock['close'][ymd], 2), 'diff': round(diff, 2), 'open': round(stock['open'][ymd], 2),
'high': round(stock['high'][ymd], 2), 'low': round(stock['low'][ymd], 2), 'volume': stock['volume'][ymd]
})
@@ -358,7 +358,7 @@ class StockCrawler:
conn.commit()
cursor.close()
conn.close()
print(idx, item_code, us_stocks[item_code], (time.time() - start_time), "s")
print(idx, item_code, special_stocks[item_code], (time.time() - start_time), "s")
start_time = time.time()
sleep(0.05)
@@ -400,9 +400,9 @@ class StockCrawler:
if date == lastDay:
lastPage = True
df = df.append(html[0], ignore_index=True)
df = pd.concat((df, html[0]), ignore_index=True)
break
df = df.append(html[0], ignore_index=True)
df = pd.concat((df, html[0]), ignore_index=True)
df = df.dropna()
if (lastPage) or (len(df) < 1) or ("날짜" not in df) or (df.날짜[1]==''):
print("\t- lastpage:", page)

View File

@@ -153,6 +153,53 @@ class Stock2Vector(HTS):
return df, minmax_df
def getTrainData(self, stock_code):
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, label FROM ' + tableName + ' WHERE CODE=? and (ymd >= ? and ymd <= ?) order by ymd desc, hms ',
(stock_code, "20220721", "20220731"))
db_result = cursor.fetchall()
temp_result = []
for rows in db_result:
temp_result.append(
[rows[0], rows[1], rows[2], rows[3], rows[4], rows[5], rows[6], 0 if rows[7] is None else rows[7]])
temp_result.sort(key=lambda x: (x[0], x[1]))
result = {"check": set(), "time": [], "open": [], "close": [], "high": [], "low": [], "vol": [], "label": []}
for rows in temp_result:
ymd = rows[0] # hts.날짜
hms = rows[1] # hts.시간
open = rows[2] # hts.시가
high = rows[3] # 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')
result["time"].append(temp)
result["open"].append(int(open))
result["close"].append(int(close))
result["high"].append(int(high))
result["low"].append(int(low))
result["vol"].append(int(vol))
result["label"].append(int(label))
return result
def preprocessData(self, 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'])
minmax_df = minmax_df.fillna(0)
return df, minmax_df
def makeTrainData(self, stock_code):
result = {"check": set(), "time": [], "open": [], "close": [], "high": [], "low": [], "vol": [], "label": []}

View File

@@ -0,0 +1,59 @@
import os
import keras
import numpy as np
from keras.applications.imagenet_utils import decode_predictions
from classification_models.keras import Classifiers
class StockPredictor:
RESOURCE_PATH = None
stock2Vector = None
def __init__(self):
return
def getDataset(self, df):
VECTOR_SIZE = 299
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())
SIZE_WIDTH = len(TOTAL_X[0])
SIZE_HEIGHT = len(TOTAL_X)
X = []
for i in range(VECTOR_SIZE, SIZE_WIDTH):
temp_X, temp_Y = np.zeros((VECTOR_SIZE, VECTOR_SIZE)), np.zeros(0)
for j in range(SIZE_HEIGHT):
temp_X[j][0:VECTOR_SIZE] = TOTAL_X[j][i - VECTOR_SIZE:i]
temp_X = np.stack([temp_X, temp_X, temp_X], axis=-1)
X.append(temp_X)
X = np.asarray(X[len(X)-1])
return X
def predict(self, df, minmax_df, isRealTime=False):
X = self.getDataset(df)
# build model
n_classes = 3
Inceptionresnetv2, preprocess_input = Classifiers.get('inceptionresnetv2')
X = preprocess_input(X)
base_model = Inceptionresnetv2(input_shape=(299, 299, 3), include_top=False)
model = keras.models.Model(inputs=[base_model.input])
checkpoint_filename = os.path.join(self.RESOURCE_PATH, "model", "stock.ckpt")
model.load_weights(checkpoint_filename)
y = model.predict(X)
# result
print(decode_predictions(y))
return