diff --git a/Simulation.py b/Simulation.py index 0e27786..ab8175f 100644 --- a/Simulation.py +++ b/Simulation.py @@ -97,6 +97,12 @@ class Simulation (HTS): volume_line = go.Scatter(x=data['date'], y=data["volume"], mode='lines', name='volume') #fast_k_line = go.Scatter(x=hts['date'], y=hts["fast_k"], mode='lines', name='fast_k') + disparity_avg5 = go.Scatter(x=data['date'], y=data["disparity_avg5"], name="disparity_avg5", line_color='#8F8203') + disparity_avg10 = go.Scatter(x=data['date'], y=data["disparity_avg10"], name="disparity_avg10", line_color='#089B5B') + disparity_avg20 = go.Scatter(x=data['date'], y=data["disparity_avg20"], name="disparity_avg20", line_color='#ff00ff') + disparity_avg60 = go.Scatter(x=data['date'], y=data["disparity_avg60"], name="disparity_avg60", line_color='#1469F4') + disparity_avg120 = go.Scatter(x=data['date'], y=data["disparity_avg120"], name="disparity_avg120", line_color='#000000') + macd_line = go.Scatter(x=data['date'], y=data["macd"], mode='lines', name='macd') macd_s_line = go.Scatter(x=data['date'], y=data["macds"], mode='lines', name='macds') macd_o_line = go.Scatter(x=data['date'], y=data["macdo"], mode='lines', name='macdo') @@ -109,6 +115,7 @@ class Simulation (HTS): candle_data = [candle_stick, upper, lower, avg3, avg6, avg9, avg12, avg20, buy_check, sell_check, laggingSpan, changeLine, baseLine] volume_data = [volume_line] + disparity_data = [disparity_avg5, disparity_avg10, disparity_avg20, disparity_avg60, disparity_avg120] macd_data = [macd_line, macd_s_line, macd_o_line] stochastic_data = [slow_k_line, slow_d_line] rsi_data = [rsi_line, rsis_line] @@ -120,17 +127,21 @@ class Simulation (HTS): fig.show() """ - fig = subplots.make_subplots(rows=5, cols=1, subplot_titles=('캔들', "거래량", "MACD", "스토캐스틱", "RSI")) + fig = subplots.make_subplots(rows=6, cols=1, + subplot_titles=('캔들', "거래량", "이격도", "MACD", "스토캐스틱", "RSI"), + row_heights=[1200, 500, 500, 500, 500, 500]) 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 macd_data: + for trace in disparity_data: fig.append_trace(trace, 3, 1) - for trace in stochastic_data: + for trace in macd_data: fig.append_trace(trace, 4, 1) - for trace in rsi_data: + for trace in stochastic_data: fig.append_trace(trace, 5, 1) + for trace in rsi_data: + fig.append_trace(trace, 6, 1) #fig.update_xaxes(nticks=5) #fig.update_layout(height=1800, title=stock_code + "_" + given_day, xaxis_rangeslider_visible=False) diff --git a/stock/analysis/AnalyzerSqlite.py b/stock/analysis/AnalyzerSqlite.py index eeb0d3a..3acaae7 100644 --- a/stock/analysis/AnalyzerSqlite.py +++ b/stock/analysis/AnalyzerSqlite.py @@ -21,6 +21,7 @@ from stock.analysis.Stochastic import Stochastic from stock.analysis.BolingerBand import BolingerBand from stock.analysis.IchimokuCloud import IchimokuCloud from stock.analysis.RSI import RSI +from stock.analysis.MACD import MACD from stock.crawler.MovingAverage import MovingAverage class AnalyzerSqlite: @@ -30,6 +31,7 @@ class AnalyzerSqlite: bolingerBand = None ichimokuCloud = None rsi = None + macd = None topCompany = None fnguide = None @@ -50,6 +52,7 @@ class AnalyzerSqlite: self.bolingerBand = BolingerBand() self.ichimokuCloud = IchimokuCloud() self.rsi = RSI() + self.macd = MACD() self.topCompany = self.getTopCompany(stockFileName, 2000) self.fnguide = self.readFnguide(stockFileName) @@ -132,6 +135,14 @@ class AnalyzerSqlite: avg120 = list(reversed(stock['avg120'])) avg240 = list(reversed(stock['avg240'])) avg300 = list(reversed(stock['avg300'])) + disparity_avg5 = list(reversed(stock['disparity_avg5'])) + disparity_avg10 = list(reversed(stock['disparity_avg10'])) + disparity_avg20 = list(reversed(stock['disparity_avg20'])) + disparity_avg60 = list(reversed(stock['disparity_avg60'])) + disparity_avg120 = list(reversed(stock['disparity_avg120'])) + macd = list(reversed(stock['macd'])) + macdo = list(reversed(stock['macdo'])) + macds = list(reversed(stock['macds'])) rsi = list(reversed(stock['rsi'])) rsis = list(reversed(stock['rsis'])) stochastic_slow_k = list(reversed(stock['stochastic_slow_k'])) @@ -168,6 +179,19 @@ class AnalyzerSqlite: volume = go.Bar(x=ymd, y=volume, name="volume") volume_data = [volume] + disparity_avg5 = go.Scatter(x=ymd, y=disparity_avg5, name="disparity_avg5", line_color='#8F8203') + disparity_avg10 = go.Scatter(x=ymd, y=disparity_avg10, name="disparity_avg10", line_color='#089B5B') + disparity_avg20 = go.Scatter(x=ymd, y=disparity_avg20, name="disparity_avg20", line_color='#ff00ff') + disparity_avg60 = go.Scatter(x=ymd, y=disparity_avg60, name="disparity_avg60", line_color='#1469F4') + disparity_avg120 = go.Scatter(x=ymd, y=disparity_avg120, name="disparity_avg120", line_color='#000000') + disparity_data = [disparity_avg5, disparity_avg10, disparity_avg20, disparity_avg60, disparity_avg120] + + # macd + macd_line = go.Scatter(x=ymd, y=macd, mode='lines', name='macd') + macd_s_line = go.Scatter(x=ymd, y=macds, mode='lines', name='macds') + macd_o_line = go.Scatter(x=ymd, y=macdo, mode='lines', name='macdo') + macd_data = [macd_line, macd_s_line, macd_o_line] + # stochastic rsi = go.Scatter(x=ymd, y=rsi, name="rsi", line_color='#8B4513') rsis = go.Scatter(x=ymd, y=rsis, name="rsis", line_color='#4169E1') @@ -178,18 +202,21 @@ class AnalyzerSqlite: 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=4, cols=1, - subplot_titles=('차트', '거래량', 'rsi', 'Stochastic'), - row_heights=[1200, 500, 500, 500]) - + fig = subplots.make_subplots(rows=6, cols=1, + subplot_titles=('캔들', "거래량", "이격도", "MACD", "스토캐스틱", "RSI"), + row_heights=[1200, 500, 500, 500, 500, 500]) 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 rsi_data: + for trace in disparity_data: fig.append_trace(trace, 3, 1) - for trace in stochastic_data: + for trace in macd_data: fig.append_trace(trace, 4, 1) + for trace in stochastic_data: + fig.append_trace(trace, 5, 1) + for trace in rsi_data: + fig.append_trace(trace, 6, 1) fig.update_layout(height=2200, xaxis_rangeslider_visible=False) @@ -305,11 +332,13 @@ class AnalyzerSqlite: sql = 'SELECT ymd, close, open, high, low, volume, ' sql += ' avg3, avg4, avg5, avg6, avg10, avg12, avg20, avg36, avg40, avg48, avg60, avg120, avg200, avg240, avg300, ' + sql += ' disparity_avg5, disparity_avg10, disparity_avg20, disparity_avg60, disparity_avg120, ' 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 += ' rsi, rsis ' - sql += ' FROM ' + TableName + ' where CODE=? order by ymd desc limit 512' + sql += ' rsi, rsis, ' + sql += ' macd, macds, macdo ' + sql += ' FROM ' + TableName + ' where CODE=? order by ymd desc limit 512 ' cursor.execute(sql, (CODE,)) prices = cursor.fetchall() @@ -319,10 +348,12 @@ class AnalyzerSqlite: ymd = [] close, open, high, low, volume = [], [], [], [], [] avg3, avg4, avg5, avg6, avg10, avg12, avg20, avg36, avg40, avg48, avg60, avg120, avg200, avg240, avg300 = [], [], [], [], [], [], [], [], [], [], [], [], [], [], [] + disparity_avg5, disparity_avg10, disparity_avg20, disparity_avg60, disparity_avg120 = [], [], [], [], [] bolingerband_upper, bolingerband_lower, bolingerband_middle = [], [], [] ichimokucloud_changeLine, ichimokucloud_baseLine, ichimokucloud_leadingSpan1, ichimokucloud_leadingSpan2 = [], [], [], [] stochastic_fast_k, stochastic_slow_k, stochastic_slow_d = [], [], [] rsi, rsis = [], [] + macd, macds, macdo = [], [], [] for price in prices: ymd.append(price[0]) @@ -346,31 +377,40 @@ class AnalyzerSqlite: avg200.append(price[18]) avg240.append(price[19]) avg300.append(price[20]) - bolingerband_upper.append(price[21]) - bolingerband_lower.append(price[22]) - bolingerband_middle.append(price[23]) - ichimokucloud_changeLine.append(price[24]) - ichimokucloud_baseLine.append(price[25]) - ichimokucloud_leadingSpan1.append(price[26]) - ichimokucloud_leadingSpan2.append(price[27]) - stochastic_fast_k.append(price[28]) - stochastic_slow_k.append(price[29]) - stochastic_slow_d.append(price[30]) - rsi.append(price[31]) - rsis.append(price[32]) + disparity_avg5.append(price[21]) + disparity_avg10.append(price[22]) + disparity_avg20.append(price[23]) + disparity_avg60.append(price[24]) + disparity_avg120.append(price[25]) + bolingerband_upper.append(price[26]) + bolingerband_lower.append(price[27]) + bolingerband_middle.append(price[28]) + ichimokucloud_changeLine.append(price[29]) + ichimokucloud_baseLine.append(price[30]) + ichimokucloud_leadingSpan1.append(price[31]) + ichimokucloud_leadingSpan2.append(price[32]) + stochastic_fast_k.append(price[33]) + stochastic_slow_k.append(price[34]) + stochastic_slow_d.append(price[35]) + rsi.append(price[36]) + rsis.append(price[37]) + macd.append(price[38]) + macds.append(price[39]) + macdo.append(price[40]) stock = { "ymd": ymd, "close": close, "open": open, "high": high, "low": low, "volume": volume, - "avg3": avg3, "avg4": avg4, "avg5": avg5, "avg6": avg6, "avg10": avg10, "avg12": avg12, "avg20": avg20, "avg36": avg36, "avg40": avg40, "avg48": avg48, "avg60": avg60, "avg120": avg120, "avg200": avg200, "avg300": avg300, - "avg240": avg240, + "avg3": avg3, "avg4": avg4, "avg5": avg5, "avg6": avg6, "avg10": avg10, "avg12": avg12, "avg20": avg20, "avg36": avg36, "avg40": avg40, "avg48": avg48, "avg60": avg60, "avg120": avg120, "avg200": avg200, "avg240": avg240, "avg300": avg300, + "disparity_avg5": disparity_avg5, "disparity_avg10": disparity_avg10, "disparity_avg20": disparity_avg20, "disparity_avg60": disparity_avg60, "disparity_avg120": disparity_avg120, "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, - "rsi": rsi, "rsis": rsis + "rsi": rsi, "rsis": rsis, + "macd": macd, "macds": macds, "macdo": macdo } return stock @@ -744,6 +784,7 @@ class AnalyzerSqlite: self.stochastic.analyze(stock) self.bolingerBand.analyze(stock) self.rsi.analyze(stock) + self.macd.analyze(stock) sorted_stock = sorted(stock["PRICE"], key=lambda x: x['ymd'], reverse=True) for price in sorted_stock: @@ -756,8 +797,8 @@ class AnalyzerSqlite: 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 += " rsi, rsis) " - sql += " VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)" + sql += " rsi, rsis, macd, macds, macdo) " + sql += " VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)" cursor.execute(sql, ( stock["CODE"], stock["NAME"], price['ymd'], price['close'], price['diff'], price['open'], price['high'], price['low'], price['volume'], @@ -767,7 +808,7 @@ class AnalyzerSqlite: price['ichimokucloud_changeLine'], price['ichimokucloud_baseLine'], price['ichimokucloud_leadingSpan1'], price['ichimokucloud_leadingSpan2'], price['stochastic_fast_k'], price['stochastic_slow_k'], price['stochastic_slow_d'], - price['rsi'], price['rsis'],)) + price['rsi'], price['rsis'], price['macd'], price['macds'], price['macdo'],)) else: sql = "UPDATE " + stockAnalysisTableName + " SET close=?, diff=?, open=?, high=?, low=?, volume=?, " @@ -777,6 +818,7 @@ class AnalyzerSqlite: sql += " ichimokucloud_changeLine=?, ichimokucloud_baseLine=?, ichimokucloud_leadingSpan1=?, ichimokucloud_leadingSpan2=?, " sql += " stochastic_fast_k=?, stochastic_slow_k=?, stochastic_slow_d=?, " sql += " rsi=?, rsis=? " + sql += " macd=?, macds=?, macdo=? " sql += " WHERE CODE=? and ymd=?" cursor.execute(sql, @@ -787,6 +829,7 @@ class AnalyzerSqlite: price['ichimokucloud_leadingSpan1'], price['ichimokucloud_leadingSpan2'], price['stochastic_fast_k'], price['stochastic_slow_k'], price['stochastic_slow_d'], price['rsi'], price['rsis'], + price['macd'], price['macds'], price['macdo'], stock["CODE"], price['ymd'],)) break @@ -960,9 +1003,9 @@ if __name__ == "__main__": stockFileName = PROJECT_HOME + '/resources/stock.db' analyzer = AnalyzerSqlite(PROJECT_HOME, stockFileName) - analyzer.analyzeDaily() - analyzer.analyzeGrouping("weekly") - analyzer.analyzeGrouping("monthly") + #analyzer.analyzeDaily() + #analyzer.analyzeGrouping("weekly") + #analyzer.analyzeGrouping("monthly") # HTML 출력 outPath = os.path.join(PROJECT_HOME, "resources", "analysis")