Files
trading-bot/notebooks/train-xboost.ipynb
T

337 lines
51 KiB
Plaintext

{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"id": "882d4907",
"metadata": {},
"outputs": [],
"source": [
"import pandas as pd\n",
"import xgboost as xgb\n",
"from sklearn.metrics import classification_report, accuracy_score\n",
"import matplotlib.pyplot as plt\n",
"import numpy as np"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "947722b7",
"metadata": {},
"outputs": [],
"source": [
"\n",
"# 1. Load data\n",
"df = pd.read_parquet(\"../data/training/spy_direction_5d.parquet\")\n",
"\n",
"# 2. Define features & target\n",
"target_col = \"spy_up_5d\"\n",
"feature_cols = [\n",
" \"VIX_rank_20\",\n",
" \"TLT_ret_10\",\n",
" \"USO_ret_5\",\n",
" \"SPY_TLT_ratio_ret\",\n",
" \"SPY_ret_5\",\n",
" \"SPY_ret_20\",\n",
" \"SPY_dist_sma50\"\n",
"]"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "5b02ce5e",
"metadata": {},
"outputs": [],
"source": [
"# 3. Create three distinct splits\n",
"train_df = df[df[\"split\"] == \"train\"]\n",
"val_df = df[df[\"split\"] == \"validation\"] # Adjust string if named \"val\"\n",
"test_df = df[df[\"split\"] == \"test\"]\n",
"\n",
"X_train, y_train = train_df[feature_cols], train_df[target_col]\n",
"X_val, y_val = val_df[feature_cols], val_df[target_col]\n",
"X_test, y_test = test_df[feature_cols], test_df[target_col]"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "93a128a7",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Train positive %: 0.5819477434679335\n",
"Val positive %: 0.6388888888888888\n",
"Test positive %: 0.5769230769230769\n",
"\n",
"Train Feature Correlations with Target:\n",
"VIX_rank_20 -0.004576\n",
"TLT_ret_10 0.162370\n",
"USO_ret_5 -0.113602\n",
"SPY_TLT_ratio_ret -0.111551\n",
"SPY_ret_5 -0.001073\n",
"SPY_ret_20 0.006523\n",
"SPY_dist_sma50 -0.035773\n",
"dtype: float64\n",
"\n",
"Stump Model Best Iteration: 22\n"
]
}
],
"source": [
"# 1. Check target distribution across splits\n",
"print(\"Train positive %:\", y_train.mean())\n",
"print(\"Val positive %: \", y_val.mean())\n",
"print(\"Test positive %: \", y_test.mean())\n",
"\n",
"# 2. Check simple linear correlation with target\n",
"print(\"\\nTrain Feature Correlations with Target:\")\n",
"print(train_df[feature_cols].apply(lambda col: col.corr(y_train)))\n",
"\n",
"# 3. Test a super simple model (Decision Stump)\n",
"stump_model = xgb.XGBClassifier(\n",
" n_estimators=100,\n",
" max_depth=2, # Decision stumps (1 split per tree, minimal overfitting)\n",
" learning_rate=0.01,\n",
" early_stopping_rounds=15,\n",
" eval_metric=\"logloss\"\n",
")\n",
"stump_model.fit(\n",
" X_train, y_train,\n",
" eval_set=[(X_train, y_train), (X_val, y_val)],\n",
" verbose=False\n",
")\n",
"print(f\"\\nStump Model Best Iteration: {stump_model.best_iteration}\")"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "2f82ce9d",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Optimal number of trees (best iteration): 131\n",
"Starting Validation Loss: 0.6606\n",
"Final Validation Loss: 0.6537\n"
]
}
],
"source": [
"\n",
"# 4. Initialize XGBoost Classifier with Early Stopping\n",
"model = xgb.XGBClassifier(\n",
" n_estimators=300, # Set higher; early stopping will truncate training automatically\n",
" max_depth=1, # Keep shallow to prevent memorizing noise\n",
" learning_rate=0.01,\n",
" subsample=0.7,\n",
" colsample_bytree=0.7,\n",
" early_stopping_rounds=20, # Stop if validation loss stops improving for 15 rounds\n",
" eval_metric=\"logloss\",\n",
" random_state=42\n",
")\n",
"\n",
"# 5. Fit using Validation set to monitor performance\n",
"model.fit(\n",
" X_train, y_train,\n",
" eval_set=[(X_train, y_train), (X_val, y_val)],\n",
" verbose=False\n",
")\n",
"\n",
"print(f\"Optimal number of trees (best iteration): {model.best_iteration}\")\n",
"\n",
"evals = model.evals_result()\n",
"val_loss = evals['validation_1']['logloss']\n",
"print(f\"Starting Validation Loss: {val_loss[0]:.4f}\")\n",
"print(f\"Final Validation Loss: {val_loss[-1]:.4f}\")\n"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "2d54aaee",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"--- Final Holdout Test Performance ---\n",
"Test Set Accuracy: 57.69%\n",
"\n",
"Classification Report:\n",
" precision recall f1-score support\n",
"\n",
" 0.0 0.00 0.00 0.00 77\n",
" 1.0 0.58 1.00 0.73 105\n",
"\n",
" accuracy 0.58 182\n",
" macro avg 0.29 0.50 0.37 182\n",
"weighted avg 0.33 0.58 0.42 182\n",
"\n",
"classification_report with custom threshold (0.5819477434679335):\n",
" precision recall f1-score support\n",
"\n",
" 0.0 0.46 0.74 0.57 77\n",
" 1.0 0.66 0.37 0.48 105\n",
"\n",
" accuracy 0.53 182\n",
" macro avg 0.56 0.56 0.52 182\n",
"weighted avg 0.58 0.53 0.52 182\n",
"\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/jarno/repos/trading-bot/.venv/lib/python3.11/site-packages/sklearn/metrics/_classification.py:1879: UndefinedMetricWarning: Precision is ill-defined and being set to 0.0 in labels with no predicted samples. Use `zero_division` parameter to control this behavior.\n",
" _warn_prf(average, modifier, f\"{metric.capitalize()} is\", result.shape[0])\n",
"/home/jarno/repos/trading-bot/.venv/lib/python3.11/site-packages/sklearn/metrics/_classification.py:1879: UndefinedMetricWarning: Precision is ill-defined and being set to 0.0 in labels with no predicted samples. Use `zero_division` parameter to control this behavior.\n",
" _warn_prf(average, modifier, f\"{metric.capitalize()} is\", result.shape[0])\n",
"/home/jarno/repos/trading-bot/.venv/lib/python3.11/site-packages/sklearn/metrics/_classification.py:1879: UndefinedMetricWarning: Precision is ill-defined and being set to 0.0 in labels with no predicted samples. Use `zero_division` parameter to control this behavior.\n",
" _warn_prf(average, modifier, f\"{metric.capitalize()} is\", result.shape[0])\n"
]
},
{
"data": {
"image/png": "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c/jhh5uTTz45w3Oyqnzc+/D555+bQoUK2fe8fPnyMZ+H3IuRAQAAAkIN8YMOOsi88MIL5tdffzX33nuvqV27tvn999+TvnbXrl3mggsuMIMGDTLffPNNyttNZd9uXwMHDjTjxo2L+Nu7775r6tSpY8aMGWPmzJljzjnnHNOzZ8+I51x00UW24frZZ5/Z/TZu3NjccccdEc/ZsGGDadKkibn77rvNjz/+aC699FLb2N+zZ0/4OR9//LE57LDDzIMPPmhuu+02M2/evAzHGr2v4447zrz00ksp78vPMT/99NPm+OOPN++//76ZOXOmfc0JJ5xg/vnnnywvH3nggQdMvXr1zKeffmoDBwUescoAuVu+kEJC7JNhw4aZGTNmmFdffTXicUX/nTt3NsOHDzfHHHOMfUxfplGjRtlIu1KlSrZXpGvXrqZgwchBmk8++cRWgEuWLDElS5Y0LVq0MFdffbU54IADsv3duuyyy8xpp51mLr74Yl/PHzJkiHnzzTcjHjv44IMzVOCJbN682ZQpU8bU7v262V2wRMrHnNcVKRAyg5vuMbdPL2B27InsSQJlxOcoPb9rSx9qZ9KNriW69qjHXXbv3m0be61atTJPPvlkwteqMbxmzRp7/SpQoIBtIKq32O92U9m329cff/xhrycvvviifVyN5wMPPNBce+215v7777ePrVixwtStW9eMHTvWtG/f3j72wQcfmHbt2oV73tXg1X6mT59uG+Vyww032Gvt7NmzTYkSJczixYvt8YwYMcJ0797dPue7774zFStWNJUrVzalSpWyDW014r2i96UAQg1tvVaBgd99+TlmtSHUi+/KXaMENWrUME899ZS54oorsrR8FHCcffbZNmA45ZRT7GMaafj7779tEBd9/d60aZMpXbq0j08h0g0jA1lAFeNPP/2U4fHt27ebadOm2S+KqMGsL5SGRvv06WO/ZOpdueSSSyJepy+xekT05VXPyeWXX24r3aOOOsosXLjQZDcNhf7111++n6+ApUiRIjYocj933XVXth4jACB1qqvVGHXUqC9atGjSNCFdg9QQVqMzs9v1u+9E+1q+fLltjCrFxqlatapNcfF2QKnR603BOemkk+y/3lEIXZPVGeeOqVatWrZB/MYbb4Sfo174WGlBXtH7UtCTmX35OWaNArhAQIoXL247E1WWWV0+6uhTUOMC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pUub4cOHp1xeP/74o3n99dfNpk2bTKtWrUynTp0i/r506VK7nWXLlpmaNWuaK6+80pZlrHNfs2aN2bt3r2nRooUpV65cyvtKVoZ+zx3wK18oFAr5fjbS1muvvWa++uor8+yzz5rcaPPmzaZMmTKmdu/Xze6CJXL6cNJOkQIhM7jpHnP79AJmx558OX04aYkyooyy8nN05plnmkKFCpl0okbkCSecYNq1a2cb4WqUqxE9cOBAc/vtt8d8zc6dO82JJ55odu3aZS677DLz3XffmY8++sg2Jhs0aGCfc+ONN5oZM2bYhvKBBx5oXn31Vdvo1WOuwevd92mnnWYmT55sG6zeffvZjlfHjh3NDz/8YAoUKGAb26mcp85j8eLFEdu7+eabzXHHHWfef//9lMrriSeeMHfeeae55pprbON70qRJplGjRuaOO+6wf//mm29so/3CCy+029fves60adNsYBB97go61Cj/559/Mpx7sn35KUM/554T128FNwpIkPvkaDCwfPly+4X5+eefbQ/D8ccfby6//HJTosR/jcGFCxeaK6644r8DzZfPlC9f3n5prr/+evPkk0/aL8MLL7xg/+b8/fffpkuXLnY75513Xtx9qxLSBzeepk2bmsGDB5sXX3zRfPLJJ2bcuHHhv6lCVaUSz6GHHmqef/55k13UOzF16tSIHoCHHnrIvPXWW2bmzJkmp/Xs2dOcfPLJ5qKLLvL9GoKBxGjoJkcZUUZ5PRi47bbbzHvvvWd+++23hI95aURADUU1KHUNlZYtW5qiRYvaxrzoenbIIYeEX7N9+3ZTu3ZtO4Jw7733ZtiPAgsFFF9//bWZMGFCeN9+tuNtFGt7ClReeumliGAgM+c5e/Zsc8wxx9jGcIcOHXxvR6Mlale8/PLLEdes1atXhxvfup6p7N55553w3/X5qFChgj326HNX+YwfP97cdNNNEefuZ1+plGGic9+fCAYCmiakL4SGGBs2bGg2btxoLr74YvPrr7+aq6++2tx6662+tqEvohrcirY1BKYhNfVUNG/e3H5hRFG1erufe+4528BesWKFGTRokG2Yv/vuu6ZJkybmqKOOsl84p1evXvZ5auwnol4BfWFFDes+ffqYt99+Ozyk5/5VBaUhO69rr73W/Pvvv/b/CxYssOftjlFKlixpspOGO9Wb4qWKJXq4NqfMmjUrojID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SSnty892/Lx/s2fPDrVo0SJUo0aNUJMmTULFixcPnXXWWfYY3OfIz/vlpwzziqDV1+76rX+ROzEykE327Nlj3n33Xds7U6BAAdsT06ZNG5MvXz779y1btpi77ror/Hz1RjVo0MCce+655o033jC///676d+/f3TgZgYMGGCOOOIIc+GFF2bXoZtHHnnENGzY0Jxxxhm+nv/mm2+ar776KuKxypUrm759+6a872YPfmZ2FyyR8uvyuiIFQmZwU2PqD/jU7Njz32cIwSqjpQ+1M+lIvcRffvllyq+bMmWKGT16tOnSpYv59ddfI/52zTXXmH///dcsXbrUlCpVyixbtsw0btzY1pGXXHKJfc6DDz5oFixYYHvHy5Yta3bs2GFOPvlkc8stt5j333/fPmfChAn2eaqfjj/+eLNo0SLTpEkTM2zYMHPrrbfG3M4///xjRyluu+0288EHH9jn/PHHH+boo4+2daOOIRb1nH/88cfh0YnJkyeb1q1b29e1b9/e9/EMHjw4Yrsqg1q1apnu3buntC8/2/Hz/qm3X8d3zDHHhPet60PRokXNOeec4/v98lOGAHIGcwaygSrFZs2ambvvvts2/jXcOmLECFuB7t69O/ycp59+2jbwDz/8cPuc3r17mxNOOMFeHIYMGWJf4/XUU0+Zxx9/3D4nO73++utm1qxZvp+vC5uG+nUe7ueQQw7J1mMEkB6U6vPTTz/Zn23btvl6zcaNG83FF19sg4FYaTlffPGF6dq1q21YykEHHWTatm1rnnvuufBz1q9fbw499FDbgJciRYrYxqYed7T9U0891Ta8RY1nBR96PNF2lMLiTbFRnasGrzueWG666aaINKXTTz/dNr6/++67lI4n2qhRo+x+zz///JT25Wc7ft6/Dh06hAMBqVKlit233sNU3i8/ZQggZzAykA1eeeUVm4cZnX+qx9zIgLei1YiBqJdFFzPlU6rR36tXL9s7rwvVb7/9Zu68807z7LPPxs159VKPlnqdVCGPGzfO/P333+axxx6zf1OvjRr8a9asMYcddpitxJVHKsOHD7d/V8/an3/+aR9TT06xYsUS7k+N/+uvvz4TpQUgN1u3bp1t0KqjQ3XGPffcY+uqRC6//HI7uqmefI0sRjvwwANtj7SXfv/hhx/Cv2sEQHWnRkuPO+44O7qgekv1r6O6NHoUVb3+6mjZ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AGmhSJEipn///vZfUD58hvieURelL+prygd5S74Qa0EBAAAAgcTIAAAAABBQBAMAAABAQBEMAAAAAAFFMIAc9ccff5irr77anHzyyaZr165m+vTpvCMeGzduNA899JDp0KGDOeuss+z///nnH8oojnvvvdc0b97cvP/++5RRlLlz55qePXuaU0891fTq1cusWrWKMvKYNWuWufLKK81pp51mOnXqZJ588kmzY8eOwJbRzp07zdixY02bNm3MGWecEfM5e/fuNSNGjAg/Z+jQoWb37t0mSPXzsGHDzEknnWRuvvnmmM/5+OOPzWWXXWZatmxpP18//PDDfj9OIBmCAeSYNWvWmOOOO86sXbvW3HnnnaZixYq2Up05cybvyv80btzY3s1SAVP37t3txVkXFV2okfGi+8Ybb5gZM2bYzxYiy6ZJkyamZMmS5p577jHHHHOM/TzhP7NnzzYnnHCCXSWnb9++pnPnzubhhx+2jbegUlD93nvvmWrVqtnvVCy33Xab/TypI6dHjx7m0UcftXVVEKiOqV+/vlmyZIkpWLCg+eWXX2J2Tjz11FO2s6tPnz72xlxNmzY1kydPzpFjBuLSakJATujTp0+oevXqoV27doUfa9myZah9+/a8If+zZcuWiLJYsGBBSF/bzz77jDLyWLFiRahatWqh2bNnhwoUKBB67rnnKJ//2bZtW6hSpUqhm266KcPj+M/9998fqly5ckRxDB06NFSqVKnAFtHff/9t/33yySdDZcqUyfD3lStX2u/a2LFjw49NmDAhlC9fvtDvv/8eyut27twZ2rp1q/1/165dQ61bt05af0vbtm1DHTp02C/HCPjFyAByzGeffWaHl9Wr4nTs2NE+ruFnGNuTG+t3Rgb+nz4r3bp1MzfddJNp2LAhH5sokyZNMqtXrzbXXnttxONFixalrP7n2GOPNRs2bDC//vqr/X3Pnj1m6tSpthc3qNSLnciXX35py6l9+/bhx1q3bm0KFy5s6/C8rlChQqZYsWIp1d/uMepvpBuCAeTofIGqVatGPKbft23bZtatW5djx5XO7r//fnPggQfalAb854EHHrD/9u7dmyKJ4eeffzalS5e2+c1Kf1Fut8pq5cqVlJenETt69Ghz/PHHm6OPPtpUr17dzs15++23KaME9bc+V94GrxrIFSpUsH9DRvPmzbOpV5qTAqQT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",
"text/plain": [
"<Figure size 640x480 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"\n",
"# 6. Evaluate strictly on the holdout Test Set\n",
"y_pred = model.predict(X_test)\n",
"y_proba = model.predict_proba(X_test)[:, 1]\n",
"\n",
"print(\"\\n--- Final Holdout Test Performance ---\")\n",
"print(f\"Test Set Accuracy: {accuracy_score(y_test, y_pred):.2%}\\n\")\n",
"print(\"Classification Report:\")\n",
"print(classification_report(y_test, y_pred))\n",
"threshold = y_train.mean()\n",
"y_pred_custom = (y_proba >= threshold).astype(int)\n",
"print(f\"classification_report with custom threshold ({threshold}):\")\n",
"print(classification_report(y_test, y_pred_custom))\n",
"\n",
"# 7. Feature Importance\n",
"xgb.plot_importance(model, importance_type=\"gain\")\n",
"plt.title(\"Feature Importance (Gain)\")\n",
"plt.show()"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "1e4b1067",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Min probability: 0.5154\n",
"Max probability: 0.6891\n",
"Mean probability: 0.5719\n",
"Median probability: 0.5641\n"
]
}
],
"source": [
"# 1. Inspect raw predicted probabilities for the test set\n",
"y_proba_test = model.predict_proba(X_test)[:, 1]\n",
"\n",
"print(f\"Min probability: {y_proba_test.min():.4f}\")\n",
"print(f\"Max probability: {y_proba_test.max():.4f}\")\n",
"print(f\"Mean probability: {y_proba_test.mean():.4f}\")\n",
"print(f\"Median probability: {np.median(y_proba_test):.4f}\")"
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "0f415ee9",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Successfully saved model to models/spy_xgb_v1.json\n"
]
}
],
"source": [
"import json\n",
"from pathlib import Path\n",
"\n",
"# 1. Create the 'models' directory if it doesn't exist\n",
"models_dir = Path(\"models\")\n",
"models_dir.mkdir(parents=True, exist_ok=True)\n",
"\n",
"# 2. Define paths\n",
"model_path = models_dir / \"spy_xgb_v1.json\"\n",
"meta_path = models_dir / \"spy_xgb_v1_meta.json\"\n",
"\n",
"# 3. Save XGBoost model (explicitly converted to str)\n",
"model.save_model(str(model_path))\n",
"\n",
"# 4. Save metadata alongside model\n",
"metadata = {\n",
" \"p_base\": float(y_train.mean()),\n",
" \"feature_cols\": feature_cols,\n",
" \"last_trained_date\": str(df[\"date\"].iloc[-1]),\n",
"}\n",
"\n",
"with open(meta_path, \"w\") as f:\n",
" json.dump(metadata, f, indent=2)\n",
"\n",
"print(f\"Successfully saved model to {model_path}\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "4d73c06a",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.15"
}
},
"nbformat": 4,
"nbformat_minor": 5
}