diff --git a/stockpredictor/analysis/AnalyzerSqlite.py b/stockpredictor/analysis/AnalyzerSqlite.py
index be0c47b..7ab21a4 100644
--- a/stockpredictor/analysis/AnalyzerSqlite.py
+++ b/stockpredictor/analysis/AnalyzerSqlite.py
@@ -1,4 +1,3 @@
-import json
import os
import time
import shutil
@@ -11,7 +10,6 @@ from matplotlib import rc
rc('font', family='AppleGothic')
plt.rcParams['axes.unicode_minus'] = False
-import pandas as pd
import plotly.graph_objs as go
from plotly import tools, subplots
import plotly.io as po
@@ -31,6 +29,9 @@ class AnalyzerSqlite:
bolingerBand = None
ichimokuCloud = None
+ top500 = None
+ fnguide = None
+
common = None
stockFileName = None
fnguideFileName = None
@@ -38,8 +39,6 @@ class AnalyzerSqlite:
moving_avg = None
- fnguide = {}
-
def __init__(self, PROJECT_HOME, stockFileName, fnguideFileName):
self.PROJECT_HOME = PROJECT_HOME
self.stockFileName = stockFileName
@@ -51,10 +50,29 @@ class AnalyzerSqlite:
self.bolingerBand = BolingerBand()
self.ichimokuCloud = IchimokuCloud()
+ self.top500 = self.getTop500(fnguideFileName)
+ self.fnguide = self.readFnguide(fnguideFileName)
+
return
- def readFnguide(self, code):
- conn = sqlite3.connect(self.fnguideFileName)
+ def getTop500(self, fnguideFileName):
+ conn = sqlite3.connect(fnguideFileName)
+ cursor = conn.cursor()
+
+ sql = "select DISTINCT CODE, NAME from fnguide order by total_ownership_interest desc limit 500"
+ cursor.execute(sql)
+ result = cursor.fetchall()
+
+ top500 = {}
+ for idx, item in enumerate(result):
+ top500[item[0]] = (idx+1, item[1])
+
+ cursor.close()
+ conn.close()
+ return top500
+
+ def readFnguide(self, fnguideFileName):
+ conn = sqlite3.connect(fnguideFileName)
cursor = conn.cursor()
today = datetime.today()
@@ -62,37 +80,34 @@ class AnalyzerSqlite:
year2 = str(today.year - 2) + ".12.01"
year3 = str(today.year - 3) + ".12.01"
- sql = "SELECT business_profits, business_profits_ratio, debt_ratio, ROA, ROE, EPS, BPS, DPS, PER, PBR FROM fnguide "
- sql += " WHERE code=? and (ymd=? or ymd=? or ymd=?) and type=''"
- sql += " order by ymd desc"
- cursor.execute(sql, (code,year1,year2,year3))
- result = cursor.fetchone()
+ sql = "SELECT CODE, NAME, ymd, business_profits, business_profits_ratio, debt_ratio, ROA, ROE, EPS, BPS, DPS, PER, PBR FROM fnguide "
+ sql += " WHERE (ymd=? or ymd=? or ymd=?) and type=''"
+ sql += " order by code, ymd desc"
+ cursor.execute(sql, (year1,year2,year3))
+ result = cursor.fetchall()
- business_profits, business_profits_ratio, debt_ratio, ROA, ROE, EPS, BPS, DPS, PER, PBR = [], [], [], [], [], [], [], [], [], []
+ fnguide = {}
for item in result:
- business_profits.append(item[0])
- business_profits_ratio.append(item[1])
- debt_ratio.append(item[2])
- ROA.append(item[3])
- ROE.append(item[4])
- EPS.append(item[5])
- BPS.append(item[6])
- DPS.append(item[7])
- PER.append(item[8])
- PBR.append(item[9])
+ if item[0] not in fnguide:
+ fnguide[item[0]] = []
+
+ fnguide[item[0]].append(
+ {'NAME': item[1],
+ 'ymd': item[2],
+ 'business_profits': item[3],
+ 'business_profits_ratio': item[4],
+ 'debt_ratio': item[5],
+ 'ROA': item[6],
+ 'ROE': item[7],
+ 'EPS': item[8],
+ 'BPS': item[9],
+ 'DPS': item[10],
+ 'PER': item[11],
+ 'PBR': item[12]})
cursor.close()
conn.close()
- return {'business_profits': business_profits,
- 'business_profits_ratio': business_profits_ratio,
- 'debt_ratio': debt_ratio,
- 'ROA': ROA,
- 'ROE': ROE,
- 'EPS': EPS,
- 'BPS': BPS,
- 'DPS': DPS,
- 'PER': PER,
- 'PBR': PBR}
+ return fnguide
def draw(self, stock):
@@ -414,14 +429,26 @@ class AnalyzerSqlite:
return
- def writeFile(self, type, CODE, NAME, stock, state):
- fig = self.draw(stock)
- title = "%s (%s), %d %s 차트 (URL1, URL2)" % (NAME, CODE, stock['close'][0], state, CODE, CODE)
- fig['layout'].update(title=title)
+ def writeFile(self, type, CODE, NAME, top, stock, state):
+ # 3년 이내 한번이라도 영업이익이 났는지 체크를 함
+ fnguide = None
+ if CODE in self.fnguide:
+ fnguide = self.fnguide[CODE]
+ check = True
+ if fnguide:
+ check = False
+ for item in fnguide:
+ if item['business_profits'] > 0:
+ check = True
- fileName = self.outPath + "/" + str(type)
- fileName = "%s/%s_%s_%s.html" % (fileName, NAME.replace(" ", ""), CODE, state)
- po.write_html(fig, file=fileName, auto_open=False)
+ if check:
+ fig = self.draw(stock)
+ title = "%s (%s), %d %s 차트 (URL1, URL2)" % (NAME, CODE, stock['close'][0], state, CODE, CODE)
+ fig['layout'].update(title=title)
+
+ fileName = self.outPath + "/" + str(type)
+ fileName = "%s/%s_%s_%s_%s.html" % (fileName, top, NAME.replace(" ", ""), CODE, state)
+ po.write_html(fig, file=fileName, auto_open=False)
return
def checkVolume(self, p_volume, volume):
@@ -464,6 +491,10 @@ class AnalyzerSqlite:
NAME = item[1]
print (idx, CODE, NAME)
+ top = "0"
+ if CODE in self.top500:
+ top = str(self.top500[CODE][0])
+
conn = sqlite3.connect(self.stockFileName)
cursor = conn.cursor()
@@ -545,27 +576,27 @@ class AnalyzerSqlite:
# 0_스토케스틱이 10 미만
if len(close) > 5 and stochastic_score is not None and stochastic_score < 10:
type = "참고_0_스토케스틱이 10 미만"
- self.writeFile(type, CODE, NAME, stock, state)
+ self.writeFile(type, CODE, NAME, top, stock, state)
# 0_bolingerband 하단
if len(close) > 60 and bolingerband_lower[0] is not None and close[0] < bolingerband_lower[0]:
type = "참고_0_bolingerband 하단"
- self.writeFile(type, CODE, NAME, stock, state)
+ self.writeFile(type, CODE, NAME, top, stock, state)
# 0_260일 위치 에너지가 10% 미만
if len(close) > 5 and positionalEnergy1 is not None and positionalEnergy1 < 0.1:
type = "참고_0_260일 위치 에너지가 10% 미만"
- self.writeFile(type, CODE, NAME, stock, state)
+ self.writeFile(type, CODE, NAME, top, stock, state)
# 0_260일 가격 반토막 이상
if len(close) > 5 and positionalEnergy2 is not None and positionalEnergy2 < 0.5:
type = "참고_0_260일 가격 반토막 이상"
- self.writeFile(type, CODE, NAME, stock, state)
+ self.writeFile(type, CODE, NAME, top, stock, state)
# 0_종가가 240일선 아래라면 매수한다.
if close[0] < avg240[0]:
type = "참고_0_240일선 아래"
- self.writeFile(type, CODE, NAME, stock, state)
+ self.writeFile(type, CODE, NAME, top, stock, state)
# 1_기준선 위 전환선 올라옴
if len(close) > 50:
@@ -576,7 +607,7 @@ class AnalyzerSqlite:
ichimokucloud_changeLine[4] <= ichimokucloud_baseLine[4]) and
volume[0] > volume[1]):
type = "참고_1_기준선 위 전환선 올라옴"
- self.writeFile(type, CODE, NAME, stock, state)
+ self.writeFile(type, CODE, NAME, top, stock, state)
# "1_기준선 위 120일선 올라옴"
if len(close) > 50:
@@ -587,7 +618,7 @@ class AnalyzerSqlite:
avg120[4] <= ichimokucloud_baseLine[4]) and
volume[0] > volume[1]):
type = "참고_1_기준선 위 120일선 올라옴"
- self.writeFile(type, CODE, NAME, stock, state)
+ self.writeFile(type, CODE, NAME, top, stock, state)
# "1_기준선 위 200일선 올라옴"
if len(close) > 50:
@@ -598,7 +629,7 @@ class AnalyzerSqlite:
avg200[4] <= ichimokucloud_baseLine[4]) and
volume[0] > volume[1]):
type = "참고_1_기준선 위 200일선 올라옴"
- self.writeFile(type, CODE, NAME, stock, state)
+ self.writeFile(type, CODE, NAME, top, stock, state)
# "1_기준선 위 240일선 올라옴"
if len(close) > 50:
@@ -609,59 +640,59 @@ class AnalyzerSqlite:
avg240[4] <= ichimokucloud_baseLine[4]) and
volume[0] > volume[1]):
type = "참고_1_기준선 위 240일선 올라옴"
- self.writeFile(type, CODE, NAME, stock, state)
+ self.writeFile(type, CODE, NAME, top, stock, state)
# 1_종가가 200일선 돌파
if len(close) > 5 and close[0] >= avg200[0] and close[1] < avg200[1] and close[2] < avg200[2] and close[3] < avg200[3] and close[4] < avg200[4]:
type = "참고_1_200일선 돌파"
- self.writeFile(type, CODE, NAME, stock, state)
+ self.writeFile(type, CODE, NAME, top, stock, state)
# 1_종가가 240일선 돌파
if len(close) > 5 and close[0] >= avg240[0] and close[1] < avg240[1] and close[2] < avg240[2] and close[3] < avg240[3] and close[4] < avg240[4]:
type = "참고_1_240일선 돌파"
- self.writeFile(type, CODE, NAME, stock, state)
+ self.writeFile(type, CODE, NAME, top, stock, state)
# 1_20일선 돌파
temp_status = self.common.check_Dolpa_Jiji(stock, '20')
if temp_status != "":
type = "참고_1_20일선 돌파"
- self.writeFile(type, CODE, NAME, stock, state)
+ self.writeFile(type, CODE, NAME, top, stock, state)
# 1_60일선 돌파
temp_status = self.common.check_Dolpa_Jiji(stock, '60')
if temp_status != "":
type = "참고_1_60일선 돌파"
- self.writeFile(type, CODE, NAME, stock, state)
+ self.writeFile(type, CODE, NAME, top, stock, state)
# 1_골든크로스
golden_cross_status = self.common.check_golded_cross(stock)
if golden_cross_status != "":
type = "참고_1_GoldenCross"
- self.writeFile(type, CODE, NAME, stock, state)
+ self.writeFile(type, CODE, NAME, top, stock, state)
# 1_거래량 5배 이상
if len(volume)>2 and volume[0] > volume[1]*10:
type = "참고_1_거래량 10배 이상"
- self.writeFile(type, CODE, NAME, stock, state)
+ self.writeFile(type, CODE, NAME, top, stock, state)
# 1_bolingerband 하단 돌파 상승
if (len(close) > 60 and (bolingerband_lower[0] is not None and bolingerband_lower[1] is not None) and
close[0] > bolingerband_lower[0] and close[1] < bolingerband_lower[1]):
type = "참고_1_bolingerband 하단 돌파 상승"
- self.writeFile(type, CODE, NAME, stock, state)
+ self.writeFile(type, CODE, NAME, top, stock, state)
# 1_정배열
right_arrange = self.common.check_RightArrange(stock)
if right_arrange != "":
type = "참고_1_정배열"
- self.writeFile(type, CODE, NAME, stock, state)
+ self.writeFile(type, CODE, NAME, top, stock, state)
# 1_모든 라인 돌파
if (len(close) > 50 and
close[0] > max(open[0], avg5[0], avg20[0], avg60[0], avg120[0], avg240[0], bolingerband_upper[0], ichimokucloud_changeLine[0], ichimokucloud_baseLine[0]) and
open[0] < max(open[0], avg5[0], avg20[0], avg60[0], avg120[0], avg240[0], bolingerband_upper[0], ichimokucloud_changeLine[0], ichimokucloud_baseLine[0])):
type = "참고_1_모든 라인 돌파"
- self.writeFile(type, CODE, NAME, stock, state)
+ self.writeFile(type, CODE, NAME, top, stock, state)
### 코스피 지수 기준 숏 전략:
# 캔들이 전환선 붕괴시키면 1을 매수한다.
@@ -674,33 +705,33 @@ class AnalyzerSqlite:
if (len(close) > 50 and close[1] < ichimokucloud_changeLine[1] and ichimokucloud_changeLine[0] < close[0]):
type = "1_캔들_전환선_위로_올라옴"
- self.writeFile(type, CODE, NAME, stock, state)
+ self.writeFile(type, CODE, NAME, top, stock, state)
if (len(close) > 50 and close[1] < ichimokucloud_baseLine[1] and ichimokucloud_baseLine[0] < close[0]):
type = "2_캔들_기준선_위로_올라옴"
- self.writeFile(type, CODE, NAME, stock, state)
+ self.writeFile(type, CODE, NAME, top, stock, state)
if (len(close) > 50 and close[0] < close[26] and close[25] < close[0]):
type = "3_후행스팬_캔들_위로_올라옴"
- self.writeFile(type, CODE, NAME, stock, state)
+ self.writeFile(type, CODE, NAME, top, stock, state)
if (len(close) > 50 and close[1] > ichimokucloud_changeLine[1] and ichimokucloud_changeLine[0] > close[0]):
type = "-1_캔들_전환선_아래로_내려옴"
- self.writeFile(type, CODE, NAME, stock, state)
+ self.writeFile(type, CODE, NAME, top, stock, state)
if (len(close) > 50 and close[1] > ichimokucloud_baseLine[1] and ichimokucloud_baseLine[0] > close[0]):
type = "-2_캔들_기준선_아래로_내려옴"
- self.writeFile(type, CODE, NAME, stock, state)
+ self.writeFile(type, CODE, NAME, top, stock, state)
if (len(close) > 50 and close[0] > close[26] and close[25] > close[0]):
type = "-3_후행스팬_캔들_아래로_내려옴"
- self.writeFile(type, CODE, NAME, stock, state)
+ self.writeFile(type, CODE, NAME, top, stock, state)
if (len(close) > 2 and close[1] < close[0] and open[0] < close[0] and
self.checkVolume(volume[1], volume[0])):
type = "1_거래량_상승"
- self.writeFile(type, CODE, NAME, stock, state)
+ self.writeFile(type, CODE, NAME, top, stock, state)
if (len(close) > covid_low_ymd_index and
close[0] > close[covid_low_ymd_index]*0.8 and close[0] < close[covid_low_ymd_index]*1.1):
type = "1_코로나_근접"
- self.writeFile(type, CODE, NAME, stock, state)
+ self.writeFile(type, CODE, NAME, top, stock, state)
return
@@ -759,6 +790,7 @@ class AnalyzerSqlite:
stock = {"CODE": item[0], "NAME": item[1], "PRICE":[]}
print("# :", rowid, ", CODE: ", stock['CODE'], ", NAME: ", stock['NAME'])
+
sql = 'SELECT ymd, close, diff, open, high, low, volume FROM ' + stockTableName + ' where CODE=? order by ymd'
cursor.execute(sql, (stock['CODE'],))
items = cursor.fetchall()