{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.12.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":30894,"databundleVersionId":3147400,"sourceType":"competition"}],"dockerImageVersionId":31259,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\nfrom sklearn.ensemble import HistGradientBoostingRegressor\nfrom sklearn.preprocessing import LabelEncoder\nimport gc\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2026-01-16T01:03:39.900492Z","iopub.execute_input":"2026-01-16T01:03:39.901163Z","iopub.status.idle":"2026-01-16T01:03:41.633412Z","shell.execute_reply.started":"2026-01-16T01:03:39.901129Z","shell.execute_reply":"2026-01-16T01:03:41.632438Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Feature Engineering\ndef get_features(df):\n    eps=1e-9\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['real_body']=np.abs(df['Close']-df['Open'])\n    \n    df['log_ret']=np.log((df['Close']+eps)/(df['Open']+eps))\n    for lag in [1,5,15]:\n        df[f'lag_ret_{lag}']=df.groupby('Asset_ID')['log_ret'].shift(lag)\n    df['volatility']=(df['High']-df['Low'])/(df['Close']+eps)\n    df['lag_vol_1']=df.groupby('Asset_ID')['volatility'].shift(1)\n\n    df=df.fillna(0)\n    return df\n\n# Load and Prepare Training Data\n\ntrain=pd.read_csv('/kaggle/input/g-research-crypto-forecasting/train.csv')\n\n# Drop rows where Target is NaN\ntrain=train.dropna(subset=['Target'])\n\n# Apply feature engineering\ntrain=get_features(train)\n\n# Select features for the model\n# Asset_ID is used as a categorical feature\nfeatures=['Asset_ID','Count','log_ret','volatility','lag_ret_1','lag_ret_5','lag_ret_15','lag_vol_1','upper_shadow','lower_shadow']\nX=train[features]\ny=train['Target']\n\n# Model Training\nmodel=HistGradientBoostingRegressor(\n    max_iter=500,\n    learning_rate=0.03,\n    max_depth=10,\n    random_state=42,\n    categorical_features=[0]\n)\n\nmodel.fit(X,y)\n\nhistory=train.groupby('Asset_ID').tail(60).reset_index(drop=True)\n\ntest_data=pd.read_csv('/kaggle/input/g-research-crypto-forecasting/example_test.csv')\nall_preds=[]\n\nfor timestamp in test_data['timestamp'].unique():\n\n    current_test=test_data[test_data['timestamp']==timestamp].copy()\n    history=pd.concat([history,current_test],axis=0).reset_index(drop=True)\n    history_with_features=get_features(history)\n    X_test=history_with_features[history_with_features['timestamp']==timestamp][features]\n    current_test['Target']=model.predict(X_test)\n    all_preds.append(current_test[['row_id','Target']])\n    history=history.groupby('Asset_ID').tail(30).reset_index(drop=True)\n# Final Submission structure\nsubmission=pd.concat(all_preds)\nsubmission.to_csv('submission.csv',index=False)\nprint('Submission file created!')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-16T02:08:13.332771Z","iopub.execute_input":"2026-01-16T02:08:13.333228Z","iopub.status.idle":"2026-01-16T02:09:25.983868Z","shell.execute_reply.started":"2026-01-16T02:08:13.333195Z","shell.execute_reply":"2026-01-16T02:09:25.983089Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"Mastering the \"Memory\" of Markets: Building a Stateful Inference Pipeline \n\n\nWhile most machine learning models treat data as static \"snapshots,\" financial markets are driven by momentum—what happened 5, 10, or 15 minutes ago dictates what happens next.\n\nIn my latest project on the G-Research Crypto Forecasting challenge, I moved beyond basic regression to build a Stateful Inference Pipeline.\n\nThe Technical Challenge: In a live trading environment, data arrives in tiny minute-by-minute packets. Standard .shift() functions fail because there is no \"previous row\" in the current packet.\n\nMy Solution: \n\n- Sliding Window Memory: I developed a custom \"History Buffer\" that persists state across predictions. This allows the model to calculate time-lagged returns (1, 5, and 15-minute intervals) in real-time. \n\n- Robust Feature Engineering: Implemented \"Shadow Analysis\" and volatility clustering to capture market sentiment and price rejection zones. \n\n- Numerical Stability: Protected the pipeline against \"Zero-Division\" and \"Log-Error\" anomalies, ensuring 100% uptime in volatile conditions.\n\nThe Result: A model that doesn't just see the current price, but understands the velocity and acceleration of the market across 14 different crypto assets simultaneously.\n\nTransitioning from tabular classification to high-frequency forecasting has been a steep learning curve, but the intersection of ML and Finance is where the most exciting challenges live!\n\n#QuantitativeFinance #DataScience #MachineLearning #AlgorithmicTrading #Python #Crypto #Fintech #AI #Forecasting","metadata":{}}]}