{"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":"markdown","source":"# INPUT","metadata":{}},{"cell_type":"code","source":"import os, gc, warnings, random, datetime, traceback, joblib, gresearch_crypto\nwarnings.filterwarnings('ignore')\n\nimport pandas as pd\nimport numpy as np\nimport lightgbm as lgb #new\n\nimport matplotlib.pyplot as plt\nimport plotly.express as px\nimport plotly.graph_objects as go\n\nimport numpy.polynomial.hermite as Herm\nimport math","metadata":{"execution":{"iopub.status.busy":"2022-01-30T22:48:41.891564Z","iopub.execute_input":"2022-01-30T22:48:41.892074Z","iopub.status.idle":"2022-01-30T22:48:44.472345Z","shell.execute_reply.started":"2022-01-30T22:48:41.891961Z","shell.execute_reply":"2022-01-30T22:48:44.471506Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"env       = gresearch_crypto.make_env()\niter_test = env.iter_test()","metadata":{"execution":{"iopub.status.busy":"2022-01-30T22:49:01.018380Z","iopub.execute_input":"2022-01-30T22:49:01.018658Z","iopub.status.idle":"2022-01-30T22:49:01.023623Z","shell.execute_reply.started":"2022-01-30T22:49:01.018629Z","shell.execute_reply":"2022-01-30T22:49:01.022717Z"},"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'\nEXAMPLE_TEST      = '/kaggle/input/g-research-crypto-forecasting/example_test.csv'\n\ndf_train          = pd.read_csv(TRAIN_CSV)\ndf_test           = pd.read_csv(EXAMPLE_TEST)\ndf_asset_details  = pd.read_csv(ASSET_DETAILS_CSV).sort_values('Asset_ID')","metadata":{"execution":{"iopub.status.busy":"2022-01-30T22:49:02.341342Z","iopub.execute_input":"2022-01-30T22:49:02.342129Z","iopub.status.idle":"2022-01-30T22:50:07.730632Z","shell.execute_reply.started":"2022-01-30T22:49:02.342080Z","shell.execute_reply":"2022-01-30T22:50:07.729844Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def fix_all_seeds(seed):\n    np.random.seed(seed)\n    random.seed(seed)\n    os.environ['PYTHONHASHSEED'] = str(seed)","metadata":{"execution":{"iopub.status.busy":"2022-01-30T22:50:07.732083Z","iopub.execute_input":"2022-01-30T22:50:07.732354Z","iopub.status.idle":"2022-01-30T22:50:07.736510Z","shell.execute_reply.started":"2022-01-30T22:50:07.732328Z","shell.execute_reply":"2022-01-30T22:50:07.735824Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"seed = 1337\nfix_all_seeds(seed)\n\nremove_cl_test_overlapping_data = True #& False #test 2-month\nremove_lb_test_overlapping_data = True & False #test 6-month(+-3 month)\nremove_op_test_overlapping_data = True & False \nbias_harmonic_oscillator        = True #& False\nfeatures_importance_check       = True & False\nvisualization                   = True & False\ntrain_models                    = True & False       \ncallbacks                       = True & False \nsave_models                     = True & False\nload_models                     = True #& False\ntest_baseline_model             = True & False\nsubmissions_test                = True #& False","metadata":{"execution":{"iopub.status.busy":"2022-01-30T22:50:07.737629Z","iopub.execute_input":"2022-01-30T22:50:07.737880Z","iopub.status.idle":"2022-01-30T22:50:07.750828Z","shell.execute_reply.started":"2022-01-30T22:50:07.737845Z","shell.execute_reply":"2022-01-30T22:50:07.750008Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Remove the features to test the LR baseline score.\nif remove_cl_test_overlapping_data:\n    df_train['datetime'] = pd.to_datetime(df_train['timestamp'], unit='s')\n    df_valid  = df_train[(df_train['datetime'] > '2021-05-21 00:00:00')].reset_index(drop=True) #max : 21-09-21\n    df_train  = df_train[(df_train['datetime'] < '2021-08-21 00:00:00')].reset_index(drop=True)\n    df_train  = df_train.drop(['datetime'],axis=1)\n    df_valid  = df_valid.drop(['datetime'],axis=1)\n    \nif remove_lb_test_overlapping_data:\n    df_train['datetime'] = pd.to_datetime(df_train['timestamp'], unit='s')\n    df_valid  = df_train[(df_train['datetime'] > '2021-03-23 00:00:00')].reset_index(drop=True) \n    df_train  = df_train[(df_train['datetime'] < '2021-07-23 00:00:00')].reset_index(drop=True) \n    df_train  = df_train.drop(['datetime'],axis=1)\n    df_valid  = df_valid.drop(['datetime'],axis=1)\n\nelif remove_op_test_overlapping_data:\n    df_train['datetime'] = pd.to_datetime(df_train['timestamp'], unit='s')\n    df_valid  = df_train[(df_train['datetime'] > '2021-05-23 00:00:00')].reset_index(drop=True)\n    df_train  = df_train.drop(['datetime'],axis=1)\n    df_valid  = df_valid.drop(['datetime'],axis=1)\n    \nelse:\n    df_train['datetime'] = pd.to_datetime(df_train['timestamp'], unit='s')\n    df_valid  = df_train[(df_train['datetime'] > '2021-02-23 00:00:00')].reset_index(drop=True)\n    df_train  = df_train.drop(['datetime'],axis=1)\n    df_valid  = df_valid.drop(['datetime'],axis=1)","metadata":{"execution":{"iopub.status.busy":"2022-01-30T22:50:07.753449Z","iopub.execute_input":"2022-01-30T22:50:07.753831Z","iopub.status.idle":"2022-01-30T22:50:15.648970Z","shell.execute_reply.started":"2022-01-30T22:50:07.753785Z","shell.execute_reply":"2022-01-30T22:50:15.648019Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_valid = df_valid.dropna(subset=['Target']).reset_index(drop=True)","metadata":{"execution":{"iopub.status.busy":"2022-01-30T22:50:15.650155Z","iopub.execute_input":"2022-01-30T22:50:15.650474Z","iopub.status.idle":"2022-01-30T22:50:15.968374Z","shell.execute_reply.started":"2022-01-30T22:50:15.650441Z","shell.execute_reply":"2022-01-30T22:50:15.967518Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#simple units\nhbar = 1.0\nm    = 1.0\nw    = 1.0\n\ndef hermite(x, n):\n    xi             = np.sqrt(m*w/hbar)*x\n    herm_coeffs    = np.zeros(n+1)\n    herm_coeffs[n] = 1\n    return Herm.hermval(xi, herm_coeffs)\n\ndef stationary_state(x,n):\n    xi        = np.sqrt(m*w/hbar)*x\n    prefactor = 1.0/math.sqrt(2.0**n * math.factorial(n)) * (m*w/(np.pi*hbar))**(0.25)\n    psi       = prefactor * np.exp(- xi**2 / 2) * hermite(x,n)\n    return psi","metadata":{"execution":{"iopub.status.busy":"2022-01-30T22:50:15.970114Z","iopub.execute_input":"2022-01-30T22:50:15.970423Z","iopub.status.idle":"2022-01-30T22:50:15.979252Z","shell.execute_reply.started":"2022-01-30T22:50:15.970381Z","shell.execute_reply":"2022-01-30T22:50:15.978049Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_features(df, drop_train=True, drop_visualization=False, bias_harmonic_oscillator=bias_harmonic_oscillator):    \n    \n    #customize\n    df['upper_Shadow'] = df['High'] - np.maximum(df['Close'], df['Open'])   \n    df['lower_Shadow'] = np.minimum(df['Close'], df['Open']) - df['Low']                      \n    df['hlco_ration']  = (df['High'] - df['Low'])/(df['Close']-df['Open'])\n    df['high_div_low'] = df['High'] / df['Low']\n    df['gtrade']       = (df['Close'] - df['Open']) / df['Count']\n    df['shadow1']      = (df['Close'] - df['Open']) / df['Volume']\n    df['shadow3']      = df['upper_Shadow'] / df['Volume']\n    df['shadow5']      = df['lower_Shadow'] / df['Volume']\n    df['mean2']        = (df['shadow1'] + df['Volume']) / 2\n    df['spread']       = df['High'] - df['Low']\n    df['log_price_co'] = np.log(df['Close']/df['Open'])\n    df['log_exp_co']   = np.logaddexp(df['Close'], df['Open'])\n    df['volume_count'] = df['Volume'] / (df['Count'] + 1)  \n    \n    #Quantum Harmonic Oscillator(QHO); Light Gradient Boosting Machine(LGBM) with an applied QHO for indicator\n    df['harmonic_oscillator_115v'] = stationary_state(df['volume_count'], 115) \n    #114.59155903 == 360/pi, 6h*60min/pi ; 6h = 1/4 of day ≈ 115+-5 so 110 <= n >= 120 for training\n    #Bias in dataset Harmonic-Oscillator If the value is prohibitively exorbitant, you can adjust the hermite value.\n    # Add :: df['hermite_n'] = hermite(df, n) ;In simple units, recommend 60 <= n >= 210\n    df['hermite_120v'] = hermite(df['volume_count'], 120)\n\n    #drop\n    if drop_train:\n        df = df.drop(['timestamp', 'VWAP', 'Close', 'Low', 'High', 'Open', 'Volume', 'Count'],axis=1)\n        if bias_harmonic_oscillator:\n            df = df.drop(['hermite_120v'],axis=1)\n    elif drop_visualization:\n        df = df.drop(['VWAP', 'Close', 'Low', 'High', 'Open', 'Volume', 'Count'],axis=1) \n        if bias_harmonic_oscillator:\n            df = df.drop(['hermite_120v'],axis=1)\n            df = df.fillna(-1)\n    else:\n        df = df.drop(['timestamp', 'VWAP', 'Close', 'Low', 'High', 'Open', 'Volume', 'Count', 'Asset_ID', 'row_id'])\n        if bias_harmonic_oscillator:\n            df = df.drop(['hermite_120v'])\n            df = df.fillna(-1)\n    return df ","metadata":{"execution":{"iopub.status.busy":"2022-01-30T22:50:15.980957Z","iopub.execute_input":"2022-01-30T22:50:15.981346Z","iopub.status.idle":"2022-01-30T22:50:15.998782Z","shell.execute_reply.started":"2022-01-30T22:50:15.981291Z","shell.execute_reply":"2022-01-30T22:50:15.997906Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_Xys_and_model_for_asset(df_train, df_valid, asset_id, df_asset_details):   \n    \n    #X_train, X_test\n    df_train, df_valid = df_train[df_train[\"Asset_ID\"] == asset_id],   df_valid[df_valid['Asset_ID'] == asset_id]\n    df_train, df_valid = df_train.dropna(subset=['Target']),           df_valid.dropna(subset=['Target'])\n    \n    #y_train, y_test\n    y_train,  y_test   = df_train['Target'],                          df_valid['Target']  \n    df_train, df_valid = df_train.drop(['Target','Asset_ID'],axis=1), df_valid.drop(['Target','Asset_ID'],axis=1)\n    df_t,     df_v     = get_features(df_train),                      get_features(df_valid)\n    x_train,  x_test   = df_t.fillna(-1),                             df_v.fillna(-1)\n            \n    #weight \n    df_weight   = df_asset_details[df_asset_details[\"Asset_ID\"] == asset_id]\n    weight      = df_weight['Weight'] \n    lr          = float(weight)/10\n        \n    best_lgb_params ={\n        'objective'              : 'regression',  \n        'metric'                 : ['rmse', 'poisson'],\n        'feature_pre_filter'     : False,\n        'lambda_l1'              : 0.010565309968664168,\n        'lambda_l2'              : 0.3120057367604998,\n        'poisson_max_delta_step' : float(weight),\n        \n        'num_leaves'        : 700,\n        'feature_fraction'  : 0.7,\n        'bagging_fraction'  : 0.7,\n        'bagging_freq'      : 0,\n        'min_child_samples' : int(weight), 'random_state' : 42,\n        \n        'tree_learner'        : 'voting',             \n        'learning_rate'       :  lr,\n        'early_stopping_round': 110,\n        'n_estimators'        : 5500} #,'device': 'gpu'\n    \n    lgb_train, lgb_valid = lgb.Dataset(x_train, y_train), lgb.Dataset(x_test, y_test) #,weight=weights     \n    model = lgb.train(best_lgb_params, lgb_train, valid_sets=[lgb_valid], verbose_eval=1000)  \n    \n    return model","metadata":{"execution":{"iopub.status.busy":"2022-01-30T22:50:16.000297Z","iopub.execute_input":"2022-01-30T22:50:16.000539Z","iopub.status.idle":"2022-01-30T22:50:16.017910Z","shell.execute_reply.started":"2022-01-30T22:50:16.000511Z","shell.execute_reply":"2022-01-30T22:50:16.016925Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#  PROCESSING","metadata":{}},{"cell_type":"code","source":"if features_importance_check:\n    df_tr = df_train.dropna(how=\"any\")\n    df_va = df_valid.dropna(how=\"any\")\n    #train : #test\n    df_t, df_v = df_tr[df_tr['Asset_ID'] == 1],  df_va[df_va['Asset_ID'] == 1] #BTC = 1\n    df_t, df_v = df_t.dropna(subset=['Target']), df_v.dropna(subset=['Target'])\n    \n    y_tr, y_te  = df_t['Target'],                          df_v['Target']  \n    df_t, df_v  = df_t.drop(['Target','Asset_ID'],axis=1), df_v.drop(['Target','Asset_ID'],axis=1)\n    df_t, df_v  = get_features(df_t),                      get_features(df_v)\n    x_tr, x_te  = df_t.fillna(-1),                         df_v.fillna(-1) \n      \n    #weight \n    df_w   = df_asset_details[df_asset_details[\"Asset_ID\"] == 1]\n    weight = df_w['Weight'] \n    lr     = float(weight)/10\n        \n    best_lgb_params ={\n        'objective'              : 'regression',  \n        'metric'                 : ['rmse', 'poisson'],\n        'feature_pre_filter'     : False,\n        'lambda_l1'              : 0.010565309968664168,\n        'lambda_l2'              : 0.3120057367604998,\n        'poisson_max_delta_step' : float(weight),\n        \n        'num_leaves'        : 700,\n        'feature_fraction'  : 0.7,\n        'bagging_fraction'  : 0.7,\n        'bagging_freq'      : 0,\n        'min_child_samples' : int(weight), 'random_state' : 42,\n        \n        'tree_learner'        : 'voting',             \n        'learning_rate'       : lr,\n        'early_stopping_round': 110,\n        'n_estimators'        : 2500} #'device': 'gpu'\n    \n    lgb_t     = lgb.Dataset(x_tr, y_tr) #,weight=weights \n    lgb_v     = lgb.Dataset(x_te, y_te)\n    model_pre = lgb.train(best_lgb_params, lgb_t, valid_sets=[lgb_v], verbose_eval=1000) \n    \n    #callbacks\n    x_pred      = pd.DataFrame()\n    x_pred['x'] = model_pre.predict(x_te)\n    print('Test score for LR baseline:', f\"{np.corrcoef(x_pred.x, y_te)[0,1]:.5f}\")\n    #x_pred  \n    features   = x_tr.columns\n    importance = sorted(list(enumerate(model_pre.feature_importance())), key=lambda x:x[1], reverse=True)\n    \n    features_list = []\n    score_list    = []\n    for i,v in importance:\n        print(f'Feature: ({i:<2}) {features[i]:<32} : score = {v:.5f}')\n        features_list.append(features[i])\n        score_list.append(v)\n    \n    fig = px.bar(x      = features_list,\n                 y      = score_list, \n                 color  = score_list,\n                 color_continuous_scale=\"bluyl\")\n    fig.update_xaxes(title =\"Features\"),  fig.update_yaxes(title=\"score\") #x:y\n    fig.update_layout(showlegend = True,\n                      title      = {\n                          'text'   : 'Features importance to model',\n                          'x'      : 0.5,\n                          'y'      : 0.95,\n                          'xanchor': 'center',\n                          'yanchor': 'top'},\n                      template  =\"plotly_white\")\n    fig.show()","metadata":{"execution":{"iopub.status.busy":"2022-01-30T22:50:16.019917Z","iopub.execute_input":"2022-01-30T22:50:16.020655Z","iopub.status.idle":"2022-01-30T22:50:16.040881Z","shell.execute_reply.started":"2022-01-30T22:50:16.020608Z","shell.execute_reply":"2022-01-30T22:50:16.039955Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"if visualization:\n    df  = df_train[df_train['Asset_ID'] == 1]\n    dfx = get_features(df, drop_train=False, drop_visualization=True)\n    dfx = dfx.dropna(how=\"any\")\n    dfx = dfx.head(1000)\n    dfx['datetime'] = pd.to_datetime(dfx['timestamp'], unit='s')\n    \n    #customize\n    \n    #regression --- target:datetime\n    if features_importance_check:\n        y_pred = pd.DataFrame()\n        y_tr   = dfx.Target\n        x_te   = dfx.drop(['datetime','timestamp','Asset_ID','Target'],axis=1)\n        \n        y_pred['x'] = model_pre.predict(x_te)\n           \n        fig = go.Figure()\n        fig.add_trace(go.Scatter(x=dfx.datetime, y=y_tr, name='train/test', mode='markers'))\n        fig.add_trace(go.Scatter(x=dfx.datetime, y=y_pred.x, name='prediction',  mode='markers'))\n        fig.update_layout(title='Correlations between train/test & prediction')\n        fig.show()\n        \n    #relationship between (quantum harmonic oscillator-111: eigenstates of the quantum harmonic oscillator) & target\n    fig = go.Figure()\n    fig.add_trace(go.Scatter(x=dfx.datetime, y=dfx.harmonic_oscillator_115v, mode='lines', name='harmonic_oscillator_115v'))\n    fig.add_trace(go.Scatter(x=dfx.datetime, y=dfx.Target, mode='markers', name='target'))\n    fig.update_layout(title='Relationship between harmonic oscillator-115v & target')\n    fig.show()\n\n    #relationship between (quantum harmonic oscillator-111: eigenstates of the quantum harmonic oscillator) & volume count\n    fig = go.Figure()\n    fig.add_trace(go.Scatter(x=dfx.datetime, y=dfx.harmonic_oscillator_115v, mode='lines', name='harmonic_oscillator_115v'))\n    fig.add_trace(go.Scatter(x=dfx.datetime, y=dfx.volume_count , mode='lines', name='volume_count'))\n    fig.update_layout(title='Relationship between harmonic oscillator-115v & volume_count')\n    fig.show()\n    \n    #candlestick volume upper-lower \n    fig = go.Figure()\n    fig.add_trace(go.Candlestick(x = dfx.datetime, open = dfx.shadow3, high = dfx.upper_Shadow, low = dfx.lower_Shadow, close = dfx.shadow5))\n    fig.update_layout(title='Candlestick volume upper-lower')\n    fig.show()","metadata":{"execution":{"iopub.status.busy":"2022-01-30T22:50:16.043431Z","iopub.execute_input":"2022-01-30T22:50:16.043893Z","iopub.status.idle":"2022-01-30T22:50:16.059353Z","shell.execute_reply.started":"2022-01-30T22:50:16.043861Z","shell.execute_reply":"2022-01-30T22:50:16.058423Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%time\nif train_models:\n    Xs     = {}\n    ys     = {}\n    models = {}\n\n    for asset_id, asset_name in zip(df_asset_details['Asset_ID'], df_asset_details['Asset_Name']):\n        print(f\"Training model for {asset_name:<16} (ID={asset_id:<2})\")\n    \n        model = get_Xys_and_model_for_asset(df_train, df_valid, asset_id, df_asset_details)\n        models[asset_id] =  model\n        \n        if callbacks:\n            #validation\n            x_pred = pd.DataFrame()\n            x      = asset_id\n            record = df_valid[df_valid.Asset_ID == x]   \n            target = record.Target \n            record = record.drop(['Target','Asset_ID'],axis=1)\n            x_test = get_features(record) \n            \n            model       = models[x]\n            x_pred['x'] = model.predict(x_test)\n            print('Test score for LR baseline:', f\"{np.corrcoef(x_pred.x, target)[0,1]:.5f}\")\n            del record\n            del x_pred\n            del x_test\n            #break","metadata":{"_kg_hide-output":true,"execution":{"iopub.status.busy":"2022-01-30T22:50:16.060504Z","iopub.execute_input":"2022-01-30T22:50:16.061130Z","iopub.status.idle":"2022-01-30T22:50:16.081012Z","shell.execute_reply.started":"2022-01-30T22:50:16.061087Z","shell.execute_reply":"2022-01-30T22:50:16.080118Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# OUTPUT","metadata":{}},{"cell_type":"code","source":"%%time\nif save_models:\n    output_models  = 'models15f_g_crypto.h5'\n    saved_models   = joblib.dump(models, output_models)\n    loaded_model   = models\n    gc.collect()\nelif load_models:\n    input_models   = '../input/fork-models15f-g-crypto/models15f_g_crypto.h5'\n    loaded_model   = joblib.load(input_models)\n    gc.collect()\nelse:\n    loaded_model   = models","metadata":{"execution":{"iopub.status.busy":"2022-01-30T22:50:16.082186Z","iopub.execute_input":"2022-01-30T22:50:16.082418Z","iopub.status.idle":"2022-01-30T22:51:19.234473Z","shell.execute_reply.started":"2022-01-30T22:50:16.082389Z","shell.execute_reply":"2022-01-30T22:51:19.233580Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%time\nif test_baseline_model:\n    x_pred = pd.DataFrame()\n    for x in range(len(df_valid.Asset_ID.unique())):\n        record           = df_valid[df_valid.Asset_ID == x]     \n        record           = record.drop(['Target','Asset_ID'],axis=1)\n        x_test           = get_features(pd.DataFrame(record))\n        model            = loaded_model[x]\n        x_test['y_pred'] = model.predict(x_test)\n        x_pred           = pd.concat([x_test,x_pred])    \n    \n    x_pred = x_pred.sort_index()    \n    print('Test score for LR baseline: ', f\"{np.corrcoef(x_pred.y_pred,df_valid.Target)[0,1]:.5f}\")","metadata":{"execution":{"iopub.status.busy":"2022-01-30T22:51:19.236537Z","iopub.execute_input":"2022-01-30T22:51:19.237460Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"if submissions_test:\n    for i, (df_test, df_pred) in enumerate(iter_test):\n        for j , row in df_test.iterrows():\n            model  = loaded_model[row['Asset_ID']]\n            x_test = get_features(row, drop_train=False)\n            y_pred = model.predict([x_test])[0]\n        \n            df_pred.loc[df_pred['row_id'] == row['row_id'], 'Target'] = y_pred \n            # Print just one sample row to get a feeling of what it looks like\n            if i == 0 and j == 1:\n                display(x_test)\n        # Display the first prediction dataframe\n        if i == 0:\n            display(df_pred)\n        # Send submissions\n        env.predict(df_pred)    ","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# REFERENCE SOURCE CODE\n1. [Quantum Harmonic Oscillators : The LibreTexts project](https://rb.gy/rm6hjh)\n2. [Single Coins Valid train(JP/EN) : Tensor Choko](https://www.kaggle.com/tensorchoko/g-research-for-single-coins-valid-train-jp-en?scriptVersionId=81667733)\n3. [64 New Features with Autoencoders : Sayantan Mazumdar](https://www.kaggle.com/swaralipibose/64-new-features-with-autoencoders/notebook)\n4. [I Purchased Bitcoin : Dragon Zhang ](https://www.kaggle.com/dragonzhang/i-purchased-bitcoin)\n5. [Simple LGB Starter : Katsu1110](https://www.kaggle.com/code1110/gresearch-simple-lgb-starter) ","metadata":{"_kg_hide-input":false,"_kg_hide-output":false}},{"cell_type":"markdown","source":"# NEXT LEVEL \n* [Crypto Forecasting(1/1) : AE-QHO : Natapong Nitarach](https://www.kaggle.com/natnitarach/crypto-forecasting-1-1-ae-qho)","metadata":{}}]}