316 lines
18 KiB
Python
316 lines
18 KiB
Python
|
|
class Common:
|
|
|
|
# 상향
|
|
def checkUpward(self, type, data):
|
|
check = True
|
|
if type != None:
|
|
for i in range(len(data)-1):
|
|
# 만약 이전이 이후보다 크다면, 상승이 아님
|
|
if data[i][type] > data[i+1][type]:
|
|
check = False
|
|
break
|
|
else:
|
|
for i in range(len(data)-1):
|
|
# 만약 이전이 이후보다 크다면, 상승이 아님
|
|
if data[i] > data[i+1]:
|
|
check = False
|
|
break
|
|
return check
|
|
|
|
# 하향
|
|
def checkDownward(self, type, data):
|
|
check = True
|
|
for i in range(len(data)-1):
|
|
# 만약 이전이 이후보다 작다면, 하락이 아님
|
|
if data[i][type] < data[i+1][type]:
|
|
check = False
|
|
break
|
|
return check
|
|
|
|
# 상향 돌파
|
|
def checkUpwardBreakthrough(self, type1, type2, data):
|
|
if (type1 in data[0] and type1 in data[1] and type1 in data[2] and
|
|
type2 in data[0] and type2 in data[1] and type2 in data[2]):
|
|
|
|
if ((data[0][type1] < data[1][type1] < data[2][type1]) and
|
|
(data[0][type1] < data[0][type2] and data[2][type1] > data[2][type2])):
|
|
return True
|
|
return False
|
|
|
|
# 하향 돌파
|
|
def checkDownwardBreakthrough(self, type1, type2, data):
|
|
if (type1 in data[0] and type1 in data[1] and type1 in data[2] and
|
|
type2 in data[0] and type2 in data[1] and type2 in data[2]):
|
|
|
|
if ((data[0][type1] > data[1][type1] > data[2][type1]) and
|
|
(data[0][type1] > data[0][type2] and data[2][type1] < data[2][type2])):
|
|
return True
|
|
return False
|
|
|
|
|
|
def getStochasticScore(self, stock, i):
|
|
score = 0
|
|
|
|
if (stock[i - 1]['slow_k'] < stock[i]['slow_k'] and
|
|
stock[i]['slow_d'] < stock[i]['slow_k']):
|
|
if stock[i]['slow_k'] < 5:
|
|
score = 8
|
|
elif 5 <= stock[i]['slow_k'] < 10:
|
|
score = 7
|
|
elif 10 <= stock[i]['slow_k'] < 15:
|
|
score = 6
|
|
elif 15 <= stock[i]['slow_k'] < 20:
|
|
score = 5
|
|
elif 20 <= stock[i]['slow_k'] < 30:
|
|
score = 4
|
|
elif 30 <= stock[i]['slow_k'] < 40:
|
|
score = 3
|
|
elif 40 <= stock[i]['slow_k'] < 50:
|
|
score = 2
|
|
else:
|
|
score = 1
|
|
|
|
if (stock[i - 1]['slow_k'] > stock[i]['slow_k'] and
|
|
stock[i - 1]['slow_k'] > stock[i - 1]['slow_d'] and
|
|
stock[i]['slow_k'] < stock[i]['slow_d']):
|
|
if stock[i]['slow_k'] > 90:
|
|
score = -6
|
|
elif 90 >= stock[i]['slow_k'] > 80:
|
|
score = -5
|
|
elif 80 >= stock[i]['slow_k'] > 70:
|
|
score = -4
|
|
elif 70 >= stock[i]['slow_k'] > 60:
|
|
score = -3
|
|
elif 60 >= stock[i]['slow_k'] > 50:
|
|
score = -2
|
|
else:
|
|
score = -1
|
|
|
|
return score
|
|
|
|
def getIchimokuCloudScore(self, stock, i):
|
|
score = 0
|
|
|
|
if stock[i - 1]['leadingSpan1'] != 0 and stock[i - 1]['leadingSpan2'] != 0:
|
|
|
|
# 후행스팬 > 선행스펜 일때, 후행스펜 > 어제 주가 > 선행스팬 이고, 오늘 주가 > 후행스팬 < 선행스팬 이라면, 매수 2점
|
|
if (stock[i - 1]['leadingSpan2'] > stock[i - 1]['leadingSpan1'] and stock[i]['leadingSpan2'] > stock[i]['leadingSpan1']):
|
|
if (stock[i - 1]['leadingSpan2'] > stock[i - 1]['close'] > stock[i - 1]['leadingSpan1'] and
|
|
stock[i]['close'] > stock[i]['leadingSpan2'] > stock[i - 1]['leadingSpan1']):
|
|
score = 2
|
|
|
|
# 후행스팬 > 선행스펜 일때, 후행스펜 > 선행스팬 > 어제 주가 이고, 오늘 주가 > 후행스팬 < 선행스팬 이라면, 매수 4점
|
|
if (stock[i - 1]['leadingSpan2'] > stock[i - 1]['leadingSpan1'] and stock[i]['leadingSpan2'] > stock[i]['leadingSpan1']):
|
|
if (stock[i - 1]['leadingSpan2'] > stock[i - 1]['leadingSpan1'] > stock[i - 1]['close'] and
|
|
stock[i]['close'] > stock[i]['leadingSpan2'] > stock[i - 1]['leadingSpan1']):
|
|
score = 4
|
|
|
|
# 선행스팬 > 후행스팬 일때, 선행스팬 > 어제 주가 > 후행스팬 이고, 오늘 주가 > 선행스팬 < 후행스팬 이라면, 매수 1점
|
|
if (stock[i - 1]['leadingSpan1'] > stock[i - 1]['leadingSpan2'] and stock[i]['leadingSpan1'] > stock[i]['leadingSpan2']):
|
|
if (stock[i - 1]['leadingSpan1'] > stock[i - 1]['close'] > stock[i - 1]['leadingSpan2'] and
|
|
stock[i]['close'] > stock[i]['leadingSpan1'] > stock[i - 1]['leadingSpan2']):
|
|
score = 1
|
|
|
|
# 선행스팬 > 후행스팬 일때, 선행스팬 > 후행스팬 > 어제 주가 이고, 오늘 주가 > 선행스팬 < 후행스팬 이라면, 매수 3점
|
|
if (stock[i - 1]['leadingSpan1'] > stock[i - 1]['leadingSpan2'] and stock[i]['leadingSpan1'] > stock[i]['leadingSpan2']):
|
|
if (stock[i - 1]['leadingSpan1'] > stock[i - 1]['leadingSpan2'] > stock[i - 1]['close'] and
|
|
stock[i]['close'] > stock[i]['leadingSpan1'] > stock[i - 1]['leadingSpan2']):
|
|
score = 3
|
|
|
|
# 어제는 주가가 선행이나 후행스팬 위에 있었지만, 오늘은 두 스팬 모두 아래로 내려왔을 때 매도
|
|
if (stock[i - 1]['close'] > stock[i - 1]['leadingSpan1'] or stock[i - 1]['close'] > stock[i - 1]['leadingSpan2']):
|
|
if (stock[i]['close'] < stock[i]['leadingSpan1'] and stock[i]['close'] < stock[i]['leadingSpan2']):
|
|
score = -1
|
|
|
|
return score
|
|
|
|
def checkLongYangBongAfterUmBong(self, stock, i):
|
|
if i > 0:
|
|
if stock[i-1]['open'] > stock[i-1]['close']: # 어제가 음봉인지 체크
|
|
if stock[i]['open'] < stock[i]['close'] and stock[i]['close'] == stock[i]['high']: # 오늘 장대양봉인지 체크
|
|
if stock[i-1]['volume']*2 < stock[i]['volume']: # 어제 거래량 보다 두배 이상일 때
|
|
return True
|
|
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, 6):
|
|
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 "ALLUPPER_"
|
|
return ""
|
|
|
|
def check_golded_cross(self, stock, i):
|
|
if i > 1:
|
|
# 60 -> 120
|
|
# 오늘 지수는 120 < 60 < 20 < 5
|
|
# 어제 지수는 60 < 120 이었다.
|
|
# 60, 20, 5일선 모두 어제 보다 오늘이 더 높다 (상승중)
|
|
# 5일과 20일선은 상승 중이며, 60일선이 120일 선을 뚫고 올라온 순간인지 체크함 (삼성전자 2021-07-29)
|
|
# 이때 바로 매수하지 않는다.
|
|
# 이 시점 이후로 5일선이 20일선을 하방으로 뚫었다가 다시 20일선을 상방으로 뚫는 순간 매수를 시도한다.
|
|
if stock[i]['avg120'] < stock[i]['avg60'] < stock[i]['avg20'] < stock[i]['avg5']:
|
|
if stock[i-1]['avg120'] > stock[i-1]['avg60']:
|
|
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 "GOLDEN#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 "GOLDEN#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 "GOLDEN#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 "BEARMARKET#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 "BEARMARKET#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 "STOCHASTIC#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 "STOCHASTIC#2_"
|
|
return ""
|
|
|
|
def check_days20_line_buying1(self, stock, i):
|
|
"""
|
|
5일 선이 20일 선을 뚫고 올라온 순간 체크
|
|
5일선이 다시 20선 아래로 내려가는 순간 손걸한다.
|
|
"""
|
|
if len(stock) > 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-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 - 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 "5-20_"
|
|
return ""
|
|
|
|
def check_days60_line_buying1(self, stock, i):
|
|
"""
|
|
5일 선이 60일 선을 뚫고 올라온 순간 체크
|
|
5일선이 다시 60선 아래로 내려가는 순간 손걸한다.
|
|
"""
|
|
if len(stock) > 61:
|
|
# 오늘 5일선이 60일선 위에 올라왔다.
|
|
# 어제부터 index1일까지 60일선이 5일선 위에 있었다.
|
|
# index1일부터 index2일까지 5일선이 60일선 위에 있었다.
|
|
if stock[i]['avg60'] < stock[i]['avg5']:
|
|
if (stock[i - 3]['avg5'] < stock[i - 3]['avg60'] or stock[i - 2]['avg5'] < stock[i - 2]['avg60'] or stock[i - 1]['avg5'] < stock[i - 1]['avg60']):
|
|
#if (stock[i - 1]['avg5'] < stock[i - 1]['avg60']):
|
|
index1 = -1
|
|
for j in range(1, 150):
|
|
if stock[i-j]['avg60'] < stock[i-j]['avg5']:
|
|
index1 = j
|
|
break
|
|
index2 = -1
|
|
for j in range(index1+1, 150):
|
|
if stock[i-j]['avg5'] < stock[i-j]['avg60']:
|
|
index2 = j
|
|
break
|
|
if (index2 != -1 and (stock[i-index2+1]['close'] < stock[i]['close'])):
|
|
return "5-60_"
|
|
return ""
|
|
|
|
def check_days60_line_buying2(self, stock, i):
|
|
"""
|
|
20일 선이 60일 선을 뚫고 올라온 순간 체크
|
|
20일선이 다시 60선 아래로 내려가는 순간 손걸한다.
|
|
"""
|
|
if len(stock) > 151:
|
|
# 오늘 20일선이 60일선 위에 올라왔다.
|
|
# 어제부터 index1일까지 60일선이 20일선 위에 있었다.
|
|
# index1일부터 index2일까지 20일선이 60일선 위에 있었다.
|
|
if stock[i]['avg60'] < stock[i]['avg20']:
|
|
if (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']):
|
|
#if (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 "20-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 ""
|
|
|
|
|