import pandas as pd from stock.analysis.Common import Common # 6. Pandas와 Plotly를 이용한 MACD 차트 그리기: https://excelsior-cjh.tistory.com/111 # 스토캐스틱 슬로우(Stochastics Slow)를 이용한 간단한 매매기법: https://bagal.tistory.com/124 # Stochastic Slow, 스토캐스틱을 통한 주식 매매법 정리: https://m.blog.naver.com/PostView.nhn?blogId=kangyh427&logNo=220957146041&proxyReferer=https:%2F%2Fwww.google.com%2F # 차트분석 2편 스토캐스틱을 활용한 매수타이밍 포착!: https://m.post.naver.com/viewer/postView.nhn?volumeNo=7446693&memberNo=32471429 class Stochastic: common = None def __init__(self): self.common = Common() return # 일자(n,m,t)에 따른 Stochastic(KDJ)의 값을 구하기 위해 함수형태로 만듬 # n=15 (%k), m=5 (%d), t=3 # n=5 (%k), m=3 (%d), t=3 # n=14 (%k), m=3 (%d), t=3 def apply(self, df, n=12, m=5, t=5): # 입력받은 값이 dataframe이라는 것을 정의해줌 df = pd.DataFrame(df) # n일중 최고가 ndays_high = df.high.rolling(n).max() # n일중 최저가 ndays_low = df.low.rolling(n).min() # Fast%K 계산 # n(15)일 동안의 최고가(high)와 최저가(low) 사이 중 현재 종가(close)의 상대적 위치를 판단하는 값 # 가격이 지속적으로 상승하고 있다면 Stochastic 값은 100에 가까워 지며, 반대로 지속적으로 하락하고 있다면 Stochastic 값은 0에 가까워 지는 경향을 나타낸다. fast_k = ((df.close - ndays_low) / (ndays_high - ndays_low)) * 100 # Fast%D (=Slow%K) 계산 # m(5)일간의 Fast%K의 이동평균 값 # 기본값으로 5일을 설정하며 Fast%K 값을 일반화하는 역할을 한다. #slow_k = fast_k.ewm(span=m).mean() slow_k = fast_k.rolling(m).mean() # Slow%D 계산 # t(3)일간의 Slow%K의 이동평균 값 # 기본값으로 3일을 설정하며 Slow%K 값을 일반화 하는 역할을 한다. #slow_d = slow_k.ewm(span=t).mean() slow_d = slow_k.rolling(t).mean() # dataframe에 컬럼 추가 #df = df.assign(fast_k=fast_k, slow_k=slow_k, slow_d=slow_d).dropna() df = df.assign(fast_k=fast_k, slow_k=slow_k, slow_d=slow_d) return df """ def analyze(self, stock): df = pd.DataFrame() df = df.from_dict(stock['PRICE']) df = self.apply(df) for i in range(len(df.fast_k)): stock['PRICE'][i]['stochastic_buy'] = 0 if "fast_k" not in stock['PRICE'][i]: stock['PRICE'][i]['fast_k'] = -1 stock['PRICE'][i]['slow_k'] = -1 stock['PRICE'][i]['slow_d'] = -1 i_ = i + len(stock['PRICE']) - len(df.fast_k) stock['PRICE'][i_]['fast_k'] = df.fast_k.values[i] stock['PRICE'][i_]['slow_k'] = df.slow_k.values[i] stock['PRICE'][i_]['slow_d'] = df.slow_d.values[i] # 0: 중립, 1: 매수, -1: 매도 stock['PRICE'][i_]['stochastic_buy'] = 0 stock['PRICE'][i_]['direction'] = '' if i_ > 2: if ('slow_k' in stock['PRICE'][i_-1] and 'slow_k' in stock['PRICE'][i_]): # %k선이 %d선을 상향 돌파하면 매수 신호 if (self.common.checkUpward('slow_k', stock['PRICE'][i_-2:i_+1]) and stock['PRICE'][i_-1]['slow_k'] < stock['PRICE'][i_-1]['slow_d'] and stock['PRICE'][i_]['slow_k'] > stock['PRICE'][i_]['slow_d']): if stock['PRICE'][i_]['slow_k'] < 5: stock['PRICE'][i_]['stochastic_buy'] = 8 elif 5 <= stock['PRICE'][i_]['slow_k'] < 10: stock['PRICE'][i_]['stochastic_buy'] = 7 elif 10 <= stock['PRICE'][i_]['slow_k'] < 15: stock['PRICE'][i_]['stochastic_buy'] = 6 elif 15 <= stock['PRICE'][i_]['slow_k'] < 20: stock['PRICE'][i_]['stochastic_buy'] = 5 elif 20 <= stock['PRICE'][i_]['slow_k'] < 30: stock['PRICE'][i_]['stochastic_buy'] = 4 elif 30 <= stock['PRICE'][i_]['slow_k'] < 40: stock['PRICE'][i_]['stochastic_buy'] = 3 elif 40 <= stock['PRICE'][i_]['slow_k'] < 50: stock['PRICE'][i_]['stochastic_buy'] = 2 else: stock['PRICE'][i_]['stochastic_buy'] = 1 if self.common.checkUpward('slow_k', stock['PRICE'][i_ - 1:i_ + 1]): stock['PRICE'][i_]['direction'] = 'up' if (self.common.checkDownward('slow_k', stock['PRICE'][i_ - 2:i_ + 1]) and stock['PRICE'][i_-1]['slow_k'] > stock['PRICE'][i_-1]['slow_d'] and stock['PRICE'][i_]['slow_k'] < stock['PRICE'][i_]['slow_d']): if stock['PRICE'][i_]['slow_k'] > 90: stock['PRICE'][i_]['stochastic_buy'] = -6 elif 90 >= stock['PRICE'][i_]['slow_k'] > 80: stock['PRICE'][i_]['stochastic_buy'] = -5 elif 80 >= stock['PRICE'][i_]['slow_k'] > 70: stock['PRICE'][i_]['stochastic_buy'] = -4 elif 70 >= stock['PRICE'][i_]['slow_k'] > 60: stock['PRICE'][i_]['stochastic_buy'] = -3 elif 60 >= stock['PRICE'][i_]['slow_k'] > 50: stock['PRICE'][i_]['stochastic_buy'] = -2 else: stock['PRICE'][i_]['stochastic_buy'] = -1 if self.common.checkDownward('slow_k', stock['PRICE'][i_ - 1:i_ + 1]): stock['PRICE'][i_]['direction'] = 'down' results = [] for day in stock['PRICE']: results.append({'DATE': day['DATE'], 'fast_k': day['fast_k'], 'slow_k': day['slow_k'], 'slow_d': day['slow_d'], 'stochastic_buy': day['stochastic_buy']}) return results """ def analyze(self, stock): df = pd.DataFrame() df = df.from_dict(stock['PRICE']) df = self.apply(df) for i in range(len(df.fast_k)): if "stochastic_fast_k" not in stock['PRICE'][i]: stock['PRICE'][i]['stochastic_fast_k'] = -1 stock['PRICE'][i]['stochastic_slow_k'] = -1 stock['PRICE'][i]['stochastic_slow_d'] = -1 stock['PRICE'][i]['stochastic_fast_k'] = df.fast_k.values[i] stock['PRICE'][i]['stochastic_slow_k'] = df.slow_k.values[i] stock['PRICE'][i]['stochastic_slow_d'] = df.slow_d.values[i] return if __name__ == "__main__": stochastic = Stochastic()