This commit is contained in:
dsyoon
2021-02-23 06:13:46 +09:00
parent 2f6b33f8f2
commit 6a933d4914
4 changed files with 202 additions and 133 deletions

View File

@@ -267,52 +267,11 @@ class Analyzer:
def analyzeFinalScore(self, last_index, STOCK, MACD, STOCHASTIC, ICHIMOKU, RSI): def analyzeFinalScore(self, last_index, STOCK, MACD, STOCHASTIC, ICHIMOKU, RSI):
""" """
[매도] 매수 조건
1. MACD #0. 최소 매수 조건은 거래량은 20만건, 종가는 2천원 이상인 종목이어야 한다.
1) MACD가 시그널설을 하향 돌파하면 매도한다. #1. 골든크로스: 5일선, 20일선, 60일선, 120일선이 순서대로 나열되는 순간
2) MACD가 기준선 (0) 아래에 있는 한 주가는 하향추세이거나 또는 상승하지 않는다.
3) 시그널 추세가 하향인 한 매수 신호가 나올 때까지 주식을 보유하지 않는다.
4) 하락형 다이버전스가 발생하면 적극 매도를 검토한다.
2. Stochasic: %K선이 %D선을 하향 돌파하면 매도 신호로 보되 다음 사항들이 일치하면 매도한다.
1) 스토캐스틱 지표가 하락추세를 보이고, 50 이하에 있어야 한다.
2) 스토캐스틱 지표가 고점이 낮아지는 하락파동에 있어야 한다.
3) 주가가 5일 또는 20일 이동 평균선 아래에 있어야 한다.
4) MACD 지표가 하락으로 전환하거나 또는 최소한 상승을 멈추어야 한다.
5) 하락형 다이버전스가 발생하면 매도를 검토한다.
3. rsi
1) rsi가 하향이고 70이하로 떨어지면 매도,
2) rsi가 하향이고 50이하로 떨어지면 매도,
3) rsi가 하향이고 30이하로 떨어지면 단기매도,
[매수]
1. MACD
1) MACD가 시그널설을 상향 돌파하면 매수한다.
2) MACD가 기준선 (0) 위에 있는 한 주가는 상승추세이거나 또는 하락하지 않는다.
3) 시그널 추세가 상승하는 한 매도 신호가 나올 때까지 주식을 보유한다.
4) 상승형 다이버전스가 발생하면 적극 매수를 검토한다.
2. Stochasic: %K선이 %D선을 상향 돌파하면 매수 신호로 보되 다음 사항들이 일치하면 매수한다.
1) 스토캐스틱 지표가 상승추세를 보이고, 50 이상에 있어야 한다.
2) 스토캐스틱 지표가 저점을 높이는 상승파동에 있어야 한다.
3) 주가가 5일 또는 20일 이동 평균선 위에 있어야 한다.
4) MACD 지표가 상승으로 전환하거나 또는 최소한 하락을 멈추어야 한다.
5) 상승형 다이버전스가 발생하면 매수를 검토한다.
3. rsi
1) 상향이고 30을 돌파하면 매수,
2) rsi가 상향이고 40을 돌파하면 매수,
3) rsi가 상향이고 70을 돌파하면 단기매수,
시장 보다 강한 종목이란 (https://biz.sbs.co.kr/article/10000976754)
""" """
i = last_index i = last_index
# 매수금액을 구
# 이전 3일 동안의 어제종가-오늘저가의 평균을 구함 --> (종가-시가)/3
# 그래서 오늘 종가에 구한 평균값을 더해서 내일 종목을 매수함
buy_price = 0 buy_price = 0
count = 0 count = 0
for idx in range(i, i-5, -1): for idx in range(i, i-5, -1):
@@ -323,79 +282,57 @@ class Analyzer:
if count == 0: if count == 0:
buy_price = STOCK[i]['close'] buy_price = STOCK[i]['close']
else: else:
# 종가 - 최저가의 최근 3일 평균 가격을 산정한다.
buy_price = round(STOCK[i]['close'] - (buy_price/count)) buy_price = round(STOCK[i]['close'] - (buy_price/count))
stochastic_score = self.common.getStochasticScore(STOCHASTIC, i)
"""
if STOCK[i]['volume'] > 10000:
if MACD[i - 1]['macd'] < MACD[i]['macd']:
if MACD[i - 1]['macd'] < MACD[i - 1]['macds'] and MACD[i]['macd'] > MACD[i]['macds']:
return True,buy_price, stochastic_score
if stochastic_score > 0:
return True, buy_price, stochastic_score
"""
status = "" status = ""
if STOCK[i]['volume'] > 100000 and STOCK[i]['close'] > 1000: if STOCK[i]['volume'] > 100000 and STOCK[i]['close'] > 2000:
# 거래량이 10만 이상이고, 종가가 1천원 이상인지 체크 (https://happpy-rich.tistory.com/94) # 거래량이 100만 이상이고, 종가가 1천원 이상인지 체크 (https://happpy-rich.tistory.com/94)
if self.common.check_on_120_daysLine(STOCK, i): all_upper_cross_status = self.common.checkAllUpperCross(STOCK, i)
# 특히 종목이 120일선을 뚫은 후 60일선이 상승세인지를 확인한다. (https://biz.sbs.co.kr/article/10000976754) if all_upper_cross_status != "":
if STOCHASTIC[i]['slow_k'] < 70: status += all_upper_cross_status
status += '120_'
if self.common.check_on_60_daysLine(STOCK, i): # GOLDENCROSS#1은 바로 매수하지 않고, 이 시점 이후로 5일선이 20일선을 하방으로 뚫었다가 다시 20일선을 상방으로 뚫는 순간 매수를 시도한다.
if STOCHASTIC[i]['slow_k'] < 70: # GOLDENCROSS#2은 바로 매수 가능
status += '60_' # GOLDENCROSS#3은 바로 매수 가능
if self.common.check_on_20_daysLine(STOCK, i): golden_cross_status = self.common.check_golded_cross(STOCK, i)
if STOCHASTIC[i]['slow_k'] < 70: if golden_cross_status != "":
status += golden_cross_status
# BUYINGBEARMARKET#1은 바로 매수 가능
# BUYINGBEARMARKET#2은 바로 매수 가능
bearmarket_buying_status = self.common.check_bearmarket_buying(STOCK, STOCHASTIC, i)
if bearmarket_buying_status != "":
status += bearmarket_buying_status
# BUYINGSTOCHASTIC#1은 바로 매수 가능
stochastic_buying_status = self.common.check_stochastic_buying(STOCK, STOCHASTIC, ICHIMOKU, i)
if stochastic_buying_status != "":
status += stochastic_buying_status
# 20
if self.common.check_20days_line_buying(STOCK, i):
if STOCHASTIC[i]['slow_k'] < 40:
status += '20_' status += '20_'
if STOCHASTIC[i]['slow_k'] < 10: # 60
# 스토캐스틱이 10 이하였다면, if self.common.check_60days_line_buying(STOCK, i):
status += 'STOCHASTIC_' if STOCHASTIC[i]['slow_k'] < 40:
status += '60_'
# STOCHASTIC
stochastic_status = self.common.check_stochastic(STOCK, STOCHASTIC, i)
if stochastic_status != "":
status += stochastic_status
# YANGBONG
if self.common.checkLongYangBongAfterUmBong(STOCK, i): if self.common.checkLongYangBongAfterUmBong(STOCK, i):
# 어제 음봉 이후 장대양봉이었다면, # 어제 음봉 이후 장대양봉이었다면,
status += 'YANGBONG_' status += 'YANGBONG_'
return status, buy_price return status, buy_price
def analyzeToFile(self, outFileName):
conn = sqlite3.connect(self.inFileName)
cursor = conn.cursor()
outfp = open(outFileName, "w", encoding="utf-8")
rowid = 1
cursor.execute('SELECT * FROM ' + self.tableName + ' WHERE rowid=?', (rowid,))
result = cursor.fetchone()
while result != None:
stock = {"CODE": result[0], "NAME": result[1], "PRICE": json.loads(result[2])}
macd = json.loads(result[3])
stochastic = json.loads(result[4])
ichimokuCloud = json.loads(result[5])
rsi = json.loads(result[6])
last_index = self.get_last_index(stock)
lastStock = stock['PRICE']
state, buy_price = self.analyzeFinalScore(last_index, lastStock, macd, stochastic, ichimokuCloud, rsi)
if state != "":
# self.macd.draw(stock)
print(stock['CODE'], stock['NAME'], str(buy_price), stochastic[last_index]['slow_k'], macd[last_index]['macd'], rsi[last_index]['rsi_buy'], ichimokuCloud[last_index]['ichimoku_buy'])
outfp.write("%s\t%s\t%s\t%d\t%s\t%s\t%s\n"%(stock['CODE'], stock['NAME'], str(buy_price), stochastic[last_index]['slow_k'], rsi[last_index]['rsi_buy'], macd[last_index]['macd'], ichimokuCloud[last_index]['ichimoku_buy']))
print("#file", rowid, stock['NAME'])
rowid += 1
cursor.execute('SELECT * FROM ' + self.tableName + ' WHERE rowid=?', (rowid,))
result = cursor.fetchone()
cursor.close()
conn.close()
outfp.close()
return
# 그래프 출력 # 그래프 출력
def analyzeToHtml(self, outPath): def analyzeToHtml(self, outPath):
tmp_path = outPath + "/tmp" tmp_path = outPath + "/tmp"
@@ -430,8 +367,6 @@ class Analyzer:
if result[5] != result[5]: result_5 = result[5].replace("NaN", "0") if result[5] != result[5]: result_5 = result[5].replace("NaN", "0")
if result[6] != result[6]: result_6 = result[6].replace("NaN", "0") if result[6] != result[6]: result_6 = result[6].replace("NaN", "0")
if rowid == 2435:
print (1)
stock = {"CODE": result[0], "NAME": result[1], "PRICE": json.loads(result[2]), "MACD": json.loads(result_3), "STOCHASTIC": json.loads(result_4), "ICHIMOKU": json.loads(result_5), "RSI": json.loads(result_6)} stock = {"CODE": result[0], "NAME": result[1], "PRICE": json.loads(result[2]), "MACD": json.loads(result_3), "STOCHASTIC": json.loads(result_4), "ICHIMOKU": json.loads(result_5), "RSI": json.loads(result_6)}
last_index = self.get_last_index(stock) last_index = self.get_last_index(stock)
@@ -441,7 +376,9 @@ class Analyzer:
ICHIMOKU = stock['ICHIMOKU'] ICHIMOKU = stock['ICHIMOKU']
RSI = stock['RSI'] RSI = stock['RSI']
# 종목 상태 체크 분석
state, buy_price = self.analyzeFinalScore(last_index, STOCK, MACD, STOCHASTIC, ICHIMOKU, RSI) state, buy_price = self.analyzeFinalScore(last_index, STOCK, MACD, STOCHASTIC, ICHIMOKU, RSI)
stochastic_score = STOCHASTIC[last_index]['slow_k'] stochastic_score = STOCHASTIC[last_index]['slow_k']
macd_score = MACD[last_index]['macd'] macd_score = MACD[last_index]['macd']
rsi_score = RSI[last_index]['rsi'] rsi_score = RSI[last_index]['rsi']
@@ -451,14 +388,14 @@ class Analyzer:
fig = self.draw(stock) fig = self.draw(stock)
title = "%s (%s), %s, buy_price (%d), stochastic(%.3f), rsi(%.3f), macd(%.3f), ichimoku(%d)) 차트" % (item_name, item_code, state, buy_price, stochastic_score, rsi_score, macd_score, ichimoku_score) title = "%s (%s), %s, buy_price (%d), stochastic(%.3f), rsi(%.3f), macd(%.3f), ichimoku(%d)) 차트" % (item_name, item_code, state, buy_price, stochastic_score, rsi_score, macd_score, ichimoku_score)
fig['layout'].update(title=title) fig['layout'].update(title=title)
fileName = "%s/%s__%.3f__%.3f__%s.html" % (outPath, state, stochastic_score, rsi_score, item_name.replace(" ", "")) fileName = "%s/%s__%.3f__%.3f__%s_%s.html" % (outPath, state, stochastic_score, rsi_score, item_name.replace(" ", ""), item_code)
po.write_html(fig, file=fileName, auto_open=False) po.write_html(fig, file=fileName, auto_open=False)
else: else:
if RSI[last_index]['rsi_buy'] == 1 and STOCK[last_index]['volume'] > 100000: if (RSI[last_index]['rsi_buy'] == 1) and STOCK[last_index]['volume'] > 1000000:
fig = self.draw(stock) fig = self.draw(stock)
title = "%s (%s) buy_price (%d), stochastic(%.3f), rsi(%.3f), macd(%.3f), ichimoku(%d)) 차트"%(item_name, item_code, buy_price, stochastic_score, rsi_score, macd_score, ichimoku_score) title = "%s (%s) buy_price (%d), stochastic(%.3f), rsi(%.3f), macd(%.3f), ichimoku(%d)) 차트"%(item_name, item_code, buy_price, stochastic_score, rsi_score, macd_score, ichimoku_score)
fig['layout'].update(title=title) fig['layout'].update(title=title)
fileName = "%s/%.3f__%.3f__%s.html"%(tmp_path, stochastic_score, rsi_score, item_name.replace(" ", "")) fileName = "%s/%.3f__%.3f__%s_%s.html"%(tmp_path, stochastic_score, rsi_score, item_name.replace(" ", ""), item_code)
po.write_html(fig, file=fileName, auto_open=False) po.write_html(fig, file=fileName, auto_open=False)
print ("#html", rowid, stock['NAME']) print ("#html", rowid, stock['NAME'])

View File

View File

@@ -133,29 +133,152 @@ class Common:
return True return True
return False return False
def checkAllUpperCross(self, stock, i):
if i > 10:
if stock[i]['avg5'] < stock[i]['close'] and stock[i]['avg20'] < stock[i]['close'] and stock[i]['avg60'] < stock[i]['close'] and stock[i]['avg120'] < stock[i]['close']:
for j in range(1, 5):
if stock[i-j]['close'] < stock[i-j]['avg5'] and stock[i-j]['close'] < stock[i-j]['avg20'] and stock[i-j]['close'] < stock[i-j]['avg60'] and stock[i-j]['close'] < stock[i-j]['avg120']:
return "ALLUPPERCROSS_"
return ""
def check_on_20_daysLine(self, stock, i): def check_golded_cross(self, stock, i):
# 20일선 돌파를 체크할 때는 5일선 < 20일선 < 120일선 < 60일선 이어야 하며, 5일선은 상승중이어야 한다. (삼성전자 2020년 4월 6일) if i > 1:
if i > 0: # 60 -> 120: 5일과 20일선은 상승 중이며, 60일선이 120일 선을 뚫고 올라온 순간인지 체크함 (삼성전자 2021-07-29)
if stock[i-1]['avg20'] > stock[i-1]['close'] and stock[i]['avg20'] < stock[i]['close']: # 이때 바로 매수하지 않는다.
if stock[i]['avg5'] < stock[i]['avg20'] < stock[i]['avg120'] < stock[i]['avg60']: # 이 시점 이후로 5일선이 20일선을 하방으로 뚫었다가 다시 20일선을 상방으로 뚫는 순간 매수를 시도한다.
if stock[i-1]['avg5'] < stock[i]['avg5']: if stock[i]['avg120'] < stock[i]['avg60'] < stock[i]['avg20'] < stock[i]['avg5']:
return True if stock[i-1]['avg120'] > stock[i-1]['avg60'] and stock[i]['avg120'] < stock[i]['avg60']:
return False if (stock[i-1]['avg60'] < stock[i]['avg60'] and stock[i-1]['avg20'] < stock[i]['avg20'] and stock[i-1]['avg5'] < stock[i]['avg5']):
return "GOLDENCROSS#1_"
# 20 -> 120: 5일과 20일, 60일선은 상승 중이며, 20일선이 120일 선을 뚫고 올라온 순간인지 체크 (SK 2021-12-09, 나노스 2021-02-04)
# 어제는 60일선 < 20일선 < 120일선 < 5일선이지만, 오늘은 60일선 < 120일선 < 20일선 < 5일선
# 이때 바로 매수하지 않는다.
# 이 시점 이후로 5일선이 20일선을 하방으로 뚫었다가 다시 20일선을 상방으로 뚫는 순간 매수를 시도한다.
if stock[i]['avg60'] < stock[i]['avg120'] < stock[i]['avg20'] < stock[i]['avg5']:
if stock[i-1]['avg60'] < stock[i-1]['avg20'] < stock[i]['avg120'] < stock[i]['avg5']:
if (stock[i-1]['avg60'] < stock[i]['avg60'] and stock[i-1]['avg20'] < stock[i]['avg20'] and stock[i-1]['avg5'] < stock[i]['avg5']):
return "GOLDENCROSS#2_"
# 20 -> 120: 5일과 20일, 60일선은 상승 중이며, 20일선이 120일 선을 뚫고 올라온 순간인지 체크 (갤럭시아머니트리 2021-02-08)
# 어제는 60일선 < 120일선 < 5일선 < 20일선이지만, 오늘은 60일선 < 120일선 < 20일선 < 5일선
if stock[i]['avg60'] < stock[i]['avg120'] < stock[i]['avg20'] < stock[i]['avg5']:
if stock[i-1]['avg60'] < stock[i-1]['avg20'] < stock[i]['avg120'] < stock[i]['avg5']:
if (stock[i-1]['avg60'] < stock[i]['avg60'] and stock[i-1]['avg20'] < stock[i]['avg20'] and stock[i-1]['avg5'] < stock[i]['avg5']):
return "GOLDENCROSS#3_"
return ""
def check_bearmarket_buying(self, stock, stochastic, i):
if i > 1:
# 5일선 상승 시점 확인 (SK 2020년 3월 24일)
# 어제는 5일선 < 20일선 < 120일선 < 60일선이며, 오늘은 20일선 < 120일선 < 60일선
# 어제와 오늘 모두 20일, 60일, 120일선은 모두 하락이다.
# 어제 종가보다 오늘 종가가 높고, 종가는 5일선 위에 올라왔다.
# 오늘 slow_k는 30 이하이며, 어제는 slow_d가 높았지만, 오늘은 slow_k가 더 높음
if (stock[i-1]['avg5'] < stock[i-1]['avg20'] < stock[i-1]['avg120'] < stock[i]['avg60']) and (stock[i]['avg20'] < stock[i-1]['avg120'] < stock[i]['avg60']):
if stock[i]['avg120'] < stock[i-1]['avg120'] and stock[i]['avg60'] < stock[i-1]['avg60'] and stock[i]['avg20'] < stock[i-1]['avg20']:
if stock[i-1]['close'] <= stock[i]['close'] and stock[i]['avg5'] <= stock[i]['close']:
if (stochastic[i]['slow_k'] < 30 and (stochastic[i-1]['slow_k'] < stochastic[i-1]['slow_d'] and stochastic[i]['slow_d'] < stochastic[i]['slow_k'])):
return "BUYINGBEARMARKET#1_"
# 5일선 상승 시점 확인 (원풍물산 2020년 3월 24일, NHN한국사이버결제 2018년 11월 2일)
# 어제는 5일선 < 20일선 < 60일선 < 120일선이며, 오늘은 20일선 < 60일선 < 120일선
# 어제와 오늘 모두 20일, 60일, 120일선은 모두 하락이다.
# 어제 종가보다 오늘 종가가 높고, 종가는 5일선 위에 올라왔다.
# 오늘 slow_k는 30 이하이며, 어제는 slow_d가 높았지만, 오늘은 slow_k가 더 높음
if (stock[i-1]['avg5'] < stock[i-1]['avg20'] < stock[i-1]['avg60'] < stock[i]['avg120']) and (stock[i]['avg20'] < stock[i-1]['avg60'] < stock[i]['avg120']):
if stock[i]['avg120'] < stock[i-1]['avg120'] and stock[i]['avg60'] < stock[i-1]['avg60'] and stock[i]['avg20'] < stock[i-1]['avg20']:
if stock[i-1]['close'] <= stock[i]['close'] and stock[i]['avg5'] <= stock[i]['close']:
if (stochastic[i]['slow_k'] < 30 and (stochastic[i-1]['slow_k'] < stochastic[i-1]['slow_d'] and stochastic[i]['slow_d'] < stochastic[i]['slow_k'])):
return "BUYINGBEARMARKET#2_"
return ""
def check_stochastic_buying(self, stock, stochastic, ichimoku, i):
if i > 3:
# 삼성전자 2020년 11월 4일
# 어제는 slow_K가 Slow_d 아래였지만, 오늘은 slow_K가 Slow_d 보다 높다.
# 에제의 slow_k는 20보다 작고, 오늘의 slow_K는 30보다 작다
# 1일전이나, 2, 3일전의 종가가 일목균형표 내의 선행스팬1 아래 존재하며,오늘 고가는 선행스팬1 위에 존재한다.
# 그저께 시가보다 어제의 시가가, 어제의 시가보다는 오늘의 시가가 높다.
if (stochastic[i-1]['slow_k'] < stochastic[i-1]['slow_d'] and stochastic[i]['slow_d'] < stochastic[i]['slow_k']):
if (stochastic[i - 1]['slow_k'] < 20 and stochastic[i]['slow_k'] < 30):
if ((stock[i-3]['close'] < ichimoku[i-3]['leadingSpan1'] or stock[i-2]['close'] < ichimoku[i-2]['leadingSpan1'] or stock[i-1]['close'] < ichimoku[i-1]['leadingSpan1']) and ichimoku[i-1]['leadingSpan1'] < stock[i-1]['high']):
if stock[i-2]['open'] < stock[i-1]['open'] < stock[i]['open']:
return "BUYINGSTOCHASTIC#1_"
# 스토케스틱이 15 이하인 경우
# 어제보다 slow_k가 상승했고, 오늘 slow_k가 slow_d 위에 있는 경우,
# 오늘 종가가 5일선 위에 있는 경우
if stochastic[i]['slow_k'] < 15:
if stochastic[i - 1]['slow_k'] < stochastic[i]['slow_k'] and stochastic[i]['slow_d'] < stochastic[i]['slow_k']:
if stock[i]['avg5'] < stock[i]['close']:
return "BUYINGSTOCHASTIC#2_"
return ""
def check_20days_line_buying(self, stock, i):
"""
3일 선이 20일 선을 뚫고 올라온 순간 체크
3일선이 다시 20선 아래로 내려가는 순간 손걸한다.
"""
if i > 61:
# 오늘 종가가 20일선을 뚫고 올라왔다. (20일선<오늘종가 and (어제종가<20 or 어제3일선<20))
# 오늘 종가는 양봉이어야 한다.
# 어제부터 index1일까지 20일선이 3일선 위에 있었다.
# index1일부터 index2일까지 3일선이 20일선 위에 있었다.
# 이전 3일선이 20일선을 뚫었던 종가보다 오늘 뚫은 종가가 높거나 혹은 오늘 종가가 더 낮더라도 장대 양봉어어야 한다.
# 주봉의 20일 평균이 이전 주봉의 20일 평균 보다 높아야 한다.
if stock[i]['avg20'] < stock[i]['close'] and (stock[i-1]['close'] < stock[i]['avg20'] or stock[i-1]['avg5'] < stock[i]['avg20']):
if (stock[i-4]['avg5'] < stock[i-4]['avg20'] or stock[i-3]['avg5'] < stock[i-3]['avg20'] or stock[i-2]['avg5'] < stock[i-2]['avg20'] or stock[i-1]['avg5'] < stock[i-1]['avg20']):
if stock[i]['open'] < stock[i]['close']:
index1 = -1
for j in range(1, 61):
if stock[i-j]['avg20'] < stock[i-j]['avg5']:
index1 = j
break
index2 = -1
for j in range(index1+1, 61):
if stock[i-j]['avg5'] < stock[i-j]['avg20']:
index2 = j
break
if (index2 != -1 and ((stock[i-index2+1]['close'] < stock[i]['close']) or (stock[i]['high']-stock[i]['close'] < stock[i]['open']-stock[i]['low']))):
# 주봉의 20일 평균이 이전 주봉의 20일 평균 보다 높아야 한다.
return "20_"
return ""
def check_60days_line_buying(self, stock, i):
"""
20일 선이 60일 선을 뚫고 올라온 순간 체크
20일선이 다시 60선 아래로 내려가는 순간 손걸한다.
"""
if i > 150:
# 오늘 20일선이 60일선 위에 올라왔다.
# 어제부터 index1일까지 60일선이 20일선 위에 있었다.
# index1일부터 index2일까지 20일선이 60일선 위에 있었다.
if stock[i]['avg60'] < stock[i]['avg20']:
if (stock[i - 4]['avg20'] < stock[i - 4]['avg60'] or stock[i - 3]['avg20'] < stock[i - 3]['avg60'] or stock[i - 2]['avg20'] < stock[i - 2]['avg60'] or stock[i - 1]['avg20'] < stock[i - 1]['avg60']):
index1 = -1
for j in range(1, 150):
if stock[i-j]['avg60'] < stock[i-j]['avg20']:
index1 = j
break
index2 = -1
for j in range(index1+1, 150):
if stock[i-j]['avg20'] < stock[i-j]['avg60']:
index2 = j
break
if (index2 != -1 and (stock[i-index2+1]['close'] < stock[i]['close'])):
return "60_"
return ""
def check_stochastic(self, stock, stochastic, i):
if i > 2:
# 스토케스틱이 15 이하인 경우
# 어제보다 slow_k가 상승했고, 오늘 slow_k가 slow_d 위에 있는 경우,
if stochastic[i]['slow_k'] < 15:
if stochastic[i-1]['slow_k'] < stochastic[i]['slow_k'] and stochastic[i]['slow_d'] < stochastic[i]['slow_k']:
return "STOCHASTIC_"
return ""
def check_on_60_daysLine(self, stock, i):
# 60일선 돌파를 체크할 때는 20일선 < 5일선 < 60일 < 120일선 이어야 하며, 5일선과 20일선은 상승중이어야 한다. (삼성전자 2020년 5월 27일)
if i > 0:
if stock[i-1]['avg60'] > stock[i-1]['close'] and stock[i]['avg60'] < stock[i]['close']:
if stock[i]['avg20'] < stock[i]['avg5'] < stock[i]['avg60'] < stock[i]['avg120']:
if stock[i-1]['avg5'] < stock[i]['avg5'] and stock[i-1]['avg20'] < stock[i]['avg20']:
return True
return False
def check_on_120_daysLine(self, stock, i):
# 120일선 돌파를 체크할 때는 60일선이 상승 중이어야 한다.
if i > 0:
if stock[i-1]['avg120'] > stock[i-1]['close'] and stock[i]['avg120'] < stock[i]['close']:
if stock[i-1]['avg5'] < stock[i]['avg5'] and stock[i-1]['avg20'] < stock[i]['avg20'] and stock[i-1]['avg60'] < stock[i]['avg60']:
return True
return False

View File

@@ -12,6 +12,15 @@ today = datetime.datetime.now().strftime("%Y-%m-%d")
PROJECT_HOME = "../../.." PROJECT_HOME = "../../.."
print("\n[지수 저장]")
kospiFileName = PROJECT_HOME + '/resources/kospi.tsv'
kosdakFileName = PROJECT_HOME + '/resources/kosdak.tsv'
outFileName = PROJECT_HOME + '/resources/stock.db'
crawler = StockCrawler()
crawler.saveIndex("KOSPI", kospiFileName, outFileName)
crawler.saveIndex("KOSDAK", kosdakFileName, outFileName)
inFnguideFileName = PROJECT_HOME + '/resources/fnguide.db' inFnguideFileName = PROJECT_HOME + '/resources/fnguide.db'
""" """
crawler = FnGuideCrawler() crawler = FnGuideCrawler()