init
This commit is contained in:
@@ -17,6 +17,7 @@ from plotly import subplots
|
||||
import plotly.io as po
|
||||
|
||||
from stock.analysis.Common import Common
|
||||
from stock.analysis.RelativePerformance import RelativePerformance
|
||||
from stock.analysis.Stochastic import Stochastic
|
||||
from stock.analysis.BolingerBand import BolingerBand
|
||||
from stock.analysis.IchimokuCloud import IchimokuCloud
|
||||
@@ -29,6 +30,7 @@ from hts.BuySellChecker import BuySellChecker
|
||||
|
||||
|
||||
class AnalyzerSqlite:
|
||||
relativePerformance = None
|
||||
stochastic = None
|
||||
bolingerBand = None
|
||||
ichimokuCloud = None
|
||||
@@ -50,6 +52,7 @@ class AnalyzerSqlite:
|
||||
def __init__(self, stockFileName=None):
|
||||
self.common = Common()
|
||||
|
||||
self.relativePerformance = RelativePerformance()
|
||||
self.stochastic = Stochastic()
|
||||
self.bolingerBand = BolingerBand()
|
||||
self.ichimokuCloud = IchimokuCloud()
|
||||
@@ -285,6 +288,7 @@ class AnalyzerSqlite:
|
||||
self.makeDir("14", "daily_이격도")
|
||||
self.makeDir("15", "daily_낙폭과대")
|
||||
self.makeDir("16", "daily_EV하단_내려옴")
|
||||
self.makeDir("17", "daily_볼린저하단_내려옴")
|
||||
|
||||
return
|
||||
|
||||
@@ -521,11 +525,12 @@ class AnalyzerSqlite:
|
||||
final_status_count += 1
|
||||
self.writeFile(dir_code, dir_name, CODE, NAME, top, stock_daily, status)
|
||||
|
||||
# 2년 중 최대 거래량인 경우
|
||||
c_index = 520
|
||||
# 52주 200일 기준 평균 + 50% 보다 높은 거래량의 경우
|
||||
c_index = 200
|
||||
if len(stock_daily['volume']) < c_index:
|
||||
c_index = len(stock_daily['volume'])
|
||||
if max(stock_daily['volume'][1:c_index]) < stock_daily['volume'][0]:
|
||||
avg = sum(stock_daily['volume'][1:c_index]) / len(stock_daily['volume'][1:c_index])
|
||||
if avg + avg/2 < stock_daily['volume'][0]:
|
||||
dir_code = "13"
|
||||
dir_name = "daily_이전에_없던_거래량"
|
||||
final_status_count += 1
|
||||
@@ -562,7 +567,7 @@ class AnalyzerSqlite:
|
||||
|
||||
if len(stock_daily['volume']) > 5:
|
||||
if stock_daily['envelope_lower'][0] is not None and stock_daily['envelope_lower'][1] is not None:
|
||||
# BB 하단에 부딪힘
|
||||
# ev 하단에 부딪힘
|
||||
if stock_daily['close'][1] < stock_daily['avg5'][1] and stock_daily['avg5'][0] < stock_daily['close'][0]:
|
||||
check = False
|
||||
for c in range(1, 4):
|
||||
@@ -575,6 +580,21 @@ class AnalyzerSqlite:
|
||||
final_status_count += 1
|
||||
self.writeFile(dir_code, dir_name, CODE, NAME, top, stock_daily, status)
|
||||
|
||||
if len(stock_daily['volume']) > 5:
|
||||
if stock_daily['bolingerband_lower'][0] is not None and stock_daily['bolingerband_lower'][1] is not None:
|
||||
# bb 하단에 부딪힘
|
||||
if stock_daily['close'][1] < stock_daily['avg5'][1] and stock_daily['avg5'][0] < stock_daily['close'][0]:
|
||||
check = False
|
||||
for c in range(1, 4):
|
||||
if stock_daily['close'][c] < stock_daily['bolingerband_lower'][c]:
|
||||
check = True
|
||||
break
|
||||
if check:
|
||||
dir_code = "17"
|
||||
dir_name = "daily_EV하단_내려옴"
|
||||
final_status_count += 1
|
||||
self.writeFile(dir_code, dir_name, CODE, NAME, top, stock_daily, status)
|
||||
|
||||
if final_status_count >= 5:
|
||||
dir_code = "0"
|
||||
dir_name = "final"
|
||||
@@ -705,7 +725,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, 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, disparity_avg5 REAL, disparity_avg10 REAL, disparity_avg20 REAL, disparity_avg60 REAL, disparity_avg120, bolingerband_upper REAL, bolingerband_lower REAL, bolingerband_middle REAL, envelope_upper REAL, envelope_lower REAL, envelope_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, macd REAL, macds REAL, macdo 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, disparity_avg5 REAL, disparity_avg10 REAL, disparity_avg20 REAL, disparity_avg60 REAL, disparity_avg120, bolingerband_upper REAL, bolingerband_lower REAL, bolingerband_middle REAL, envelope_upper REAL, envelope_lower REAL, envelope_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, macd REAL, macds REAL, macdo REAL, rp REAL)")
|
||||
|
||||
# 키 생성
|
||||
create_key = "CREATE INDEX IF NOT EXISTS " + stockAnalysisTableName + "_idx on " + stockAnalysisTableName + " (CODE, ymd) "
|
||||
@@ -779,29 +799,8 @@ class AnalyzerSqlite:
|
||||
cursor.execute("commit",)
|
||||
return
|
||||
|
||||
def analyzeDaily(self):
|
||||
stockTableName = 'stock'
|
||||
|
||||
conn = sqlite3.connect(self.stockFileName)
|
||||
cursor = conn.cursor()
|
||||
|
||||
cursor.execute('SELECT distinct code, name FROM ' + stockTableName + ' order by code')
|
||||
items = cursor.fetchall()
|
||||
|
||||
for rowid, item in enumerate(items):
|
||||
|
||||
stock = {"CODE": item[0], "NAME": item[1], "PRICE":[]}
|
||||
print("Daily # :", rowid, ", CODE: ", stock['CODE'], ", NAME: ", stock['NAME'])
|
||||
|
||||
sql = 'SELECT ymd, close, diff, open, high, low, volume FROM ' + stockTableName + ' where CODE=? order by ymd desc '
|
||||
sql += ' limit 350'
|
||||
cursor.execute(sql, (stock['CODE'],))
|
||||
items = cursor.fetchall()
|
||||
|
||||
items_reverse = reversed(items)
|
||||
for item in items_reverse:
|
||||
stock['PRICE'].append(
|
||||
{
|
||||
def setItem(self, item):
|
||||
return {
|
||||
"ymd": item[0],
|
||||
"close": item[1],
|
||||
"diff": item[2],
|
||||
@@ -847,7 +846,32 @@ class AnalyzerSqlite:
|
||||
"macd": -1,
|
||||
"macds": -1,
|
||||
"macdo": -1,
|
||||
"rp": -1
|
||||
}
|
||||
|
||||
def analyzeDaily(self):
|
||||
stockTableName = 'stock'
|
||||
|
||||
conn = sqlite3.connect(self.stockFileName)
|
||||
cursor = conn.cursor()
|
||||
|
||||
cursor.execute('SELECT distinct code, name FROM ' + stockTableName + ' order by code')
|
||||
items = cursor.fetchall()
|
||||
|
||||
for rowid, item in enumerate(items):
|
||||
|
||||
stock = {"CODE": item[0], "NAME": item[1], "PRICE":[]}
|
||||
print("Daily # :", rowid, ", CODE: ", stock['CODE'], ", NAME: ", stock['NAME'])
|
||||
|
||||
sql = 'SELECT ymd, close, diff, open, high, low, volume FROM ' + stockTableName + ' where CODE=? order by ymd desc '
|
||||
sql += ' limit 350'
|
||||
cursor.execute(sql, (stock['CODE'],))
|
||||
items = cursor.fetchall()
|
||||
|
||||
items_reverse = reversed(items)
|
||||
for item in items_reverse:
|
||||
stock['PRICE'].append(
|
||||
self.setItem(item)
|
||||
)
|
||||
|
||||
self.analyzeAdditionalInfo(stock, cursor)
|
||||
@@ -880,53 +904,7 @@ class AnalyzerSqlite:
|
||||
items_reverse = reversed(items)
|
||||
for item in items_reverse:
|
||||
stock['PRICE'].append(
|
||||
{
|
||||
"ymd": item[0],
|
||||
"close": item[1],
|
||||
"diff": item[2],
|
||||
"open": item[3],
|
||||
"high": item[4],
|
||||
"low": item[5],
|
||||
"volume": item[6],
|
||||
"avg3": -1,
|
||||
"avg4": -1,
|
||||
"avg5": -1,
|
||||
"avg6": -1,
|
||||
"avg10": -1,
|
||||
"avg12": -1,
|
||||
"avg20": -1,
|
||||
"avg36": -1,
|
||||
"avg40": -1,
|
||||
"avg48": -1,
|
||||
"avg60": -1,
|
||||
"avg120": -1,
|
||||
"avg200": -1,
|
||||
"avg240": -1,
|
||||
"avg300": -1,
|
||||
"disparity_avg5": -1,
|
||||
"disparity_avg10": -1,
|
||||
"disparity_avg20": -1,
|
||||
"disparity_avg60": -1,
|
||||
"disparity_avg120": -1,
|
||||
"bolingerband_upper": -1,
|
||||
"bolingerband_lower": -1,
|
||||
"bolingerband_middle": -1,
|
||||
"envelope_upper": -1,
|
||||
"envelope_lower": -1,
|
||||
"envelope_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,
|
||||
"rsi": -1,
|
||||
"rsis": -1,
|
||||
"macd": -1,
|
||||
"macds": -1,
|
||||
"macdo": -1
|
||||
}
|
||||
self.setItem(item)
|
||||
)
|
||||
|
||||
agg_dict = {'open': 'first',
|
||||
@@ -957,6 +935,60 @@ class AnalyzerSqlite:
|
||||
return
|
||||
|
||||
|
||||
def analyzeRP (self):
|
||||
|
||||
type = {200:None, 52: "weekly", 12: "monthly"}
|
||||
limits = [200, 52, 12]
|
||||
|
||||
for limit in limits:
|
||||
if type[limit]==None:
|
||||
stockAnalysisTableName = 'stock_analysis'
|
||||
else:
|
||||
stockAnalysisTableName = 'stock_analysis_' + type[limit]
|
||||
|
||||
conn = sqlite3.connect(self.stockFileName)
|
||||
cursor = conn.cursor()
|
||||
|
||||
# S: Kospi 구하기 (RP 계산을 위함)
|
||||
kospi = {"CODE": "^KS11", "NAME": "Kospi", "PRICE": []}
|
||||
sql = "SELECT CODE, NAME, ymd, close, diff, open, high, low, volume, avg200 FROM " + stockAnalysisTableName + " where CODE=? order by ymd desc "
|
||||
sql += ' limit ' + str(limit)
|
||||
cursor.execute(sql, (kospi['CODE'],))
|
||||
items = cursor.fetchall()
|
||||
|
||||
items_reverse = reversed(items)
|
||||
for item in items_reverse:
|
||||
kospi['PRICE'].append(self.setItem(item))
|
||||
# E: Kospi 구하기 (RP 계산을 위함)
|
||||
|
||||
# S: 종목 구하기
|
||||
cursor.execute('SELECT distinct code, name FROM ' + stockAnalysisTableName + ' order by code')
|
||||
items = cursor.fetchall()
|
||||
|
||||
for rowid, item in enumerate(items):
|
||||
|
||||
stock = {"CODE": item[0], "NAME": item[1], "PRICE": []}
|
||||
print("Daily # :", rowid, ", CODE: ", stock['CODE'], ", NAME: ", stock['NAME'])
|
||||
|
||||
sql = "SELECT CODE, NAME, ymd, close, diff, open, high, low, volume, avg200 FROM " + stockAnalysisTableName + " where CODE=? order by ymd desc "
|
||||
sql += ' limit ' + str(limit)
|
||||
cursor.execute(sql, (stock['CODE'],))
|
||||
items = cursor.fetchall()
|
||||
|
||||
items_reverse = reversed(items)
|
||||
for item in items_reverse:
|
||||
stock['PRICE'].append(self.setItem(item))
|
||||
|
||||
self.relativePerformance.analyze(stock, kospi)
|
||||
|
||||
sql = "UPDATE " + stockAnalysisTableName + " SET rp=? WHERE CODE=? and ymd=?"
|
||||
|
||||
cursor.execute(sql, (price['rp'], stock["CODE"], price['ymd'],))
|
||||
|
||||
cursor.execute("commit",)
|
||||
|
||||
return
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
start = time.time()
|
||||
@@ -966,11 +998,11 @@ if __name__ == "__main__":
|
||||
stockFileName = os.path.join(RESOURCE_PATH, 'stock.db')
|
||||
analyzer = AnalyzerSqlite(stockFileName)
|
||||
|
||||
"""
|
||||
analyzer.analyzeDaily()
|
||||
analyzer.analyzeGrouping("weekly")
|
||||
analyzer.analyzeGrouping("monthly")
|
||||
"""
|
||||
#analyzer.analyzeDaily()
|
||||
#analyzer.analyzeGrouping("weekly")
|
||||
#analyzer.analyzeGrouping("monthly")
|
||||
|
||||
#analyzer.analyzeRP()
|
||||
|
||||
# HTML 출력
|
||||
outPath = os.path.join(PROJECT_HOME, "resources", "analysis")
|
||||
|
||||
@@ -12,7 +12,7 @@ class BolingerBand:
|
||||
self.common = Common()
|
||||
return
|
||||
|
||||
def apply(self, df, n=13, t=2):
|
||||
def apply(self, df, n=25, t=2):
|
||||
# 입력받은 값이 dataframe이라는 것을 정의해줌
|
||||
df = pd.DataFrame(df)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user