import pandas as pd
import numpy as np
from stock.analysis.Common import Common
from stock.analysis.Stochastic import Stochastic
from stock.analysis.RSI import RSI
from stock.analysis.MACD import MACD
from stock.analysis.IchimokuCloud import IchimokuCloud

class BuySellChecker:

    common = None
    stochastic = None
    rsi = None
    macd = None
    ichimokuCloud = None

    BUY_COUNT = None

    def __init__(self):
        self.common = Common()
        self.stochastic = Stochastic()
        self.rsi = RSI()
        self.macd = MACD()
        self.ichimokuCloud = IchimokuCloud()

        self.BUY_COUNT = 0
        return


    def isYangbong(self, data, i):
        if data['close'][i] > data['open'][i]:
            return True
        else:
            if data['low'][i] < data['close'][i] == data['open'][i] == data['high'][i]:
                return True
            if data['low'][i] < data['open'][i] == data['close'][i] < data['high'][i]:
                return True
        return False

    def isUmbong(self, data, i):
        if data['close'][i] < data['open'][i]:
            return True
        else:
            if data['low'][i] == data['close'][i] == data['open'][i] < data['high'][i]:
                return True
            if data['low'][i] < data['open'][i] == data['close'][i] < data['high'][i]:
                return True
        return False

    # 지난 1시간 30분 동안 12분 선이 20분 선위에 20분 이상 있었는지 체크
    def check_12_over_20_for_30(self, data, i, default=90):
        if i - default < 381:
            return False

        check_12_over_20_for_30 = False
        for c in range(i - default, i - 20):
            if data['avg20'][c] < data['avg20'][i]:
                value = [1 if data['avg20'][d] < data['avg12'][d] else 0 for d in range(c, c + 20)]
                if len(value) == 20 and sum(value) == 20:
                    check_12_over_20_for_30 = True
                    break
        return check_12_over_20_for_30

    # 지난 1시간 동안 3, 6, 9, 12분 선이 10분 이상 20분 선 아래 있었는지 체크
    def check_under_20_for_10(self, data, i, within=60, during=10):
        if i - within < 381:
            return False

        check_under_20_for_10 = False
        for c in range(i - within, i - during):
            value = [1 if max(data['avg3'][d], data['avg6'][d], data['avg9'][d], data['avg12'][d]) < data['avg20'][d] else 0 for d in range(c, c + during)]
            if len(value) == during and sum(value) == during:
                check_under_20_for_10 = True
                break
        return check_under_20_for_10

    def max_min_avg(self, data, i):
        return max(data['avg3'][i], data['avg6'][i], data['avg9'][i], data['avg12'][i], data['avg20'][i]) - min(data['avg3'][i], data['avg6'][i], data['avg9'][i], data['avg12'][i], data['avg20'][i])

    def check_inverse_arrangement_before(self, data, i, within=30, during=5):
        if i - within < 381:
            return False

        inverse_arrangement = False
        for c in range(i-within, i-during):
            value = [1 if data['avg3'][d] < data['avg6'][d] < data['avg9'][d] < data['avg12'][d] < data['avg20'][d] else 0 for d in range(c, c + during)]
            if len(value) == during and sum(value) == during-1:
                inverse_arrangement = True
                break
        return inverse_arrangement

    def checkUpDirection(self, data, i):
        # 0: 무추세, -1: 하락 추세, 1: 상승 추세
        close = data['close'][i]
        #up_count = sum([1 if data['high'][c] < close else 0 for c in range(i-20, i)])
        #down_count = sum([1 if close < data['low'][c] else 0 for c in range(i - 20, i)])

        lagging_change = sum([1 if data['laggingSpan'][c] < data['changeLine'][c] else 0 for c in range(i-20, i)])
        change_lagging = sum([1 if data['laggingSpan'][c] > data['changeLine'][c] else 0 for c in range(i-20, i)])

        if lagging_change>10:
            return 1
        if change_lagging==20:
            return -1
        return 0

    def getBuyPriceAndWeight(self, data, i):
        buy, weight, type = -1, -1, -1

        START_TIME_INDEX = 0
        for c in range(370, len(data.index)):
            if data.index[c].strftime("%H:%M:%S") == "09:01:00":
                START_TIME_INDEX = c
                break

        if i > START_TIME_INDEX:
            # 매수 분석

            if i > 381 + 70:
                if data['macdo'][i-1] < data['macdo'][i] and data['macdo'][i] < -10:
                    buy = max(data["open"][i], data["close"][i])
                    weight = 1
                    type = 1
                    return buy, weight, type
            else:
                if data['macdo'][i - 1] < data['macdo'][i] and data['macdo'][i] < -10:
                    if -2 < data['macds'][381]:
                        buy = max(data["open"][i], data["close"][i])
                        weight = 1
                        type = 1
                        return buy, weight, type

            if data['changeLine'][i - 1] <= data['baseLine'][i - 1] and data['baseLine'][i] < data['changeLine'][i]:
                changeLine_count = sum([1 if data['changeLine'][c] <= data['baseLine'][c] else 0 for c in range(i-30, i)])
                if changeLine_count >= 19 and data['slow_k'][i] < 70:
                    buy = min(data["open"][i], data["close"][i])
                    weight = 1
                    type = 1
                    return buy, weight, type

            """
            if i > 381 + 26:
                if data['laggingSpan'][i-1] < data['avg3'][i-1] and data['avg3'][i] < data['laggingSpan'][i]:
                    if self.checkUpDirection(data, i) == 1:
                        avg20_line = sum([1 if data['avg20'][c] < data['avg20'][c-1] else 0 for c in range(i - 10, i)])
                        if avg20_line < 10:
                            if data["macd"][i] < 0:
                                buy = min(data["open"][i], data["close"][i])
                                weight = 1
                                type = 1
                                return buy, weight, type
            """
        return buy, weight, type

    def getSellPriceAndWeight(self, data, i):
        sell, weight, type = -1, -1, -1

        START_TIME_INDEX = 0
        for c in range(370, len(data.index)):
            if data.index[c].strftime("%H:%M:%S") == "09:01:00":
                START_TIME_INDEX = c
                break

        if i > START_TIME_INDEX:
            # 매도 분석

            if data['changeLine'][i - 1] >= data['laggingSpan'][i - 1] and data['laggingSpan'][i] < data['changeLine'][i]:
                changeLine_count = sum([1 if data['changeLine'][c] <= data['laggingSpan'][c] else 0 for c in range(i - 20, i)])
                if changeLine_count >= 17:
                    sell = min(data["open"][i], data["close"][i])
                    weight = 1
                    type = 1
                    return sell, weight, type

        return sell, weight, type

    def analyze(self, result):
        # 기본 캔들 정보
        open = result["open"]
        close = result["close"]
        high = result["high"]
        low = result["low"]
        vol = result["vol"]
        label = result["label"]

        # 이동 평균
        close_df = pd.DataFrame(close)
        avg3_list = close_df.rolling(window=3).mean().fillna(close[0]).values.tolist()
        avg3 = [item[0] for item in avg3_list]
        avg6_list = close_df.rolling(window=6).mean().fillna(close[0]).values.tolist()
        avg6 = [item[0] for item in avg6_list]
        avg9_list = close_df.rolling(window=9).mean().fillna(close[0]).values.tolist()
        avg9 = [item[0] for item in avg9_list]
        avg12_list = close_df.rolling(window=12).mean().fillna(close[0]).values.tolist()
        avg12 = [item[0] for item in avg12_list]
        avg20_list = close_df.rolling(window=20).mean().fillna(close[0]).values.tolist()
        avg20 = [item[0] for item in avg20_list]

        # 볼린져 밴드
        df = pd.DataFrame(close)
        max20 = df.rolling(window=20).mean()
        stddev20 = df.rolling(window=20).std()
        upper_df = max20 + (stddev20 * 2) # 상단 볼린저 밴드
        lower_df = max20 - (stddev20 * 2) # 하단 볼린저 밴드

        upper, lower = [], []
        for i in range(len(upper_df)):
            if i < 10:
                upper.append(upper_df.values[0][0])
                lower.append(lower_df.values[0][0])
            else:
                upper.append(upper_df.values[i][0])
                lower.append(lower_df.values[i][0])

        point_temp = result["time"]
        STOCK = []
        for i in range(len(open)):
            STOCK.append({'volume': vol[i], 'close': close[i], 'open': open[i], 'high': high[i], 'low': low[i],
                          'avg20': avg20[i]})

        # stochastic
        stochastic_df = self.stochastic.apply(STOCK, n=30, m=5, t=5)
        fast_k = stochastic_df['fast_k'].values.tolist()
        slow_k = stochastic_df['slow_k'].values.tolist()
        slow_d = stochastic_df['slow_d'].values.tolist()

        # macd
        macd_df = self.macd.apply(STOCK, short=12, long=26, t=9)
        macd = macd_df['macd'].values.tolist()
        macds = macd_df['macds'].values.tolist()
        macdo = macd_df['macdo'].values.tolist()

        # rsi
        rsi_df = self.rsi.apply(STOCK, period=30, window=5)
        rsi = rsi_df['rsi'].values.tolist()
        rsis = rsi_df['rsis'].values.tolist()

        # ichimokuCloud
        ichimokuCloud_df = self.ichimokuCloud.apply(STOCK, c=9, b=26, l=52)
        ichimokuCloud_df = ichimokuCloud_df[:len(ichimokuCloud_df) - 51]
        changeLine = ichimokuCloud_df['changeLine'].values.tolist()
        baseLine = ichimokuCloud_df['baseLine'].values.tolist()
        laggingSpan = ichimokuCloud_df['laggingSpan'].values.tolist()
        leadingSpan1 = ichimokuCloud_df['leadingSpan1'].values.tolist()
        leadingSpan2 = ichimokuCloud_df['leadingSpan2'].values.tolist()

        # 결과
        temp = {
            "date": point_temp,
            "open": open, "high": high, "low": low, "close": close, "volume": vol,
            "avg3": avg3,"avg6": avg6,"avg9": avg9,"avg12": avg12, "avg20": avg20,
            "upper": upper, "lower": lower,
            "macd": macd, "macds": macds, "macdo": macdo,
            "fast_k": fast_k, "slow_k": slow_k, "slow_d": slow_d,
            "rsi": rsi, "rsis": rsis,
            "changeLine": changeLine, "baseLine": baseLine, "laggingSpan": laggingSpan, "leadingSpan1": leadingSpan1, "leadingSpan2": leadingSpan2,

            "label": label
        }

        data = pd.DataFrame(temp)
        df_final_time = pd.DatetimeIndex(point_temp)
        data.index = df_final_time

        data = data.fillna(close[0])
        return data

    def analyze1(self, result):
        # 기본 캔들 정보
        open = result["open"]
        close = result["close"]
        high = result["high"]
        low = result["low"]
        vol = result["vol"]
        label = result["label"]

        # 캔들 정보 연산
        height = [close[i] - open[i] for i in range(0, len(close))]
        top_tail_height = [high[i] - max(open[i], close[i]) for i in range(0, len(close))]
        bottom_tail_height = [min(open[i], close[i]) - low[i] for i in range(0, len(close))]

        # 이동 평균
        close_df = pd.DataFrame(close)
        avg3_list = close_df.rolling(window=3).mean().fillna(close[0]).values.tolist()
        avg3 = [item[0] for item in avg3_list]
        avg6_list = close_df.rolling(window=6).mean().fillna(close[0]).values.tolist()
        avg6 = [item[0] for item in avg6_list]
        avg9_list = close_df.rolling(window=9).mean().fillna(close[0]).values.tolist()
        avg9 = [item[0] for item in avg9_list]
        avg12_list = close_df.rolling(window=12).mean().fillna(close[0]).values.tolist()
        avg12 = [item[0] for item in avg12_list]
        avg27_list = close_df.rolling(window=27).mean().fillna(close[0]).values.tolist()
        avg27 = [item[0] for item in avg27_list]
        avg54_list = close_df.rolling(window=54).mean().fillna(close[0]).values.tolist()
        avg54 = [item[0] for item in avg54_list]

        abs_avg_1 = [max(avg3[i], avg6[i], avg9[i], avg12[i], avg27[i], avg54[i]) - min(avg3[i], avg6[i], avg9[i], avg12[i], avg27[i], avg54[i]) for i in range(0, len(close))]
        abs_avg_2 = [max(avg3[i], avg6[i], avg9[i], avg12[i], avg27[i]) - min(avg3[i], avg6[i], avg9[i], avg12[i], avg27[i]) for i in range(0, len(close))]
        abs_avg_3 = [max(avg3[i], avg6[i], avg9[i], avg12[i]) - min(avg3[i], avg6[i], avg9[i], avg12[i]) for i in range(0, len(close))]
        abs_avg_4 = [max(avg3[i], avg6[i], avg9[i]) - min(avg3[i], avg6[i], avg9[i]) for i in range(0, len(close))]
        abs_avg_5 = [max(avg3[i], avg6[i]) - min(avg3[i], avg6[i]) for i in range(0, len(close))]

        diff_open, diff_close, diff_low, diff_high = [], [], [], []
        diff_open.append(0)
        for i in range(1, len(open)):
            diff_open.append(open[i] - open[i - 1])
        diff_close.append(0)
        for i in range(1, len(close)):
            diff_close.append(close[i] - close[i - 1])
        diff_low.append(0)
        for i in range(1, len(low)):
            diff_low.append(low[i] - low[i - 1])
        diff_high.append(0)
        for i in range(1, len(high)):
            diff_high.append(high[i] - high[i - 1])

        diff_avg3, diff_avg6, diff_avg9, diff_avg12, diff_avg27, diff_avg54 = [], [], [], [], [], []
        diff_avg3.append(0)
        for i in range(1, len(avg3)):
            diff_avg3.append(avg3[i]-avg3[i-1])
        diff_avg6.append(0)
        for i in range(1, len(avg6)):
            diff_avg6.append(avg6[i] - avg6[i - 1])
        diff_avg9.append(0)
        for i in range(1, len(avg9)):
            diff_avg9.append(avg9[i] - avg9[i - 1])
        diff_avg12.append(0)
        for i in range(1, len(avg12)):
            diff_avg12.append(avg12[i] - avg12[i - 1])
        diff_avg27.append(0)
        for i in range(1, len(avg27)):
            diff_avg27.append(avg27[i] - avg27[i - 1])
        diff_avg54.append(0)
        for i in range(1, len(avg54)):
            diff_avg54.append(avg54[i] - avg54[i - 1])


        diff_avg3_avg6 = [avg3[i] - avg6[i] for i in range(0, len(close))]
        diff_avg3_avg9 = [avg3[i] - avg9[i] for i in range(0, len(close))]
        diff_avg3_avg12 = [avg3[i] - avg12[i] for i in range(0, len(close))]
        diff_avg3_avg27 = [avg3[i] - avg27[i] for i in range(0, len(close))]
        diff_avg3_avg54 = [avg3[i] - avg54[i] for i in range(0, len(close))]
        diff_avg6_avg9 = [avg6[i] - avg9[i] for i in range(0, len(close))]
        diff_avg6_avg12 = [avg6[i] - avg12[i] for i in range(0, len(close))]
        diff_avg6_avg27 = [avg6[i] - avg27[i] for i in range(0, len(close))]
        diff_avg6_avg54 = [avg6[i] - avg54[i] for i in range(0, len(close))]
        diff_avg9_avg12 = [avg9[i] - avg12[i] for i in range(0, len(close))]
        diff_avg9_avg27 = [avg9[i] - avg27[i] for i in range(0, len(close))]
        diff_avg9_avg54 = [avg9[i] - avg54[i] for i in range(0, len(close))]
        diff_avg12_avg27 = [avg12[i] - avg27[i] for i in range(0, len(close))]
        diff_avg12_avg54 = [avg12[i] - avg54[i] for i in range(0, len(close))]
        diff_avg27_avg54 = [avg27[i] - avg54[i] for i in range(0, len(close))]

        # 볼린져 밴드
        df = pd.DataFrame(close)
        max20 = df.rolling(window=20).mean()
        stddev20 = df.rolling(window=20).std()
        upper_df = max20 + (stddev20 * 2) # 상단 볼린저 밴드
        lower_df = max20 - (stddev20 * 2) # 하단 볼린저 밴드

        upper, lower = [], []
        for i in range(len(upper_df)):
            if i < 10:
                upper.append(upper_df.values[0][0])
                lower.append(lower_df.values[0][0])
            else:
                upper.append(upper_df.values[i][0])
                lower.append(lower_df.values[i][0])

        point_temp = result["time"]
        STOCK = []
        for i in range(len(open)):
            STOCK.append({'volume': vol[i], 'close': close[i], 'open': open[i], 'high': high[i], 'low': low[i],
                          'avg3': avg3[i], 'avg6': avg6[i],'avg9': avg9[i],'avg12': avg12[i],'avg27': avg27[i],'avg54': avg54[i]})

        # stochastic
        stochastic_df = self.stochastic.apply(STOCK, n=30, m=5, t=5)
        fast_k = stochastic_df['fast_k'].values.tolist()
        slow_k = stochastic_df['slow_k'].values.tolist()
        slow_d = stochastic_df['slow_d'].values.tolist()

        # macd
        macd_df = self.macd.apply(STOCK, short=12, long=26, t=9)
        macd = macd_df['macd'].values.tolist()
        macds = macd_df['macds'].values.tolist()
        macdo = macd_df['macdo'].values.tolist()

        # rsi
        rsi_df = self.rsi.apply(STOCK, period=30, window=5)
        rsi = rsi_df['rsi'].values.tolist()
        rsis = rsi_df['rsis'].values.tolist()

        # ichimokuCloud
        ichimokuCloud_df = self.ichimokuCloud.apply(STOCK, c=9, b=26, l=52)
        ichimokuCloud_df = ichimokuCloud_df[:len(ichimokuCloud_df) - 51]
        changeLine = ichimokuCloud_df['changeLine'].values.tolist()
        baseLine = ichimokuCloud_df['baseLine'].values.tolist()
        leadingSpan1 = ichimokuCloud_df['leadingSpan1'].values.tolist()
        leadingSpan2 = ichimokuCloud_df['leadingSpan2'].values.tolist()

        # 간격
        ##### 볼린져 밴드
        diff_upper_lower = [upper[i] - lower[i] for i in range(0, len(upper))]
        diff_open_lower = [open[i] - lower[i] for i in range(0, len(open))]
        diff_open_upper = [open[i] - upper[i] for i in range(0, len(open))]
        diff_close_lower = [close[i] - lower[i] for i in range(0, len(close))]
        diff_close_upper = [close[i] - upper[i] for i in range(0, len(close))]
        diff_high_lower = [high[i] - lower[i] for i in range(0, len(high))]
        diff_high_upper = [high[i] - upper[i] for i in range(0, len(high))]
        diff_low_lower = [low[i] - lower[i] for i in range(0, len(low))]
        diff_low_upper = [low[i] - upper[i] for i in range(0, len(low))]


        ##### 일목균형표
        diff_lead1_lead2 = [leadingSpan1[i] - leadingSpan2[i] for i in range(0, len(leadingSpan1))]
        diff_change_base = [changeLine[i] - baseLine[i] for i in range(0, len(baseLine))]
        diff_base_lead1 = [baseLine[i] - leadingSpan1[i] for i in range(0, len(baseLine))]
        diff_base_lead2 = [baseLine[i] - leadingSpan2[i] for i in range(0, len(baseLine))]
        diff_change_lead1 = [changeLine[i] - leadingSpan1[i] for i in range(0, len(changeLine))]
        diff_change_lead2 = [changeLine[i] - leadingSpan2[i] for i in range(0, len(changeLine))]
        diff_open_lead2 = [open[i] - leadingSpan2[i] for i in range(0, len(open))]
        diff_open_lead1 = [open[i] - leadingSpan1[i] for i in range(0, len(open))]
        diff_open_change = [open[i] - changeLine[i] for i in range(0, len(open))]
        diff_open_base = [open[i] - baseLine[i] for i in range(0, len(open))]
        diff_close_lead2 = [close[i] - leadingSpan2[i] for i in range(0, len(close))]
        diff_close_lead1 = [close[i] - leadingSpan1[i] for i in range(0, len(close))]
        diff_close_change = [close[i] - changeLine[i] for i in range(0, len(close))]
        diff_close_base = [close[i] - baseLine[i] for i in range(0, len(close))]
        diff_high_lead2 = [high[i] - leadingSpan2[i] for i in range(0, len(high))]
        diff_high_lead1 = [high[i] - leadingSpan1[i] for i in range(0, len(high))]
        diff_high_change = [high[i] - changeLine[i] for i in range(0, len(high))]
        diff_high_base = [high[i] - baseLine[i] for i in range(0, len(high))]
        diff_low_lead2 = [low[i] - leadingSpan2[i] for i in range(0, len(low))]
        diff_low_lead1 = [low[i] - leadingSpan1[i] for i in range(0, len(low))]
        diff_low_change = [low[i] - changeLine[i] for i in range(0, len(low))]
        diff_low_base = [low[i] - baseLine[i] for i in range(0, len(low))]
        diff_macd_macds = [macd[i] - macds[i] for i in range(0, len(macd))]
        diff_slowk_slowd = [slow_k[i] - slow_d[i] for i in range(0, len(slow_k))]
        diff_rsi_rsis = [rsi[i] - rsis[i] for i in range(0, len(rsi))]


        diff_macd, diff_macdo, diff_macds = [], [], []
        diff_macd.append(0)
        for i in range(1, len(macd)):
            diff_macd.append(macd[i] - macd[i - 1])
        diff_macdo.append(0)
        for i in range(1, len(macdo)):
            diff_macdo.append(macdo[i] - macdo[i - 1])
        diff_macds.append(0)
        for i in range(1, len(macds)):
            diff_macds.append(macds[i] - macds[i - 1])

        diff_fast_k, diff_slow_k, diff_slow_d = [], [], []
        diff_fast_k.append(0)
        for i in range(1, len(fast_k)):
            diff_fast_k.append(fast_k[i] - fast_k[i - 1])
        diff_slow_k.append(0)
        for i in range(1, len(slow_k)):
            diff_slow_k.append(slow_k[i] - slow_k[i - 1])
        diff_slow_d.append(0)
        for i in range(1, len(slow_d)):
            diff_slow_d.append(slow_d[i] - slow_d[i - 1])

        diff_rsi, diff_rsis = [], []
        diff_rsi.append(0)
        for i in range(1, len(rsi)):
            diff_rsi.append(rsi[i] - rsi[i - 1])
        diff_rsis.append(0)
        for i in range(1, len(rsis)):
            diff_rsis.append(rsis[i] - rsis[i - 1])

        diff_changeLine, diff_baseLine = [], []
        diff_changeLine.append(0)
        for i in range(1, len(changeLine)):
            diff_changeLine.append(changeLine[i] - changeLine[i - 1])
        diff_baseLine.append(0)
        for i in range(1, len(baseLine)):
            diff_baseLine.append(baseLine[i] - baseLine[i - 1])

        diff_upper, diff_lower = [], []
        diff_upper.append(0)
        for i in range(1, len(upper)):
            diff_upper.append(upper[i] - upper[i - 1])
        diff_lower.append(0)
        for i in range(1, len(lower)):
            diff_lower.append(lower[i] - lower[i - 1])

        # 결과
        temp = {
            "date": point_temp,
            "open": open, "high": high, "low": low, "close": close, "volume": vol,
            "avg3": avg3, "avg6": avg6, "avg9": avg9, "avg12": avg12, "avg27": avg27, "avg54": avg54,
            "upper": upper, "lower": lower,
            "macd": macd, "macds": macds, "macdo": macdo,
            "fast_k": fast_k, "slow_k": slow_k, "slow_d": slow_d,
            "rsi": rsi, "rsis": rsis,
            "changeLine": changeLine, "baseLine": baseLine, "leadingSpan1": leadingSpan1, "leadingSpan2": leadingSpan2,
            "height": height, "top_tail_height": top_tail_height, "bottom_tail_height": bottom_tail_height,
            "abs_avg_1": abs_avg_1, "abs_avg_2": abs_avg_2, "abs_avg_3": abs_avg_3, "abs_avg_4": abs_avg_4, "abs_avg_5": abs_avg_5,
            "diff_open": diff_open, "diff_close": diff_close, "diff_low": diff_low, "diff_high": diff_high,
            "diff_avg3":diff_avg3, "diff_avg6":diff_avg6, "diff_avg9":diff_avg9, "diff_avg12":diff_avg12, "diff_avg27":diff_avg27, "diff_avg54":diff_avg54,
            "diff_macd":diff_macd, "diff_macdo":diff_macdo, "diff_macds":diff_macds,
            "diff_fast_k":diff_fast_k, "diff_slow_k":diff_slow_k, "diff_slow_d":diff_slow_d,
            "diff_rsi":diff_rsi, "diff_rsis":diff_rsis,
            "diff_changeLine":diff_changeLine, "diff_baseLine":diff_baseLine,
            "diff_upper":diff_upper, "diff_lower":diff_lower,
            "diff_avg3_avg6": diff_avg3_avg6,
            "diff_avg3_avg9": diff_avg3_avg9,
            "diff_avg3_avg12": diff_avg3_avg12,
            "diff_avg3_avg27": diff_avg3_avg27,
            "diff_avg3_avg54": diff_avg3_avg54,
            "diff_avg6_avg9": diff_avg6_avg9,
            "diff_avg6_avg12": diff_avg6_avg12,
            "diff_avg6_avg27": diff_avg6_avg27,
            "diff_avg6_avg54": diff_avg6_avg54,
            "diff_avg9_avg12": diff_avg9_avg12,
            "diff_avg9_avg27": diff_avg9_avg27,
            "diff_avg9_avg54": diff_avg9_avg54,
            "diff_avg12_avg27": diff_avg12_avg27,
            "diff_avg12_avg54": diff_avg12_avg54,
            "diff_avg27_avg54": diff_avg27_avg54,
            "diff_upper_lower": diff_upper_lower,
            "diff_open_lower": diff_open_lower,
            "diff_open_upper": diff_open_upper,
            "diff_close_lower": diff_close_lower,
            "diff_close_upper": diff_close_upper,
            "diff_high_lower": diff_high_lower,
            "diff_high_upper": diff_high_upper,
            "diff_low_lower": diff_low_lower,
            "diff_low_upper": diff_low_upper,
            "diff_lead1_lead2": diff_lead1_lead2,
            "diff_change_base": diff_change_base,
            "diff_base_lead1": diff_base_lead1,
            "diff_base_lead2": diff_base_lead2,
            "diff_change_lead1": diff_change_lead1,
            "diff_change_lead2": diff_change_lead2,
            "diff_open_lead2": diff_open_lead2,
            "diff_open_lead1": diff_open_lead1,
            "diff_open_change": diff_open_change,
            "diff_open_base": diff_open_base,
            "diff_close_lead2": diff_close_lead2,
            "diff_close_lead1": diff_close_lead1,
            "diff_close_change": diff_close_change,
            "diff_close_base": diff_close_base,
            "diff_high_lead2": diff_high_lead2,
            "diff_high_lead1": diff_high_lead1,
            "diff_high_change": diff_high_change,
            "diff_high_base": diff_high_base,
            "diff_low_lead2": diff_low_lead2,
            "diff_low_lead1": diff_low_lead1,
            "diff_low_change": diff_low_change,
            "diff_low_base": diff_low_base,
            "diff_macd_macds": diff_macd_macds,
            "diff_slowk_slowd": diff_slowk_slowd,
            "diff_rsi_rsis": diff_rsi_rsis,

            "label": label
        }

        data = pd.DataFrame(temp)
        df_final_time = pd.DatetimeIndex(point_temp)
        data.index = df_final_time

        data = data.fillna(close[0])
        return data

    def write(self, outFp, df, i):
        outFp.write(str(df["macd"][i]) + "\t")
        outFp.write(str(df["macds"][i]) + "\t")
        outFp.write(str(df["macdo"][i]) + "\t")
        outFp.write(str(df["fast_k"][i]) + "\t")
        outFp.write(str(df["slow_k"][i]) + "\t")
        outFp.write(str(df["slow_d"][i]) + "\t")
        outFp.write(str(df["rsi"][i]) + "\t")
        outFp.write(str(df["rsis"][i]) + "\t")
        outFp.write(str(df["height"][i]) + "\t")
        outFp.write(str(df["top_tail_height"][i]) + "\t")
        outFp.write(str(df["bottom_tail_height"][i]) + "\t")
        outFp.write(str(df["abs_avg_1"][i]) + "\t")
        outFp.write(str(df["abs_avg_2"][i]) + "\t")
        outFp.write(str(df["abs_avg_3"][i]) + "\t")
        outFp.write(str(df["abs_avg_4"][i]) + "\t")
        outFp.write(str(df["abs_avg_5"][i]) + "\t")
        outFp.write(str(df["diff_open"][i]) + "\t")
        outFp.write(str(df["diff_close"][i]) + "\t")
        outFp.write(str(df["diff_low"][i]) + "\t")
        outFp.write(str(df["diff_high"][i]) + "\t")
        outFp.write(str(df["diff_avg3"][i]) + "\t")
        outFp.write(str(df["diff_avg6"][i]) + "\t")
        outFp.write(str(df["diff_avg9"][i]) + "\t")
        outFp.write(str(df["diff_avg12"][i]) + "\t")
        outFp.write(str(df["diff_avg27"][i]) + "\t")
        outFp.write(str(df["diff_avg54"][i]) + "\t")
        outFp.write(str(df["diff_macd"][i]) + "\t")
        outFp.write(str(df["diff_macdo"][i]) + "\t")
        outFp.write(str(df["diff_macds"][i]) + "\t")
        outFp.write(str(df["diff_fast_k"][i]) + "\t")
        outFp.write(str(df["diff_slow_k"][i]) + "\t")
        outFp.write(str(df["diff_slow_d"][i]) + "\t")
        outFp.write(str(df["diff_rsi"][i]) + "\t")
        outFp.write(str(df["diff_rsis"][i]) + "\t")
        outFp.write(str(df["diff_changeLine"][i]) + "\t")
        outFp.write(str(df["diff_baseLine"][i]) + "\t")
        outFp.write(str(df["diff_upper"][i]) + "\t")
        outFp.write(str(df["diff_lower"][i]) + "\t")
        outFp.write(str(df["diff_avg3_avg6"][i]) + "\t")
        outFp.write(str(df["diff_avg3_avg9"][i]) + "\t")
        outFp.write(str(df["diff_avg3_avg12"][i]) + "\t")
        outFp.write(str(df["diff_avg3_avg27"][i]) + "\t")
        outFp.write(str(df["diff_avg3_avg54"][i]) + "\t")
        outFp.write(str(df["diff_avg6_avg9"][i]) + "\t")
        outFp.write(str(df["diff_avg6_avg12"][i]) + "\t")
        outFp.write(str(df["diff_avg6_avg27"][i]) + "\t")
        outFp.write(str(df["diff_avg6_avg54"][i]) + "\t")
        outFp.write(str(df["diff_avg9_avg12"][i]) + "\t")
        outFp.write(str(df["diff_avg9_avg27"][i]) + "\t")
        outFp.write(str(df["diff_avg9_avg54"][i]) + "\t")
        outFp.write(str(df["diff_avg12_avg27"][i]) + "\t")
        outFp.write(str(df["diff_avg12_avg54"][i]) + "\t")
        outFp.write(str(df["diff_avg27_avg54"][i]) + "\t")
        outFp.write(str(df["diff_upper_lower"][i]) + "\t")
        outFp.write(str(df["diff_open_lower"][i]) + "\t")
        outFp.write(str(df["diff_open_upper"][i]) + "\t")
        outFp.write(str(df["diff_close_lower"][i]) + "\t")
        outFp.write(str(df["diff_close_upper"][i]) + "\t")
        outFp.write(str(df["diff_high_lower"][i]) + "\t")
        outFp.write(str(df["diff_high_upper"][i]) + "\t")
        outFp.write(str(df["diff_low_lower"][i]) + "\t")
        outFp.write(str(df["diff_low_upper"][i]) + "\t")
        outFp.write(str(df["diff_lead1_lead2"][i]) + "\t")
        outFp.write(str(df["diff_change_base"][i]) + "\t")
        outFp.write(str(df["diff_base_lead1"][i]) + "\t")
        outFp.write(str(df["diff_base_lead2"][i]) + "\t")
        outFp.write(str(df["diff_change_lead1"][i]) + "\t")
        outFp.write(str(df["diff_change_lead2"][i]) + "\t")
        outFp.write(str(df["diff_open_lead2"][i]) + "\t")
        outFp.write(str(df["diff_open_lead1"][i]) + "\t")
        outFp.write(str(df["diff_open_change"][i]) + "\t")
        outFp.write(str(df["diff_open_base"][i]) + "\t")
        outFp.write(str(df["diff_close_lead2"][i]) + "\t")
        outFp.write(str(df["diff_close_lead1"][i]) + "\t")
        outFp.write(str(df["diff_close_change"][i]) + "\t")
        outFp.write(str(df["diff_close_base"][i]) + "\t")
        outFp.write(str(df["diff_high_lead2"][i]) + "\t")
        outFp.write(str(df["diff_high_lead1"][i]) + "\t")
        outFp.write(str(df["diff_high_change"][i]) + "\t")
        outFp.write(str(df["diff_high_base"][i]) + "\t")
        outFp.write(str(df["diff_low_lead2"][i]) + "\t")
        outFp.write(str(df["diff_low_lead1"][i]) + "\t")
        outFp.write(str(df["diff_low_change"][i]) + "\t")
        outFp.write(str(df["diff_low_base"][i]) + "\t")
        outFp.write(str(df["diff_macd_macds"][i]) + "\t")
        outFp.write(str(df["diff_slowk_slowd"][i]) + "\t")
        outFp.write(str(df["diff_rsi_rsis"][i]) + "\t")
        outFp.write(str(df["label"][i]) + "\n")
        return

    def checkTransaction(self, data, stock_code, isRealTime=True):
        # 4일치 중에서 앞에 2일은 제거한다.
        date = data['date'].dt.date.unique().tolist()
        data = data[data['date'].dt.date != date[0]]
        data = data[data['date'].dt.date != date[1]]

        # 어제 오늘 데이터로 분석
        bsLine = {}
        size = len(data["close"])

        if isRealTime:
            # isRealTime=True, 실시간 적용
            last_index = size - 1

            buy, buy_weight, buy_type = self.getBuyPriceAndWeight(data, last_index)
            sell, sell_weight, sell_type = self.getSellPriceAndWeight(data, last_index)

            if buy > -1 or self.BUY_COUNT == 1:
                if buy == -1 or self.BUY_COUNT == 1:
                    buy = min(data['open'][last_index], data['close'][last_index])
                    buy_weight = 1
                self.BUY_COUNT += 1

            bsLine['buy'] = [buy]
            bsLine['buy_weight'] = [buy_weight]
            bsLine['sell'] = [sell]
            bsLine['sell_weight'] = [sell_weight]

            if self.BUY_COUNT > 1:
                self.BUY_COUNT = 0
        else:
            # Type=False, 시뮬레이션 적용
            bsLine['buy'] = [-1 for i in range(size)]
            bsLine['buy_weight'] = [-1 for i in range(size)]
            bsLine['sell'] = [-1 for i in range(size)]
            bsLine['sell_weight'] = [-1 for i in range(size)]

            for i in range(size):
                buy, buy_weight, buy_type = self.getBuyPriceAndWeight(data, i)
                sell, sell_weight, sell_type = self.getSellPriceAndWeight(data, i)

                if buy > -1 or self.BUY_COUNT == 1:
                    if buy == -1 or self.BUY_COUNT == 1:
                        buy = data['low'][i]
                        buy_weight = 1
                    self.BUY_COUNT += 1

                bsLine['buy'][i] = buy
                bsLine['buy_weight'][i] = buy_weight
                bsLine['sell'][i] = sell
                bsLine['sell_weight'][i] = sell_weight

                if self.BUY_COUNT > 1:
                    self.BUY_COUNT = 0

        return bsLine, data


    def checkTransactionML(self, data, stock_code, predY, isRealTime=True):
        # 4일치 중에서 앞에 2일은 제거한다.
        date = data['date'].dt.date.unique().tolist()
        data = data[data['date'].dt.date != date[0]]
        data = data[data['date'].dt.date != date[1]]

        # 어제 오늘 데이터로 분석
        bsLine = {}
        size = len(data["close"])
        if isRealTime:
            # isRealTime=True, 실시간 적용
            last_index = size - 1

            # Type=False, 시뮬레이션 적용
            bsLine['buy'] = [-1 for i in range(size)]
            bsLine['buy_weight'] = [-1 for i in range(size)]
            bsLine['sell'] = [-1 for i in range(size)]
            bsLine['sell_weight'] = [-1 for i in range(size)]

            sell, sell_weight, buy, buy_weight = -1, -1, -1, -1
            if predY[last_index] == 1:
                sell = int((data["open"][last_index] + data["close"][last_index]) / 2)
                sell_weight = 1
            elif predY[last_index] == 2:
                buy = int((data["open"][last_index] + data["close"][last_index]) / 2)
                buy_weight = 1

            bsLine['buy'] = [buy]
            bsLine['buy_weight'] = [buy_weight]
            bsLine['sell'] = [sell]
            bsLine['sell_weight'] = [sell_weight]
        else:
            # Type=False, 시뮬레이션 적용
            bsLine['buy'] = [-1 for i in range(size)]
            bsLine['buy_weight'] = [-1 for i in range(size)]
            bsLine['sell'] = [-1 for i in range(size)]
            bsLine['sell_weight'] = [-1 for i in range(size)]

            for i in range(size):
                if predY[i] == 1:
                    bsLine['sell'][i] = int((data["open"][i] + data["close"][i]) / 2)
                    bsLine['sell_weight'][i] = 1
                elif predY[i] == 2:
                    bsLine['buy'][i] = int((data["open"][i] + data["close"][i]) / 2)
                    bsLine['buy_weight'][i] = 1

        return bsLine, data