{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.11.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":96164,"databundleVersionId":11418275,"sourceType":"competition"}],"dockerImageVersionId":31089,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import pandas as pd \nimport numpy as np","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-11T06:23:27.118891Z","iopub.execute_input":"2025-07-11T06:23:27.119368Z","iopub.status.idle":"2025-07-11T06:23:27.124682Z","shell.execute_reply.started":"2025-07-11T06:23:27.119338Z","shell.execute_reply":"2025-07-11T06:23:27.123657Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train = pd.read_parquet(\"/kaggle/input/drw-crypto-market-prediction/train.parquet\")\ntest = pd.read_parquet(\"/kaggle/input/drw-crypto-market-prediction/test.parquet\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-11T06:23:27.126105Z","iopub.execute_input":"2025-07-11T06:23:27.126363Z","iopub.status.idle":"2025-07-11T06:24:11.059625Z","shell.execute_reply.started":"2025-07-11T06:23:27.126344Z","shell.execute_reply":"2025-07-11T06:24:11.058828Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-11T06:24:11.061210Z","iopub.execute_input":"2025-07-11T06:24:11.061501Z","iopub.status.idle":"2025-07-11T06:24:11.082524Z","shell.execute_reply.started":"2025-07-11T06:24:11.061475Z","shell.execute_reply":"2025-07-11T06:24:11.081657Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"base_features = [\n    \"X752\",\n    \"X287\",\n    \"X298\",\n    \"X759\",\n    \"X302\",\n    \"X55\",\n    \"X56\",\n    \"X52\",\n    \"X303\",\n    \"X51\",\n    \"X598\", \"X385\", \"X603\", \"X674\",\n    \"X415\", \"X345\", \"X174\", \"X178\", \"X168\", \"X612\",\n    \"bid_qty\", \"ask_qty\", \"buy_qty\", \"sell_qty\", \"volume\", \"label\"\n    ]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-11T06:24:11.083429Z","iopub.execute_input":"2025-07-11T06:24:11.083737Z","iopub.status.idle":"2025-07-11T06:24:11.107507Z","shell.execute_reply.started":"2025-07-11T06:24:11.083710Z","shell.execute_reply":"2025-07-11T06:24:11.106649Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train = train[base_features]\ntest = test[base_features]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-11T06:24:11.109756Z","iopub.execute_input":"2025-07-11T06:24:11.110056Z","iopub.status.idle":"2025-07-11T06:24:11.552177Z","shell.execute_reply.started":"2025-07-11T06:24:11.110036Z","shell.execute_reply":"2025-07-11T06:24:11.551367Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def add_features(df):\n    # Original features\n    df['bid_ask_interaction'] = df['bid_qty'] * df['ask_qty']\n    df['bid_buy_interaction'] = df['bid_qty'] * df['buy_qty']\n    df['bid_sell_interaction'] = df['bid_qty'] * df['sell_qty']\n    df['ask_buy_interaction'] = df['ask_qty'] * df['buy_qty']\n    df['ask_sell_interaction'] = df['ask_qty'] * df['sell_qty']\n\n    df['volume_weighted_sell'] = df['sell_qty'] * df['volume']\n    df['buy_sell_ratio'] = df['buy_qty'] / (df['sell_qty'] + 1e-10)\n    df['selling_pressure'] = df['sell_qty'] / (df['volume'] + 1e-10)\n    df['log_volume'] = np.log1p(df['volume'])\n\n    df['effective_spread_proxy'] = np.abs(df['buy_qty'] - df['sell_qty']) / (df['volume'] + 1e-10)\n    df['bid_ask_imbalance'] = (df['bid_qty'] - df['ask_qty']) / (df['bid_qty'] + df['ask_qty'] + 1e-10)\n    df['order_flow_imbalance'] = (df['buy_qty'] - df['sell_qty']) / (df['buy_qty'] + df['sell_qty'] + 1e-10)\n    df['liquidity_ratio'] = (df['bid_qty'] + df['ask_qty']) / (df['volume'] + 1e-10)\n    \n    # === NEW MICROSTRUCTURE FEATURES ===\n    \n    # Price Pressure Indicators\n    df['net_order_flow'] = df['buy_qty'] - df['sell_qty']\n    df['normalized_net_flow'] = df['net_order_flow'] / (df['volume'] + 1e-10)\n    df['buying_pressure'] = df['buy_qty'] / (df['volume'] + 1e-10)\n    df['volume_weighted_buy'] = df['buy_qty'] * df['volume']\n    \n    # Liquidity Depth Measures\n    df['total_depth'] = df['bid_qty'] + df['ask_qty']\n    df['depth_imbalance'] = (df['bid_qty'] - df['ask_qty']) / (df['total_depth'] + 1e-10)\n    df['relative_spread'] = np.abs(df['bid_qty'] - df['ask_qty']) / (df['total_depth'] + 1e-10)\n    df['log_depth'] = np.log1p(df['total_depth'])\n    \n    # Order Flow Toxicity Proxies\n    df['kyle_lambda'] = np.abs(df['net_order_flow']) / (df['volume'] + 1e-10)\n    df['flow_toxicity'] = np.abs(df['order_flow_imbalance']) * df['volume']\n    df['aggressive_flow_ratio'] = (df['buy_qty'] + df['sell_qty']) / (df['total_depth'] + 1e-10)\n    \n    # Market Activity Indicators\n    df['volume_depth_ratio'] = df['volume'] / (df['total_depth'] + 1e-10)\n    df['activity_intensity'] = (df['buy_qty'] + df['sell_qty']) / (df['volume'] + 1e-10)\n    df['log_buy_qty'] = np.log1p(df['buy_qty'])\n    df['log_sell_qty'] = np.log1p(df['sell_qty'])\n    df['log_bid_qty'] = np.log1p(df['bid_qty'])\n    df['log_ask_qty'] = np.log1p(df['ask_qty'])\n    \n    # Microstructure Volatility Proxies\n    df['realized_spread_proxy'] = 2 * np.abs(df['net_order_flow']) / (df['volume'] + 1e-10)\n    df['price_impact_proxy'] = df['net_order_flow'] / (df['total_depth'] + 1e-10)\n    df['quote_volatility_proxy'] = np.abs(df['depth_imbalance'])\n    \n    # Complex Interaction Terms\n    df['flow_depth_interaction'] = df['net_order_flow'] * df['total_depth']\n    df['imbalance_volume_interaction'] = df['order_flow_imbalance'] * df['volume']\n    df['depth_volume_interaction'] = df['total_depth'] * df['volume']\n    df['buy_sell_spread'] = np.abs(df['buy_qty'] - df['sell_qty'])\n    df['bid_ask_spread'] = np.abs(df['bid_qty'] - df['ask_qty'])\n    \n    # Information Asymmetry Measures\n    df['trade_informativeness'] = df['net_order_flow'] / (df['bid_qty'] + df['ask_qty'] + 1e-10)\n    df['execution_shortfall_proxy'] = df['buy_sell_spread'] / (df['volume'] + 1e-10)\n    df['adverse_selection_proxy'] = df['net_order_flow'] / (df['total_depth'] + 1e-10) * df['volume']\n    \n    # Market Efficiency Indicators\n    df['fill_probability'] = df['volume'] / (df['buy_qty'] + df['sell_qty'] + 1e-10)\n    df['execution_rate'] = (df['buy_qty'] + df['sell_qty']) / (df['total_depth'] + 1e-10)\n    df['market_efficiency'] = df['volume'] / (df['bid_ask_spread'] + 1e-10)\n    \n    # Non-linear Transformations\n    df['sqrt_volume'] = np.sqrt(df['volume'])\n    df['sqrt_depth'] = np.sqrt(df['total_depth'])\n    df['volume_squared'] = df['volume'] ** 2\n    df['imbalance_squared'] = df['order_flow_imbalance'] ** 2\n    \n    # Relative Measures\n    df['bid_ratio'] = df['bid_qty'] / (df['total_depth'] + 1e-10)\n    df['ask_ratio'] = df['ask_qty'] / (df['total_depth'] + 1e-10)\n    df['buy_ratio'] = df['buy_qty'] / (df['buy_qty'] + df['sell_qty'] + 1e-10)\n    df['sell_ratio'] = df['sell_qty'] / (df['buy_qty'] + df['sell_qty'] + 1e-10)\n    \n    # Market Stress Indicators\n    df['liquidity_consumption'] = (df['buy_qty'] + df['sell_qty']) / (df['total_depth'] + 1e-10)\n    df['market_stress'] = df['volume'] / (df['total_depth'] + 1e-10) * np.abs(df['order_flow_imbalance'])\n    df['depth_depletion'] = df['volume'] / (df['bid_qty'] + df['ask_qty'] + 1e-10)\n    \n    # Directional Indicators\n    df['net_buying_ratio'] = df['net_order_flow'] / (df['volume'] + 1e-10)\n    df['directional_volume'] = df['net_order_flow'] * np.log1p(df['volume'])\n    df['signed_volume'] = np.sign(df['net_order_flow']) * df['volume']\n    \n    # Replace infinities and NaNs\n    df = df.replace([np.inf, -np.inf], 0).fillna(0)\n    \n    return df","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-11T06:24:11.553084Z","iopub.execute_input":"2025-07-11T06:24:11.553371Z","iopub.status.idle":"2025-07-11T06:24:11.572466Z","shell.execute_reply.started":"2025-07-11T06:24:11.553337Z","shell.execute_reply":"2025-07-11T06:24:11.571251Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"x_train = add_features(train)\nx_train.shape\n\nimport warnings \n\nwarnings.filterwarnings('ignore')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-11T06:24:11.573722Z","iopub.execute_input":"2025-07-11T06:24:11.574052Z","iopub.status.idle":"2025-07-11T06:24:12.889479Z","shell.execute_reply.started":"2025-07-11T06:24:11.574005Z","shell.execute_reply":"2025-07-11T06:24:12.888675Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"x_test = add_features(test)\nx_test.shape","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-11T06:24:12.890282Z","iopub.execute_input":"2025-07-11T06:24:12.890513Z","iopub.status.idle":"2025-07-11T06:24:14.157801Z","shell.execute_reply.started":"2025-07-11T06:24:12.890495Z","shell.execute_reply":"2025-07-11T06:24:14.156773Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Ensure the index is a datetime type\nx_train.index = pd.to_datetime(x_train.index)\n\n# Sort the dataset by timestamp (index)\nx_train = x_train.sort_index()\n\n# Define the split point (80% train, 20% validation)\nsplit_index = int(len(x_train) * 0.8)\n\n# Slice by index — NO shuffling\ntrain_split = x_train.iloc[:split_index]\nval_split = x_train.iloc[split_index:]\n\n# Training features and labels\nX_train = train_split.drop(columns=['label'])\ny_train = train_split['label']\n\n# Validation features and labels\nX_val = val_split.drop(columns=['label'])\ny_val = val_split['label']","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-11T06:24:14.158921Z","iopub.execute_input":"2025-07-11T06:24:14.159229Z","iopub.status.idle":"2025-07-11T06:24:14.424313Z","shell.execute_reply.started":"2025-07-11T06:24:14.159201Z","shell.execute_reply":"2025-07-11T06:24:14.423585Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"y_train.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-11T06:24:14.425192Z","iopub.execute_input":"2025-07-11T06:24:14.425460Z","iopub.status.idle":"2025-07-11T06:24:14.432580Z","shell.execute_reply.started":"2025-07-11T06:24:14.425436Z","shell.execute_reply":"2025-07-11T06:24:14.431507Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from xgboost import XGBRegressor\nfrom sklearn.metrics import mean_squared_error, r2_score, mean_absolute_error\n\nXGB_PARAMS = {\n    \"tree_method\": \"hist\",\n    \"device\": \"gpu\",\n    \"colsample_bylevel\": 0.4778,\n    \"colsample_bynode\": 0.3628,\n    \"colsample_bytree\": 0.7107,\n    \"gamma\": 1.7095,\n    \"learning_rate\": 0.02213,\n    \"max_depth\": 20,\n    \"max_leaves\": 12,\n    \"min_child_weight\": 16,\n    \"n_estimators\": 1667,\n    \"subsample\": 0.06567,\n    \"reg_alpha\": 39.3524,\n    \"reg_lambda\": 75.4484,\n    \"verbosity\": 0,\n    \"random_state\": 42,\n    \"n_jobs\": -1\n}\n\nLEARNERS = [\n    {\"name\": \"xgb\", \"Estimator\": XGBRegressor, \"params\": XGB_PARAMS}\n]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-11T06:24:14.435268Z","iopub.execute_input":"2025-07-11T06:24:14.435538Z","iopub.status.idle":"2025-07-11T06:24:16.091638Z","shell.execute_reply.started":"2025-07-11T06:24:14.435519Z","shell.execute_reply":"2025-07-11T06:24:16.090802Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from xgboost import XGBRegressor\nimport numpy as np\n\nmodel = XGBRegressor(**XGB_PARAMS)\nmodel.fit(X_train, y_train)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-11T06:24:16.092532Z","iopub.execute_input":"2025-07-11T06:24:16.093011Z","iopub.status.idle":"2025-07-11T06:25:39.064594Z","shell.execute_reply.started":"2025-07-11T06:24:16.092988Z","shell.execute_reply":"2025-07-11T06:25:39.063861Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"y_val_pred = model.predict(X_val)\n\nfrom scipy.stats import pearsonr\n\n# Pearson correlation\npearson_corr, _ = pearsonr(y_val, y_val_pred)\n\nprint(f\"✅ Pearson Correlation: {pearson_corr:.4f}\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-11T06:25:39.065340Z","iopub.execute_input":"2025-07-11T06:25:39.065591Z","iopub.status.idle":"2025-07-11T06:25:40.297456Z","shell.execute_reply.started":"2025-07-11T06:25:39.065571Z","shell.execute_reply":"2025-07-11T06:25:40.296583Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"X = x_train.drop(columns=['label'])\ny = x_train['label']\nfeature_names = X.columns.tolist()  # ✅ Save exact feature names\n\n\nx_test = x_test[feature_names]  # ✅ Ensure same columns, same order\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-11T06:25:40.298287Z","iopub.execute_input":"2025-07-11T06:25:40.298566Z","iopub.status.idle":"2025-07-11T06:25:40.531604Z","shell.execute_reply.started":"2025-07-11T06:25:40.298545Z","shell.execute_reply":"2025-07-11T06:25:40.530646Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"y_pred = model.predict(x_test)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-11T06:25:40.532585Z","iopub.execute_input":"2025-07-11T06:25:40.532812Z","iopub.status.idle":"2025-07-11T06:25:47.722863Z","shell.execute_reply.started":"2025-07-11T06:25:40.532794Z","shell.execute_reply":"2025-07-11T06:25:47.722204Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"submission = pd.read_csv(\"/kaggle/input/drw-crypto-market-prediction/sample_submission.csv\")\nsubmission[\"prediction\"] = y_pred\nsubmission.to_csv(\"submission.csv\", index=False)\nprint(\"📁 Submission file saved as 'submission.csv'\")\nsubmission.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-11T06:25:47.723435Z","iopub.execute_input":"2025-07-11T06:25:47.723635Z","iopub.status.idle":"2025-07-11T06:25:48.942452Z","shell.execute_reply.started":"2025-07-11T06:25:47.723618Z","shell.execute_reply":"2025-07-11T06:25:48.941282Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}