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']['close'][i + 26]
            else:
                stock['PRICE'][i]['ichimokucloud_laggingSpan'] = -1
        return


if __name__ == "__main__":
    ichimokuCloud = IchimokuCloud()
