This commit is contained in:
dsyoon
2021-04-26 00:46:47 +09:00
parent 5ec270bbb9
commit bcac177c61
3 changed files with 210 additions and 293 deletions

View File

@@ -3,17 +3,13 @@ import os
import time
import shutil
from stockpredictor.analysis.Common import Common
from stockpredictor.analysis.MACD import MACD
from stockpredictor.analysis.RSI import RSI
from stockpredictor.analysis.Stochastic import Stochastic
from stockpredictor.analysis.IchimokuCloud import IchimokuCloud
import matplotlib.pyplot as plt
import datetime
import sqlite3
from datetime import datetime
from matplotlib import rc
import math
rc('font', family='AppleGothic')
plt.rcParams['axes.unicode_minus'] = False
@@ -30,10 +26,7 @@ class Analyzer:
stocks = None
candidate = None
macd = None
rsi = None
stochastic = None
ichimokuCloud = None
common = None
inFileName = None
@@ -51,10 +44,7 @@ class Analyzer:
self.common = Common()
self.macd = MACD()
self.rsi = RSI()
self.stochastic = Stochastic()
self.ichimokuCloud = IchimokuCloud()
self.readFnguide()
return
@@ -97,57 +87,29 @@ class Analyzer:
if last_index > 300:
index = 300 # 최대 300일치 그래프 확인
df_stock = pd.DataFrame(stock["PRICE"][len(stock["PRICE"]) - index:])
df_macd = pd.DataFrame(stock["MACD"][len(stock["MACD"]) - index:last_index+1])
df_stochastic = pd.DataFrame(stock["STOCHASTIC"][len(stock["STOCHASTIC"]) - index:last_index+1])
df_rsi = pd.DataFrame(stock["RSI"][len(stock["RSI"]) - index:last_index+1])
df_ichimoku = pd.DataFrame(stock["ICHIMOKU"][len(stock["ICHIMOKU"]) - index:])
else:
index = last_index
df_stock = pd.DataFrame(stock["PRICE"][:index+1])
df_macd = pd.DataFrame(stock["MACD"][:index+1])
df_stochastic = pd.DataFrame(stock["STOCHASTIC"][:index+1])
df_ichimoku = pd.DataFrame(stock["ICHIMOKU"][:index+1])
df_rsi = pd.DataFrame(stock["RSI"][:index+1])
# general
volume = go.Bar(x=df_stock.DATE, y=df_stock['volume'], name="volume")
volume_data = [volume]
leadingSpan1 = go.Scatter(x=df_ichimoku.DATE, y=df_ichimoku['leadingSpan1'], name="선행스팬", line_color='#8B4513')
leadingSpan2 = go.Scatter(x=df_ichimoku.DATE, y=df_ichimoku['leadingSpan2'], name="후행스팬", line_color='#4169E1')
cnadle = go.Candlestick(x=df_stock.DATE, open=df_stock.open, high=df_stock.high, low=df_stock.low, close=df_stock.close, increasing_line_color= 'red', decreasing_line_color= 'blue')
ichimokuCloud_data = [leadingSpan1, leadingSpan2, cnadle]
# macd
macd = go.Scatter(x=df_macd.DATE, y=df_macd['macd'], name="MACD", line_color='#8B4513')
macd_signal = go.Scatter(x=df_macd.DATE, y=df_macd['macds'], name="MACD Signal", line_color='#4169E1')
oscillator = go.Bar(x=df_macd.DATE, y=df_macd['macdo'], name="oscillator")
macd_data = [macd, macd_signal, oscillator]
# stochastic
slow_k = go.Scatter(x=df_stochastic.DATE, y=df_stochastic['slow_k'], name="Slow%K", line_color='#8B4513')
slow_d = go.Scatter(x=df_stochastic.DATE, y=df_stochastic['slow_d'], name="Slow%D", line_color='#4169E1')
stochastic_data = [slow_k, slow_d]
# rsi
rsi = go.Scatter(x=df_macd.DATE, y=df_rsi['rsi'], name="RSI", line_color='#8B4513')
rsi_signal = go.Scatter(x=df_macd.DATE, y=df_rsi['rsis'], name="RSI Signal", line_color='#4169E1')
rsi_data = [rsi, rsi_signal]
fig = subplots.make_subplots(rows=2, cols=1, subplot_titles=('거래량', 'Stochastic'))
fig = subplots.make_subplots(rows=5, cols=1, subplot_titles=('MACD', 'Stochastic', 'RSI', '거래량', '일목균형표'))
for trace in macd_data:
for trace in volume_data:
fig.append_trace(trace, 1, 1)
for trace in stochastic_data:
fig.append_trace(trace, 2, 1)
for trace in rsi_data:
fig.append_trace(trace, 3, 1)
for trace in volume_data:
fig.append_trace(trace, 4, 1)
for trace in ichimokuCloud_data:
fig.append_trace(trace, 5, 1)
fig.update_layout(height=2000)
fig.update_layout(height=800)
return fig
@@ -157,63 +119,6 @@ class Analyzer:
return i-1
return len(stock['PRICE']) - 1
def analyzeMACD(self):
conn = sqlite3.connect(self.inFileName)
cursor = conn.cursor()
# 기존 분석 데이터를 모두 지움
cursor.execute('update ' + self.tableName + ' set MACD = ""')
rowid = 1
cursor.execute('SELECT * FROM ' + self.tableName + ' WHERE rowid=?', (rowid,))
result = cursor.fetchone()
while result != None:
stock = {"CODE": result[0], "NAME": result[1], "PRICE": json.loads(result[2])}
results = self.macd.analyze(stock)
text = json.dumps(results, ensure_ascii=False)
cursor.execute("UPDATE " + self.tableName + " SET MACD=? WHERE CODE=?", (text, stock["CODE"]))
print("#analyzeMACD", rowid, stock['NAME'])
rowid += 1
cursor.execute('SELECT * FROM ' + self.tableName + ' WHERE rowid=?', (rowid,))
result = cursor.fetchone()
conn.commit()
cursor.close()
conn.close()
return
def analyzeRSI(self):
conn = sqlite3.connect(self.inFileName)
cursor = conn.cursor()
# 기존 분석 데이터를 모두 지움
cursor.execute('update ' + self.tableName + ' set RSI = ""')
rowid = 1
cursor.execute('SELECT * FROM ' + self.tableName + ' WHERE rowid=?', (rowid,))
result = cursor.fetchone()
while result != None:
prices = json.loads(result[2])
for price in prices:
del price['diff']
stock = {"CODE": result[0], "NAME": result[1], "PRICE": prices}
results = self.rsi.analyze(stock)
text = json.dumps(results, ensure_ascii=False)
cursor.execute("UPDATE " + self.tableName + " SET RSI=? WHERE CODE=?", (text, stock["CODE"]))
print("#analyzeRSI", rowid, stock['NAME'])
rowid += 1
cursor.execute('SELECT * FROM ' + self.tableName + ' WHERE rowid=?', (rowid,))
result = cursor.fetchone()
conn.commit()
cursor.close()
conn.close()
return
def analyzeStochastic(self):
conn = sqlite3.connect(self.inFileName)
cursor = conn.cursor()
@@ -240,33 +145,7 @@ class Analyzer:
conn.close()
return
def analyzeIchimokuCloud(self):
conn = sqlite3.connect(self.inFileName)
cursor = conn.cursor()
# 기존 분석 데이터를 모두 지움
cursor.execute('update ' + self.tableName + ' set ICHIMOKU = ""')
rowid = 1
cursor.execute('SELECT * FROM ' + self.tableName + ' WHERE rowid=?', (rowid,))
result = cursor.fetchone()
while result != None:
stock = {"CODE": result[0], "NAME": result[1], "PRICE": json.loads(result[2])}
results = self.ichimokuCloud.analyze(stock)
text = json.dumps(results, ensure_ascii=False)
cursor.execute("UPDATE " + self.tableName + " SET ICHIMOKU=? WHERE CODE=?", (text, stock["CODE"]))
print("#analyzeIchimokuCloud", rowid, stock['NAME'])
rowid += 1
cursor.execute('SELECT * FROM ' + self.tableName + ' WHERE rowid=?', (rowid,))
result = cursor.fetchone()
conn.commit()
cursor.close()
conn.close()
return
def analyzeFinalScore(self, last_index, STOCK, MACD, STOCHASTIC, ICHIMOKU, RSI):
def analyzeFinalScore(self, last_index, STOCK, STOCHASTIC):
"""
매수 조건
#0. 최소 매수 조건은 거래량은 20만건, 종가는 2천원 이상인 종목이어야 한다.
@@ -290,40 +169,69 @@ class Analyzer:
if STOCK[i]['volume'] > 100000 and STOCK[i]['close'] > 2000:
# 거래량이 100만 이상이고, 종가가 1천원 이상인지 체크 (https://happpy-rich.tistory.com/94)
# 5-20
days20_line_buying1_status = self.common.check_days5_20_line_buying(STOCK, i)
if days20_line_buying1_status != "":
# 정배열 체크
temp_status = self.common.check_RightArrange(STOCK, i)
if temp_status != "":
#if STOCHASTIC[i]['slow_k'] < 40:
status += days20_line_buying1_status
status += temp_status
# 5-60
days60_line_buying1_status = self.common.check_days5_60_line_buying(STOCK, i)
if days60_line_buying1_status != "":
# if STOCHASTIC[i]['slow_k'] < 40:
status += days60_line_buying1_status
# 5-120
days120_line_buying1_status = self.common.check_days5_120_line_buying(STOCK, i)
if days120_line_buying1_status != "":
# if STOCHASTIC[i]['slow_k'] < 40:
status += days120_line_buying1_status
# 5-240
days240_line_buying1_status = self.common.check_days5_240_line_buying(STOCK, i)
if days240_line_buying1_status != "":
# if STOCHASTIC[i]['slow_k'] < 40:
status += days240_line_buying1_status
# 20-60
days60_line_buying2_status = self.common.check_days20_60_line_buying(STOCK, i)
if days60_line_buying2_status != "":
# 20
temp_status = self.common.check_Dolpa_Jiji(STOCK, i, '20')
if temp_status != "":
#if STOCHASTIC[i]['slow_k'] < 40:
status += days60_line_buying2_status
status += temp_status
# 60
temp_status = self.common.check_Dolpa_Jiji(STOCK, i, '60')
if temp_status != "":
#if STOCHASTIC[i]['slow_k'] < 40:
status += temp_status
# 120
temp_status = self.common.check_Dolpa_Jiji(STOCK, i, '120')
if temp_status != "":
#if STOCHASTIC[i]['slow_k'] < 40:
status += temp_status
# 240
temp_status = self.common.check_Dolpa_Jiji(STOCK, i, '240')
if temp_status != "":
#if STOCHASTIC[i]['slow_k'] < 40:
status += temp_status
# 270일 최고가 돌파
temp_status = self.common.check_highest_270(STOCK, i)
if temp_status != "":
# if STOCHASTIC[i]['slow_k'] < 40:
status += temp_status
# 20일선 지지 매수가 추천
temp_status = self.common.check_Dolpa_Jiji_20(STOCK, i)
if temp_status != "":
# if STOCHASTIC[i]['slow_k'] < 40:
status += temp_status
# 단타 #1
temp_status = self.common.check_Danta1(STOCK, i)
if temp_status != "":
# if STOCHASTIC[i]['slow_k'] < 40:
status += temp_status
# 단타 #2
temp_status = self.common.check_Danta2(STOCK, i)
if temp_status != "":
# if STOCHASTIC[i]['slow_k'] < 40:
status += temp_status
all_upper_cross_status = self.common.checkAllUpperCross(STOCK, i)
if all_upper_cross_status != "":
status += all_upper_cross_status
# 1주일 동안 몇 10% 이상 오른 종목
w1Rate = self.common.check_W1Rate(STOCK, i)
if w1Rate != "":
status += w1Rate
# GOLDENCROSS#1은 바로 매수하지 않고, 이 시점 이후로 5일선이 20일선을 하방으로 뚫었다가 다시 20일선을 상방으로 뚫는 순간 매수를 시도한다.
# GOLDENCROSS#2은 바로 매수 가능
# GOLDENCROSS#3은 바로 매수 가능
@@ -337,11 +245,6 @@ class Analyzer:
if bearmarket_buying_status != "":
status += bearmarket_buying_status
# BUYINGSTOCHASTIC#1은 바로 매수 가능
stochastic_buying_status = self.common.check_stochastic_buying(STOCK, STOCHASTIC, ICHIMOKU, i)
if stochastic_buying_status != "":
status += stochastic_buying_status
# STOCHASTIC
stochastic_status = self.common.check_stochastic(STOCK, STOCHASTIC, i)
if stochastic_status != "":
@@ -376,51 +279,74 @@ class Analyzer:
if ((item_code in self.fnguide and not self.fnguide[item_code]) or (item_code == "KOSPI" or item_code == "KOSDAK") or result[3] == ''):
rowid += 1
# 다음 종목을 가져옴
cursor.execute('SELECT * FROM ' + self.tableName + ' WHERE rowid=?', (rowid,))
cursor.execute('SELECT CODE, NAME, PRICE, STOCHASTIC FROM ' + self.tableName + ' WHERE rowid=?', (rowid,))
result = cursor.fetchone()
continue
result_3 = result[3]
result_4 = result[4]
result_5 = result[5]
result_6 = result[6]
if result[3] != result[3]: result_3 = result[3].replace("NaN", "0")
if result[4] != result[4]: result_4 = result[4].replace("NaN", "0")
if result[5] != result[5]: result_5 = result[5].replace("NaN", "0")
if result[6] != result[6]: result_6 = result[6].replace("NaN", "0")
if result[3] != result[3]:
result_3 = result[3].replace("NaN", "0")
if result[3]==None:
rowid += 1
cursor.execute('SELECT CODE, NAME, PRICE, STOCHASTIC FROM ' + self.tableName + ' WHERE rowid=?', (rowid,))
result = cursor.fetchone()
continue
stock = {"CODE": result[0], "NAME": result[1], "PRICE": json.loads(result[2]), "MACD": json.loads(result_3), "STOCHASTIC": json.loads(result_4), "ICHIMOKU": json.loads(result_5), "RSI": json.loads(result_6)}
stock = {"CODE": result[0], "NAME": result[1], "PRICE": json.loads(result[2]), "STOCHASTIC": json.loads(result_3)}
last_index = self.get_last_index(stock)
STOCK = stock['PRICE']
MACD = stock['MACD']
STOCHASTIC = stock['STOCHASTIC']
ICHIMOKU = stock['ICHIMOKU']
RSI = stock['RSI']
stochastic_score = STOCHASTIC[last_index]['slow_k']
if stochastic_score < 50:
macd_score = MACD[last_index]['macd']
rsi_score = RSI[last_index]['rsi']
ichimoku_score = ICHIMOKU[last_index]['ichimoku_buy']
# 종목 상태 체크 분석
state, buy_price = self.analyzeFinalScore(last_index, STOCK, MACD, STOCHASTIC, ICHIMOKU, RSI)
state, buy_price = self.analyzeFinalScore(last_index, STOCK, STOCHASTIC)
if state != "":
fig = self.draw(stock)
title = "%s (%s), %s, buy_price (%d), stochastic(%.3f), rsi(%.3f), macd(%.3f), ichimoku(%d) 차트" % (item_name, item_code, state, buy_price, stochastic_score, rsi_score, macd_score, ichimoku_score)
title = "%s (%s), %s, buy_price (%d), stochastic(%.3f) 차트" % (item_name, item_code, state, buy_price, stochastic_score)
fig['layout'].update(title=title)
fileName = "%s/%s__%.3f__%.3f__%s_%s.html" % (outPath, state, stochastic_score, rsi_score, item_name.replace(" ", ""), item_code)
fileName = "%s/%s__%.3f__%s_%s.html" % (outPath, state, stochastic_score, item_name.replace(" ", ""), item_code)
po.write_html(fig, file=fileName, auto_open=False)
else:
if (RSI[last_index]['rsi_buy'] == 1) and STOCK[last_index]['volume'] > 1000000:
if STOCK[last_index]['volume'] > 1000000:
fig = self.draw(stock)
title = "%s (%s) buy_price (%d), stochastic(%.3f), rsi(%.3f), macd(%.3f), ichimoku(%d) 차트"%(item_name, item_code, buy_price, stochastic_score, rsi_score, macd_score, ichimoku_score)
title = "%s (%s) buy_price (%d), stochastic(%.3f) 차트"%(item_name, item_code, buy_price, stochastic_score)
fig['layout'].update(title=title)
fileName = "%s/%.3f__%.3f__%s_%s.html"%(tmp_path, stochastic_score, rsi_score, item_name.replace(" ", ""), item_code)
fileName = "%s/%.3f__%s_%s.html"%(tmp_path, stochastic_score, item_name.replace(" ", ""), item_code)
po.write_html(fig, file=fileName, auto_open=False)
"""
try:
stock = {"CODE": result[0], "NAME": result[1], "PRICE": json.loads(result[2]), "STOCHASTIC": json.loads(result_3)}
last_index = self.get_last_index(stock)
STOCK = stock['PRICE']
STOCHASTIC = stock['STOCHASTIC']
stochastic_score = STOCHASTIC[last_index]['slow_k']
if stochastic_score < 50:
# 종목 상태 체크 분석
state, buy_price = self.analyzeFinalScore(last_index, STOCK, STOCHASTIC)
if state != "":
fig = self.draw(stock)
title = "%s (%s), %s, buy_price (%d), stochastic(%.3f) 차트" % (item_name, item_code, state, buy_price, stochastic_score)
fig['layout'].update(title=title)
fileName = "%s/%s__%.3f__%s_%s.html" % (outPath, state, stochastic_score, item_name.replace(" ", ""), item_code)
po.write_html(fig, file=fileName, auto_open=False)
else:
if STOCK[last_index]['volume'] > 1000000:
fig = self.draw(stock)
title = "%s (%s) buy_price (%d), stochastic(%.3f) 차트"%(item_name, item_code, buy_price, stochastic_score)
fig['layout'].update(title=title)
fileName = "%s/%.3f__%s_%s.html"%(tmp_path, stochastic_score, item_name.replace(" ", ""), item_code)
po.write_html(fig, file=fileName, auto_open=False)
except:
print ("error")
"""
rowid += 1
cursor.execute('SELECT * FROM ' + self.tableName + ' WHERE rowid=?', (rowid,))
result = cursor.fetchone()
@@ -434,7 +360,7 @@ class Analyzer:
cursor = conn.cursor()
# 기존 분석 데이터를 모두 지움
cursor.execute('update ' + self.tableName + ' set ICHIMOKU = "", MACD = "", STOCHASTIC = "", RSI = ""')
cursor.execute('update ' + self.tableName + ' set STOCHASTIC = ""')
rowid = 1
cursor.execute('SELECT * FROM ' + self.tableName + ' WHERE rowid=?', (rowid,))
@@ -443,17 +369,8 @@ class Analyzer:
stock = {"CODE": result[0], "NAME": result[1], "PRICE": json.loads(result[2])}
try:
results_ICHIMOKU = self.ichimokuCloud.analyze(stock)
text_ICHIMOKU = json.dumps(results_ICHIMOKU, ensure_ascii=False)
results_MACD = self.macd.analyze(stock)
text_MACD = json.dumps(results_MACD, ensure_ascii=False)
results_STOCHASTIC = self.stochastic.analyze(stock)
text_STOCHASTIC = json.dumps(results_STOCHASTIC, ensure_ascii=False)
results_RSI = self.rsi.analyze(stock)
text_RSI = json.dumps(results_RSI, ensure_ascii=False)
except:
print("#", rowid, stock['NAME'])
rowid += 1
@@ -461,7 +378,7 @@ class Analyzer:
result = cursor.fetchone()
continue
cursor.execute("UPDATE " + self.tableName + " SET ICHIMOKU=?, MACD=?, STOCHASTIC=?, RSI=? WHERE CODE=?", (text_ICHIMOKU,text_MACD,text_STOCHASTIC,text_RSI, stock["CODE"]))
cursor.execute("UPDATE " + self.tableName + " SET STOCHASTIC=? WHERE CODE=?", (text_STOCHASTIC, stock["CODE"]))
print("#", rowid, stock['NAME'])
rowid += 1
cursor.execute('SELECT * FROM ' + self.tableName + ' WHERE rowid=?', (rowid,))
@@ -483,14 +400,8 @@ if __name__ == "__main__":
# 분석 & update DB
"""
#print ("analyze IchimokuCloud...")
analyzer.analyzeIchimokuCloud()
#print ("analyze MACD...")
analyzer.analyzeMACD()
#print ("analyze Stochastic...")
analyzer.analyzeStochastic()
#print ("analyze RSI...")
analyzer.analyzeRSI()
"""
###analyzer.analyze()