{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.11.11","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"gpu","dataSources":[{"sourceId":96164,"databundleVersionId":11418275,"sourceType":"competition"}],"dockerImageVersionId":31040,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import pandas as pd\nimport gc\nfrom sklearn.linear_model import LinearRegression\nimport numpy as np\nfrom sklearn.metrics import mean_absolute_error, mean_squared_error , r2_score\nfrom scipy.stats import pearsonr\nfrom IPython.display import display\nimport math\nimport matplotlib.pyplot as plt\nimport seaborn as sns\nimport warnings\nfrom tqdm import tqdm\nimport xgboost as xgb\nimport lightgbm as lgh \nfrom catboost import CatBoostRegressor\nfrom sklearn.model_selection import train_test_split\nwarnings.filterwarnings('ignore')","metadata":{"_uuid":"0181befa-e1bb-4f33-a0b7-48babdbcc6d3","_cell_guid":"0e151168-ae3c-4199-922e-686ad749bc6f","trusted":true,"collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2025-05-30T05:47:21.134149Z","iopub.execute_input":"2025-05-30T05:47:21.134682Z","iopub.status.idle":"2025-05-30T05:47:29.901025Z","shell.execute_reply.started":"2025-05-30T05:47:21.134653Z","shell.execute_reply":"2025-05-30T05:47:29.900082Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Preprocessing","metadata":{"_uuid":"95fb4313-f842-4c8c-ba61-89fad43c2ea0","_cell_guid":"a180ee29-b5ea-4f54-9335-1103c820b942","trusted":true,"collapsed":false,"jupyter":{"outputs_hidden":false}}},{"cell_type":"code","source":"train_df = pd.read_parquet('/kaggle/input/drw-crypto-market-prediction/train.parquet', engine='pyarrow')\ntrain_df.head(3)","metadata":{"_uuid":"a1db5acc-7a92-4976-852c-cb05af508ecc","_cell_guid":"67ac58cb-9e93-4b93-86e1-58c14ab8d79e","trusted":true,"collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2025-05-30T05:47:29.902927Z","iopub.execute_input":"2025-05-30T05:47:29.903745Z","iopub.status.idle":"2025-05-30T05:47:54.705300Z","shell.execute_reply.started":"2025-05-30T05:47:29.903703Z","shell.execute_reply":"2025-05-30T05:47:54.704312Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_df.replace([np.inf, -np.inf], 0, inplace=True)","metadata":{"_uuid":"6bfde823-a7a7-4c4f-9a12-a1d2198c7567","_cell_guid":"3bfb5799-cf9b-4b12-b42b-1960be570733","trusted":true,"collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2025-05-30T05:47:54.706404Z","iopub.execute_input":"2025-05-30T05:47:54.706830Z","iopub.status.idle":"2025-05-30T05:47:58.558435Z","shell.execute_reply.started":"2025-05-30T05:47:54.706803Z","shell.execute_reply":"2025-05-30T05:47:58.557204Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_df.shape","metadata":{"_uuid":"64d721ab-1207-4c9a-bbfc-bd88ed59c298","_cell_guid":"9fd78a92-91ae-48e1-91d1-3661b8011696","trusted":true,"collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2025-05-30T05:47:58.560531Z","iopub.execute_input":"2025-05-30T05:47:58.560936Z","iopub.status.idle":"2025-05-30T05:47:58.568273Z","shell.execute_reply.started":"2025-05-30T05:47:58.560893Z","shell.execute_reply":"2025-05-30T05:47:58.566982Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"_train_df = train_df.iloc[:500000]\n_test_df = train_df.iloc[500000:]","metadata":{"_uuid":"ba864e23-4f20-48ce-a278-73467f8dc50d","_cell_guid":"a230e3f7-555b-4823-81d2-29d24744242e","trusted":true,"collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2025-05-30T05:47:58.569152Z","iopub.execute_input":"2025-05-30T05:47:58.569505Z","iopub.status.idle":"2025-05-30T05:47:58.592231Z","shell.execute_reply.started":"2025-05-30T05:47:58.569475Z","shell.execute_reply":"2025-05-30T05:47:58.591091Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def add_technical_indicators(df, price_col='Target', ema_periods=[5, 12, 26]):\n    df = df.copy()\n    \n    for period in ema_periods:\n        df[f'ema_{period}'] = df[price_col].ewm(span=period, adjust=False).mean()\n\n    \n    delta = df[price_col].diff()\n    gain = delta.where(delta > 0, 0.0)\n    loss = -delta.where(delta < 0, 0.0)\n    avg_gain = gain.rolling(window=14).mean()\n    avg_loss = loss.rolling(window=14).mean()\n    rs = avg_gain / (avg_loss + 1e-10)\n    df['rsi'] = 100 - (100 / (1 + rs))\n\n    df.fillna(0, inplace=True)\n    return df\n\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-30T05:47:58.593016Z","iopub.execute_input":"2025-05-30T05:47:58.593595Z","iopub.status.idle":"2025-05-30T05:47:58.626799Z","shell.execute_reply.started":"2025-05-30T05:47:58.593558Z","shell.execute_reply":"2025-05-30T05:47:58.625650Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# 1. Combine train and test temporarily for rolling features\ncombined_df = pd.concat([_train_df, _test_df], axis=0).reset_index(drop=True)\n\n# 2. Add indicators\ncombined_df = add_technical_indicators(combined_df, price_col='label')\n\n# 3. Drop NaNs from rolling stats\ncombined_df.dropna(inplace=True)\n\n# 4. Split back to train and test\ntrain_len = len(_train_df)\n_train_df = combined_df.iloc[:train_len]\n_test_df = combined_df.iloc[train_len:]\n\n# 5. Final split\nx_train = _train_df.drop(columns=['label'])\ny_train = _train_df['label']\nx_test = _test_df.drop(columns=['label'])\ny_test = _test_df['label']\n\n# 6. Train-validation split (time-aware)\nx_train, x_val, y_train, y_val = train_test_split(\n    x_train, y_train, test_size=0.2, shuffle=False\n)","metadata":{"_uuid":"3e292d78-6d52-43e2-994b-2c44a37aa663","_cell_guid":"349097b8-2532-4795-a42b-fcca44c84c49","trusted":true,"collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2025-05-30T05:47:58.628025Z","iopub.execute_input":"2025-05-30T05:47:58.628384Z","iopub.status.idle":"2025-05-30T05:48:14.296852Z","shell.execute_reply.started":"2025-05-30T05:47:58.628353Z","shell.execute_reply":"2025-05-30T05:48:14.295929Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"del _train_df\ndel train_df\ngc.collect()","metadata":{"_uuid":"3383b92c-ab22-489d-85d9-986298ed4182","_cell_guid":"84f1aa39-2849-48a9-861b-15a745336605","trusted":true,"collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2025-05-30T05:48:14.297967Z","iopub.execute_input":"2025-05-30T05:48:14.298238Z","iopub.status.idle":"2025-05-30T05:48:14.452142Z","shell.execute_reply.started":"2025-05-30T05:48:14.298218Z","shell.execute_reply":"2025-05-30T05:48:14.450956Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"%system free -m","metadata":{"_uuid":"94437a47-525a-4a11-9af3-06b172996395","_cell_guid":"00820b8b-9f85-48b3-b8cc-4e5f2f9c20ba","trusted":true,"collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2025-05-30T05:48:14.453705Z","iopub.execute_input":"2025-05-30T05:48:14.454115Z","iopub.status.idle":"2025-05-30T05:48:14.544725Z","shell.execute_reply.started":"2025-05-30T05:48:14.454083Z","shell.execute_reply":"2025-05-30T05:48:14.543559Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Train model","metadata":{"_uuid":"b5341118-dc7a-40b8-bdcc-d402cf24d2ac","_cell_guid":"9f97929b-7a66-4ed1-bfe1-861a6a229d47","trusted":true,"collapsed":false,"jupyter":{"outputs_hidden":false}}},{"cell_type":"code","source":"\n\ncat_model = CatBoostRegressor(\n    iterations=500,\n    learning_rate=0.05,\n    depth=8,\n    loss_function='RMSE',\n    bagging_temperature = 0.2 ,\n    reg_lambda = 3,\n    random_seed=42,\n    verbose=100,\n    early_stopping_rounds=50 ,\n    task_type =\"GPU\",\n)\n\ncat_model.fit(x_train, y_train,\n              eval_set=(x_train, y_train),\n              plot=True)\n\ncat_pred = cat_model.predict(x_test)\nmodel_features = x_train.columns\nprint(f\"CatBoost RMSE: {mean_squared_error(y_test, cat_pred, squared=False):.4f}\")\nprint(\"Model HyperParameters Set\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-30T05:48:14.547535Z","iopub.execute_input":"2025-05-30T05:48:14.547791Z","iopub.status.idle":"2025-05-30T05:48:14.809152Z","shell.execute_reply.started":"2025-05-30T05:48:14.547773Z","shell.execute_reply":"2025-05-30T05:48:14.807695Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Predict","metadata":{"_uuid":"8f8ca959-1b36-4b1a-a38f-f1204673a762","_cell_guid":"8596d4ef-a1dd-4e15-87b1-c3fdebc1ce3a","trusted":true,"collapsed":false,"jupyter":{"outputs_hidden":false}}},{"cell_type":"code","source":"y_pred = cat_model.predict(x_test)\ny_pred","metadata":{"_uuid":"3a08d247-7ff6-4e29-9dcd-ae3f40e881f8","_cell_guid":"b5e17a57-1a29-437a-bde6-d2a0a21e8c93","trusted":true,"collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2025-05-30T05:48:14.809866Z","iopub.status.idle":"2025-05-30T05:48:14.810210Z","shell.execute_reply.started":"2025-05-30T05:48:14.810072Z","shell.execute_reply":"2025-05-30T05:48:14.810086Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Test and evaluate","metadata":{"_uuid":"bb609e02-6b7d-484b-a2f8-cd50d66f5036","_cell_guid":"c8bddad1-aafa-46dc-bbe7-1d4f4fa4e57c","trusted":true,"collapsed":false,"jupyter":{"outputs_hidden":false}}},{"cell_type":"code","source":"mae = mean_absolute_error(y_test, y_pred)\nmse = mean_squared_error(y_test, y_pred)\nrmse = np.sqrt(mse)\nr2 = r2_score(y_test, y_pred)\ncorr_coef, p_value = pearsonr(y_test, y_pred)\n\nresults = pd.DataFrame({\n    'Model': ['CatBoost'],\n    'MAE': [mae],\n    'MSE': [mse],\n    'RMSE': [rmse],\n    'R2': [r2],\n    'Pearson Correlation Coefficient':[corr_coef],\n    'P value':[p_value],\n})\ndisplay(results)\n\nnp.random.seed(42)  # for reproducibility\nsample_indices = np.random.choice(len(y_test), size=100, replace=False)\n\n# Extract corresponding values\ny_test_sample = y_test.iloc[sample_indices].reset_index(drop=True)\ny_pred_sample = pd.Series(y_pred[sample_indices])\n\n# Plot comparison\nplt.figure(figsize=(12, 6))\nplt.plot(y_test_sample, label='Actual', marker='o')\nplt.plot(y_pred_sample, label='Predicted', marker='x')\nplt.title(\"Actual vs Predicted (100 Random Samples)\")\nplt.xlabel(\"Sample Index\")\nplt.ylabel(\"Target Value\")\nplt.legend()\nplt.tight_layout()\nplt.show()","metadata":{"_uuid":"0e7f26a5-d339-4e9e-9a12-6e7fe002bb26","_cell_guid":"dc701dd4-99a0-4d75-a5c8-422bc197550c","trusted":true,"collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2025-05-30T05:48:14.811389Z","iopub.status.idle":"2025-05-30T05:48:14.811774Z","shell.execute_reply.started":"2025-05-30T05:48:14.811568Z","shell.execute_reply":"2025-05-30T05:48:14.811585Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Submission","metadata":{"_uuid":"1733ff0d-9c27-44c6-9271-9758c39a861a","_cell_guid":"50d782cd-6d7a-4786-b083-691579f2bb64","trusted":true,"collapsed":false,"jupyter":{"outputs_hidden":false}}},{"cell_type":"code","source":"test_df = pd.read_parquet('/kaggle/input/drw-crypto-market-prediction/test.parquet', engine='pyarrow')\ntest_df = add_technical_indicators(test_df, price_col='label')\n\n# Select only the features the model was trained on\ntest_df = test_df[model_features]  # avoid feature mismatch error\n\ntest_df.replace([np.inf, -np.inf], 0, inplace=True)\n\npreds = cat_model.predict(test_df)\n","metadata":{"_uuid":"f33943dc-d253-4bd4-9472-1f89589de9ac","_cell_guid":"8a27004c-2e74-4373-896b-25e9316998db","trusted":true,"collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2025-05-30T05:48:14.813351Z","iopub.status.idle":"2025-05-30T05:48:14.813751Z","shell.execute_reply.started":"2025-05-30T05:48:14.813567Z","shell.execute_reply":"2025-05-30T05:48:14.813585Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"sample_submission = pd.read_csv('/kaggle/input/drw-crypto-market-prediction/sample_submission.csv')\nsample_submission['prediction'] = preds\nsample_submission.to_csv('sample_submission.csv',index = False )","metadata":{"_uuid":"21d3f99c-4279-4f8b-966e-31298c64ddc0","_cell_guid":"7e2483ef-7b28-4992-836f-661b903d7f93","trusted":true,"collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2025-05-30T05:48:14.815304Z","iopub.status.idle":"2025-05-30T05:48:14.815693Z","shell.execute_reply.started":"2025-05-30T05:48:14.815514Z","shell.execute_reply":"2025-05-30T05:48:14.815532Z"}},"outputs":[],"execution_count":null}]}