import pandas as pd from stock.analysis.Common import Common # graph: https://plotly.com/python/candlestick-charts/ # https://www.nanumtrading.com/fx-%EB%B0%B0%EC%9A%B0%EA%B8%B0/%EC%B0%A8%ED%8A%B8-%EB%B3%B4%EC%A1%B0%EC%A7%80%ED%91%9C-%EC%9D%B4%ED%95%B4/06-%EC%9D%BC%EB%AA%A9%EA%B7%A0%ED%98%95%ED%91%9C/ # 일목균형표 - 매매기법 알아보기 !: https://layhope.tistory.com/222 class IchimokuCloud: common = None def __init__(self): self.common = Common() return # c=9, b=26, l=52 def apply(self, df, c=9, b=26, l=52): # 입력받은 값이 dataframe이라는 것을 정의해줌 df = pd.DataFrame(df) # 1. 전환선 = (과거 9일 동안 최고가 + 최저가) / 2 # 당일을 포함한 9일 동안의 최고가와 최저가의 중간 값을 평균으로 나타낸다. changeLine = (df.high.rolling(c).max() + df.low.rolling(c).min()) / 2 # 2. 기준선 = 과거 26일 동안 최고가 + 최저가) / 2 # 당일을 포함한 26일 동안의 최고가와 최저가의 중간 값을 평균으로 나타낸다. baseLine = (df.high.rolling(b).max() + df.low.rolling(b).min()) / 2 # 3. 후행스팬 = 현재 close가격의 26일전 반영 laggingSpan = [df.close.values[i+26] for i in range(len(df.close)-26)] laggingSpan += [df.close.values[len(df.close)-1] for i in range(26)] # 4. 선행스팬 1 = ((기준선 + 전환선) / 2)를 26일 선행하여 배치 # 전환선과 기준선의 평균값을 구해 당일 포함 26일 앞으로 이동시킨 선 (중-단기 구간의 힘을 보여줌) leadingSpan1 = (changeLine + baseLine) / 2 move_LeadingSpan1 = list(leadingSpan1.values) for i in range(b - 1): move_LeadingSpan1.insert(0, None) # 5. 선행스팬 2 = ((최근 52일 동안 최고가 + 최저가) / 2)를 26일 선행하여 배치 # 당일을 포함한 52일 동안의 최고가와 최저가의 평균을 26일 앞으로 이동시킨 선 (장기으로 형성된 선이기 때문에 가장 느리게 변함) leadingSpan2 = (df.high.rolling(l).max() + df.low.rolling(l).min()) / 2 move_LeadingSpan2 = list(leadingSpan2.values) for i in range(l - 1): move_LeadingSpan2.insert(0, None) # leadingSpan2에 맞추어 뒤로 빈 row를 채운다. data = {"DATE": [], "close": [], "diff": [], "open": [], "high": [], "low": [], "volume": [], "avg5": [], "avg10": [], "avg20": [], "avg60": [], "avg120": [], "avg200": [], "avg240": []} for i in range(len(move_LeadingSpan2) - len(df)): #df = df.append({"DATE": None, "close": None, "diff": None, "open": None, "high": None, "low": None, "volume": None,"avg3": None, "avg5": None, "avg7": None, "avg10": None, "avg20": None, "avg30": None, "avg60": None,"avg90": None, "avg100": None, "avg120": None, "avg150": None, "avg180": None, "avg200": None,"avg240": None}, ignore_index=True) data["DATE"].append(None) data["close"].append(None) data["diff"].append(None) data["open"].append(None) data["high"].append(None) data["low"].append(None) data["volume"].append(None) data["avg5"].append(None) data["avg10"].append(None) data["avg20"].append(None) data["avg60"].append(None) data["avg120"].append(None) data["avg200"].append(None) data["avg240"].append(None) df_temp = pd.DataFrame(data) df = pd.concat([df, df_temp]) move_changeLine = list(changeLine.values) for i in range(len(move_LeadingSpan2) - len(move_changeLine)): move_changeLine.append(None) move_baseLine = list(baseLine.values) for i in range(len(move_LeadingSpan2) - len(move_baseLine)): move_baseLine.append(None) for i in range(len(move_LeadingSpan2) - len(move_baseLine)): move_LeadingSpan1.append(None) # dataframe에 컬럼 추가 df = df.assign(changeLine=pd.Series(move_changeLine), baseLine=pd.Series(move_baseLine), laggingSpan=pd.Series(laggingSpan), leadingSpan1=pd.Series(move_LeadingSpan1), leadingSpan2=pd.Series(move_LeadingSpan2)) return df # 일목균형표의 구성을 훑어보면 주가를 선행과 후행으로 과거의 주가를 통해 미래 혹은 현재의 주식의 가격의 추세를 예측해보려는 지표라는 것을 이해할 수 있다. # 또한 구름층의 색을 통해서 주식의 추세를 손쉽게 확인할 수 있을 것 같다는 것도 이해할 수 있다면 끝 ! def analyze(self, stock): df = pd.DataFrame() df = df.from_dict(stock['PRICE']) df = self.apply(df) diff = len(df.changeLine) - len(stock['PRICE']) """ lastDay = stock['PRICE'][len(stock['PRICE']) - 1]['ymd'] tmpLastDay = datetime.datetime.strptime(lastDay, "%Y.%m.%d") for i in range(diff): nextDay = tmpLastDay + datetime.timedelta(days=(i + 1)) stock['PRICE'].append( {"ymd": nextDay.strftime("%Y-%m-%d"), "close": 0, "diff": 0, "open": 0, "high": 0, "low": 0, "volume": 0, "avg3": 0, "avg5": 0, "avg7": 0, "avg10": 0, "avg20": 0, "avg30": 0, "avg60": 0, "avg90": 0, "avg100": 0, "avg120": 0, "avg150": 0, "avg180": 0, "avg200": 0, "avg240": 0}) """ for i in range(len(df.changeLine)-diff): stock['PRICE'][i]['ichimokucloud_changeLine'] = df.changeLine.values[i] stock['PRICE'][i]['ichimokucloud_baseLine'] = df.baseLine.values[i] stock['PRICE'][i]['ichimokucloud_leadingSpan1'] = df.leadingSpan1.values[i] stock['PRICE'][i]['ichimokucloud_leadingSpan2'] = df.leadingSpan2.values[i] for i in range(len(df.changeLine)-diff): if i < len(df.changeLine)-diff-26: stock['PRICE'][i]['ichimokucloud_laggingSpan'] = stock['PRICE'][i + 26]['close'] else: stock['PRICE'][i]['ichimokucloud_laggingSpan'] = -1 return if __name__ == "__main__": ichimokuCloud = IchimokuCloud()