{"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":"## The Previous Notebooks : <br>\n### [Questions and answers📝EDA to Forecasting🚀](https://www.kaggle.com/yassershrief/notebook00ec514ff5/edit)<br>\n### [LGBM Regressor Forecasting and Evaluation 📈](https://www.kaggle.com/yassershrief/lgbm-regressor-forecasting-and-evaluation/edit)","metadata":{}},{"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport seaborn as sns\nimport datatable as dt\nimport math\nfrom sklearn.preprocessing import RobustScaler\nfrom datetime import timedelta\nimport matplotlib.pyplot as plt\nplt.style.use(\"bmh\")\nfrom tensorflow.keras.models import Sequential , load_model\nfrom tensorflow.keras.layers import Activation, Dense, Dropout, LSTM ,GRU\nfrom tensorflow.keras import layers\nfrom keras.callbacks import ModelCheckpoint,EarlyStopping\nimport random\nimport gresearch_crypto\nimport traceback\nfrom sklearn.metrics import mean_absolute_error, mean_squared_error , r2_score\nfrom sklearn.preprocessing import MinMaxScaler\nimport warnings\nwarnings.filterwarnings(\"ignore\")","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2022-02-01T18:16:35.759286Z","iopub.execute_input":"2022-02-01T18:16:35.759635Z","iopub.status.idle":"2022-02-01T18:16:42.710474Z","shell.execute_reply.started":"2022-02-01T18:16:35.759547Z","shell.execute_reply":"2022-02-01T18:16:42.709592Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Datatable** (heavily inspired by R's data.table) can read large datasets fairly quickly and is often faster than pandas. It is specifically meant for data processing of tabular datasets with emphasis on speed and support for large sized data. 👌","metadata":{}},{"cell_type":"code","source":"import datatable as dt","metadata":{"execution":{"iopub.status.busy":"2022-02-01T18:16:42.712054Z","iopub.execute_input":"2022-02-01T18:16:42.712274Z","iopub.status.idle":"2022-02-01T18:16:42.716583Z","shell.execute_reply.started":"2022-02-01T18:16:42.712246Z","shell.execute_reply":"2022-02-01T18:16:42.715705Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_all=dt.fread('../input/g-research-crypto-forecasting/train.csv').to_pandas()\nasset_details = pd.read_csv('../input/g-research-crypto-forecasting/asset_details.csv')\nasset_details.sort_values(\"Weight\", ascending=False)","metadata":{"execution":{"iopub.status.busy":"2022-02-01T18:16:42.717658Z","iopub.execute_input":"2022-02-01T18:16:42.718066Z","iopub.status.idle":"2022-02-01T18:17:26.904459Z","shell.execute_reply.started":"2022-02-01T18:16:42.718029Z","shell.execute_reply":"2022-02-01T18:17:26.903681Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Bitcoin prediction","metadata":{}},{"cell_type":"code","source":"#Bitcoin\ndf1 = df_all[(df_all.Asset_ID == 1)]\n\ndef get_row_feats(df):\n    \"\"\"Feature engineering by row\n    \"\"\"\n    df['upper_shadow'] = df['High'] / df[['Close', 'Open']].max(axis=1)\n    df['lower_shadow'] = df[['Close', 'Open']].min(axis=1) / df['Low']\n    df['open2close'] = df['Close'] / df['Open']\n    df['high2low'] = df['High'] / df['Low']\n    mean_price = df[['Open', 'High', 'Low', 'Close']].mean(axis=1)\n    median_price = df[['Open', 'High', 'Low', 'Close']].median(axis=1)\n    df['high2mean'] = df['High'] / mean_price\n    df['low2mean'] = df['Low'] / mean_price\n    df['high2median'] = df['High'] / median_price\n    df['low2median'] = df['Low'] / median_price\n    df['volume2count'] = df['Volume'] / (df['Count'] + 1)\n    return df   \ndf = get_row_feats(df1)\n\ndf['datetime'] = pd.to_datetime(df['timestamp'], unit='s') \ndf['datetime_d'] = df['datetime'].dt.strftime(\"%Y-%m-%d\") \n\ndf = df.groupby(by = [\"Asset_ID\", 'datetime_d']).mean()          \ndf=df.reset_index([\"Asset_ID\"])                                               \ndf.drop(['timestamp','Asset_ID','Target','Open', 'High', 'Low', 'Volume', 'VWAP'],axis='columns', inplace=True) \n# Converting the index as date\ndf.index = pd.to_datetime(df.index)\n# data = df[(df.index.year >= 2019)]\ndata=df.copy()","metadata":{"execution":{"iopub.status.busy":"2022-02-01T18:17:29.107970Z","iopub.execute_input":"2022-02-01T18:17:29.108491Z","iopub.status.idle":"2022-02-01T18:17:45.175019Z","shell.execute_reply.started":"2022-02-01T18:17:29.108449Z","shell.execute_reply":"2022-02-01T18:17:45.174179Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Split data\nTraning data before `13-06-2021` and validation data from `14-06-2021` to the end<br>\nKindly refer to the [topic](https://www.kaggle.com/c/g-research-crypto-forecasting/discussion/285505)","metadata":{}},{"cell_type":"code","source":"aim = 'Close'\ntrain_data = data.iloc[:1259]\ntest_data = data.iloc[1259:]\n\ndef line_plot(line1, line2, label1=None, label2=None, title='', lw=2):\n    fig, ax = plt.subplots(1, figsize=(13, 7))\n    ax.plot(line1, label=label1, linewidth=lw)\n    ax.plot(line2, label=label2, linewidth=lw)\n    ax.set_ylabel('USD', fontsize=14)\n    ax.set_title(title, fontsize=16)\n    ax.legend(loc='best', fontsize=16);","metadata":{"execution":{"iopub.status.busy":"2022-02-01T18:17:59.487107Z","iopub.execute_input":"2022-02-01T18:17:59.487418Z","iopub.status.idle":"2022-02-01T18:17:59.495553Z","shell.execute_reply.started":"2022-02-01T18:17:59.487380Z","shell.execute_reply":"2022-02-01T18:17:59.494210Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"line_plot(train_data[aim], test_data[aim], 'training', 'test', title='')","metadata":{"execution":{"iopub.status.busy":"2022-02-01T18:18:00.394314Z","iopub.execute_input":"2022-02-01T18:18:00.394648Z","iopub.status.idle":"2022-02-01T18:18:00.799559Z","shell.execute_reply.started":"2022-02-01T18:18:00.394613Z","shell.execute_reply":"2022-02-01T18:18:00.796949Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def normalise_zero_base(continuous):\n    return continuous / continuous.iloc[0] - 1","metadata":{"execution":{"iopub.status.busy":"2022-02-01T18:18:04.250529Z","iopub.execute_input":"2022-02-01T18:18:04.250798Z","iopub.status.idle":"2022-02-01T18:18:04.254902Z","shell.execute_reply.started":"2022-02-01T18:18:04.250769Z","shell.execute_reply":"2022-02-01T18:18:04.254323Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def extract_window_data(continuous, window_len=5, zero_base=True):\n    window_data = []\n    for idx in range(len(continuous) - window_len):\n        tmp = continuous[idx: (idx + window_len)].copy()\n        if zero_base:\n            tmp = normalise_zero_base(tmp)\n        window_data.append(tmp.values)\n    return np.array(window_data)\ndef prepare_data(continuous, aim, window_len=10, zero_base=True, test_size=0.2):\n    X_train = extract_window_data(train_data, window_len, zero_base)\n    X_test = extract_window_data(test_data, window_len, zero_base)\n    y_train = train_data[aim][window_len:].values\n    y_test = test_data[aim][window_len:].values\n    if zero_base:\n        y_train = y_train / train_data[aim][:-window_len].values - 1\n        y_test = y_test / test_data[aim][:-window_len].values - 1\n\n    return train_data, test_data, X_train, X_test, y_train, y_test\n","metadata":{"execution":{"iopub.status.busy":"2022-02-01T18:18:04.515354Z","iopub.execute_input":"2022-02-01T18:18:04.515783Z","iopub.status.idle":"2022-02-01T18:18:04.523940Z","shell.execute_reply.started":"2022-02-01T18:18:04.515753Z","shell.execute_reply":"2022-02-01T18:18:04.522999Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def build_lstm_model(input_data, output_size, neurons, activ_func='linear',\n                     dropout=0.2, loss='mse', optimizer='adam'):\n    model = Sequential()\n    model.add(LSTM(neurons, input_shape=(input_data.shape[1], input_data.shape[2])))\n    model.add(Dropout(dropout))\n    model.add(Dense(units=output_size))\n    model.add(Activation(activ_func))\n\n    model.compile(loss=loss, optimizer=optimizer)\n    return model\nnp.random.seed(0)\nwindow_len = 7\ntest_size = 0.2\nzero_base = True\nlstm_neurons = 50\nepochs = 150\nbatch_size = 32\nloss = 'mse'\ndropout = 0.25\noptimizer = 'adam'\ntrain_data, test_data, X_train, X_test, y_train, y_test = prepare_data(\n    data, aim, window_len=window_len, zero_base=zero_base, test_size=test_size)","metadata":{"execution":{"iopub.status.busy":"2022-02-01T18:27:17.197368Z","iopub.execute_input":"2022-02-01T18:27:17.197685Z","iopub.status.idle":"2022-02-01T18:27:18.060606Z","shell.execute_reply.started":"2022-02-01T18:27:17.197650Z","shell.execute_reply":"2022-02-01T18:27:18.059812Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(X_train.shape)","metadata":{"execution":{"iopub.status.busy":"2022-02-01T18:27:18.750865Z","iopub.execute_input":"2022-02-01T18:27:18.751138Z","iopub.status.idle":"2022-02-01T18:27:18.755510Z","shell.execute_reply.started":"2022-02-01T18:27:18.751108Z","shell.execute_reply":"2022-02-01T18:27:18.754871Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = build_lstm_model(\n    X_train, output_size=1, neurons=lstm_neurons, dropout=dropout, loss=loss,\n    optimizer=optimizer)\nmodelfit = model.fit(\n    X_train, y_train, validation_data=(X_test, y_test), epochs=epochs, batch_size=batch_size, shuffle=False,\n    callbacks=EarlyStopping(monitor='val_loss', verbose=1,patience=10))\n","metadata":{"execution":{"iopub.status.busy":"2022-02-01T18:27:18.962865Z","iopub.execute_input":"2022-02-01T18:27:18.963121Z","iopub.status.idle":"2022-02-01T18:27:45.172880Z","shell.execute_reply.started":"2022-02-01T18:27:18.963095Z","shell.execute_reply":"2022-02-01T18:27:45.171826Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.plot(modelfit.history['loss'])\nplt.plot(modelfit.history['val_loss'])\nplt.title('model loss')\nplt.ylabel('loss')\nplt.xlabel('epoch')\nplt.legend(['train', 'validation'], loc='upper left')","metadata":{"execution":{"iopub.status.busy":"2022-02-01T18:27:47.962891Z","iopub.execute_input":"2022-02-01T18:27:47.963168Z","iopub.status.idle":"2022-02-01T18:27:48.207959Z","shell.execute_reply.started":"2022-02-01T18:27:47.963138Z","shell.execute_reply":"2022-02-01T18:27:48.207172Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"targets = test_data[aim][window_len:]\npreds = model.predict(X_test).squeeze()\nprint('MAE for Bitcoin Model :',mean_absolute_error(preds, y_test))","metadata":{"execution":{"iopub.status.busy":"2022-02-01T18:27:51.866506Z","iopub.execute_input":"2022-02-01T18:27:51.867340Z","iopub.status.idle":"2022-02-01T18:27:52.327150Z","shell.execute_reply.started":"2022-02-01T18:27:51.867300Z","shell.execute_reply":"2022-02-01T18:27:52.326505Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"preds = model.predict(X_test).squeeze()\nSCORE_MSE=mean_squared_error(preds, y_test)\nprint('MSE for Bitcoin Model :',SCORE_MSE)","metadata":{"execution":{"iopub.status.busy":"2022-02-01T18:27:53.031404Z","iopub.execute_input":"2022-02-01T18:27:53.031925Z","iopub.status.idle":"2022-02-01T18:27:53.093821Z","shell.execute_reply.started":"2022-02-01T18:27:53.031875Z","shell.execute_reply":"2022-02-01T18:27:53.092939Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from sklearn.metrics import r2_score\nr2_score=r2_score(y_test, preds)\nprint('R2 for Bitcoin Model :',r2_score*100)","metadata":{"execution":{"iopub.status.busy":"2022-02-01T18:27:54.242579Z","iopub.execute_input":"2022-02-01T18:27:54.243063Z","iopub.status.idle":"2022-02-01T18:27:54.250715Z","shell.execute_reply.started":"2022-02-01T18:27:54.243013Z","shell.execute_reply":"2022-02-01T18:27:54.249450Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"preds = test_data [aim].values[:-window_len] * (preds + 1)\npreds = pd.Series(index=targets.index, data=preds)\nline_plot(targets, preds, 'actual', 'prediction', lw=3)","metadata":{"execution":{"iopub.status.busy":"2022-02-01T18:27:55.143098Z","iopub.execute_input":"2022-02-01T18:27:55.143752Z","iopub.status.idle":"2022-02-01T18:27:55.441547Z","shell.execute_reply.started":"2022-02-01T18:27:55.143695Z","shell.execute_reply":"2022-02-01T18:27:55.440635Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Evaluate 2022 price\nCheck the accuracy of LSTM prediction. We got live price to date from [Yahoo Finance](https://finance.yahoo.com/quote/BTC-USD/history/)","metadata":{}},{"cell_type":"markdown","source":"BTC from 26/10/2021 to 26/01/2021","metadata":{}},{"cell_type":"code","source":"BTC = pd.read_csv('../input/btc-2612022/BTC-USD.csv')\nBTC","metadata":{"execution":{"iopub.status.busy":"2022-02-01T18:27:58.478615Z","iopub.execute_input":"2022-02-01T18:27:58.479421Z","iopub.status.idle":"2022-02-01T18:27:58.502476Z","shell.execute_reply.started":"2022-02-01T18:27:58.479379Z","shell.execute_reply":"2022-02-01T18:27:58.501879Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# btc_quote = web.DataReader('BTC-USD', data_source='yahoo', start='2018-01-01', end='2021-09-20')\n# Create a new dataframe\nnew_df = BTC.filter(['Close'])\n# Get the last 60 days closing price\nlast_60_days = new_df[-60:].values\n# Scale the data to be values between 0 and 1\nscaler = MinMaxScaler(feature_range=(0,1))\nlast_60_days_scaled = scaler.fit_transform(last_60_days)\n#Create an empty list\nX_test = []\n# Append the past 60 days\nX_test.append(last_60_days_scaled)\n# convert to numpy array\nX_test = np.array(X_test)\n# Reshape\ntrain_data1, test_data1, X_train1, X_test1, y_train1, y_test1 = prepare_data(\n    X_test, new_df, window_len=window_len, zero_base=zero_base, test_size=test_size)\n# Get the predicted scaled price\npred_price = model.predict(X_test1)\n# undo the scaling\n\npred_price1 = scaler.inverse_transform(pred_price)[-1]\n# # btc_quote2 = web.DataReader('BTC-USD', data_source='yahoo', start='2021-09-20', end='2021-09-20')\nactual_price1 = BTC['Close'][-1:].values\n# actual_price1\naccuracy = ((pred_price1-actual_price1)/actual_price1)*100\nprint('Prediction close price at 26-01-2022: $', pred_price1, sep='')\nprint('Actual price at 26/01/2022: $', actual_price1, sep='')\nprint('error: ', accuracy, '%', sep='')","metadata":{"execution":{"iopub.status.busy":"2022-02-01T18:27:59.150833Z","iopub.execute_input":"2022-02-01T18:27:59.151243Z","iopub.status.idle":"2022-02-01T18:28:00.041676Z","shell.execute_reply.started":"2022-02-01T18:27:59.151215Z","shell.execute_reply":"2022-02-01T18:28:00.040726Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Loop over all assets","metadata":{}},{"cell_type":"code","source":"temp = df_all.reset_index(drop = True) \ntemp['datetime'] = pd.to_datetime(temp['timestamp'], unit='s')\ntrain_data = temp","metadata":{"execution":{"iopub.status.busy":"2022-02-01T18:29:18.334363Z","iopub.execute_input":"2022-02-01T18:29:18.334666Z","iopub.status.idle":"2022-02-01T18:29:21.143663Z","shell.execute_reply.started":"2022-02-01T18:29:18.334636Z","shell.execute_reply":"2022-02-01T18:29:21.142930Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# train test split df_train into 90% train rows and 10% valid rows\n\ndef get_Xy_and_model_for_asset(df_train, asset_id):\n    df = df_train[df_train[\"Asset_ID\"] == asset_id]\n    df = df.filter(['Close'])\n    df = df.values\n    training_data_len = math.ceil(len(df) * .001)\n    # Scale the Data\n    scaler = MinMaxScaler(feature_range=(0,1))\n    scaled_data = scaler.fit_transform(df)\n    # Create the training data set\n    # Create the scaled training data set\n    train_data = scaled_data[0:training_data_len, :]\n\n    # Split the data itno x_train and y_train data sets\n    x_train = []\n    y_train = []\n\n    for i in range(60, len(train_data)):\n        x_train.append(train_data[i-60:i,0])\n        y_train.append(train_data[i,0])\n\n    # Convert the x_train and y_train to numpy arrays\n    x_train, y_train = np.array(x_train), np.array(y_train)\n    # Reshape the data\n    x_train = np.reshape(x_train, (x_train.shape[0], x_train.shape[1], 1))\n    # x_train.shape\n    # Build the LSTM Model\n    model = Sequential()\n    model.add(LSTM(50, return_sequences=True, input_shape=(x_train.shape[1], 1)))\n    model.add(LSTM(50, return_sequences=False))\n    model.add(Dense(25))\n    model.add(Dropout(dropout))\n    model.add(Dense(units=1))\n    model.add(Activation('linear'))\n    # Compile the model\n    model.compile(optimizer='adam', loss='mse')\n    # Train the model\n    model.fit(x_train, y_train, batch_size=1, epochs=1) # LSTM model\n    return x_train, y_train, model\n\nXs = {}\nys = {}\nmodels = {}\n\nfor asset_id, asset_name in zip(asset_details['Asset_ID'], asset_details['Asset_Name']):\n    print(f\"Training model for {asset_name:<16} (ID={asset_id:<2})\")\n    X, y, model = get_Xy_and_model_for_asset(train_data, asset_id)       \n    try:\n        Xs[asset_id], ys[asset_id], models[asset_id] = X, y, model\n    except: \n        Xs[asset_id], ys[asset_id], models[asset_id] = None, None, None","metadata":{"execution":{"iopub.status.busy":"2022-02-01T18:29:22.145162Z","iopub.execute_input":"2022-02-01T18:29:22.145421Z","iopub.status.idle":"2022-02-01T18:39:37.278028Z","shell.execute_reply.started":"2022-02-01T18:29:22.145392Z","shell.execute_reply":"2022-02-01T18:39:37.277359Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sup_train = pd.read_csv('../input/g-research-crypto-forecasting/supplemental_train.csv', \n                 usecols=['Close', 'Target', 'Asset_ID','timestamp'], dtype={'Asset_ID': 'int8'})\nsup_train['datetime'] = pd.to_datetime(sup_train['timestamp'], unit='s')\nsup_train = sup_train.set_index('datetime').drop('timestamp', axis=1)\n# sup_train = sup_train[(sup_train.index.year == 2021) & (sup_train.index.month > 5)]\nsup_trains = {asset_id: sup_train[sup_train['Asset_ID'] == asset_id].resample('1min').interpolate().copy() for asset_id in sup_train['Asset_ID'].unique()}\ndel sup_train","metadata":{"execution":{"iopub.status.busy":"2022-02-01T18:41:22.674813Z","iopub.execute_input":"2022-02-01T18:41:22.675699Z","iopub.status.idle":"2022-02-01T18:41:30.381092Z","shell.execute_reply.started":"2022-02-01T18:41:22.675653Z","shell.execute_reply":"2022-02-01T18:41:30.380361Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Predict & submit","metadata":{}},{"cell_type":"code","source":"import gresearch_crypto\nenv = gresearch_crypto.make_env()\niter_test = env.iter_test()","metadata":{"execution":{"iopub.status.busy":"2022-02-01T18:41:47.869300Z","iopub.execute_input":"2022-02-01T18:41:47.870187Z","iopub.status.idle":"2022-02-01T18:41:47.874275Z","shell.execute_reply.started":"2022-02-01T18:41:47.870147Z","shell.execute_reply":"2022-02-01T18:41:47.873707Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df = pd.read_csv('../input/g-research-crypto-forecasting/supplemental_train.csv', \n                 usecols=['Target', 'Asset_ID','timestamp'], dtype={'Asset_ID': 'int8'})\ndf['datetime'] = pd.to_datetime(df['timestamp'], unit='s')\ndf = df.set_index('datetime').drop('timestamp', axis=1)\n# df = df[(df.index.year == 2021) & (df.index.month > 5)]\ndfs = {asset_id: df[df['Asset_ID'] == asset_id].resample('1min').interpolate().copy() for asset_id in df['Asset_ID'].unique()}\ndel df\nfor df_test, df_pred in iter_test:\n    df_test['datetime'] = pd.to_datetime(df_test['timestamp'], unit='s')\n    for _, row in df_test.iterrows():\n        try:\n            df = dfs[row['Asset_ID']]\n            closest_train_sample = df.iloc[df.index.get_loc(row['datetime'], method='nearest')]\n            df_pred.loc[df_pred['row_id'] == row['row_id'], 'Target'] = closest_train_sample['Target']\n        except:\n            df_pred.loc[df_pred['row_id'] == row['row_id'], 'Target'] = 0\n    df_pred['Target'] = df_pred['Target'].fillna(0)\n    env.predict(df_pred)","metadata":{"execution":{"iopub.status.busy":"2022-02-01T18:41:52.753634Z","iopub.execute_input":"2022-02-01T18:41:52.754313Z","iopub.status.idle":"2022-02-01T18:41:56.534756Z","shell.execute_reply.started":"2022-02-01T18:41:52.754254Z","shell.execute_reply":"2022-02-01T18:41:56.534119Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}