This commit is contained in:
dosangyoon
2022-07-03 03:28:28 +09:00
parent 7ac901dbdb
commit f5f4d64058

View File

@@ -29,7 +29,7 @@ class AnalyzerSqlite:
bolingerBand = None
ichimokuCloud = None
top500 = None
topCompany = None
fnguide = None
common = None
@@ -48,26 +48,26 @@ class AnalyzerSqlite:
self.bolingerBand = BolingerBand()
self.ichimokuCloud = IchimokuCloud()
self.top500 = self.getTop500(stockFileName)
self.topCompany = self.getTopCompany(stockFileName, 2000)
self.fnguide = self.readFnguide(stockFileName)
return
def getTop500(self, fnguideFileName):
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 500"
sql = "select DISTINCT CODE, NAME from fnguide order by total_ownership_interest desc limit " + str(top)
cursor.execute(sql)
result = cursor.fetchall()
top500 = {}
top_company = {}
for idx, item in enumerate(result):
top500[item[0]] = (idx+1, item[1])
top_company[item[0]] = (idx+1, item[1])
cursor.close()
conn.close()
return top500
return top_company
def readFnguide(self, fnguideFileName):
conn = sqlite3.connect(fnguideFileName)
@@ -163,204 +163,6 @@ class AnalyzerSqlite:
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)일 중 가장 찾은 금액과 가장 높았던 금액 중 현재가의 위치 계산
@@ -396,39 +198,7 @@ class AnalyzerSqlite:
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_기준선 위 120일선 올라옴")
self.makeDir("참고_1_기준선 위 200일선 올라옴")
self.makeDir("참고_1_기준선 위 240일선 올라옴")
self.makeDir("참고_1_240일선 돌파")
self.makeDir("참고_1_200일선 돌파")
self.makeDir("참고_1_20일선 돌파")
self.makeDir("참고_1_60일선 돌파")
self.makeDir("참고_1_GoldenCross")
self.makeDir("참고_1_모든 라인 돌파")
self.makeDir("1_캔들_전환선_위로_올라옴")
self.makeDir("2_캔들_기준선_위로_올라옴")
self.makeDir("3_후행스팬_캔들_위로_올라옴")
self.makeDir("-1_캔들_전환선_아래로_내려옴")
self.makeDir("-2_캔들_기준선_아래로_내려옴")
self.makeDir("-3_후행스팬_캔들_아래로_내려옴")
self.makeDir("1_거래량_상승")
self.makeDir("1_코로나_근접")
self.makeDir("4_정배열")
self.makeDir("5_거래량 7배 이상_120일선_위_기준선")
self.makeDir("6_거래량 7배 이상_20일선_위_기준선")
self.makeDir("7_bolingerband 하단 돌파 상승")
self.makeDir("8_정배열_볼린저밴드 하단 돌파 매수")
self.makeDir("9_완전 정배열_볼린저밴드 하단 돌파 매수")
self.makeDir("9_bolingerband 하단 근접 매수")
self.makeDir("-9_bolingerband 상단 근접 매도")
self.makeDir("20주선_40주선_상향돌파")
return
@@ -473,12 +243,80 @@ class AnalyzerSqlite:
return True
return False
def getStockData(self, TableName, CODE):
conn = sqlite3.connect(self.stockFileName)
cursor = conn.cursor()
sql = 'SELECT ymd, close, open, high, low, volume, '
sql += ' avg5, avg10, avg20, avg40, avg60, avg120, avg200, avg240, avg300, '
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 ' + TableName + ' where CODE=? order by ymd desc limit 512'
cursor.execute(sql, (CODE,))
prices = cursor.fetchall()
cursor.close()
conn.close()
ymd = []
close, open, high, low, volume = [], [], [], [], []
avg5, avg10, avg20, avg40, avg60, avg120, avg200, avg240, avg300 = [], [], [], [], [], [], [], [], []
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])
close.append(price[1])
open.append(price[2])
high.append(price[3])
low.append(price[4])
volume.append(price[5])
avg5.append(price[6])
avg10.append(price[7])
avg20.append(price[8])
avg40.append(price[9])
avg60.append(price[10])
avg120.append(price[11])
avg200.append(price[12])
avg240.append(price[13])
avg300.append(price[14])
bolingerband_upper.append(price[15])
bolingerband_lower.append(price[16])
bolingerband_middle.append(price[17])
ichimokucloud_changeLine.append(price[18])
ichimokucloud_baseLine.append(price[19])
ichimokucloud_leadingSpan1.append(price[20])
ichimokucloud_leadingSpan2.append(price[21])
stochastic_fast_k.append(price[22])
stochastic_slow_k.append(price[23])
stochastic_slow_d.append(price[24])
stock = {
"ymd": ymd,
"close": close, "open": open, "high": high, "low": low, "volume": volume,
"avg5": avg5, "avg10": avg10, "avg20": avg20, "avg40": avg40, "avg60": avg60, "avg120": avg120, "avg200": avg200, "avg300": avg300,
"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
}
return stock
# 후보 찾기
def findCandidate(self, outPath):
self.makeDirectory(outPath)
stockTableName = 'stock'
stockAnalysisTableName = 'stock_analysis'
stockAnalysisWeeklyTableName = 'stock_analysis_weekly'
stockAnalysisMonthlyTableName = 'stock_analysis_monthly'
conn = sqlite3.connect(self.stockFileName)
cursor = conn.cursor()
@@ -496,275 +334,27 @@ class AnalyzerSqlite:
print("Analysis # :", idx, ", CODE: ", CODE, ", NAME: ", NAME)
top = "0"
if CODE in self.top500:
top = str(self.top500[CODE][0])
if CODE in self.topCompany:
top = str(self.topCompany[CODE][0])
conn = sqlite3.connect(self.stockFileName)
cursor = conn.cursor()
stock_daily = self.getStockData(stockAnalysisTableName, CODE)
stock_weekly = self.getStockData(stockAnalysisWeeklyTableName, CODE)
stock_monthly = self.getStockData(stockAnalysisMonthlyTableName, CODE)
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])
covid_low_ymd_index = 0
for i in ymd_:
if i == '2020.03.19':
break
covid_low_ymd_index += 1
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:
# 거래량이 100만 이상이고, 종가가 1천원 이상인지 체크 (https://happpy-rich.tistory.com/94)
if stock_weekly['volume'][0] > 100000 and stock_weekly['close'][0] > 1000:
# 종목 상태 체크 분석
state = self.analyzeFinalScore(stock)
status = ""
# 0_스토케스틱이 10 미만
if len(close) > 5 and stochastic_score is not None and stochastic_score < 10:
type = "참고_0_스토케스틱이 10 미만"
self.writeFile(type, CODE, NAME, top, stock, state)
# 0_bolingerband 하단
if len(close) > 60:
if bolingerband_lower[0] is not None and close[0] < bolingerband_lower[0]:
type = "참고_0_bolingerband 하단"
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, 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, top, stock, state)
# 0_종가가 240일선 아래라면 매수한다.
if close[0] < avg240[0]:
type = "참고_0_240일선 아래"
self.writeFile(type, CODE, NAME, top, stock, state)
# 1_기준선 위 전환선 올라옴
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
ichimokucloud_changeLine[3] <= ichimokucloud_baseLine[3] and
ichimokucloud_changeLine[4] <= ichimokucloud_baseLine[4]) and
volume[0] > volume[1]):
type = "참고_1_기준선 위 전환선 올라옴"
self.writeFile(type, CODE, NAME, top, stock, state)
# "1_기준선 위 120일선 올라옴"
if len(close) > 50:
if ((avg120[0] > ichimokucloud_baseLine[0] and
avg120[1] <= ichimokucloud_baseLine[1] and
avg120[2] <= ichimokucloud_baseLine[2] and
avg120[3] <= ichimokucloud_baseLine[3] and
avg120[4] <= ichimokucloud_baseLine[4]) and
volume[0] > volume[1]):
type = "참고_1_기준선 위 120일선 올라옴"
self.writeFile(type, CODE, NAME, top, stock, state)
# "1_기준선 위 200일선 올라옴"
if len(close) > 50:
if ((avg200[0] > ichimokucloud_baseLine[0] and
avg200[1] <= ichimokucloud_baseLine[1] and
avg200[2] <= ichimokucloud_baseLine[2] and
avg200[3] <= ichimokucloud_baseLine[3] and
avg200[4] <= ichimokucloud_baseLine[4]) and
volume[0] > volume[1]):
type = "참고_1_기준선 위 200일선 올라옴"
self.writeFile(type, CODE, NAME, top, stock, state)
# "1_기준선 위 240일선 올라옴"
if len(close) > 50:
if ((avg240[0] > ichimokucloud_baseLine[0] and
avg240[1] <= ichimokucloud_baseLine[1] and
avg240[2] <= ichimokucloud_baseLine[2] and
avg240[3] <= ichimokucloud_baseLine[3] and
avg240[4] <= ichimokucloud_baseLine[4]) and
volume[0] > volume[1]):
type = "참고_1_기준선 위 240일선 올라옴"
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, 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, top, stock, state)
# 1_20일선 돌파
temp_status = self.common.check_Dolpa_Jiji(stock, '20')
# 정배열 체크
temp_status = self.common.check_RightArrange(stock_weekly)
if temp_status != "":
type = "참고_1_20일선 돌파"
self.writeFile(type, CODE, NAME, top, stock, state)
status += temp_status
# 1_60일선 돌파
temp_status = self.common.check_Dolpa_Jiji(stock, '60')
if temp_status != "":
type = "참고_1_60일선 돌파"
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, 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, top, stock, state)
### 코스피 지수 기준 숏 전략:
# 캔들이 전환선 붕괴시키면 1을 매수한다.
# 기준선 붕괴하면 3을 매수한다.
# 후행스팬 캔들 밑으로 내려오면 1씩 매수한다.
### 매도전략:
# 캔들이 전환선 올라오면 1을 매도한다.
# 기준선 올라타면 3을 매도한다.
# 후행스팬 캔들 위로 올라오면 매도한다.
if (len(close) > 50 and close[1] < ichimokucloud_changeLine[1] and ichimokucloud_changeLine[0] < close[0]):
type = "1_캔들_전환선_위로_올라옴"
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, top, stock, state)
if (len(close) > 50 and close[0] < close[26] and close[25] < close[0]):
type = "3_후행스팬_캔들_위로_올라옴"
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, 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, top, stock, state)
if (len(close) > 50 and close[0] > close[26] and close[25] > close[0]):
type = "-3_후행스팬_캔들_아래로_내려옴"
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, 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, top, stock, state)
right_arrange = self.common.check_RightArrange(stock)
if right_arrange != "":
type = "4_정배열"
self.writeFile(type, CODE, NAME, top, stock, state)
if len(volume)>2:
if volume[0] > volume[1]*7:
if ichimokucloud_baseLine[0] is not None and avg120[0] < ichimokucloud_baseLine[0]:
type = "5_거래량 7배 이상_120일선_위_기준선"
self.writeFile(type, CODE, NAME, top, stock, state)
if len(volume)>2:
if volume[0] > volume[1]*7:
if ichimokucloud_baseLine[0] is not None and avg20[0] < ichimokucloud_baseLine[0]:
type = "6_거래량 7배 이상_20일선_위_기준선"
self.writeFile(type, CODE, NAME, top, stock, state)
if len(close) > 60:
if ((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 = "7_bolingerband 하단 돌파 상승"
self.writeFile(type, CODE, NAME, top, stock, state)
if len(close) > 60:
if avg5[0]<avg20[0]<avg60[0]:
if open[0] <= bolingerband_lower[0] and close[0] > bolingerband_lower[0]:
type = "8_정배열_볼린저밴드 하단 돌파 매수"
self.writeFile(type, CODE, NAME, top, stock, state)
if len(close) > 60:
if avg5[0]<avg20[0]<avg60[0]<avg120[0]<avg240[0]:
if open[0] <= bolingerband_lower[0] and close[0] > bolingerband_lower[0]:
type = "9_완전 정배열_볼린저밴드 하단 돌파 매수"
self.writeFile(type, CODE, NAME, top, stock, state)
if len(close) > 60:
if bolingerband_lower[0] is not None and close[0] <= bolingerband_lower[0]:
type = "9_bolingerband 하단 근접 매수"
self.writeFile(type, CODE, NAME, top, stock, state)
if len(close) > 60:
if bolingerband_upper[0] is not None and close[0] >= bolingerband_upper[0]:
type = "-9_bolingerband 상단 근접 매도"
self.writeFile(type, CODE, NAME, top, stock, state)
if len(stock_weekly['close']) > 40:
if stock_weekly['avg20'][1] <= stock_weekly['avg40'][1] and stock_weekly['avg20'][0] > stock_weekly['avg40'][0]:
type = "20주선_40주선_상향돌파"
self.writeFile(type, CODE, NAME, top, stock_weekly, status)
return
@@ -772,27 +362,33 @@ class AnalyzerSqlite:
q_5 = MovingAverage(5)
q_10 = MovingAverage(10)
q_20 = MovingAverage(20)
q_40 = MovingAverage(40)
q_60 = MovingAverage(60)
q_120 = MovingAverage(120)
q_200 = MovingAverage(200)
q_240 = MovingAverage(240)
q_300 = MovingAverage(300)
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_40.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'])
q_300.enqueue(stock[i]['close'])
stock[i]['avg5'] = q_5.avg()
stock[i]['avg10'] = q_10.avg()
stock[i]['avg20'] = q_20.avg()
stock[i]['avg40'] = q_40.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()
stock[i]['avg300'] = q_300.avg()
return
@@ -803,29 +399,31 @@ class AnalyzerSqlite:
stock_price.append(
{
"ymd": ts.strftime("%Y.%m.%d"),
"close": weekDict['close'][ts],
"diff": weekDict['close'][ts] - previous_close,
"open": weekDict['open'][ts],
"high": weekDict['high'][ts],
"low": weekDict['low'][ts],
"volume": weekDict['volume'][ts],
"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
"close": weekDict['close'][ts],
"diff": weekDict['close'][ts] - previous_close,
"open": weekDict['open'][ts],
"high": weekDict['high'][ts],
"low": weekDict['low'][ts],
"volume": weekDict['volume'][ts],
"avg5": -1,
"avg10": -1,
"avg20": -1,
"avg40": -1,
"avg60": -1,
"avg120": -1,
"avg200": -1,
"avg240": -1,
"avg300": -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
}
)
previous_close = weekDict['close'][ts]
@@ -839,7 +437,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, 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)")
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, avg5 REAL, avg10 REAL, avg20 REAL, avg40 REAL, avg60 REAL, avg120 REAL, avg200 REAL, avg240 REAL, avg300 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) "
@@ -858,7 +456,8 @@ class AnalyzerSqlite:
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, close, diff, open, high, low, volume, avg5, avg10, avg20, avg60, avg120, avg200, avg240, "
sql = "INSERT INTO " + stockAnalysisTableName + "(CODE, NAME, ymd, close, diff, open, high, low, volume, "
sql += " avg5, avg10, avg20, avg40, avg60, avg120, avg200, avg240, avg300, "
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) "
@@ -866,7 +465,7 @@ class AnalyzerSqlite:
cursor.execute(sql, (
stock["CODE"], stock["NAME"], price['ymd'], price['close'], price['diff'], price['open'], price['high'], price['low'], price['volume'],
price['avg5'], price['avg10'], price['avg20'], price['avg60'], price['avg120'], price['avg200'], price['avg240'],
price['avg5'], price['avg10'], price['avg20'], price['avg40'], price['avg60'], price['avg120'], price['avg200'], price['avg240'], price['avg300'],
price['bolingerband_upper'], price['bolingerband_lower'], price['bolingerband_middle'],
price['ichimokucloud_changeLine'], price['ichimokucloud_baseLine'], price['ichimokucloud_leadingSpan1'],
price['ichimokucloud_leadingSpan2'],
@@ -874,7 +473,7 @@ class AnalyzerSqlite:
else:
sql = "UPDATE " + stockAnalysisTableName + " SET close=?, diff=?, open=?, high=?, low=?, volume=? "
sql += " avg5=?, avg10=?, avg20=?, avg60=?, avg120=?, avg200=?, avg240=?, "
sql += " avg5=?, avg10=?, avg20=?, avg40=?, avg60=?, avg120=?, avg200=?, avg240=?, avg300=?, "
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=? "
@@ -882,7 +481,7 @@ class AnalyzerSqlite:
cursor.execute(sql,
(price['close'], price['diff'], price['open'], price['high'], price['low'], price['volume'],
price['avg5'], price['avg10'], price['avg20'], price['avg60'], price['avg120'], price['avg200'], price['avg240'],
price['avg5'], price['avg10'], price['avg20'], price['avg40'], price['avg60'], price['avg120'], price['avg200'], price['avg240'], price['avg300'],
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'],
@@ -924,10 +523,12 @@ class AnalyzerSqlite:
"avg5": -1,
"avg10": -1,
"avg20": -1,
"avg40": -1,
"avg60": -1,
"avg120": -1,
"avg200": -1,
"avg240": -1,
"avg300": -1,
"bolingerband_upper": -1,
"bolingerband_lower": -1,
"bolingerband_middle": -1,
@@ -978,10 +579,12 @@ class AnalyzerSqlite:
"avg5": -1,
"avg10": -1,
"avg20": -1,
"avg40": -1,
"avg60": -1,
"avg120": -1,
"avg200": -1,
"avg240": -1,
"avg300": -1,
"bolingerband_upper": -1,
"bolingerband_lower": -1,
"bolingerband_middle": -1,
@@ -1033,7 +636,6 @@ if __name__ == "__main__":
analyzer.analyzeGrouping("weekly")
analyzer.analyzeGrouping("monthly")
"""
day = datetime.today().strftime("%Y%m%d")
# HTML 출력
@@ -1043,7 +645,6 @@ if __name__ == "__main__":
os.mkdir(outPath)
print("print to Html...")
analyzer.findCandidate(outPath)
"""
print("time : %6.2f" % (time.time() - start))