Files
DeepStock/stockpredictor/analysis/AnalyzerSqlite.py
dosangyoon da2164d599 init
2022-02-02 15:19:43 +09:00

725 lines
29 KiB
Python

import json
import os
import time
import shutil
import matplotlib.pyplot as plt
import datetime
import sqlite3
from datetime import datetime
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
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.crawler.sQLite.MovingAverage import MovingAverage
class AnalyzerSqlite:
PROJECT_HOME = None
stochastic = None
bolingerBand = None
ichimokuCloud = None
common = None
stockFileName = None
fnguideFileName = None
analyzedFileName = None
moving_avg = None
fnguide = {}
def __init__(self, PROJECT_HOME, stockFileName, fnguideFileName):
self.PROJECT_HOME = PROJECT_HOME
self.stockFileName = stockFileName
self.fnguideFileName = fnguideFileName
self.common = Common()
self.stochastic = Stochastic()
self.bolingerBand = BolingerBand()
self.ichimokuCloud = IchimokuCloud()
return
def readFnguide(self, code):
conn = sqlite3.connect(self.fnguideFileName)
cursor = conn.cursor()
today = datetime.today()
year1 = str(today.year - 1) + ".12.01"
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()
business_profits, business_profits_ratio, debt_ratio, ROA, ROE, EPS, BPS, DPS, PER, PBR = [], [], [], [], [], [], [], [], [], []
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])
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}
def draw(self, stock):
ymd = list(reversed(stock['ymd']))
open = list(reversed(stock['open']))
close = list(reversed(stock['close']))
high = list(reversed(stock['high']))
low = list(reversed(stock['low']))
volume = list(reversed(stock['volume']))
avg5 = list(reversed(stock['avg5']))
avg20 = list(reversed(stock['avg20']))
avg60 = list(reversed(stock['avg60']))
avg120 = list(reversed(stock['avg120']))
avg240 = list(reversed(stock['avg240']))
stochastic_slow_k = list(reversed(stock['stochastic_slow_k']))
stochastic_slow_d = list(reversed(stock['stochastic_slow_d']))
bolingerband_upper = list(reversed(stock['bolingerband_upper']))
bolingerband_lower = list(reversed(stock['bolingerband_lower']))
ichimokucloud_changeLine = list(reversed(stock['ichimokucloud_changeLine']))
ichimokucloud_baseLine = list(reversed(stock['ichimokucloud_baseLine']))
# general
candle_stick = go.Candlestick(x=ymd, open=open, high=high, low=low, close=close, increasing_line_color='red', decreasing_line_color='blue')
avg5 = go.Scatter(x=ymd, y=avg5, name="avg5", line_color='#000000')
avg20 = go.Scatter(x=ymd, y=avg20, name="avg20", line_color='#f84c43')
avg60 = go.Scatter(x=ymd, y=avg60, name="avg60", line_color='#f89543')
avg120 = go.Scatter(x=ymd, y=avg120, name="avg120", line_color='#0ed604')
avg240 = go.Scatter(x=ymd, y=avg240, name="avg240", line_color='#00FF49')
bolinger_upper = go.Scatter(x=ymd, y=bolingerband_upper, name="upper", line_color='#8B4513')
bolinger_lower = go.Scatter(x=ymd, y=bolingerband_lower, name="lower", line_color='#8B4513')
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, avg5, avg20, avg60, avg120, avg240, bolinger_upper, bolinger_lower, changeLine, baseLine]
volume = go.Bar(x=ymd, y=volume, name="volume")
volume_data = [volume]
# stochastic
slow_k = go.Scatter(x=ymd, y=stochastic_slow_k, name="Slow%K", line_color='#8B4513')
slow_d = go.Scatter(x=ymd, y=stochastic_slow_d, name="Slow%D", line_color='#4169E1')
stochastic_data = [slow_k, slow_d]
fig = subplots.make_subplots(rows=3, cols=1, subplot_titles=('차트', '거래량', 'Stochastic'))
for trace in candle_data:
fig.append_trace(trace, 1, 1)
for trace in volume_data:
fig.append_trace(trace, 2, 1)
for trace in stochastic_data:
fig.append_trace(trace, 3, 1)
fig.update_layout(height=1500, xaxis_rangeslider_visible=False)
return fig
def analyzeFinalScore(self, STOCK):
status = ""
if STOCK['volume'][0] > 100000 and STOCK['close'][0] > 1000:
# 거래량이 100만 이상이고, 종가가 1천원 이상인지 체크 (https://happpy-rich.tistory.com/94)
# 정배열 체크
temp_status = self.common.check_RightArrange(STOCK)
if temp_status != "":
status += temp_status
# 20일선 돌파
temp_status = self.common.check_Dolpa_Jiji(STOCK, '20')
if temp_status != "":
status += temp_status
# 60일선 돌파
temp_status = self.common.check_Dolpa_Jiji(STOCK, '60')
if temp_status != "":
status += temp_status
# 120일선 돌파
temp_status = self.common.check_Dolpa_Jiji(STOCK, '120')
if temp_status != "":
status += temp_status
# 240일선 돌파
temp_status = self.common.check_Dolpa_Jiji(STOCK, '240')
if temp_status != "":
status += temp_status
# 20일선 지지 매수가 추천
temp_status = self.common.check_Dolpa_Jiji_20(STOCK)
if temp_status != "":
status += temp_status
# 음봉인데 어제보다 종가가 더 높은 경우
# 이 경우 정배열 상태인지도 함께 체크를 한다.
higher_umbong_status = self.common.checkHigherUmbong(STOCK)
if higher_umbong_status != "":
status += higher_umbong_status
"""
# 단타 #1
temp_status = self.common.check_Danta1(STOCK)
if temp_status != "":
status += temp_status
# 단타 #2
temp_status = self.common.check_Danta2(STOCK)
if temp_status != "":
status += temp_status
all_upper_cross_status = self.common.checkAllUpperCross(STOCK)
if all_upper_cross_status != "":
status += all_upper_cross_status
# 1주일 동안 몇 10% 이상 오른 종목
W1Rise = self.common.check_W1Rise(STOCK, 0.1)
if W1Rise != "":
status += W1Rise
# 1일 동안 몇 10% 이상 내린 종목
W1Fall = self.common.check_D1Fall(STOCK, -0.1)
if W1Fall != "":
status += W1Fall
"""
# GOLDENCROSS#1은 바로 매수하지 않고, 이 시점 이후로 5일선이 20일선을 하방으로 뚫었다가 다시 20일선을 상방으로 뚫는 순간 매수를 시도한다.
# GOLDENCROSS#2은 바로 매수 가능
# GOLDENCROSS#3은 바로 매수 가능
golden_cross_status = self.common.check_golded_cross(STOCK)
if golden_cross_status != "":
status += golden_cross_status
"""
# BUYINGBEARMARKET#1은 바로 매수 가능
# BUYINGBEARMARKET#2은 바로 매수 가능
bearmarket_buying_status = self.common.check_bearmarket_buying(STOCK)
if bearmarket_buying_status != "":
status += bearmarket_buying_status
"""
# STOCHASTIC
stochastic_status = self.common.check_stochastic(STOCK)
if stochastic_status != "":
status += stochastic_status
# YANGBONG
"""
longYangBongAfterUmBong_status = self.common.checkLongYangBongAfterUmBong(STOCK)
# 어제 음봉 이후 장대양봉이었다면,
if longYangBongAfterUmBong_status != "":
status += longYangBongAfterUmBong_status
"""
# Doji
doji_status = self.common.checkDoji(STOCK)
# 하락 추세에서 도지가 나오면 매수
if doji_status != "":
status += doji_status
"""---------------------------------
# Gravestone
gravestone_status = self.common.checkGravestone(STOCK)
# 상승 추세에서 그레이브스톤이 나오면 매도
if gravestone_status != "":
status += gravestone_status
---------------------------------"""
"""
# Dragonfly
dragonfly_status = self.common.checkDragonfly(STOCK)
# 하락 추세에서 드레곤플라이가 나오면 매수
if dragonfly_status != "":
status += dragonfly_status
# Hammer
hammer_status = self.common.checkHammer(STOCK)
# 하락 추세에서 해머가 나오면 매수
if hammer_status != "":
status += hammer_status
"""
"""---------------------------------
# Hangingman
hangingman_status = self.common.checkHangingman(STOCK)
# 상승 추세에서 행잉맨이 나오면 매도
if hangingman_status != "":
status += hangingman_status
---------------------------------"""
"""
# 상승장악형 (Engulfing) - 다음 날도 양봉이라면 매수
engulfing_status = self.common.checkEngulfingHigh(STOCK)
# 하락 추세에서 상승장악형이 나오면 매수
if engulfing_status != "":
status += engulfing_status
"""
"""---------------------------------
# 하락장악형 (Engulfing)
engulfing_status = self.common.checkEngulfingLow(STOCK)
# 상승 추세에서 하락장악형이 나오면 매도
if engulfing_status != "":
status += engulfing_status
---------------------------------"""
"""
# 상승 포아형 (Harami)
harami_status = self.common.checkHaramiHigh(STOCK)
# 하락 추세에서 상승포아형이 나오면 매수
if harami_status != "":
status += harami_status
"""
"""---------------------------------
# 하락 포아형 (Harami)
harami_status = self.common.checkHaramiLow(STOCK)
# 상승 추세에서 하락포아형이 나오면 매도
if harami_status != "":
status += harami_status
---------------------------------"""
"""
# 관통형 (piercing)
piercing_status = self.common.checkPiercing(STOCK)
# 하락 추세에서 관통형이 나오면 매수
if piercing_status != "":
status += piercing_status
"""
"""---------------------------------
# 흑운형 (Dark-cloud)
darkcloud_status = self.common.checkDarkCloud(STOCK)
# 상승 추세에서 흑운형이 나오면 매도
if darkcloud_status != "":
status += darkcloud_status
---------------------------------"""
"""
# 샛별 (Morning start)
morningstar_status = self.common.checkMorningstar(STOCK)
# 하락 추세에서 샛별형이 나오면 매수
if morningstar_status != "":
status += morningstar_status
"""
"""---------------------------------
# 저녁별 (Evening start)
eveningstar_status = self.common.checkEveningstar(STOCK)
# 상승 추세에서 저녁별형이 나오면 매도
if eveningstar_status != "":
status += eveningstar_status
---------------------------------"""
return status
def getPositionalEnergy(self, close):
# 260 (= 52 * 5)일 중 가장 찾은 금액과 가장 높았던 금액 중 현재가의 위치 계산
top = close[0]
bottom = close[0]
for i in range(1, 260):
if i >= len(close):
break
if top < close[i]:
top = close[i]
if bottom > close[i]:
bottom = close[i]
if top-close[0] == 0:
energy1 = 100.0
else:
energy1 = round((close[0]-bottom) / (top-close[0]), 2)
energy2 = round((close[0] / top), 2)
return energy1, energy2
def makeDir(self, type):
if os.path.isdir(self.outPath + "/" + type):
os.rmdir(self.outPath + "/" + type)
os.mkdir(self.outPath + "/" + type)
return
def makeDirectory(self, outPath):
self.outPath = outPath
if os.path.isdir(outPath):
shutil.rmtree(outPath)
os.mkdir(outPath)
self.makeDir("0_스토케스틱이 10 미만")
self.makeDir("0_bolingerband 하단")
self.makeDir("0_260일 위치 에너지가 10% 미만")
self.makeDir("0_260일 가격 반토막 이상")
self.makeDir("0_240일선 아래")
self.makeDir("1_기준선 위 전환선")
self.makeDir("1_240일선 돌파")
self.makeDir("1_20일선 돌파")
self.makeDir("1_60일선 돌파")
self.makeDir("1_거래량 5배 이상")
self.makeDir("1_bolingerband 하단 돌파 상승")
self.makeDir("1_정배열")
self.makeDir("1_GoldenCross")
self.makeDir("1_모든 라인 돌파")
return
def writeFile(self, type, CODE, NAME, stock, state):
fig = self.draw(stock)
title = "%s (%s), %d %s 차트" % (NAME, CODE, stock['close'][0], state)
fig['layout'].update(title=title)
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)
return
# 후보 찾기
def findCandidate(self, outPath):
self.makeDirectory(outPath)
stockTableName = 'stock'
stockAnalysisTableName = 'stock_analysis'
conn = sqlite3.connect(self.stockFileName)
cursor = conn.cursor()
cursor.execute('SELECT distinct code, name FROM ' + stockTableName + ' order by code')
items = cursor.fetchall()
cursor.close()
conn.close()
for idx, item in enumerate(items):
CODE = item[0]
NAME = item[1]
print (idx, CODE, NAME)
conn = sqlite3.connect(self.stockFileName)
cursor = conn.cursor()
sql = 'SELECT ymd, close, open, high, low, volume '
sql += ' FROM ' + stockTableName + ' where CODE=? order by ymd desc limit 512'
cursor.execute(sql, (CODE,))
prices = cursor.fetchall()
ymd_, close, open, high, low, volume = [], [], [], [], [], []
for price in prices:
ymd_.append(price[0])
close.append(price[1])
open.append(price[2])
high.append(price[3])
low.append(price[4])
volume.append(price[5])
sql = 'SELECT ymd, avg5, avg10, avg20, avg60, avg120, avg200, avg240, '
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 += ' FROM ' + stockAnalysisTableName + ' where CODE=? order by ymd desc limit 512'
cursor.execute(sql, (CODE,))
prices = cursor.fetchall()
cursor.close()
conn.close()
ymd = []
avg5, avg10, avg20, avg60, avg120, avg200, avg240 = [], [], [], [], [], [], []
bolingerband_upper, bolingerband_lower, bolingerband_middle = [], [], []
ichimokucloud_changeLine, ichimokucloud_baseLine, ichimokucloud_leadingSpan1, ichimokucloud_leadingSpan2 = [], [], [], []
stochastic_fast_k, stochastic_slow_k, stochastic_slow_d = [], [], []
for price in prices:
ymd.append(price[0])
avg5.append(price[1])
avg10.append(price[2])
avg20.append(price[3])
avg60.append(price[4])
avg120.append(price[5])
avg200.append(price[6])
avg240.append(price[7])
bolingerband_upper.append(price[8])
bolingerband_lower.append(price[9])
bolingerband_middle.append(price[10])
ichimokucloud_changeLine.append(price[11])
ichimokucloud_baseLine.append(price[12])
ichimokucloud_leadingSpan1.append(price[13])
ichimokucloud_leadingSpan2.append(price[14])
stochastic_fast_k.append(price[15])
stochastic_slow_k.append(price[16])
stochastic_slow_d.append(price[17])
stock = {
"ymd":ymd,
"close":close, "open":open, "high":high, "low":low, "volume":volume,
"avg5":avg5, "avg10":avg10, "avg20":avg20, "avg60":avg60, "avg120":avg120, "avg200":avg200, "avg240":avg240,
"bolingerband_upper":bolingerband_upper, "bolingerband_lower":bolingerband_lower, "bolingerband_middle":bolingerband_middle,
"ichimokucloud_changeLine":ichimokucloud_changeLine, "ichimokucloud_baseLine":ichimokucloud_baseLine, "ichimokucloud_leadingSpan1":ichimokucloud_leadingSpan1, "ichimokucloud_leadingSpan2":ichimokucloud_leadingSpan2,
"stochastic_fast_k":stochastic_fast_k, "stochastic_slow_k":stochastic_slow_k, "stochastic_slow_d":stochastic_slow_d
}
stochastic_score = stochastic_slow_k[0]
# 위치 에너지
positionalEnergy1, positionalEnergy2 = self.getPositionalEnergy(close)
if volume[0] > 100000 and close[0] > 1000:
# 종목 상태 체크 분석
state = self.analyzeFinalScore(stock)
# 스토케스틱이 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)
# 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)
# 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)
# 260일 가격 반토막 이상
if len(close) > 5 and positionalEnergy2 is not None and positionalEnergy2 < 0.5:
type = "0_260일 가격 반토막 이상"
self.writeFile(type, CODE, NAME, stock, state)
# 종가가 240일선 아래라면 매수한다.
if close[0] < avg240[0]:
type = "0_240일선 아래"
self.writeFile(type, CODE, NAME, stock, state)
# 기준선 위 전환선
if len(close) > 50:
if ((ichimokucloud_changeLine[0] > ichimokucloud_baseLine[0] and
ichimokucloud_changeLine[1] < ichimokucloud_baseLine[1] and
ichimokucloud_changeLine[2] < ichimokucloud_baseLine[2]) and
volume[0] > volume[1]):
type = "1_기준선 위 전환선"
self.writeFile(type, CODE, NAME, stock, state)
# 종가가 240일선 돌파
if close[0] > avg240[0] and close[1] < avg240[1]:
type = "1_240일선 돌파"
self.writeFile(type, CODE, NAME, stock, state)
# 20일선 돌파
temp_status = self.common.check_Dolpa_Jiji(stock, '20')
if temp_status != "":
type = "1_20일선 돌파"
self.writeFile(type, CODE, NAME, stock, state)
# 60일선 돌파
temp_status = self.common.check_Dolpa_Jiji(stock, '60')
if temp_status != "":
type = "1_60일선 돌파"
self.writeFile(type, CODE, NAME, stock, state)
# 골든크로스
golden_cross_status = self.common.check_golded_cross(stock)
if golden_cross_status != "":
type = "1_GoldenCross"
self.writeFile(type, CODE, NAME, stock, state)
# 거래량 5배 이상
if volume[0] > volume[1]*5:
type = "1_거래량 5배 이상"
self.writeFile(type, CODE, NAME, stock, state)
# 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)
# 정배열
right_arrange = self.common.check_RightArrange(stock)
if right_arrange != "":
type = "1_정배열"
self.writeFile(type, CODE, NAME, stock, state)
# 모든 라인 돌파
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]):
type = "1_모든 라인 돌파"
self.writeFile(type, CODE, NAME, stock, state)
return
def get_moving_average(self, stock):
q_5 = MovingAverage(5)
q_10 = MovingAverage(10)
q_20 = MovingAverage(20)
q_60 = MovingAverage(60)
q_120 = MovingAverage(120)
q_200 = MovingAverage(200)
q_240 = MovingAverage(240)
for i in range(len(stock)):
q_5.enqueue(stock[i]['close'])
q_10.enqueue(stock[i]['close'])
q_20.enqueue(stock[i]['close'])
q_60.enqueue(stock[i]['close'])
q_120.enqueue(stock[i]['close'])
q_200.enqueue(stock[i]['close'])
q_240.enqueue(stock[i]['close'])
stock[i]['avg5'] = q_5.avg()
stock[i]['avg10'] = q_10.avg()
stock[i]['avg20'] = q_20.avg()
stock[i]['avg60'] = q_60.avg()
stock[i]['avg120'] = q_120.avg()
stock[i]['avg200'] = q_200.avg()
stock[i]['avg240'] = q_240.avg()
return
def analyze(self):
stockTableName = 'stock'
stockAnalysisTableName = 'stock_analysis'
conn = sqlite3.connect(self.stockFileName)
cursor = conn.cursor()
# 테이블 생성
cursor.execute("CREATE TABLE IF NOT EXISTS " + stockAnalysisTableName + " (CODE text, NAME text, ymd text, avg5 REAL, avg10 REAL, avg20 REAL, avg60 REAL, avg120 REAL, avg200 REAL, avg240 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)")
# 키 생성
create_key = "CREATE INDEX IF NOT EXISTS " + stockAnalysisTableName + "_idx on " + stockAnalysisTableName + " (CODE, ymd) "
cursor.execute(create_key)
cursor.execute('SELECT distinct code, name FROM ' + stockTableName + ' order by code')
items = cursor.fetchall()
cursor.close()
conn.close()
for rowid, item in enumerate(items):
conn = sqlite3.connect(self.stockFileName)
cursor = conn.cursor()
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()
for item in items:
stock['PRICE'].append(
{"ymd": item[0],
"close": item[1],
"diff": item[2],
"open": item[3],
"high": item[4],
"low": item[5],
"volume": item[6],
"avg5": -1,
"avg10": -1,
"avg20": -1,
"avg60": -1,
"avg120": -1,
"avg200": -1,
"avg240": -1,
"bolingerband_upper": -1,
"bolingerband_lower": -1,
"bolingerband_middle": -1,
"ichimokucloud_changeLine": -1,
"ichimokucloud_baseLine": -1,
"ichimokucloud_leadingSpan1": -1,
"ichimokucloud_leadingSpan2": -1,
"stochastic_fast_k": -1,
"stochastic_slow_k": -1,
"stochastic_slow_d": -1})
# 이동 평균 계산
stock["PRICE"] = sorted(stock["PRICE"], key=lambda x: x['ymd'])
self.get_moving_average(stock["PRICE"])
self.ichimokuCloud.analyze(stock)
self.stochastic.analyze(stock)
self.bolingerBand.analyze(stock)
for price in stock["PRICE"]:
cursor.execute('SELECT * FROM ' + stockAnalysisTableName + ' WHERE CODE=? and ymd=?', (stock['CODE'], price['ymd'],))
result = cursor.fetchone()
if result == None:
sql = "INSERT INTO " + stockAnalysisTableName + "(CODE, NAME, ymd, avg5, avg10, avg20, avg60, avg120, avg200, avg240, "
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 += " VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"
cursor.execute(sql, (stock["CODE"], stock["NAME"], price['ymd'], price['avg5'], price['avg10'], price['avg20'], price['avg60'], price['avg120'], price['avg200'], price['avg240'],
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'],))
else:
break
conn.commit()
cursor.close()
conn.close()
return
if __name__ == "__main__":
start = time.time()
PROJECT_HOME = os.path.join(os.path.dirname(os.path.join(os.path.dirname(os.path.join(os.path.dirname(__file__))))))
stockFileName = PROJECT_HOME + '/resources/stock.db'
fnguideFileName = PROJECT_HOME + '/resources/fnguide.db'
analyzer = AnalyzerSqlite(PROJECT_HOME, stockFileName, fnguideFileName)
#analyzer.analyze()
day = datetime.today().strftime("%Y%m%d")
# HTML 출력
outPath = PROJECT_HOME + "/resources/analysis/"+day
if os.path.isdir(outPath):
shutil.rmtree(outPath)
os.mkdir(outPath)
print("print to Html...")
analyzer.findCandidate(outPath)
print("time : %6.2f" % (time.time() - start))
print("done...")