{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2022-01-22T03:34:58.45284Z","iopub.execute_input":"2022-01-22T03:34:58.453265Z","iopub.status.idle":"2022-01-22T03:34:58.470962Z","shell.execute_reply.started":"2022-01-22T03:34:58.453215Z","shell.execute_reply":"2022-01-22T03:34:58.470169Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"TRAIN_CSV = '/kaggle/input/g-research-crypto-forecasting/train.csv'\nASSET_DETAILS_CSV = '/kaggle/input/g-research-crypto-forecasting/asset_details.csv'","metadata":{"execution":{"iopub.status.busy":"2022-01-22T03:34:12.22607Z","iopub.execute_input":"2022-01-22T03:34:12.226518Z","iopub.status.idle":"2022-01-22T03:34:12.254817Z","shell.execute_reply.started":"2022-01-22T03:34:12.226396Z","shell.execute_reply":"2022-01-22T03:34:12.254043Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train = pd.read_csv(TRAIN_CSV)\ndf_train","metadata":{"execution":{"iopub.status.busy":"2022-01-22T03:35:02.938088Z","iopub.execute_input":"2022-01-22T03:35:02.93865Z","iopub.status.idle":"2022-01-22T03:36:04.548978Z","shell.execute_reply.started":"2022-01-22T03:35:02.938611Z","shell.execute_reply":"2022-01-22T03:36:04.547918Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_test = pd.read_csv('../input/g-research-crypto-forecasting/example_test.csv')\ndf_test.head()","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Feature Engineering","metadata":{}},{"cell_type":"code","source":"# define function to compute log returns\ndef log_return(series, periods=5):\n    return np.log(series).diff(periods=periods)\n\n# Two features from the competition tutorial\ndef upper_shadow(df): return df['High'] - np.maximum(df['Close'], df['Open'])\ndef lower_shadow(df): return np.minimum(df['Close'], df['Open']) - df['Low']","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"***copy from [1st Place of Jane Street](https://www.kaggle.com/yamqwe/1st-place-of-jane-street-adapted-to-crypto#Feature-Engineering-%F0%9F%94%AC)***","metadata":{}},{"cell_type":"code","source":"# simple and common\n\ndef upper_shadow(df): return df['High'] - np.maximum(df['Close'], df['Open'])\ndef lower_shadow(df): return np.minimum(df['Close'], df['Open']) - df['Low']\n\n# Credit: https://www.kaggle.com/swaralipibose/64-new-features-with-autoencoders/code\ndef get_features(df, row = False):\n    df_feat = df[['Count', 'Open', 'High', 'Low', 'Close', 'Volume', 'VWAP']].copy()\n    df_feat['upper_Shadow'] = upper_shadow(df_feat)\n    df_feat['lower_Shadow'] = lower_shadow(df_feat)\n    df_feat[\"high_div_low\"] = df_feat[\"High\"] / df_feat[\"Low\"]\n    df_feat['trade'] = df_feat['Close'] - df_feat['Open']\n    df_feat['gtrade'] = df_feat['trade'] / df_feat['Count']\n    df_feat['shadow1'] = df_feat['trade'] / df_feat['Volume']\n    df_feat['shadow3'] = df_feat['upper_Shadow'] / df_feat['Volume']\n    df_feat['shadow5'] = df_feat['lower_Shadow'] / df_feat['Volume']\n    df_feat['diff1'] = df_feat['Volume'] - df_feat['Count']\n    df_feat['mean1'] = (df_feat['shadow5'] + df_feat['shadow3']) / 2\n    df_feat['mean2'] = (df_feat['shadow1'] + df_feat['Volume']) / 2\n    df_feat['mean3'] = (df_feat['trade'] + df_feat['gtrade']) / 2\n    df_feat['mean4'] = (df_feat['diff1'] + df_feat['upper_Shadow']) / 2\n    df_feat['mean5'] = (df_feat['diff1'] + df_feat['lower_Shadow']) / 2\n    return df_feat","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"***Copy from [JP](https://www.kaggle.com/tensorchoko/g-research-for-single-coins-valid-train-jp-en)***","metadata":{}},{"cell_type":"code","source":"def add_features(df):\n    \n    df[\"high_div_low\"] = df[\"High\"] / df[\"Low\"]\n    df[\"open_sub_close\"] = df[\"Open\"] - df[\"Close\"]\n    #df[\"open_sub_close2\"] = df[\"Open\"] / df[\"Close\"] #\n    df[\"open_sub_close_1\"] = df[\"open_sub_close\"].shift(-4)\n    \n    df['Open_shift-1'] = df['Open'].shift(-1)\n    df['Open_shift-4'] = df['Open'].shift(-4)\n    df['Open_shift-7'] = df['Open'].shift(-7)\n    \n    df['Open_shift1'] = df['Open'].shift(1)\n    \n    #df['Close_shift-1'] = df['Close'].shift(-1)\n    \n    df['close_log1'] = log_return(df['Close'],periods=1)\n    df['close_log4'] = log_return(df['Close'],periods=4)\n    #df['close_log7'] = log_return(df['Close'],periods=7)#\n    \n    #df['open_log1'] = log_return(df['Open'],periods=1)#\n    \n    #df['close_log4-1'] =df['close_log4'].shift(-1) #\n    #df['avg5'] =  ta.SMA(df['Open'], timeperiod=5) #移動平均\n    #df['avg25'] = ta.SMA(df['Open'], timeperiod=25) #df['Open'].rolling(25).mean()\n    df['avg75'] = ta.SMA(df['Open'], timeperiod=75 )#df['Open'].rolling(75).mean()\n    df['ema']   =ta.EMA(df['Open'], timeperiod=20) \n    df['willr'] = ta.WILLR(df['High'], df['Low'],np.array(df.loc[:, 'Close']), timeperiod=14)\n    times = pd.to_datetime(df[\"timestamp\"],unit=\"s\",infer_datetime_format=True)\n    df[\"hour\"] = times.dt.hour  \n    df[\"dayofweek\"] = times.dt.dayofweek \n    df[\"day\"] = times.dt.day \n    \n    #df['RSI-9'] = ta.RSI(df['Close'], timeperiod=9)#\n    df['RSI'] = ta.RSI(df['Close'], timeperiod=14)\n    df['RSI1'] = df['RSI'].shift(-1)\n    df['RSI4'] = df['RSI'].shift(-4)\n    df['RSI7'] = df['RSI'].shift(-7)\n    df['RSI10'] = df['RSI'].shift(-10)\n    df['RSI13'] = df['RSI'].shift(-13) \n    df['RSI16'] = df['RSI'].shift(-16)  \n    df['RSI~4'] = df['RSI'].shift(4)  #\n    #df['RSI~7'] = df['RSI'].shift(7)  #\n    #df['RSI+1'] = df['RSI'].shift(1)\n    \n    df['MACD'], df['macdsignal'], df['MACD_HIST'] = ta.MACD(df['Close'], fastperiod=12, slowperiod=26, signalperiod=9)\n    #df['MACD1'] = df['MACD'].shift(-1)\n    #df['MACD4'] = df['MACD'].shift(-4)\n    #df['MACD7'] = df['MACD'].shift(-7)\n    #df['MACD_HIST-4'] =df['MACD_HIST'].shift(4)# \n    df['MACD_HIST1'] =df['MACD_HIST'].shift(-1) \n    df['MACD_HIST4'] =df['MACD_HIST'].shift(-4) \n    df['MACD_HIST7'] =df['MACD_HIST'].shift(-7) \n    #df['MACD_HIST10'] =df['MACD_HIST'].shift(-10)#\n    #df['u_bandx'], df['m_bandx'], df['l_bandx'] = ta.BBANDS(df['Close'], timeperiod=7, nbdevup=2, nbdevdn=2, matype=0)#\n    \n    df['u_band'], df['m_band'], df['l_band'] = ta.BBANDS(df['Close'], timeperiod=5, nbdevup=2, nbdevdn=2, matype=0) \n    df['adx'] = ta.ADX(df['High'], df['Low'],np.array(df.loc[:, 'Close']),timeperiod=14)\n    df['adx1'] = df['adx'].shift(-1)\n    df['adx4'] = df['adx'].shift(-4)\n    df['adx+1'] = df['adx'].shift(1)\n    #df['adx+2'] = df['adx'].shift(7)\n    df['adx7'] = df['adx'].shift(-7)\n    #df['adx10'] = df['adx'].shift(-10)#\n    #df['adx+4'] = df['adx'].shift(4)\n    #df['adx+1'] = df['adx'].shift(1)\n    #df['adx7-12'] = ta.ADX(df['High'], df['Low'],np.array(df.loc[:, 'Close']),timeperiod=4) #\n    \n    df['macdsignal1'] = df['macdsignal'].shift(-1)\n    df['macdsignal4'] = df['macdsignal'].shift(-4)\n    df['macdsignal7'] = df['macdsignal'].shift(-7)\n    #df['macdsignal10'] = df['macdsignal'].shift(-10) #\n    \n    df['DI_plus'] = ta.PLUS_DI(df['High'], df['Low'],np.array(df.loc[:, 'Close']), timeperiod=14)\n    df['DI_minus'] = ta.MINUS_DI(df['High'], df['Low'],np.array(df.loc[:, 'Close']), timeperiod=14)\n    \n    #df = df.drop(['Close'],axis=1)\n    #df['DI_plus1+1'] = df['DI_plus'].shift(1) #\n    df['DI_plus1'] = df['DI_plus'].shift(-1)\n    df['DI_plus4'] = df['DI_plus'].shift(-4)\n    df['DI_plus7'] = df['DI_plus'].shift(-7) #いる\n    df['DI_plus10'] = df['DI_plus'].shift(-10)\n    \n    df['DI_minus1'] = df['DI_minus'].shift(-1)\n    df['DI_minus4'] = df['DI_minus'].shift(-4)\n    df['DI_minus7'] = df['DI_minus'].shift(-7)\n    #df['DI_minus10'] = df['DI_minus'].shift(-10) #\n    \n    df['ROCP'] =ta.ROCP(df['Open'])\n    df['momentam'] =ta.MOM(df['Open'])\n    \n    df['APO'] =ta.APO(df['Open'])\n    df['APO1'] = df['APO'].shift(-1)\n    df['APO4'] = df['APO'].shift(-4)\n    df['APO7'] = df['APO'].shift(-7) \n    \n    df['PPO'] =ta.PPO(df['Open'])\n    #df['PPO1'] = df['PPO'].shift(-1)\n    #df['PPO4'] = df['PPO'].shift(-4)\n    #df['PPO7'] = df['PPO'].shift(-7)\n    #df['vwap-c'] =(1-np.exp(df['VWAP']))\n    df = df.drop(['VWAP'],axis=1)\n\n    df['CMO'] =ta.CMO(df['Open'])\n    df['MIDPOINT'] =ta.MIDPOINT(df['Open'])\n    #df['MIDPOINT1'] =df['MIDPOINT'].shift(-1)\n    df['TRENDLINE'] =ta.HT_TRENDLINE(df['Open'])\n    #df['TRENDLINE1']= df['TRENDLINE'].shift(-1)\n    #df['timestamp1'] = df['timestamp'].shift(-1)\n    return df ","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"\n***Copy from [YAM](https://www.kaggle.com/yamqwe/crypto-prediction-technical-analysis-feats-2#Feature-Engineering-%F0%9F%94%AC)***","metadata":{}},{"cell_type":"code","source":"\ndef rolling_mean(series, window): return series.rolling(window).mean()\ndef rolling_std(series, window): return series.rolling(window).std()\ndef rolling_sum(series, window): return series.rolling(window).sum()\ndef ewma(series, span, min_periods): return series.ewm(span = span, min_periods = min_periods).mean()\ndef get_value(df, idx, col): return df.iloc[idx][col]\n\n#Moving Average\ndef MA(df, n):\n    MA = pd.Series(rolling_mean(df['Close'], n), name = 'MA_' + str(n))\n    df['MA'] = MA\n    return df\n\n#Exponential Moving Average\ndef EMA(df, n):\n    EMA = pd.Series(ewma(df['Close'], span = n, min_periods = n - 1), name = 'EMA_' + str(n))\n    df['EMA'] = EMA\n    return df\n\n#Momentum\ndef MOM(df, n):\n    M = pd.Series(df['Close'].diff(n), name = 'Momentum_' + str(n))\n    df['MOM'] = M\n    return df\n\n#Rate of Change\ndef ROC(df, n):\n    M = df['Close'].diff(n - 1)\n    N = df['Close'].shift(n - 1)\n    ROC = pd.Series(M / N, name = 'ROC_' + str(n))\n    df['ROC'] = ROC\n    return df\n\n#Average True Range\ndef ATR(df, n):\n    i = 0\n    TR_l = [0]\n    while i < len(df) - 1:\n        TR = max(get_value(df, i + 1, 'High'), get_value(df, i, 'Close')) - min(get_value(df, i + 1, 'Low'), get_value(df, i, 'Close'))\n        TR_l.append(TR)\n        i = i + 1\n    TR_s = pd.Series(TR_l)\n    ATR = pd.Series(ewma(TR_s, span = n, min_periods = n), name = 'ATR_' + str(n))\n    df['ATR'] = ATR\n    return df\n\n#Bollinger Bands\ndef BBANDS(df, n):\n    MA = pd.Series(rolling_mean(df['Close'], n))\n    MSD = pd.Series(rolling_std(df['Close'], n))\n    b1 = 4 * MSD / MA\n    B1 = pd.Series(b1, name = 'BollingerB_' + str(n))\n    df['B1'] = B1\n    b2 = (df['Close'] - MA + 2 * MSD) / (4 * MSD)\n    B2 = pd.Series(b2, name = 'Bollinger%b_' + str(n))\n    df['B2'] = B2\n    return df\n\n#Pivot Points, Supports and Resistances\ndef PPSR(df):\n    PP = pd.Series((df['High'] + df['Low'] + df['Close']) / 3)\n    R1 = pd.Series(2 * PP - df['Low'])\n    S1 = pd.Series(2 * PP - df['High'])\n    R2 = pd.Series(PP + df['High'] - df['Low'])\n    S2 = pd.Series(PP - df['High'] + df['Low'])\n    R3 = pd.Series(df['High'] + 2 * (PP - df['Low']))\n    S3 = pd.Series(df['Low'] - 2 * (df['High'] - PP))\n    psr = {'PP':PP, 'R1':R1, 'S1':S1, 'R2':R2, 'S2':S2, 'R3':R3, 'S3':S3}\n    PSR = pd.DataFrame(psr)\n    for col in PSR.columns:\n        df['PSR_' + col] = PSR[col]\n    return df\n\n#Stochastic oscillator %K\ndef STOK(df):\n    SOk = pd.Series((df['Close'] - df['Low']) / (df['High'] - df['Low']), name = 'SO%k')\n    df['SOk'] = SOk\n    return df\n\n# Stochastic Oscillator, EMA smoothing, nS = slowing (1 if no slowing)\ndef STO(df,  nK, nD, nS=1):\n    SOk = pd.Series((df['Close'] - df['Low'].rolling(nK).min()) / (df['High'].rolling(nK).max() - df['Low'].rolling(nK).min()), name = 'SO%k'+str(nK))\n    SOd = pd.Series(SOk.ewm(ignore_na=False, span=nD, min_periods=nD-1, adjust=True).mean(), name = 'SO%d'+str(nD))\n    SOk = SOk.ewm(ignore_na=False, span=nS, min_periods=nS-1, adjust=True).mean()\n    SOd = SOd.ewm(ignore_na=False, span=nS, min_periods=nS-1, adjust=True).mean()\n    df['SOk'] = SOk\n    df['SOd'] = SOd\n    return df\n\n#Trix\ndef TRIX(df, n):\n    EX1 = ewma(df['Close'], span = n, min_periods = n - 1)\n    EX2 = ewma(EX1, span = n, min_periods = n - 1)\n    EX3 = ewma(EX2, span = n, min_periods = n - 1)\n    i = 0\n    ROC_l = [0]\n    while i + 1 <= len(df) - 1:\n        ROC = (EX3.iloc[i + 1] - EX3.iloc[i]) / EX3.iloc[i]\n        ROC_l.append(ROC)\n        i = i + 1\n    Trix = pd.Series(ROC_l, name = 'Trix_' + str(n))\n    df['Trix'] = Trix\n    return df\n\n#Average Directional Movement Index\ndef ADX(df, n, n_ADX):\n    i = 0\n    UpI = []\n    DoI = []\n    while i + 1 <= len(df) - 1:\n        UpMove = get_value(df, i + 1, 'High') - get_value(df, i, 'High')\n        DoMove = get_value(df, i, 'Low') - get_value(df, i + 1, 'Low')\n        if UpMove > DoMove and UpMove > 0:\n            UpD = UpMove\n        else: UpD = 0\n        UpI.append(UpD)\n        if DoMove > UpMove and DoMove > 0:\n            DoD = DoMove\n        else: DoD = 0\n        DoI.append(DoD)\n        i = i + 1\n    i = 0\n    TR_l = [0]\n    while i < len(df) - 1:\n        TR = max(get_value(df, i + 1, 'High'), get_value(df, i, 'Close')) - min(get_value(df, i + 1, 'Low'), get_value(df, i, 'Close'))\n        TR_l.append(TR)\n        i = i + 1\n    TR_s = pd.Series(TR_l)\n    ATR = pd.Series(ewma(TR_s, span = n, min_periods = n))\n    UpI = pd.Series(UpI)\n    DoI = pd.Series(DoI)\n    PosDI = pd.Series(ewma(UpI, span = n, min_periods = n - 1) / ATR)\n    NegDI = pd.Series(ewma(DoI, span = n, min_periods = n - 1) / ATR)\n    ADX = pd.Series(ewma(abs(PosDI - NegDI) / (PosDI + NegDI), span = n_ADX, min_periods = n_ADX - 1), name = 'ADX_' + str(n) + '_' + str(n_ADX))\n    df['ADX'] = ADX\n    return df\n\n#MACD, MACD Signal and MACD difference\ndef MACD(df, n_fast, n_slow):\n    EMAfast = pd.Series(ewma(df['Close'], span = n_fast, min_periods = n_slow - 1))\n    EMAslow = pd.Series(ewma(df['Close'], span = n_slow, min_periods = n_slow - 1))\n    MACD = pd.Series(EMAfast - EMAslow, name = 'MACD_' + str(n_fast) + '_' + str(n_slow))\n    MACDsign = pd.Series(ewma(MACD, span = 9, min_periods = 8), name = 'MACDsign_' + str(n_fast) + '_' + str(n_slow))\n    MACDdiff = pd.Series(MACD - MACDsign, name = 'MACDdiff_' + str(n_fast) + '_' + str(n_slow))\n    df['MACD'] = MACD\n    df['MACDsign'] = MACDsign\n    df['MACDdiff'] = MACDdiff\n    return df\n\n#Mass Index\ndef MassI(df):\n    Range = df['High'] - df['Low']\n    EX1 = ewma(Range, span = 9, min_periods = 8)\n    EX2 = ewma(EX1, span = 9, min_periods = 8)\n    Mass = EX1 / EX2\n    MassI = pd.Series(rolling_sum(Mass, 25), name = 'Mass Index')\n    df['MassI'] = MassI\n    return df\n\n#Vortex Indicator: http://www.vortexindicator.com/VFX_VORTEX.PDF\ndef Vortex(df, n):\n    i = 0\n    TR = [0]\n    while i < len(df) - 1:\n        Range = max(get_value(df, i + 1, 'High'), get_value(df, i, 'Close')) - min(get_value(df, i + 1, 'Low'), get_value(df, i, 'Close'))\n        TR.append(Range)\n        i = i + 1\n    i = 0\n    VM = [0]\n    while i < len(df) - 1:\n        Range = abs(get_value(df, i + 1, 'High') - get_value(df, i, 'Low')) - abs(get_value(df, i + 1, 'Low') - get_value(df, i, 'High'))\n        VM.append(Range)\n        i = i + 1\n    VI = pd.Series(rolling_sum(pd.Series(VM), n) / rolling_sum(pd.Series(TR), n), name = 'Vortex_' + str(n))\n    df['VI'] = VI\n    return df\n\n#KST Oscillator\ndef KST(df, r1, r2, r3, r4, n1, n2, n3, n4):\n    M = df['Close'].diff(r1 - 1)\n    N = df['Close'].shift(r1 - 1)\n    ROC1 = M / N\n    M = df['Close'].diff(r2 - 1)\n    N = df['Close'].shift(r2 - 1)\n    ROC2 = M / N\n    M = df['Close'].diff(r3 - 1)\n    N = df['Close'].shift(r3 - 1)\n    ROC3 = M / N\n    M = df['Close'].diff(r4 - 1)\n    N = df['Close'].shift(r4 - 1)\n    ROC4 = M / N\n    KST = pd.Series(rolling_sum(ROC1, n1) + rolling_sum(ROC2, n2) * 2 + rolling_sum(ROC3, n3) * 3 + rolling_sum(ROC4, n4) * 4, name = 'KST_' + str(r1) + '_' + str(r2) + '_' + str(r3) + '_' + str(r4) + '_' + str(n1) + '_' + str(n2) + '_' + str(n3) + '_' + str(n4))\n    df['KST'] = KST\n    return df\n\n#Relative Strength Index\ndef RSI(df, n):\n    i = 0\n    UpI = [0]\n    DoI = [0]\n    while i + 1 <= len(df) - 1:\n        UpMove = get_value(df, i + 1, 'High') - get_value(df, i, 'High')\n        DoMove = get_value(df, i, 'Low') - get_value(df, i + 1, 'Low')\n        if UpMove > DoMove and UpMove > 0:\n            UpD = UpMove\n        else: UpD = 0\n        UpI.append(UpD)\n        if DoMove > UpMove and DoMove > 0:\n            DoD = DoMove\n        else: DoD = 0\n        DoI.append(DoD)\n        i = i + 1\n    UpI = pd.Series(UpI)\n    DoI = pd.Series(DoI)\n    PosDI = pd.Series(ewma(UpI, span = n, min_periods = n - 1))\n    NegDI = pd.Series(ewma(DoI, span = n, min_periods = n - 1))\n    RSI = pd.Series(PosDI / (PosDI + NegDI), name = 'RSI_' + str(n))\n    df['RSI'] = RSI\n    return df\n\n#True Strength Index\ndef TSI(df, r, s):\n    M = pd.Series(df['Close'].diff(1))\n    aM = abs(M)\n    EMA1 = pd.Series(ewma(M, span = r, min_periods = r - 1))\n    aEMA1 = pd.Series(ewma(aM, span = r, min_periods = r - 1))\n    EMA2 = pd.Series(ewma(EMA1, span = s, min_periods = s - 1))\n    aEMA2 = pd.Series(ewma(aEMA1, span = s, min_periods = s - 1))\n    TSI = pd.Series(EMA2 / aEMA2, name = 'TSI_' + str(r) + '_' + str(s))\n    df['TSI'] = TSI\n    return df\n\n#Accumulation/Distribution\ndef ACCDIST(df, n):\n    ad = (2 * df['Close'] - df['High'] - df['Low']) / (df['High'] - df['Low']) * df['Volume']\n    M = ad.diff(n - 1)\n    N = ad.shift(n - 1)\n    ROC = M / N\n    AD = pd.Series(ROC, name = 'Acc/Dist_ROC_' + str(n))\n    df['AD'] = AD\n    return df\n\n#Chaikin Oscillator\ndef Chaikin(df):\n    ad = (2 * df['Close'] - df['High'] - df['Low']) / (df['High'] - df['Low']) * df['Volume']\n    Chaikin = pd.Series(ewma(ad, span = 3, min_periods = 2) - ewma(ad, span = 10, min_periods = 9), name = 'Chaikin')\n    df['Chaikin'] = Chaikin\n    return df\n\n#Money Flow Index and Ratio\ndef MFI(df, n):\n    PP = (df['High'] + df['Low'] + df['Close']) / 3\n    i = 0\n    PosMF = [0]\n    while i < len(df) - 1:\n        if PP.iloc[i + 1] > PP.iloc[i]:\n            PosMF.append(PP.iloc[i + 1] * get_value(df, i + 1, 'Volume'))\n        else:\n            PosMF.append(0)\n        i = i + 1\n    PosMF = pd.Series(PosMF)\n    TotMF = PP * df['Volume']\n    MFR = pd.Series(PosMF / TotMF)\n    MFI = pd.Series(rolling_mean(MFR, n), name = 'MFI_' + str(n))\n    df['MFI'] = MFI\n    return df\n\n#On-balance Volume\ndef OBV(df, n):\n    i = 0\n    OBV = [0]\n    while i < len(df) - 1:\n        if get_value(df, i + 1, 'Close') - get_value(df, i, 'Close') > 0:\n            OBV.append(get_value(df, i + 1, 'Volume'))\n        if get_value(df, i + 1, 'Close') - get_value(df, i, 'Close') == 0:\n            OBV.append(0)\n        if get_value(df, i + 1, 'Close') - get_value(df, i, 'Close') < 0:\n            OBV.append(-get_value(df, i + 1, 'Volume'))\n        i = i + 1\n    OBV = pd.Series(OBV)\n    OBV_ma = pd.Series(rolling_mean(OBV, n), name = 'OBV_' + str(n))\n    df['OBV_ma'] = OBV_ma\n    return df\n\n#Force Index\ndef FORCE(df, n):\n    F = pd.Series(df['Close'].diff(n) * df['Volume'].diff(n), name = 'Force_' + str(n))\n    df['F'] = F\n    return df\n\n#Ease of Movement\ndef EOM(df, n):\n    EoM = (df['High'].diff(1) + df['Low'].diff(1)) * (df['High'] - df['Low']) / (2 * df['Volume'])\n    Eom_ma = pd.Series(rolling_mean(EoM, n), name = 'EoM_' + str(n))\n    df['Eom_ma'] = Eom_ma\n    return df\n\n#Commodity Channel Index\ndef CCI(df, n):\n    PP = (df['High'] + df['Low'] + df['Close']) / 3\n    CCI = pd.Series((PP - rolling_mean(PP, n)) / rolling_std(PP, n), name = 'CCI_' + str(n))\n    df['CCI'] = CCI\n    return df\n\n#Coppock Curve\ndef COPP(df, n):\n    M = df['Close'].diff(int(n * 11 / 10) - 1)\n    N = df['Close'].shift(int(n * 11 / 10) - 1)\n    ROC1 = M / N\n    M = df['Close'].diff(int(n * 14 / 10) - 1)\n    N = df['Close'].shift(int(n * 14 / 10) - 1)\n    ROC2 = M / N\n    Copp = pd.Series(ewma(ROC1 + ROC2, span = n, min_periods = n), name = 'Copp_' + str(n))\n    df['Copp'] = Copp\n    return df\n\n#Keltner Channel\ndef KELCH(df, n):\n    KelChM = pd.Series(rolling_mean((df['High'] + df['Low'] + df['Close']) / 3, n), name = 'KelChM_' + str(n))\n    KelChU = pd.Series(rolling_mean((4 * df['High'] - 2 * df['Low'] + df['Close']) / 3, n), name = 'KelChU_' + str(n))\n    KelChD = pd.Series(rolling_mean((-2 * df['High'] + 4 * df['Low'] + df['Close']) / 3, n), name = 'KelChD_' + str(n))\n    df['KelChM'] = KelChM\n    df['KelChU'] = KelChU\n    df['KelChD'] = KelChD\n    return df\n\n#Ultimate Oscillator\ndef ULTOSC(df):\n    i = 0\n    TR_l = [0]\n    BP_l = [0]\n    while i < len(df) - 1:\n        TR = max(get_value(df, i + 1, 'High'), get_value(df, i, 'Close')) - min(get_value(df, i + 1, 'Low'), get_value(df, i, 'Close'))\n        TR_l.append(TR)\n        BP = get_value(df, i + 1, 'Close') - min(get_value(df, i + 1, 'Low'), get_value(df, i, 'Close'))\n        BP_l.append(BP)\n        i = i + 1\n    UltO = pd.Series((4 * rolling_sum(pd.Series(BP_l), 7) / rolling_sum(pd.Series(TR_l), 7)) + (2 * rolling_sum(pd.Series(BP_l), 14) / rolling_sum(pd.Series(TR_l), 14)) + (rolling_sum(pd.Series(BP_l), 28) / rolling_sum(pd.Series(TR_l), 28)), name = 'Ultimate_Osc')\n    df['UltO'] = UltO\n    return df\n\n#Donchian Channel\ndef DONCH(df, n):\n    i = 0\n    DC_l = []\n    while i < n - 1:\n        DC_l.append(0)\n        i = i + 1\n    i = 0\n    while i + n - 1 < len(df) - 1:\n        DC = max(df['High'].iloc[i:i + n - 1]) - min(df['Low'].iloc[i:i + n - 1])\n        DC_l.append(DC)\n        i = i + 1\n    DonCh = pd.Series(DC_l, name = 'Donchian_' + str(n))\n    DonCh = DonCh.shift(n - 1)\n    df['DonCh'] = DonCh\n    return df\n\n#Standard Deviation\ndef STDDEV(df, n):\n    std_dev = pd.Series(rolling_std(df['Close'], n), name = 'STD_' + str(n))\n    df['std_dev'] = std_dev\n    return df\n\n\n\n\n\nn = 15\nnK = 5\nnD = 7\nn_fast = 5\nn_slow = 10\nn_ADX = 10\nr = 3\ns = 7\n\ndf = MA(df, n)\ndf = EMA(df, n)\ndf = MOM(df, n)\ndf = ROC(df, n)\ndf = ATR(df, n)\ndf = BBANDS(df, n)\ndf = PPSR(df)\ndf = STOK(df)\ndf = STO(df,  nK, nD, nS=1)\ndf = TRIX(df, n)\ndf = ADX(df, n, n_ADX)\ndf = MACD(df, n_fast, n_slow)\ndf = MassI(df)\ndf = Vortex(df, n)\ndf = RSI(df, n)\ndf = TSI(df, r, s)\ndf = ACCDIST(df, n)\ndf = Chaikin(df)\ndf = MFI(df, n)\ndf = OBV(df, n)\ndf = FORCE(df, n)\ndf = EOM(df, n)\ndf = CCI(df, n)\ndf = COPP(df, n)\ndf = KELCH(df, n)\ndf = ULTOSC(df)\ndf = DONCH(df, n)\ndf = STDDEV(df, n)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}