Files
DeepStock/stock/analysis/AnalyzerSqlite.py
dsyoon 6438003081 init
2024-03-20 23:07:50 +09:00

706 lines
42 KiB
Python

import os
import time
import shutil
import matplotlib.pyplot as plt
import datetime
import sqlite3
import math
from math import nan
from datetime import datetime, timedelta
from dateutil.relativedelta import relativedelta
from matplotlib import rc
import pandas as pd
import numpy as np
from stock.analysis.JSDPattern_simulation import JSDPattern_simulation
from hts.BuySell_Daily import BuySell_Daily
rc('font', family='AppleGothic')
plt.rcParams['axes.unicode_minus'] = False
import plotly.graph_objs as go
from plotly import subplots
import plotly.io as po
from stock.analysis.Common import Common
from stock.util.TelegramBot import TelegramBot
class AnalyzerSqlite:
jSDPattern = None
buySell_Daily = None
topCompany = None
fnguide = None
bot = None
common = None
stockFileName = None
analyzedFileName = None
moving_avg = None
def __init__(self, RESOURCE_PATH):
self.common = Common()
self.stockFileName = os.path.join(RESOURCE_PATH, 'stock.db')
self.jSDPattern = JSDPattern_simulation(self.stockFileName)
self.buySell_Daily = BuySell_Daily()
self.stockFileName = self.stockFileName
self.topCompany = self.getTopCompany(self.stockFileName, 2000)
self.fnguide = self.readFnguide(self.stockFileName)
self.bot = TelegramBot()
return
def getTopCompany(self, fnguideFileName, top):
conn = sqlite3.connect(fnguideFileName)
cursor = conn.cursor()
sql = "select DISTINCT CODE, NAME from fnguide order by total_ownership_interest desc limit " + str(top)
cursor.execute(sql)
result = cursor.fetchall()
top_company = {}
for idx, item in enumerate(result):
top_company[item[0]] = (idx+1, item[1])
cursor.close()
conn.close()
return top_company
def readFnguide(self, fnguideFileName):
conn = sqlite3.connect(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 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()
fnguide = {}
for item in result:
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 fnguide
def cz(self, value):
if value is None or math.isnan(value):
return 0
return value
def clear_BSLINE(self, BUY_LIST, sell_type=None):
if sell_type is None or sell_type == '':
BUY_LIST['avg_buy_price'] = 0
BUY_LIST['buy_count'] = 0
BUY_LIST['buy_list'].clear()
else:
BUY_LIST['avg_buy_price'] = 0
BUY_LIST['buy_count'] = 0
tmp_sell_type = sell_type.split(',')
for i, buy_list in reversed(list(enumerate(BUY_LIST['buy_list']))):
for t_sell_type in tmp_sell_type:
if buy_list['buy_type'].strip() == t_sell_type.strip():
del BUY_LIST['buy_list'][i]
break
return
def draw(self, stock_code, data, bsLine=None):
# 어제 데이터는 지운다.
#data = data.loc[pd.DatetimeIndex(data.index).day == int(given_day[6:])]
buy_price_line, buy_count_line, buy_type, buy_count_line, sell_price_line, sell_count_line, sell_type = [], [], [], [], [], [], []
buy_sell_size, buy_colors, sell_colors, buy_colors = [], [], [], []
if bsLine is not None:
buy_price_line = bsLine['buy_price']
buy_count_line = bsLine['buy_count']
sell_price_line = bsLine['sell_price']
sell_count_line = bsLine['sell_count']
buy_type = bsLine['buy_type']
sell_type = bsLine['sell_type']
for i in range(len(data)):
if buy_price_line[i] < 1:
buy_colors.append("#ffffff")
buy_price_line[i] = nan
buy_sell_size.append(0)
else:
buy_colors.append("#0C752E")
buy_sell_size.append(14)
for i in range(len(data)):
if sell_price_line[i] < 1:
sell_colors.append("#ffffff")
sell_price_line[i] = nan
else:
sell_colors.append("#00ced1")
volume_colors = []
for i in range(len(data)):
if data['open'][i] > data['close'][i]:
volume_colors.append("#FF0000")
elif data['open'][i] < data['close'][i]:
volume_colors.append("#FF0000")
else:
volume_colors.append("#000000")
# 그래프를 설정한다.
if bsLine is not None:
buy_text_list, sell_text_list = [], []
for i in range(len(data['ymd'])):
buy_text_list.append(
"{}, {}, {} ({:,.2f})<br><br>"
"avg5: {:.2f}, avg10: {:.2f}, avg20: {:.2f}, avg60: {:.2f}, avg90: {:.2f}, avg120: {:.2f}, avg240: {:.2f}<br>"
"avg360: {:.2f}, avg480: {:.2f}, avg720: {:.2f}, avg1440: {:.2f}, avg2880: {:.2f}<br><br>"
"loc_k: {:.2f}, loc_d: {:.2f}, loc_s: {:.2f}<br><br>"
"laggingSpan_close_diff: {:.4f} ({:.4f})<br>"
"laggingSpan_changeLine_diff: {:.4f} ({:.4f})<br>"
"laggingSpan_baseLine_diff: {:.4f} ({:.4f})<br>"
"laggingSpan_leadingSpan1_diff: {:.4f} ({:.4f})<br>"
"laggingSpan_leadingSpan2_diff: {:.4f} ({:.4f})<br>"
"laggingSpan_avg60_diff: {:.4f} ({:.4f})<br>"
"laggingSpan_lower10_diff: {:.4f} ({:.4f})<br>"
"laggingSpan_middle10_diff: {:.4f} ({:.4f})<br>"
"laggingSpan_upper10_diff: {:.4f} ({:.4f})<br>"
"laggingSpan_lower20_diff: {:.4f} ({:.4f})<br>"
"laggingSpan_middle20_diff: {:.4f} ({:.4f})<br>"
"laggingSpan_upper20_diff: {:.4f} ({:.4f})<br>"
"baseLine_close_diff: {:.4f} ({:.4f})<br>"
"changeLine_close_diff: {:.4f} ({:.4f})<br>"
"changeLine_baseLine_diff: {:.4f} ({:.4f})<br>"
"leadingSpan1_leadingSpan2_diff: {:.4f} ({:.4f})<br>"
.format(data['ymd'][i].strftime('%Y-%m-%d %H:%M'), buy_type[i], self.cz(buy_price_line[i]), self.cz(buy_price_line[i])*self.cz(buy_count_line[i]),
self.cz(data["avg5"][i]), self.cz(data["avg10"][i]), self.cz(data["avg20"][i]), self.cz(data["avg60"][i]), self.cz(data["avg90"][i]), self.cz(data["avg120"][i]), self.cz(data["avg240"][i]), self.cz(data["avg360"][i]), self.cz(data["avg480"][i]), self.cz(data["avg720"][i]), self.cz(data["avg1440"][i]), self.cz(data["avg2880"][i]),
self.cz(data['loc_240_k'][i]), self.cz(data['loc_240_d'][i]), self.cz(data['loc_240_s'][i]),
self.cz(data['laggingSpan_close_diff'][i]), self.cz(data['laggingSpan_close_diff_rate'][i]),
self.cz(data['laggingSpan_changeLine_diff'][i]), self.cz(data['laggingSpan_changeLine_diff_rate'][i]),
self.cz(data['laggingSpan_baseLine_diff'][i]), self.cz(data['laggingSpan_baseLine_diff_rate'][i]),
self.cz(data['laggingSpan_leadingSpan1_diff'][i]), self.cz(data['laggingSpan_leadingSpan1_diff_rate'][i]),
self.cz(data['laggingSpan_leadingSpan2_diff'][i]), self.cz(data['laggingSpan_leadingSpan2_diff_rate'][i]),
self.cz(data['laggingSpan_avg60_diff'][i]), self.cz(data['laggingSpan_avg60_diff_rate'][i]),
self.cz(data['laggingSpan_lower10_diff'][i]), self.cz(data['laggingSpan_lower10_diff_rate'][i]),
self.cz(data['laggingSpan_middle10_diff'][i]), self.cz(data['laggingSpan_middle10_diff_rate'][i]),
self.cz(data['laggingSpan_upper10_diff'][i]), self.cz(data['laggingSpan_upper10_diff_rate'][i]),
self.cz(data['laggingSpan_lower20_diff'][i]), self.cz(data['laggingSpan_lower20_diff_rate'][i]),
self.cz(data['laggingSpan_middle20_diff'][i]), self.cz(data['laggingSpan_middle20_diff_rate'][i]),
self.cz(data['laggingSpan_upper20_diff'][i]), self.cz(data['laggingSpan_upper20_diff_rate'][i]),
self.cz(data['baseLine_close_diff'][i]), self.cz(data['baseLine_close_diff_rate'][i]),
self.cz(data['changeLine_close_diff'][i]), self.cz(data['changeLine_close_diff_rate'][i]),
self.cz(data['changeLine_baseLine_diff'][i]), self.cz(data['changeLine_baseLine_diff_rate'][i]),
self.cz(data['leadingSpan1_leadingSpan2_diff'][i]), self.cz(data['leadingSpan1_leadingSpan2_diff_rate'][i])
))
sell_text_list.append(
"{}, {}, {} ({:,.2f})<br><br>"
"avg5: {:.2f}, avg10: {:.2f}, avg20: {:.2f}, avg60: {:.2f}, avg90: {:.2f}, avg120: {:.2f}, avg240: {:.2f}<br>"
"avg360: {:.2f}, avg480: {:.2f}, avg720: {:.2f}, avg1440: {:.2f}, avg2880: {:.2f}<br><br>"
"loc_k: {:.2f}, loc_d: {:.2f}, loc_s: {:.2f}<br><br>"
"laggingSpan_close_diff: {:.4f} ({:.4f})<br>"
"laggingSpan_changeLine_diff: {:.4f} ({:.4f})<br>"
"laggingSpan_baseLine_diff: {:.4f} ({:.4f})<br>"
"laggingSpan_leadingSpan1_diff: {:.4f} ({:.4f})<br>"
"laggingSpan_leadingSpan2_diff: {:.4f} ({:.4f})<br>"
"laggingSpan_avg60_diff: {:.4f} ({:.4f})<br>"
"laggingSpan_lower10_diff: {:.4f} ({:.4f})<br>"
"laggingSpan_middle10_diff: {:.4f} ({:.4f})<br>"
"laggingSpan_upper10_diff: {:.4f} ({:.4f})<br>"
"laggingSpan_lower20_diff: {:.4f} ({:.4f})<br>"
"laggingSpan_middle20_diff: {:.4f} ({:.4f})<br>"
"laggingSpan_upper20_diff: {:.4f} ({:.4f})<br>"
"baseLine_close_diff: {:.4f} ({:.4f})<br>"
"changeLine_close_diff: {:.4f} ({:.4f})<br>"
"changeLine_baseLine_diff: {:.4f} ({:.4f})<br>"
"leadingSpan1_leadingSpan2_diff: {:.4f} ({:.4f})<br>"
.format(
data['ymd'][i].strftime('%Y-%m-%d %H:%M'), sell_type[i], self.cz(sell_price_line[i]), self.cz(sell_price_line[i])*self.cz(sell_count_line[i]),
self.cz(data["avg5"][i]), self.cz(data["avg10"][i]), self.cz(data["avg20"][i]), self.cz(data["avg60"][i]), self.cz(data["avg90"][i]), self.cz(data["avg120"][i]), self.cz(data["avg240"][i]), self.cz(data["avg360"][i]), self.cz(data["avg480"][i]), self.cz(data["avg720"][i]), self.cz(data["avg1440"][i]), self.cz(data["avg2880"][i]),
self.cz(data['loc_240_k'][i]), self.cz(data['loc_240_d'][i]), self.cz(data['loc_240_s'][i]),
self.cz(data['laggingSpan_close_diff'][i]), self.cz(data['laggingSpan_close_diff_rate'][i]),
self.cz(data['laggingSpan_changeLine_diff'][i]), self.cz(data['laggingSpan_changeLine_diff_rate'][i]),
self.cz(data['laggingSpan_baseLine_diff'][i]), self.cz(data['laggingSpan_baseLine_diff_rate'][i]),
self.cz(data['laggingSpan_leadingSpan1_diff'][i]), self.cz(data['laggingSpan_leadingSpan1_diff_rate'][i]),
self.cz(data['laggingSpan_leadingSpan2_diff'][i]), self.cz(data['laggingSpan_leadingSpan2_diff_rate'][i]),
self.cz(data['laggingSpan_avg60_diff'][i]), self.cz(data['laggingSpan_avg60_diff_rate'][i]),
self.cz(data['laggingSpan_lower10_diff'][i]), self.cz(data['laggingSpan_lower10_diff_rate'][i]),
self.cz(data['laggingSpan_middle10_diff'][i]), self.cz(data['laggingSpan_middle10_diff_rate'][i]),
self.cz(data['laggingSpan_upper10_diff'][i]), self.cz(data['laggingSpan_upper10_diff_rate'][i]),
self.cz(data['laggingSpan_lower20_diff'][i]), self.cz(data['laggingSpan_lower20_diff_rate'][i]),
self.cz(data['laggingSpan_middle20_diff'][i]), self.cz(data['laggingSpan_middle20_diff_rate'][i]),
self.cz(data['laggingSpan_upper20_diff'][i]), self.cz(data['laggingSpan_upper20_diff_rate'][i]),
self.cz(data['baseLine_close_diff'][i]), self.cz(data['baseLine_close_diff_rate'][i]),
self.cz(data['changeLine_close_diff'][i]), self.cz(data['changeLine_close_diff_rate'][i]),
self.cz(data['changeLine_baseLine_diff'][i]), self.cz(data['changeLine_baseLine_diff_rate'][i]),
self.cz(data['leadingSpan1_leadingSpan2_diff'][i]), self.cz(data['leadingSpan1_leadingSpan2_diff_rate'][i])
))
buy_check = go.Scatter(x=data['ymd'], y=buy_price_line, mode='markers', name="buy_price", marker=dict(size=buy_sell_size, color=buy_colors, line_width=0), text=buy_text_list, hoverinfo="text")
sell_check = go.Scatter(x=data['ymd'], y=sell_price_line, mode='markers', name="sell_price", marker=dict(size=14, color=sell_colors, line_width=0), text=sell_text_list, hoverinfo="text")
volume_line = go.Bar(x=data['ymd'], y=data["volume"], marker_color=volume_colors, name='volume')
avg5 = go.Scatter(x=data['ymd'], y=data["avg5"], name="avg5", line_color='#079118')
avg10 = go.Scatter(x=data['ymd'], y=data["avg10"], name="avg10", line_color='grey')
avg20 = go.Scatter(x=data['ymd'], y=data["avg20"], name="avg20", line_color='#d755e8')
avg60 = go.Scatter(x=data['ymd'], y=data["avg60"], name="avg60", line_color='#099B92')
avg90 = go.Scatter(x=data['ymd'], y=data["avg90"], name="avg90", line_color='#2a9c0c')
avg120 = go.Scatter(x=data['ymd'], y=data["avg120"], name="avg120", line_color='#079118')
avg240 = go.Scatter(x=data['ymd'], y=data["avg240"], name="avg240", line_color='#e68456')
avg360 = go.Scatter(x=data['ymd'], y=data["avg360"], name="avg360", line_color='#e6b55c')
avg480 = go.Scatter(x=data['ymd'], y=data["avg480"], name="avg480", line_color='#2a9c0c')
avg720 = go.Scatter(x=data['ymd'], y=data["avg720"], name="avg720", line_color='#e75d53')
avg1440 = go.Scatter(x=data['ymd'], y=data["avg1440"], name="avg1440", line_color='#2a9c0c')
avg2880 = go.Scatter(x=data['ymd'], y=data["avg2880"], name="avg2880", line_color='#46406c')
laggingSpan_0_8_limit = [0.8 for i in data['ymd']]
laggingSpan_0_2_limit = [0.2 for i in data['ymd']]
laggingSpan_0_limit = [0 for i in data['ymd']]
laggingSpan__0_2_limit = [-0.2 for i in data['ymd']]
laggingSpan__0_8_limit = [-0.8 for i in data['ymd']]
laggingSpan_0_8_limit_line = go.Scatter(x=data['ymd'], y=laggingSpan_0_8_limit, line=dict(color='grey', width=1), name='laggingSpan_0_8_limit')
laggingSpan_0_2_limit_line = go.Scatter(x=data['ymd'], y=laggingSpan_0_2_limit, line=dict(color='grey', width=1), name='laggingSpan_0_2_limit')
laggingSpan_0_limit_line = go.Scatter(x=data['ymd'], y=laggingSpan_0_limit, line=dict(color='grey', width=1), name='laggingSpan_0_limit')
laggingSpan__0_2_limit_line = go.Scatter(x=data['ymd'], y=laggingSpan__0_2_limit, line=dict(color='grey', width=1), name='laggingSpan__0_2_limit')
laggingSpan__0_8_limit_line = go.Scatter(x=data['ymd'], y=laggingSpan__0_8_limit, line=dict(color='grey', width=1), name='laggingSpan__0_8_limit')
laggingSpan_close_diff = go.Scatter(x=data['ymd'], y=data["laggingSpan_close_diff"], name="laggingSpan_close_diff", line_color='#079118')
laggingSpan_changeLine_diff = go.Scatter(x=data['ymd'], y=data["laggingSpan_changeLine_diff"], name="laggingSpan_changeLine_diff", line_color='grey')
laggingSpan_baseLine_diff = go.Scatter(x=data['ymd'], y=data["laggingSpan_baseLine_diff"], name="laggingSpan_baseLine_diff", line_color='#d755e8')
laggingSpan_leadingSpan1_diff = go.Scatter(x=data['ymd'], y=data["laggingSpan_leadingSpan1_diff"], name="laggingSpan_leadingSpan1_diff", line_color='#d755e8')
laggingSpan_leadingSpan2_diff = go.Scatter(x=data['ymd'], y=data["laggingSpan_leadingSpan2_diff"], name="laggingSpan_leadingSpan2_diff", line_color='#d755e8')
laggingSpan_avg60_diff = go.Scatter(x=data['ymd'], y=data["laggingSpan_avg60_diff"], name="laggingSpan_avg60_diff", line_color='#d755e8')
laggingSpan_lower10_diff = go.Scatter(x=data['ymd'], y=data["laggingSpan_lower10_diff"], name="laggingSpan_lower10_diff", line_color='#d755e8')
laggingSpan_middle10_diff = go.Scatter(x=data['ymd'], y=data["laggingSpan_middle10_diff"], name="laggingSpan_middle10_diff", line_color='#d755e8')
laggingSpan_upper10_diff = go.Scatter(x=data['ymd'], y=data["laggingSpan_upper10_diff"], name="laggingSpan_upper10_diff", line_color='#d755e8')
laggingSpan_lower20_diff = go.Scatter(x=data['ymd'], y=data["laggingSpan_lower20_diff"], name="laggingSpan_lower20_diff", line_color='#d755e8')
laggingSpan_middle20_diff = go.Scatter(x=data['ymd'], y=data["laggingSpan_middle20_diff"], name="laggingSpan_middle20_diff", line_color='#d755e8')
laggingSpan_upper20_diff = go.Scatter(x=data['ymd'], y=data["laggingSpan_upper20_diff"], name="laggingSpan_upper20_diff", line_color='#d755e8')
baseLine_close_diff = go.Scatter(x=data['ymd'], y=data["baseLine_close_diff"], name="baseLine_close_diff", line_color='#d755e8')
changeLine_close_diff = go.Scatter(x=data['ymd'], y=data["changeLine_close_diff"], name="changeLine_close_diff", line_color='#d755e8')
changeLine_baseLine_diff = go.Scatter(x=data['ymd'], y=data["changeLine_baseLine_diff"], name="changeLine_baseLine_diff", line_color='#d755e8')
changeLine_leadingSpan1_diff = go.Scatter(x=data['ymd'], y=data["changeLine_leadingSpan1_diff"], name="changeLine_leadingSpan1_diff", line_color='#d755e8')
leadingSpan1_leadingSpan2_diff = go.Scatter(x=data['ymd'], y=data["leadingSpan1_leadingSpan2_diff"], name="leadingSpan1_leadingSpan2_diff", line_color='#d755e8')
laggingSpan_close_diff_rate = go.Scatter(x=data['ymd'], y=data["laggingSpan_close_diff_rate"], name="laggingSpan_close_diff_rate", line_color='#d755e8')
laggingSpan_changeLine_diff_rate = go.Scatter(x=data['ymd'], y=data["laggingSpan_changeLine_diff_rate"], name="laggingSpan_changeLine_diff_rate", line_color='#d755e8')
laggingSpan_baseLine_diff_rate = go.Scatter(x=data['ymd'], y=data["laggingSpan_baseLine_diff_rate"], name="laggingSpan_baseLine_diff_rate", line_color='#d755e8')
laggingSpan_leadingSpan1_diff_rate = go.Scatter(x=data['ymd'], y=data["laggingSpan_leadingSpan1_diff_rate"], name="laggingSpan_leadingSpan1_diff_rate", line_color='#d755e8')
laggingSpan_leadingSpan2_diff_rate = go.Scatter(x=data['ymd'], y=data["laggingSpan_leadingSpan2_diff_rate"], name="laggingSpan_leadingSpan2_diff_rate", line_color='#d755e8')
laggingSpan_avg60_diff_rate = go.Scatter(x=data['ymd'], y=data["laggingSpan_avg60_diff_rate"], name="laggingSpan_avg60_diff_rate", line_color='#d755e8')
laggingSpan_lower10_diff_rate = go.Scatter(x=data['ymd'], y=data["laggingSpan_lower10_diff_rate"], name="laggingSpan_lower10_diff_rate", line_color='#d755e8')
laggingSpan_middle10_diff_rate = go.Scatter(x=data['ymd'], y=data["laggingSpan_middle10_diff_rate"], name="laggingSpan_middle10_diff_rate", line_color='#d755e8')
laggingSpan_upper10_diff_rate = go.Scatter(x=data['ymd'], y=data["laggingSpan_upper10_diff_rate"], name="laggingSpan_upper10_diff_rate", line_color='#d755e8')
laggingSpan_lower20_diff_rate = go.Scatter(x=data['ymd'], y=data["laggingSpan_lower20_diff_rate"], name="laggingSpan_lower20_diff_rate", line_color='#d755e8')
laggingSpan_middle20_diff_rate = go.Scatter(x=data['ymd'], y=data["laggingSpan_middle20_diff_rate"], name="laggingSpan_middle20_diff_rate", line_color='#d755e8')
laggingSpan_upper20_diff_rate = go.Scatter(x=data['ymd'], y=data["laggingSpan_upper20_diff_rate"], name="laggingSpan_upper20_diff_rate", line_color='#d755e8')
baseLine_close_diff_rate = go.Scatter(x=data['ymd'], y=data["baseLine_close_diff_rate"], name="baseLine_close_diff_rate", line_color='#d755e8')
changeLine_close_diff_rate = go.Scatter(x=data['ymd'], y=data["changeLine_close_diff_rate"], name="changeLine_close_diff_rate", line_color='#d755e8')
changeLine_baseLine_diff_rate = go.Scatter(x=data['ymd'], y=data["changeLine_baseLine_diff_rate"], name="changeLine_baseLine_diff_rate", line_color='#d755e8')
changeLine_leadingSpan1_diff_rate = go.Scatter(x=data['ymd'], y=data["changeLine_leadingSpan1_diff_rate"], name="changeLine_leadingSpan1_diff_rate", line_color='#d755e8')
leadingSpan1_leadingSpan2_diff_rate = go.Scatter(x=data['ymd'], y=data["leadingSpan1_leadingSpan2_diff_rate"], name="leadingSpan1_leadingSpan2_diff_rate", line_color='#d755e8')
changeLine = go.Scatter(x=data['ymd'], y=data["changeLine"], name="changeLine", line_color='#0196ff')
baseLine = go.Scatter(x=data['ymd'], y=data["baseLine"], name="baseLine", line_color='#991515')
laggingSpan = go.Scatter(x=data['ymd'], y=data["laggingSpan"], name="laggingSpan", line_color='#12A524')
leadingSpan1 = go.Scatter(x=data['ymd'], y=data["leadingSpan1"], name="leadingSpan1", line_color='#008001')
leadingSpan2 = go.Scatter(x=data['ymd'], y=data["leadingSpan2"], name="leadingSpan2", line_color='#830fd4')
upper_10_Line = go.Scatter(x=data['ymd'], y=data["upper_10"], name="upper_10", line_color='#0196ff')
lower_10_Line = go.Scatter(x=data['ymd'], y=data["lower_10"], name="lower_10", line_color='#991515')
middle_10_line = go.Scatter(x=data['ymd'], y=data["middle_10"], name="middle_10", line_color='#12A524')
upper_20_Line = go.Scatter(x=data['ymd'], y=data["upper_20"], name="upper_20", line_color='#0196ff')
lower_20_Line = go.Scatter(x=data['ymd'], y=data["lower_20"], name="lower_20", line_color='#991515')
middle_20_line = go.Scatter(x=data['ymd'], y=data["middle_20"], name="middle_20", line_color='#12A524')
loc_240_k = go.Scatter(x=data['ymd'], y=data["loc_240_k"], name="loc_240_k", line_color='#0196ff')
loc_240_d = go.Scatter(x=data['ymd'], y=data["loc_240_d"], name="loc_240_d", line_color='#991515')
loc_240_s = go.Scatter(x=data['ymd'], y=data["loc_240_s"], name="loc_240_s", line_color='#12A524')
new_high_9 = go.Scatter(x=data['ymd'], y=data["new_high_9"], name="new_high_9", line_color='#0196ff')
new_high_26 = go.Scatter(x=data['ymd'], y=data["new_high_26"], name="new_high_26", line_color='#991515')
new_high_33 = go.Scatter(x=data['ymd'], y=data["new_high_33"], name="new_high_33", line_color='#12A524')
new_high_52 = go.Scatter(x=data['ymd'], y=data["new_high_52"], name="new_high_52", line_color='#099B92')
new_low_9 = go.Scatter(x=data['ymd'], y=data["new_low_9"], name="new_low_9", line_color='#0196ff')
new_low_26 = go.Scatter(x=data['ymd'], y=data["new_low_26"], name="new_low_26", line_color='#991515')
new_low_33 = go.Scatter(x=data['ymd'], y=data["new_low_33"], name="new_low_33", line_color='#12A524')
new_low_52 = go.Scatter(x=data['ymd'], y=data["new_low_52"], name="new_low_52", line_color='#099B92')
slowk_up_limit = [80 for i in data['ymd']]
slowk_middle_limit = [50 for i in data['ymd']]
slowk_down_limit = [20 for i in data['ymd']]
slowk_up_limit = go.Scatter(x=data['ymd'], y=slowk_up_limit, line=dict(color='grey', width=1), name='slowk_up_limit')
slowk_middle_limit = go.Scatter(x=data['ymd'], y=slowk_middle_limit, line=dict(color='grey', width=1), name='slowk_middle_limit')
slowk_down_limit = go.Scatter(x=data['ymd'], y=slowk_down_limit, line=dict(color='grey', width=1), name='slowk_down_limit')
slowk_12 = go.Scatter(x=data['ymd'], y=data["slowk_12"], line=dict(color='#079118', width=2), name='slowk_12')
slowd_12 = go.Scatter(x=data['ymd'], y=data["slowd_12"], line=dict(dash='dashdot', color='#079118', width=2), name='slowd_12')
slowk_26 = go.Scatter(x=data['ymd'], y=data["slowk_26"], line=dict(color='grey', width=2), name='slowk_26')
slowd_26 = go.Scatter(x=data['ymd'], y=data["slowd_26"], line=dict(dash='dashdot', color='grey', width=2), name='slowd_26')
slowk_52 = go.Scatter(x=data['ymd'], y=data["slowk_52"], line=dict(color='#d755e8', width=2), name='slowk_52')
slowd_52 = go.Scatter(x=data['ymd'], y=data["slowd_52"], line=dict(dash='dashdot', color='#d755e8', width=2), name='slowd_52')
text_list = []
for i in range(len(data['ymd'])):
text_list.append(
"{}<br><br>"
"avg5: {:.2f}, avg10: {:.2f}, avg20: {:.2f}, avg60: {:.2f}, avg90: {:.2f}, avg120: {:.2f}, avg240: {:.2f}<br>"
"avg360: {:.2f}, avg480: {:.2f}, avg720: {:.2f}, avg1440: {:.2f}, avg2880: {:.2f}<br><br>"
"loc_k: {:.2f}, loc_d: {:.2f}, loc_s: {:.2f}<br><br>"
"laggingSpan_close_diff: {:.4f} ({:.4f})<br>"
"laggingSpan_changeLine_diff: {:.4f} ({:.4f})<br>"
"laggingSpan_baseLine_diff: {:.4f} ({:.4f})<br>"
"laggingSpan_leadingSpan1_diff: {:.4f} ({:.4f})<br>"
"laggingSpan_leadingSpan2_diff: {:.4f} ({:.4f})<br>"
"laggingSpan_avg60_diff: {:.4f} ({:.4f})<br>"
"laggingSpan_lower10_diff: {:.4f} ({:.4f})<br>"
"laggingSpan_middle10_diff: {:.4f} ({:.4f})<br>"
"laggingSpan_upper10_diff: {:.4f} ({:.4f})<br>"
"laggingSpan_lower20_diff: {:.4f} ({:.4f})<br>"
"laggingSpan_middle20_diff: {:.4f} ({:.4f})<br>"
"laggingSpan_upper20_diff: {:.4f} ({:.4f})<br>"
"baseLine_close_diff: {:.4f} ({:.4f})<br>"
"changeLine_close_diff: {:.4f} ({:.4f})<br>"
"changeLine_baseLine_diff: {:.4f} ({:.4f})<br>"
"leadingSpan1_leadingSpan2_diff: {:.4f} ({:.4f})<br>"
.format(
data['ymd'][i].strftime('%Y-%m-%d %H:%M'),
self.cz(data["avg5"][i]), self.cz(data["avg10"][i]), self.cz(data["avg20"][i]), self.cz(data["avg60"][i]), self.cz(data["avg90"][i]), self.cz(data["avg120"][i]), self.cz(data["avg240"][i]), self.cz(data["avg360"][i]), self.cz(data["avg480"][i]), self.cz(data["avg720"][i]), self.cz(data["avg1440"][i]), self.cz(data["avg2880"][i]),
self.cz(data['loc_240_k'][i]), self.cz(data['loc_240_d'][i]), self.cz(data['loc_240_s'][i]),
self.cz(data['laggingSpan_close_diff'][i]), self.cz(data['laggingSpan_close_diff_rate'][i]),
self.cz(data['laggingSpan_changeLine_diff'][i]), self.cz(data['laggingSpan_changeLine_diff_rate'][i]),
self.cz(data['laggingSpan_baseLine_diff'][i]), self.cz(data['laggingSpan_baseLine_diff_rate'][i]),
self.cz(data['laggingSpan_leadingSpan1_diff'][i]), self.cz(data['laggingSpan_leadingSpan1_diff_rate'][i]),
self.cz(data['laggingSpan_leadingSpan2_diff'][i]), self.cz(data['laggingSpan_leadingSpan2_diff_rate'][i]),
self.cz(data['laggingSpan_avg60_diff'][i]), self.cz(data['laggingSpan_avg60_diff_rate'][i]),
self.cz(data['laggingSpan_lower10_diff'][i]), self.cz(data['laggingSpan_lower10_diff_rate'][i]),
self.cz(data['laggingSpan_middle10_diff'][i]), self.cz(data['laggingSpan_middle10_diff_rate'][i]),
self.cz(data['laggingSpan_upper10_diff'][i]), self.cz(data['laggingSpan_upper10_diff_rate'][i]),
self.cz(data['laggingSpan_lower20_diff'][i]), self.cz(data['laggingSpan_lower20_diff_rate'][i]),
self.cz(data['laggingSpan_middle20_diff'][i]), self.cz(data['laggingSpan_middle20_diff_rate'][i]),
self.cz(data['laggingSpan_upper20_diff'][i]), self.cz(data['laggingSpan_upper20_diff_rate'][i]),
self.cz(data['baseLine_close_diff'][i]), self.cz(data['baseLine_close_diff_rate'][i]),
self.cz(data['changeLine_close_diff'][i]), self.cz(data['changeLine_close_diff_rate'][i]),
self.cz(data['changeLine_baseLine_diff'][i]), self.cz(data['changeLine_baseLine_diff_rate'][i]),
self.cz(data['leadingSpan1_leadingSpan2_diff'][i]), self.cz(data['leadingSpan1_leadingSpan2_diff_rate'][i])
))
candle_stick = go.Candlestick(x=data['ymd'],
open=data['open'], high=data['high'], low=data['low'], close=data['close'],
increasing_line_color='red', decreasing_line_color='blue',
name='candle', text=text_list, hoverinfo="text"
)
if bsLine is not None:
candle_data = [avg5, avg10, avg20, avg60, avg90, avg120, avg240, avg360, avg480, avg720, avg1440, avg2880, buy_check, sell_check, candle_stick, changeLine, baseLine, laggingSpan, leadingSpan1, leadingSpan2, upper_10_Line, lower_10_Line, middle_10_line, upper_20_Line, lower_20_Line, middle_20_line]
else:
candle_data = [avg5, avg10, avg20, avg60, avg90, avg120, avg240, avg360, avg480, avg720, avg1440, avg2880, candle_stick,changeLine, baseLine, laggingSpan, leadingSpan1, leadingSpan2]
volume_data = [volume_line]
disparity_data = [laggingSpan_close_diff, laggingSpan_changeLine_diff, laggingSpan_baseLine_diff, laggingSpan_leadingSpan1_diff, laggingSpan_leadingSpan2_diff, laggingSpan_avg60_diff, laggingSpan_lower10_diff, laggingSpan_middle10_diff, laggingSpan_upper10_diff, laggingSpan_lower20_diff, laggingSpan_middle20_diff, laggingSpan_upper20_diff, baseLine_close_diff, changeLine_close_diff, changeLine_baseLine_diff, changeLine_leadingSpan1_diff, leadingSpan1_leadingSpan2_diff]
loc_disparity_data = [laggingSpan_0_8_limit_line, laggingSpan_0_2_limit_line, laggingSpan_0_limit_line, laggingSpan__0_2_limit_line, laggingSpan__0_8_limit_line,
laggingSpan_close_diff_rate, laggingSpan_changeLine_diff_rate, laggingSpan_baseLine_diff_rate, laggingSpan_leadingSpan1_diff_rate, laggingSpan_leadingSpan2_diff_rate, laggingSpan_avg60_diff_rate, laggingSpan_lower10_diff_rate, laggingSpan_middle10_diff_rate, laggingSpan_upper10_diff_rate, laggingSpan_lower20_diff_rate, laggingSpan_middle20_diff_rate, laggingSpan_upper20_diff_rate, baseLine_close_diff_rate, changeLine_close_diff_rate, changeLine_baseLine_diff_rate,changeLine_leadingSpan1_diff_rate, leadingSpan1_leadingSpan2_diff_rate,
loc_240_k, loc_240_d, loc_240_s,
new_high_9 ,new_high_26, new_high_33, new_high_52,new_low_9 ,new_low_26, new_low_33, new_low_52
]
stochastic_data = [
slowk_up_limit, slowk_middle_limit, slowk_down_limit,
slowk_12, slowd_12,
slowk_26, slowd_26,
slowk_52, slowd_52
]
# 그래프를 그린다.
"""
fig = go.Figure(data=candle_data)
fig.update_layout(title=stock_code)
fig.show()
"""
fig = subplots.make_subplots(
rows=5, cols=1,
subplot_titles=("이격도", "이격도 위치", "캔들", "slowkd", "거래량"),
shared_xaxes=True, horizontal_spacing=0.03, vertical_spacing=0.01,
row_heights=[200, 200, 700, 200, 200]
)
for trace in disparity_data:
fig.append_trace(trace, 1, 1)
for trace in loc_disparity_data:
fig.append_trace(trace, 2, 1)
for trace in candle_data:
fig.append_trace(trace, 3, 1)
for trace in stochastic_data:
fig.append_trace(trace, 4, 1)
for trace in volume_data:
fig.append_trace(trace, 5, 1)
#fig.update_xaxes(nticks=5)
#fig.update_layout(height=2400, title=stock_code, xaxis_rangeslider_visible=False)
df = pd.DataFrame(bsLine)
df = df.fillna(-1)
buy_count = 0
if bsLine is not None:
buy_count = len(df.loc[df["buy_price"] > 0])
fig.update_layout(height=1400,
title="{}, buy: {}".format(stock_code, buy_count),
xaxis_rangeslider_visible=False,
xaxis2_rangeslider_visible=False,
xaxis3_rangeslider_visible=False,
xaxis4_rangeslider_visible=False
)
# 화면으로 출력함
return fig
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 writeSummary(self, param):
bull = list(param['bull'])
bear = list(param['bear'])
even = list(param['even'])
ymd = [i for i in range(len(bull))]
bull_line = go.Scatter(x=ymd, y=bull, name="bull", line_color='#FF33A2')
bear_line = go.Scatter(x=ymd, y=bear, name="bear", line_color='#1469F4')
even_line = go.Scatter(x=ymd, y=even, name="even", line_color='#8B4513')
line_data = [bull_line, bear_line, even_line]
fig = subplots.make_subplots(
rows=1, cols=1,
subplot_titles=("주식 상황"),
shared_xaxes=True, horizontal_spacing=0.03, vertical_spacing=0.01,
row_heights=[800]
)
for trace in line_data:
fig.append_trace(trace, 1, 1)
fig.update_layout(height=810, xaxis_rangeslider_visible=False)
sum = param['bull'][0] + param['bear'][0] + param['even'][0]
title = "[Summary] bull: %d (%.2f), bear: %d (%.2f), even: %d (%.2f)" % (param['bull'][0], param['bull'][0]/sum, param['bear'][0], param['bear'][0]/sum, param['even'][0], param['even'][0]/sum)
fig['layout'].update(title=title)
fileName = "%s/summary.html" % (self.outPath)
po.write_html(fig, file=fileName, auto_open=False)
return
def writeFile(self, outPath, CODE, NAME, top, stock, bsLine):
# 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
if check:
fig = self.draw(CODE, stock, bsLine)
title = "%s (%s), 차트 (<a href=\"https://alphasquare.co.kr/home/stock/financial-information?code=%s\">URL1</a>, <a href=\"https://www.tradingview.com/chart/jJ8zOXz0/?symbol=KRX:%s\">URL2</a>, <a href=\"https://www.investing.com/search/?q=%s\">URL3</a>)" % (NAME, CODE, CODE, CODE, CODE)
fig['layout'].update(title=title)
fileName = outPath + "/%s_%s_%s_%s.html" % (datetime.today().strftime("%Y%m%d"), top, NAME.replace(" ", ""), CODE)
po.write_html(fig, file=fileName, auto_open=False)
return
def checkVolume(self, p_volume, volume):
if 0 < p_volume <= 10000 and p_volume * 700 < volume:
return True
if 10000 < p_volume <= 50000 and p_volume * 40 < volume:
return True
if 50000 < p_volume <= 100000 and p_volume * 25 < volume:
return True
if 100000 < p_volume <= 200000 and p_volume * 15 < volume:
return True
if 200000 < p_volume <= 700000 and p_volume * 13 < volume:
return True
if 700000 < p_volume <= 1000000 and p_volume * 10 < volume:
return True
if 5000000 < p_volume <= 5000000 and p_volume * 5 < volume:
return True
if 5000000 < p_volume and p_volume * 4 < volume:
return True
return False
def getStockData(self, CODE):
data_daily, ci_daily = self.jSDPattern.getData(CODE, ymd=(datetime.now()+timedelta(days=1)).strftime('%Y%m%d'), get_days=1500)
return data_daily, ci_daily
def makeDir(self, dir_name):
if os.path.isdir(self.outPath + "/" + dir_name):
os.rmdir(self.outPath + "/" + dir_name)
os.mkdir(self.outPath + "/" + dir_name)
return
def checkTransaction(self, ticker, data, ci):
# 어제 오늘 데이터로 분석
bsLine = {}
if data is not None and 'close' in data.columns:
size = len(data["close"])
bsLine['buy_ymd'] = [None for i in range(size)]
bsLine['buy_price'] = [0 for i in range(size)]
bsLine['buy_count'] = [0 for i in range(size)]
bsLine['buy_type'] = ['' for i in range(size)]
bsLine['buy_cut'] = [None for i in range(size)]
bsLine['sell_price'] = [0 for i in range(size)]
bsLine['sell_count'] = [0 for i in range(size)]
bsLine['sell_type'] = ['' for i in range(size)]
bsLine['sell_cut'] = [0 for i in range(size)]
size = ci
start = 0
for i in range(start, size):
# 매도 확인
sell_price, sell_count, sell_type = self.buySell_Daily.getSellPrice(data, i, bsLine)
bsLine['sell_price'][i] = sell_price
bsLine['sell_count'][i] = sell_count
bsLine['sell_type'][i] = sell_type
bsLine['sell_cut'][i] = 0
if sell_price < 1:
buy_ymd, buy_price, buy_count, buy_type, buy_cut = self.buySell_Daily.getBuyPrice(data, i, bsLine)
bsLine['buy_ymd'][i] = buy_ymd
bsLine['buy_price'][i] = buy_price
bsLine['buy_count'][i] = buy_count
bsLine['buy_type'][i] = buy_type
bsLine['buy_cut'][i] = buy_cut
return bsLine
# 후보 찾기
def findCandidates(self, outPath):
buy_stock_list = []
stockTableName = 'stock'
fnguideTableName = 'fnguide'
conn = sqlite3.connect(self.stockFileName)
cursor = conn.cursor()
cursor.execute('SELECT distinct code, name FROM ' + stockTableName + ' order by code')
#cursor.execute('select CODE, NAME, max(ymd) as ymd from ' + fnguideTableName + ' where type != "E" group by 1 order by total_assets desc')
items = cursor.fetchall()
cursor.close()
conn.close()
for idx, item in enumerate(items):
CODE = item[0]
NAME = item[1]
print("#", idx, ", CODE: ", CODE, ", NAME: ", NAME)
CODE = item[0]
stock_daily, ci = self.getStockData(CODE)
bsLine = self.checkTransaction(CODE, stock_daily, ci)
if bsLine['buy_ymd'][ci-1] is not None:
top = "0"
if CODE in self.topCompany:
top = str(self.topCompany[CODE][0])
# 거래량이 10만 이상이고, 종가가 1천원 이상인지 체크 (https://happpy-rich.tistory.com/94)
if stock_daily['volume'][ci-1] > 100000 and stock_daily['close'][ci-1] > 1000:
# 종목 상태 체크 분석
self.writeFile(outPath, CODE, NAME, top, stock_daily, bsLine)
buy_stock_list.append({'CODE': CODE, 'NAME': NAME})
buy_stock_str = ''
for i, item in enumerate(buy_stock_list):
buy_stock_str += str(i + 1) + ". " + item['CODE'] + "(" + item['NAME'] + ")\n"
self.bot.sendMsg("{}".format(buy_stock_str))
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__))))))
RESOURCE_PATH = os.path.join(PROJECT_HOME, 'resources')
analyzerSqlite = AnalyzerSqlite(RESOURCE_PATH)
# HTML 출력
outPath = os.path.join(PROJECT_HOME, "resources", "analysis")
if not os.path.isdir(outPath):
os.mkdir(outPath)
day = datetime.today().strftime("%Y%m%d")
before_7_day = datetime.today() + relativedelta(days=-7)
dayList = os.listdir(outPath)
for dayDir in dayList:
if dayDir[0] != '.' and dayDir < before_7_day.strftime("%Y%m%d"):
if os.path.exists(os.path.join(outPath, dayDir)) and os.path.isdir(os.path.join(outPath, dayDir)):
shutil.rmtree(os.path.join(outPath, dayDir))
outPath = os.path.join(outPath, day)
if os.path.isdir(outPath):
shutil.rmtree(outPath)
os.mkdir(outPath)
print("print to Html...")
analyzerSqlite.findCandidates(outPath)
print("time : %6.2f" % (time.time() - start))
print("done...")